latest novapolis client for 1.5

--HG--
branch : novattd150
This commit is contained in:
Pavel Stupnikov
2015-03-16 03:20:50 +03:00
parent d201932121
commit e48d2d58e0
69 changed files with 3756 additions and 486 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="openttd"
ProjectGUID="{668328A0-B40E-4CDB-BD72-D0064424414A}"
RootNamespace="openttd"
@@ -15,6 +15,8 @@
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
@@ -53,7 +55,7 @@
FavorSizeOrSpeed="2"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;WITH_ASSERT"
StringPooling="true"
ExceptionHandling="1"
RuntimeLibrary="0"
@@ -88,7 +90,8 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib icuuc.lib icuin.lib icudt.lib icule.lib iculx.lib"
AdditionalOptions="/IGNORE:4099"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames=""
@@ -123,100 +126,6 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\objs\$(PlatformName)\$(ConfigurationName)\"
IntermediateDirectory="..\objs\$(PlatformName)\$(ConfigurationName)\"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/openttd.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
AssemblerListingLocation="$(IntDir)/"
ObjectFile="$(IntDir)/"
ProgramDataBaseFileName="$(IntDir)/$(TargetName).pdb"
WarningLevel="3"
WarnAsError="false"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
CallingConvention="1"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib icuuc.lib icuin.lib icudt.lib icule.lib iculx.lib"
LinkIncremental="0"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="LIBCMT.lib"
GenerateDebugInformation="true"
SubSystem="2"
StackReserveSize="1048576"
StackCommitSize="1048576"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="..\objs\$(PlatformName)\$(ConfigurationName)"
@@ -255,7 +164,7 @@
FavorSizeOrSpeed="2"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;_SQ64;WITH_ASSERT"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;_SQ64;WITH_ASSERT"
StringPooling="true"
ExceptionHandling="1"
RuntimeLibrary="0"
@@ -290,7 +199,8 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib icuuc.lib icuin.lib icudt.lib icule.lib iculx.lib"
AdditionalOptions="/IGNORE:4099"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames=""
@@ -320,7 +230,98 @@
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\objs\$(PlatformName)\$(ConfigurationName)\"
IntermediateDirectory="..\objs\$(PlatformName)\$(ConfigurationName)\"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/openttd.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
AssemblerListingLocation="$(IntDir)/"
ObjectFile="$(IntDir)/"
ProgramDataBaseFileName="$(IntDir)/$(TargetName).pdb"
WarningLevel="3"
WarnAsError="false"
SuppressStartupBanner="true"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
CallingConvention="1"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib"
LinkIncremental="0"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="LIBCMT.lib"
GenerateDebugInformation="true"
SubSystem="2"
StackReserveSize="1048576"
StackCommitSize="1048576"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
@@ -359,7 +360,7 @@
AdditionalOptions="/MP"
Optimization="0"
AdditionalIncludeDirectories="..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;WITH_ICU;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;_SQ64"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;LZMA_API_STATIC;WITH_PNG;WITH_FREETYPE;U_STATIC_IMPLEMENTATION;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR=\&quot;OpenTTD\&quot;;_SQ64"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
@@ -389,7 +390,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib icuuc.lib icuin.lib icudt.lib icule.lib iculx.lib"
AdditionalDependencies="winmm.lib ws2_32.lib imm32.lib libpng.lib zlibstat.lib lzo2.lib liblzma.lib libfreetype2.lib"
LinkIncremental="0"
SuppressStartupBanner="true"
IgnoreDefaultLibraryNames="LIBCMT.lib"
@@ -417,9 +418,6 @@
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
@@ -447,6 +445,10 @@
RelativePath=".\..\src\autoreplace.cpp"
>
</File>
<File
RelativePath=".\..\src\base_consist.cpp"
>
</File>
<File
RelativePath=".\..\src\bmp.cpp"
>
@@ -507,6 +509,10 @@
RelativePath=".\..\src\dedicated.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\demands.cpp"
>
</File>
<File
RelativePath=".\..\src\depot.cpp"
>
@@ -543,6 +549,10 @@
RelativePath=".\..\src\fios.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\flowmapper.cpp"
>
</File>
<File
RelativePath=".\..\src\fontcache.cpp"
>
@@ -551,10 +561,6 @@
RelativePath=".\..\src\fontdetection.cpp"
>
</File>
<File
RelativePath=".\..\src\base_consist.cpp"
>
</File>
<File
RelativePath=".\..\src\gamelog.cpp"
>
@@ -568,11 +574,11 @@
>
</File>
<File
RelativePath=".\..\src\gfxinit.cpp"
RelativePath=".\..\src\gfx_layout.cpp"
>
</File>
<File
RelativePath=".\..\src\gfx_layout.cpp"
RelativePath=".\..\src\gfxinit.cpp"
>
</File>
<File
@@ -607,14 +613,6 @@
RelativePath=".\..\src\landscape.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\demands.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\flowmapper.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\linkgraph.cpp"
>
@@ -627,18 +625,14 @@
RelativePath=".\..\src\linkgraph\linkgraphschedule.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\mcf.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\refresh.cpp"
>
</File>
<File
RelativePath=".\..\src\map.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\mcf.cpp"
>
</File>
<File
RelativePath=".\..\src\misc.cpp"
>
@@ -703,6 +697,10 @@
RelativePath=".\..\src\rail.cpp"
>
</File>
<File
RelativePath=".\..\src\linkgraph\refresh.cpp"
>
</File>
<File
RelativePath=".\..\src\rev.cpp"
>
@@ -751,6 +749,10 @@
RelativePath=".\..\src\station.cpp"
>
</File>
<File
RelativePath=".\..\src\story.cpp"
>
</File>
<File
RelativePath=".\..\src\strgen\strgen_base.cpp"
>
@@ -767,10 +769,6 @@
RelativePath=".\..\src\strings.cpp"
>
</File>
<File
RelativePath=".\..\src\story.cpp"
>
</File>
<File
RelativePath=".\..\src\subsidy.cpp"
>
@@ -867,6 +865,10 @@
RelativePath=".\..\src\autoslope.h"
>
</File>
<File
RelativePath=".\..\src\base_consist.h"
>
</File>
<File
RelativePath=".\..\src\base_media_base.h"
>
@@ -887,6 +889,10 @@
RelativePath=".\..\src\bridge.h"
>
</File>
<File
RelativePath="..\src\cargo_table_gui.h"
>
</File>
<File
RelativePath=".\..\src\cargo_type.h"
>
@@ -999,6 +1005,10 @@
RelativePath=".\..\src\video\dedicated_v.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\demands.h"
>
</File>
<File
RelativePath=".\..\src\depot_base.h"
>
@@ -1091,6 +1101,10 @@
RelativePath=".\..\src\fios.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\flowmapper.h"
>
</File>
<File
RelativePath=".\..\src\fontcache.h"
>
@@ -1099,10 +1113,6 @@
RelativePath=".\..\src\fontdetection.h"
>
</File>
<File
RelativePath=".\..\src\base_consist.h"
>
</File>
<File
RelativePath=".\..\src\gamelog.h"
>
@@ -1199,6 +1209,10 @@
RelativePath=".\..\src\ini_type.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\init.h"
>
</File>
<File
RelativePath=".\..\src\landscape.h"
>
@@ -1211,18 +1225,6 @@
RelativePath=".\..\src\language.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\demands.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\flowmapper.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\init.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\linkgraph.h"
>
@@ -1251,14 +1253,6 @@
RelativePath=".\..\src\linkgraph\linkgraphschedule.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\mcf.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\refresh.h"
>
</File>
<File
RelativePath=".\..\src\livery.h"
>
@@ -1271,6 +1265,10 @@
RelativePath=".\..\src\map_type.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\mcf.h"
>
</File>
<File
RelativePath=".\..\src\mixer.h"
>
@@ -1519,6 +1517,10 @@
RelativePath=".\..\src\rail_type.h"
>
</File>
<File
RelativePath=".\..\src\linkgraph\refresh.h"
>
</File>
<File
RelativePath=".\..\src\rev.h"
>
@@ -1859,6 +1861,10 @@
RelativePath=".\..\src\viewport_type.h"
>
</File>
<File
RelativePath="..\src\watch_gui.h"
>
</File>
<File
RelativePath=".\..\src\water.h"
>
@@ -1903,6 +1909,10 @@
RelativePath=".\..\src\window_type.h"
>
</File>
<File
RelativePath="..\src\zoning.h"
>
</File>
<File
RelativePath=".\..\src\zoom_func.h"
>
@@ -2055,10 +2065,18 @@
RelativePath=".\..\src\build_vehicle_gui.cpp"
>
</File>
<File
RelativePath="..\src\cargo_table_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\cheat_gui.cpp"
>
</File>
<File
RelativePath="..\src\commands_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\company_gui.cpp"
>
@@ -2255,20 +2273,28 @@
RelativePath=".\..\src\viewport_gui.cpp"
>
</File>
<File
RelativePath="..\src\watch_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\waypoint_gui.cpp"
>
</File>
<File
RelativePath="..\src\zoning_gui.cpp"
>
</File>
</Filter>
<Filter
Name="Widgets"
>
<File
RelativePath=".\..\src\widgets\airport_widget.h"
RelativePath=".\..\src\widgets\ai_widget.h"
>
</File>
<File
RelativePath=".\..\src\widgets\ai_widget.h"
RelativePath=".\..\src\widgets\airport_widget.h"
>
</File>
<File
@@ -2287,6 +2313,10 @@
RelativePath=".\..\src\widgets\build_vehicle_widget.h"
>
</File>
<File
RelativePath="..\src\widgets\cargo_table_widget.h"
>
</File>
<File
RelativePath=".\..\src\widgets\cheat_widget.h"
>
@@ -2599,6 +2629,10 @@
RelativePath=".\..\src\waypoint_cmd.cpp"
>
</File>
<File
RelativePath="..\src\zoning_cmd.cpp"
>
</File>
</Filter>
<Filter
Name="Save/Load handlers"
@@ -2744,11 +2778,11 @@
>
</File>
<File
RelativePath=".\..\src\saveload\strings_sl.cpp"
RelativePath=".\..\src\saveload\story_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\story_sl.cpp"
RelativePath=".\..\src\saveload\strings_sl.cpp"
>
</File>
<File
@@ -3468,11 +3502,11 @@
>
</File>
<File
RelativePath=".\..\src\script\api\script_storypagelist.hpp"
RelativePath=".\..\src\script\api\script_storypageelementlist.hpp"
>
</File>
<File
RelativePath=".\..\src\script\api\script_storypageelementlist.hpp"
RelativePath=".\..\src\script\api\script_storypagelist.hpp"
>
</File>
<File
@@ -3728,11 +3762,11 @@
>
</File>
<File
RelativePath=".\..\src\script\api\script_storypagelist.cpp"
RelativePath=".\..\src\script\api\script_storypageelementlist.cpp"
>
</File>
<File
RelativePath=".\..\src\script\api\script_storypageelementlist.cpp"
RelativePath=".\..\src\script\api\script_storypagelist.cpp"
>
</File>
<File
@@ -3839,14 +3873,6 @@
RelativePath=".\..\src\blitter\32bpp_simple.hpp"
>
</File>
<File
RelativePath=".\..\src\blitter\32bpp_sse_func.hpp"
>
</File>
<File
RelativePath=".\..\src\blitter\32bpp_sse_type.h"
>
</File>
<File
RelativePath=".\..\src\blitter\32bpp_sse2.cpp"
>
@@ -3863,6 +3889,14 @@
RelativePath=".\..\src\blitter\32bpp_sse4.hpp"
>
</File>
<File
RelativePath=".\..\src\blitter\32bpp_sse_func.hpp"
>
</File>
<File
RelativePath=".\..\src\blitter\32bpp_sse_type.h"
>
</File>
<File
RelativePath=".\..\src\blitter\32bpp_ssse3.cpp"
>

View File

@@ -143,6 +143,7 @@ base_media_func.h
base_station_base.h
bmp.h
bridge.h
cargo_table_gui.h
cargo_type.h
cargoaction.h
cargomonitor.h
@@ -386,6 +387,7 @@ vehiclelist.h
viewport_func.h
viewport_sprite_sorter.h
viewport_type.h
watch_gui.h
water.h
waypoint_base.h
waypoint_func.h
@@ -397,6 +399,7 @@ video/win32_v.h
window_func.h
window_gui.h
window_type.h
zoning.h
zoom_func.h
zoom_type.h
#if WIN32
@@ -452,7 +455,9 @@ autoreplace_gui.cpp
bootstrap_gui.cpp
bridge_gui.cpp
build_vehicle_gui.cpp
cargo_table_gui.cpp
cheat_gui.cpp
commands_gui.cpp
company_gui.cpp
console_gui.cpp
date_gui.cpp
@@ -501,8 +506,10 @@ train_gui.cpp
transparency_gui.cpp
tree_gui.cpp
vehicle_gui.cpp
watch_gui.cpp
viewport_gui.cpp
waypoint_gui.cpp
zoning_gui.cpp
# Widgets
widgets/airport_widget.h
@@ -511,6 +518,7 @@ widgets/autoreplace_widget.h
widgets/bootstrap_widget.h
widgets/bridge_widget.h
widgets/build_vehicle_widget.h
widgets/cargo_table_widget.h
widgets/cheat_widget.h
widgets/company_widget.h
widgets/console_widget.h
@@ -590,6 +598,7 @@ vehicle_cmd.cpp
void_cmd.cpp
water_cmd.cpp
waypoint_cmd.cpp
zoning_cmd.cpp
# Save/Load handlers
saveload/afterload.cpp

View File

@@ -24,6 +24,7 @@
#include "cmd_helper.h"
#include "tunnelbridge_map.h"
#include "road_gui.h"
#include "tilehighlight_func.h"
#include "widgets/bridge_widget.h"
@@ -72,6 +73,8 @@ void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uin
DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(p1));
ConnectRoadToStructure(p1, start_direction);
}
StoreRailPlacementEndpoints(p1, end_tile, (TileX(p1) == TileX(end_tile)) ? TRACK_Y : TRACK_X, false);
}
/** Window class for handling the bridge-build GUI. */

View File

@@ -34,7 +34,7 @@
#include "autoreplace_func.h"
#include "widgets/build_vehicle_widget.h"
#include "hotkeys.h"
#include "table/strings.h"
#include "safeguards.h"
@@ -1481,13 +1481,28 @@ struct BuildVehicleWindow : Window {
{
this->vscroll->SetCapacityFromWidget(this, WID_BV_LIST);
}
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
};
HotkeyList BuildVehicleWindow::hotkeys("build_vehicle", build_vehicle_hotkeys);
static WindowDesc _build_vehicle_desc(
WDP_AUTO, "build_vehicle", 240, 268,
WC_BUILD_VEHICLE, WC_NONE,
WDF_CONSTRUCTION,
_nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets)
_nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets),
&BuildVehicleWindow::hotkeys
);
void ShowBuildVehicleWindow(TileIndex tile, VehicleType type)

View File

@@ -26,6 +26,10 @@
#include "signal_func.h"
#include "core/backup_type.hpp"
#include "object_base.h"
#include "window_func.h"
#include "watch_gui.h"
#include "network/network_base.h"
#include "window_func.h"
#include "table/strings.h"
@@ -547,14 +551,19 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd)
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
{
/* Cost estimation is generally only done when the
* local user presses shift while doing somthing.
* However, in case of incoming network commands,
* map generation or the pause button we do want
* to execute. */
bool estimate_only = _shift_pressed && IsLocalCompany() &&
!_generating_world &&
!(cmd & CMD_NETWORK_COMMAND) &&
(cmd & CMD_ID_MASK) != CMD_PAUSE;
* local user presses shift while constructing somthing.
* However, in case of incoming network commands or
* map generation we do want to execute. */
bool estimate_only = false;
switch (_command_proc_table[cmd & CMD_ID_MASK].type) {
case CMDT_LANDSCAPE_CONSTRUCTION:
case CMDT_VEHICLE_CONSTRUCTION:
estimate_only = _shift_pressed && IsLocalCompany() &&
!_generating_world && !(cmd & CMD_NETWORK_COMMAND);
break;
default:
break; // just to silence warnings
}
/* We're only sending the command, so don't do
* fancy things for 'success'. */
@@ -756,6 +765,23 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
if (c != NULL) c->last_build_coordinate = tile;
}
/* Send Tile Number to Watching Company Windows */
WatchCompany *wc;
for(int watching_window = 0; ; watching_window++){
wc = dynamic_cast<WatchCompany*>(FindWindowById(WC_WATCH_COMPANY, watching_window));
if(wc != NULL) wc->OnDoCommand(_current_company, tile);
else break;
}
NetworkClientInfo *ci;
FOR_ALL_CLIENT_INFOS(ci) {
if (ci->client_playas == _current_company) {
wc = dynamic_cast<WatchCompany*>(FindWindowById(WC_WATCH_COMPANYA, ci->client_id));
if (wc != NULL) wc->OnDoCommand(_current_company, tile);
break;
}
}
SubtractMoneyFromCompany(res2);
/* update signals if needed */

View File

@@ -17,6 +17,7 @@
#include "autoreplace_type.h"
#include "tile_type.h"
#include "settings_type.h"
#include "cargo_type.h"
#include "group.h"
/** Statistics about the economy. */
@@ -26,6 +27,7 @@ struct CompanyEconomyEntry {
CargoArray delivered_cargo; ///< The amount of delivered cargo.
int32 performance_history; ///< Company score (scale 0-1000)
Money company_value; ///< The value of the company.
Money cargo_income[NUM_CARGO]; ///< Cargo income from each cargo type
};
struct CompanyInfrastructure {
@@ -124,6 +126,12 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
CompanyInfrastructure infrastructure; ///< NOSAVE: Counts of company owned infrastructure.
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
/**
* Is this company a valid company, controlled by the computer (a NoAI program)?
* @param index Index in the pool.

View File

@@ -38,6 +38,7 @@
#include "story_base.h"
#include "table/strings.h"
#include "cargo_type.h"
#include "safeguards.h"
@@ -69,6 +70,8 @@ Company::Company(uint16 name_1, bool is_ai)
for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY);
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
}
/** Destructor. */
@@ -91,6 +94,8 @@ void Company::PostDestructor(size_t index)
InvalidateWindowData(WC_LINKGRAPH_LEGEND, 0);
/* If the currently shown error message has this company in it, then close it. */
InvalidateWindowData(WC_ERRMSG, 0);
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
}
/**
@@ -576,9 +581,23 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
Game::NewEvent(new ScriptEventCompanyNew(c->index));
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);
return c;
}
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]));
}
/** Start the next competitor now. */
void StartupCompanies()
{
@@ -1081,6 +1100,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
free(c->name);
c->name = reset ? NULL : stredup(text);
MarkWholeScreenDirty();
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
CompanyAdminUpdate(c);
}

View File

@@ -31,6 +31,7 @@ void SubtractMoneyFromCompany(CommandCost cost);
void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cost);
CommandCost CheckOwnership(Owner owner, TileIndex tile = 0);
CommandCost CheckTileOwnership(TileIndex tile);
void CargoResetPeriods(Company *c);
extern CompanyByte _local_company;
extern CompanyByte _current_company;

View File

@@ -1917,6 +1917,9 @@ static const NWidgetPart _nested_company_widgets[] = {
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_C_RELOCATE_HQ), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_RELOCATE_HQ, STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS),
NWidget(NWID_SPACER), SetMinimalSize(90, 0),
EndContainer(),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_RESET), SetFill(1, 0), SetDataTip(STR_XI_RESET2, STR_XI_RESET),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_SUSPEND), SetFill(1, 0), SetDataTip(STR_XI_SUSPEND2, STR_XI_SUSPEND),
NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_RESUME), SetFill(1, 0), SetDataTip(STR_XI_RESUME2, STR_XI_RESUME),
NWidget(NWID_SPACER), SetFill(0, 1),
EndContainer(),
EndContainer(),
@@ -1950,6 +1953,7 @@ static const NWidgetPart _nested_company_widgets[] = {
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_PASSWORD), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_PASSWORD, STR_COMPANY_VIEW_PASSWORD_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_JOIN), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP),
EndContainer(),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_JOIN2), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP),
EndContainer(),
EndContainer(),
EndContainer(),
@@ -1987,6 +1991,16 @@ static const StringID _company_view_vehicle_count_strings[] = {
/**
* Window with general information about a company
*/
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);
}
}
struct CompanyWindow : Window
{
CompanyWidgets query_widget;
@@ -2083,6 +2097,13 @@ struct CompanyWindow : Window
}
}
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);
}
this->DrawWidgets();
}
@@ -2139,6 +2160,15 @@ struct CompanyWindow : Window
break;
}
case CW_WIDGET_COMPANY_RESUME:
case CW_WIDGET_COMPANY_SUSPEND:
case CW_WIDGET_COMPANY_RESET:
case CW_WIDGET_COMPANY_JOIN2:
if(!_networking || !_novarole){
size->width = 0;
size->height = 0;
}
break;
#ifdef ENABLE_NETWORK
case WID_C_HAS_PASSWORD:
*size = maxdim(*size, GetSpriteSize(SPR_LOCK));
@@ -2365,6 +2395,44 @@ struct CompanyWindow : Window
/* just send the join command */
NetworkClientRequestMove(company);
}
MarkWholeScreenDirty();
break;
}
case CW_WIDGET_COMPANY_JOIN2:{
CompanyID company2 = (CompanyID)this->window_number;
this->query_widget = CW_WIDGET_COMPANY_JOIN2;
char msg[128];
seprintf(msg, lastof(msg), "!move %i", company2 + 1);
NetworkClientSendChatToServer(msg);
MarkWholeScreenDirty();
break;
}
case CW_WIDGET_COMPANY_RESET:{
if (!_networking) return;
this->query_widget = CW_WIDGET_COMPANY_RESET;
ShowQuery(STR_XI_RESET_CAPTION, STR_XI_REALY_RESET, this, ResetCallback);
MarkWholeScreenDirty();
break;
}
case CW_WIDGET_COMPANY_SUSPEND:{
if (!_networking) return;
this->query_widget = CW_WIDGET_COMPANY_SUSPEND;
CompanyID company2 = (CompanyID)this->window_number;
char msg[128];
seprintf(msg, lastof(msg), "!lockp %i", company2 + 1);
NetworkClientSendChatToServer(msg);
MarkWholeScreenDirty();
break;
}
case CW_WIDGET_COMPANY_RESUME:{
if (!_networking) return;
this->query_widget = CW_WIDGET_COMPANY_RESUME;
CompanyID company2 = (CompanyID)this->window_number;
char msg[128];
seprintf(msg, lastof(msg), "!lockp %i", company2 + 1);
NetworkClientSendChatToServer(msg);
MarkWholeScreenDirty();
break;
}
#endif /* ENABLE_NETWORK */

View File

@@ -87,7 +87,7 @@ char *CrashLog::LogCompiler(char *buffer, const char *last) const
char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const
{
return buffer + seprintf(buffer, last,
"OpenTTD version:\n"
"OpenTTD version: Novapolis patched client http://www.novapolis.net\n\n\n"
" Version: %s (%d)\n"
" NewGRF ver: %08x\n"
" Bits: %d\n"
@@ -313,7 +313,7 @@ char *CrashLog::LogGamelog(char *buffer, const char *last) const
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
{
time_t cur_time = time(NULL);
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\nNovapolis patched client http://www.novapolis.net\nPlease, unless you encounter this bug with unpatched OpenTTD version, report bug to Novapolis team\n\n");
buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time)));
YearMonthDay ymd;

View File

@@ -28,7 +28,7 @@
#include "vehiclelist.h"
#include "order_backup.h"
#include "zoom_func.h"
#include "hotkeys.h"
#include "widgets/depot_widget.h"
#include "table/strings.h"
@@ -81,34 +81,6 @@ static const NWidgetPart _nested_train_depot_widgets[] = {
EndContainer(),
};
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)
);
extern void DepotSortList(VehicleList *list);
/**
@@ -295,9 +267,16 @@ struct DepotWindow : Window {
this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
/* Length of consist in tiles with 1 fractional digit (rounded up) */
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
}
break;
}
@@ -995,8 +974,24 @@ struct DepotWindow : Window {
return ES_NOT_HANDLED;
}
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
};
HotkeyList DepotWindow::hotkeys("depot_gui", depot_hotkeys);
static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
{
if (confirmed) {
@@ -1007,6 +1002,38 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
}
}
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
);
/**
* Opens a depot window
* @param tile The tile where the depot/hangar is located

View File

@@ -53,6 +53,7 @@
#include "table/strings.h"
#include "table/pricebase.h"
#include "cargo_table_gui.h"
#include "safeguards.h"
@@ -386,6 +387,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
/* Reset the ratings for the old owner */
t->ratings[old_owner] = RATING_INITIAL;
ClrBit(t->have_ratings, old_owner);
ClrBit(t->fund_regularly, old_owner);
/* Transfer exclusive rights */
if (t->exclusive_counter > 0 && t->exclusivity == old_owner) {
@@ -1081,6 +1083,14 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti
const CargoSpec *cs = CargoSpec::Get(cargo_type);
st->town->received[cs->town_effect].new_act += accepted;
/* 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;
InvalidateWindowData(WC_CB_TOWN, st->town->index);
}
}
/* Determine profit */
Money profit = GetTransportedGoodsIncome(accepted, DistanceManhattan(source_tile, st->xy), days_in_transit, cargo_type);
@@ -1097,6 +1107,16 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti
}
}
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);
return profit;
}
@@ -1923,6 +1943,11 @@ void CompaniesMonthlyLoop()
}
CompaniesPayInterest();
HandleEconomyFluctuations();
Company *c;
FOR_ALL_COMPANIES(c){
CargoResetPeriods(c);
}
}
static void DoAcquireCompany(Company *c)

View File

@@ -33,6 +33,7 @@ bool _fullscreen;
byte _support8bpp;
CursorVars _cursor;
bool _ctrl_pressed; ///< Is Ctrl pressed?
bool _alt_pressed; ///< Is Alt pressed?
bool _shift_pressed; ///< Is Shift pressed?
byte _fast_forward;
bool _left_button_down; ///< Is left mouse button pressed?

View File

@@ -55,6 +55,7 @@ extern bool _fullscreen;
extern byte _support8bpp;
extern CursorVars _cursor;
extern bool _ctrl_pressed; ///< Is Ctrl pressed?
extern bool _alt_pressed; ///< Is Alt pressed?
extern bool _shift_pressed; ///< Is Shift pressed?
extern byte _fast_forward;

View File

@@ -104,6 +104,16 @@ enum WindowKeyCodes {
WKC_COMMA = 151, ///< , Comma
WKC_PERIOD = 152, ///< . Period
WKC_MINUS = 153, ///< - Minus
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
};
/** A single sprite of a list of animated cursors */

View File

@@ -192,6 +192,7 @@ static void LoadSpriteTables()
i++
);
}
LoadGrfFile("innerhighlight.grf", SPR_INNER_HIGHLIGHT_BASE, i++);
/* Initialize the unicode to sprite mapping table */
InitializeUnicodeGlyphMap();

View File

@@ -184,7 +184,15 @@ struct GoalListWindow : public Window {
resize->height = d.height;
d.height *= 5;
uint num = 0;
const Goal *s;
FOR_ALL_GOALS(s) {
if (s->company == INVALID_COMPANY || s->company == this->window_number) {
num++;
}
}
d.height *= (5 + num);
d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
*size = maxdim(*size, d);

View File

@@ -103,6 +103,23 @@ struct GraphLegendWindow : Window {
}
};
/** Construct the row containing the digit keys. */
static NWidgetBase *MakeCargoButtons(int *biggest_index)
{
NWidgetVertical *ver = new NWidgetVertical;
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
NWidgetBackground *leaf = new NWidgetBackground(WWT_PANEL, COLOUR_ORANGE, WID_CPR_CARGO_FIRST + i, NULL);
leaf->tool_tip = STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO;
leaf->SetFill(1, 0);
leaf->SetLowered(true);
ver->Add(leaf);
}
*biggest_index = WID_CPR_CARGO_FIRST + _sorted_standard_cargo_specs_size - 1;
return ver;
}
/**
* Construct a vertical list of buttons, one for each company.
* @param biggest_index Storage for collecting the biggest index used in the returned tree.
@@ -533,10 +550,64 @@ public:
return INVALID_DATAPOINT;
}
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 UpdateLoweredWidgets()
{
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
this->SetWidgetLoweredState(WID_CPR_CARGO_FIRST + i, !HasBit(this->excluded_data, i));
}
}
virtual void OnClick(Point pt, int widget, int click_count)
{
switch (widget) {
/* Clicked on legend? */
if (widget == WID_CV_KEY_BUTTON) ShowGraphLegend();
case WID_CV_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->UpdateLoweredWidgets();
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->UpdateLoweredWidgets();
this->SetDirty();
break;
}
default:
if (widget >= WID_CPR_CARGO_FIRST) {
int i = widget - WID_CPR_CARGO_FIRST;
ToggleBit(_legend_excluded_cargo, _sorted_cargo_specs[i]->Index());
this->ToggleWidgetLoweredState(widget);
this->UpdateExcludedData();
this->SetDirty();
}
break;
}
}
virtual void OnTick()
@@ -674,8 +745,60 @@ struct IncomeGraphWindow : BaseGraphWindow {
virtual OverflowSafeInt64 GetGraphData(const Company *c, int j)
{
if(_legend_excluded_cargo == 0){
return c->old_economy[j].income;
}
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;
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget < WID_CPR_CARGO_FIRST) {
BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
return;
}
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
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);
}
virtual void DrawWidget(const Rect &r, int widget) const
{
if (widget < WID_CPR_CARGO_FIRST) {
BaseGraphWindow::DrawWidget(r, widget);
return;
}
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
bool rtl = _current_text_dir == TD_RTL;
/* Since the buttons have no text, no images,
* both the text and the coloured box have to be manually painted.
* clk_dif will move one pixel down and one pixel to the right
* when the button is clicked */
byte clk_dif = this->IsWidgetLowered(widget) ? 1 : 0;
int x = r.left + WD_FRAMERECT_LEFT;
int y = r.top;
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);
}
};
static const NWidgetPart _nested_income_graph_widgets[] = {
@@ -690,6 +813,14 @@ static const NWidgetPart _nested_income_graph_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_CV_BACKGROUND),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),//add
NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 0), SetResize(0, 1),
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),
NWidgetFunction(MakeCargoButtons),
NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1), SetResize(0, 1),
EndContainer(),//add
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
@@ -723,8 +854,60 @@ struct DeliveredCargoGraphWindow : BaseGraphWindow {
virtual OverflowSafeInt64 GetGraphData(const Company *c, int j)
{
if(_legend_excluded_cargo == 0){
return c->old_economy[j].delivered_cargo.GetSum<OverflowSafeInt64>();
}
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;
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget < WID_CPR_CARGO_FIRST) {
BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize);
return;
}
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
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);
}
virtual void DrawWidget(const Rect &r, int widget) const
{
if (widget < WID_CPR_CARGO_FIRST) {
BaseGraphWindow::DrawWidget(r, widget);
return;
}
const CargoSpec *cs = _sorted_cargo_specs[widget - WID_CPR_CARGO_FIRST];
bool rtl = _current_text_dir == TD_RTL;
/* Since the buttons have no text, no images,
* both the text and the coloured box have to be manually painted.
* clk_dif will move one pixel down and one pixel to the right
* when the button is clicked */
byte clk_dif = this->IsWidgetLowered(widget) ? 1 : 0;
int x = r.left + WD_FRAMERECT_LEFT;
int y = r.top;
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);
}
};
static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
@@ -739,6 +922,15 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_CV_BACKGROUND),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CV_GRAPH), SetMinimalSize(576, 128), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_VERTICAL),//add
NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 0), SetResize(0, 1),
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),
NWidgetFunction(MakeCargoButtons),
NWidget(NWID_SPACER), SetMinimalSize(0, 24), SetFill(0, 1), SetResize(0, 1),
EndContainer(),//add
NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetFill(0, 1), SetResize(0, 1),
NWidget(WWT_RESIZEBOX, COLOUR_GREY, WID_CV_RESIZE),
@@ -899,7 +1091,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
}
this->first_init = false;
}
/*
void UpdateExcludedData()
{
this->excluded_data = 0;
@@ -918,7 +1110,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
this->SetWidgetLoweredState(WID_CPR_CARGO_FIRST + i, !HasBit(this->excluded_data, i));
}
}
*/
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
if (widget < WID_CPR_CARGO_FIRST) {
@@ -960,12 +1152,12 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
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);
}
/*
virtual void OnClick(Point pt, int widget, int click_count)
{
switch (widget) {
case WID_CPR_ENABLE_CARGOES:
/* Remove all cargoes from the excluded lists. */
/* Remove all cargoes from the excluded lists. * /
_legend_excluded_cargo = 0;
this->excluded_data = 0;
this->UpdateLoweredWidgets();
@@ -973,7 +1165,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
break;
case WID_CPR_DISABLE_CARGOES: {
/* Add all cargoes to the excluded lists. */
/* Add all cargoes to the excluded lists. * /
int i = 0;
const CargoSpec *cs;
FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
@@ -997,7 +1189,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
break;
}
}
*/
virtual void OnTick()
{
/* Override default OnTick */
@@ -1031,23 +1223,6 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
}
};
/** Construct the row containing the digit keys. */
static NWidgetBase *MakeCargoButtons(int *biggest_index)
{
NWidgetVertical *ver = new NWidgetVertical;
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
NWidgetBackground *leaf = new NWidgetBackground(WWT_PANEL, COLOUR_ORANGE, WID_CPR_CARGO_FIRST + i, NULL);
leaf->tool_tip = STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO;
leaf->SetFill(1, 0);
leaf->SetLowered(true);
ver->Add(leaf);
}
*biggest_index = WID_CPR_CARGO_FIRST + _sorted_standard_cargo_specs_size - 1;
return ver;
}
static const NWidgetPart _nested_cargo_payment_rates_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
@@ -1582,3 +1757,4 @@ void ShowPerformanceRatingDetail()
{
AllocateWindowDescFront<PerformanceRatingDetailWindow>(&_performance_rating_detail_desc, 0);
}

View File

@@ -39,6 +39,10 @@ Window *ShowBuildDocksScenToolbar();
/* airport_gui.cpp */
Window *ShowBuildAirToolbar();
/* commands_gui.cpp */
void ShowCommandsToolbar();
void ShowLoginWindow();
/* tgp_gui.cpp */
void ShowGenerateLandscape();
void ShowHeightmapLoad();

View File

@@ -61,6 +61,22 @@ static const KeycodeNames _keycode_to_name[] = {
{"NUM_MINUS", WKC_NUM_MINUS},
{"=", WKC_EQUALS},
{"-", WKC_MINUS},
{"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},
};
/**

View File

@@ -30,6 +30,7 @@
#include "tilehighlight_func.h"
#include "string_func.h"
#include "sortlist_type.h"
#include "widgets/dropdown_type.h"
#include "widgets/dropdown_func.h"
#include "company_base.h"
#include "core/geometry_func.hpp"
@@ -41,6 +42,7 @@
#include "widgets/industry_widget.h"
#include "table/strings.h"
#include "hotkeys.h"
#include "safeguards.h"
@@ -188,14 +190,6 @@ static const NWidgetPart _nested_build_industry_widgets[] = {
EndContainer(),
};
/** 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)
);
/** Build (fund or prospect) a new industry, */
class BuildIndustryWindow : public Window {
int selected_index; ///< index of the element in the matrix
@@ -267,7 +261,7 @@ class BuildIndustryWindow : public Window {
}
public:
BuildIndustryWindow() : Window(&_build_industry_desc)
BuildIndustryWindow(WindowDesc *desc) : Window(desc)
{
this->timer_enabled = _loaded_newgrf_features.has_newindustries;
@@ -625,13 +619,38 @@ public:
if (indsp == NULL) this->enabled[this->selected_index] = _settings_game.difficulty.industry_density != ID_FUND_ONLY;
this->SetButtons();
}
virtual EventState OnHotkey(int hotkey)
{
return Window::OnHotkey(hotkey);
}
static HotkeyList hotkeys;
};
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
);
void ShowBuildIndustryWindow()
{
if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
if (BringWindowToFrontById(WC_BUILD_INDUSTRY, 0)) return;
new BuildIndustryWindow();
new BuildIndustryWindow(&_build_industry_desc);
}
static void UpdateIndustryProduction(Industry *i);
@@ -1059,6 +1078,7 @@ static const NWidgetPart _nested_industry_directory_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_FILTER), SetDataTip(STR_BUTTON_FILTER, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_SCROLLBAR), EndContainer(),
@@ -1086,6 +1106,10 @@ protected:
static const StringID sorter_names[];
static GUIIndustryList::SortFunction * const sorter_funcs[];
/* type_filter[industry_type] is set to true if player wishes that type to by displayed */
static bool type_filter[NUM_INDUSTRYTYPES];
static bool initialized;
GUIIndustryList industries;
Scrollbar *vscroll;
@@ -1097,7 +1121,9 @@ protected:
const Industry *i;
FOR_ALL_INDUSTRIES(i) {
*this->industries.Append() = i;
if (this->type_filter[i->type]){
*this->industries.Append() = i;
}
}
this->industries.Compact();
@@ -1229,9 +1255,17 @@ protected:
}
}
void initIndustryTypeFilter()
{
for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt)
this->type_filter[indt] = true;
IndustryDirectoryWindow::initialized = true;
}
public:
IndustryDirectoryWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
{
if (IndustryDirectoryWindow::initialized == false) this->initIndustryTypeFilter();
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_ID_SCROLLBAR);
@@ -1300,6 +1334,11 @@ public:
break;
}
case WID_ID_DROPDOWN_FILTER: {
size->width = 65;
break;
}
case WID_ID_INDUSTRY_LIST: {
Dimension d = GetStringBoundingBox(STR_INDUSTRY_DIRECTORY_NONE);
for (uint i = 0; i < this->industries.Length(); i++) {
@@ -1328,6 +1367,22 @@ public:
ShowDropDownMenu(this, IndustryDirectoryWindow::sorter_names, this->industries.SortType(), WID_ID_DROPDOWN_CRITERIA, 0, 0);
break;
case WID_ID_DROPDOWN_FILTER: {
DropDownList *list = new DropDownList();
*list->Append() = new DropDownListStringItem(STR_BUTTON_FILTER_SELECT_ALL, -2, false);
*list->Append() = new DropDownListStringItem(STR_BUTTON_FILTER_SELECT_NONE, -1, false);
*list->Append() = new DropDownListItem(-3, false);
for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt) {
const IndustrySpec *inds = GetIndustrySpec(indt);
if (inds->enabled)
*list->Append() = new DropDownListCheckedItem(inds->name, indt, false, IndustryDirectoryWindow::type_filter[indt]);
}
ShowDropDownList(this, list, -2, WID_ID_DROPDOWN_FILTER, 0, true, false);
break;
}
case WID_ID_INDUSTRY_LIST: {
uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WD_FRAMERECT_TOP);
if (p < this->industries.Length()) {
@@ -1344,10 +1399,27 @@ public:
virtual void OnDropdownSelect(int widget, int index)
{
if (this->industries.SortType() != index) {
this->industries.SetSortType(index);
this->BuildSortIndustriesList();
if (widget == WID_ID_DROPDOWN_CRITERIA) {
if (this->industries.SortType() != index) {
this->industries.SetSortType(index);
}
}
else if (widget == WID_ID_DROPDOWN_FILTER) {
if ( index == -1 ) { // aka SELECT NONE
for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt)
IndustryDirectoryWindow::type_filter[indt] = false;
// must SetDurty to force redraw of the listing widget
this->SetDirty();
}
else if ( index == -2 ) { // aka SELECT ALL
for (IndustryType indt = 0; indt < NUM_INDUSTRYTYPES; ++indt)
IndustryDirectoryWindow::type_filter[indt] = true;
}
else
IndustryDirectoryWindow::type_filter[index] = IndustryDirectoryWindow::type_filter[index] ? false: true;
this->industries.ForceRebuild();
}
this->BuildSortIndustriesList();
}
virtual void OnResize()
@@ -1385,6 +1457,8 @@ public:
Listing IndustryDirectoryWindow::last_sorting = {false, 0};
const Industry *IndustryDirectoryWindow::last_industry = NULL;
bool IndustryDirectoryWindow::initialized = false;
bool IndustryDirectoryWindow::type_filter[NUM_INDUSTRYTYPES];
/* Available station sorting functions. */
GUIIndustryList::SortFunction * const IndustryDirectoryWindow::sorter_funcs[] = {

View File

@@ -232,6 +232,9 @@ STR_TOOLTIP_GROUP_ORDER :{BLACK}Select g
STR_TOOLTIP_SORT_ORDER :{BLACK}Select sorting order (descending/ascending)
STR_TOOLTIP_SORT_CRITERIA :{BLACK}Select sorting criteria
STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Select filtering criteria
STR_BUTTON_FILTER :{BLACK}Filter
STR_BUTTON_FILTER_SELECT_ALL :Select All
STR_BUTTON_FILTER_SELECT_NONE :Select None
STR_BUTTON_SORT_BY :{BLACK}Sort by
STR_BUTTON_LOCATION :{BLACK}Location
STR_BUTTON_RENAME :{BLACK}Rename
@@ -322,9 +325,11 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Display
STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Display subsidies
STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Display list of company's stations
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Display company finances information
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_CARGOS :{BLACK}Display company cargos information
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Display general company information
STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Display story book
STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Display goal list
STR_TOOLBAR_TOOLTIP_DISPLAY_WATCH :{BLACK}Watch company's actions
STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Display graphs
STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Display company league table
STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Fund construction of new industry or list all industries
@@ -376,6 +381,7 @@ STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Settings
STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Game script settings
STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF settings
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparency options
STR_SETTINGS_MENU_ZONING :Zoning
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Town names displayed
STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Station names displayed
STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Waypoint names displayed
@@ -400,6 +406,7 @@ STR_MAP_MENU_MAP_OF_WORLD :Map of world
STR_MAP_MENU_EXTRA_VIEW_PORT :Extra viewport
STR_MAP_MENU_LINGRAPH_LEGEND :Cargo Flow Legend
STR_MAP_MENU_SIGN_LIST :Sign list
STR_MAP_MENU_WATCH_COMPANY :Watch Company
############ range for town menu starts
STR_TOWN_MENU_TOWN_DIRECTORY :Town directory
@@ -468,7 +475,7 @@ STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Message history
############ range for about menu starts
STR_ABOUT_MENU_LAND_BLOCK_INFO :Land area information
STR_ABOUT_MENU_SEPARATOR :
STR_ABOUT_MENU_SEPARATOR :Novapolis
STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console
STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug
STR_ABOUT_MENU_SCREENSHOT :Screenshot
@@ -479,6 +486,7 @@ STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD'
STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes
STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Toggle colouring of dirty blocks
STR_ABOUT_MENU_LOGIN_WINDOW :Login Window
############ range ends here
############ range for ordinal numbers used for the place in the highscore window
@@ -1707,6 +1715,26 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Allow trains to
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change setting value
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
# Config errors
STR_CONFIG_ERROR :{WHITE}Error with the configuration file...
STR_CONFIG_ERROR_ARRAY :{WHITE}... error in array '{RAW_STRING}'
@@ -2316,6 +2344,7 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Maglev Construc
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Build railway track using the Autorail mode. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate
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
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for buying and servicing trains). Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Convert rail to waypoint. Ctrl enables joining waypoints. Shift toggles building/showing cost estimate
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Build railway station. Ctrl enables joining stations. Shift toggles building/showing cost estimate
@@ -2333,6 +2362,7 @@ STR_RAIL_NAME_MAGLEV :Maglev
# Rail depot construction window
STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Train Depot Orientation
STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Select railway depot orientation
STR_BUILD_DEPOT_TRAIN_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select railway depot orientation based on environment
# Rail waypoint construction window
STR_WAYPOINT_CAPTION :{WHITE}Waypoint
@@ -2341,6 +2371,8 @@ STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Select w
# Rail station construction window
STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Rail Station Selection
STR_STATION_BUILD_ORIENTATION :{BLACK}Orientation
STR_STATION_BUILD_ORIENTATION_AUTO :{BLACK}Auto
STR_STATION_BUILD_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select station orientation based on environment
STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Select railway station orientation
STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Number of tracks
STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Select number of platforms for railway station
@@ -2396,6 +2428,7 @@ STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramway
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build road section. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_FULLROAD :{BLACK}Build road section using the Autoroad mode with only full tile roads. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate
@@ -2416,6 +2449,7 @@ STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Road Dep
STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Select road vehicle depot orientation
STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Tram Depot Orientation
STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Select tram vehicle depot orientation
STR_BUILD_DEPOT_ROAD_ORIENTATION_AUTO_TOOLTIP :{BLACK}Automatically select road depot orientation based on environment
# Road vehicle station construction window
STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Bus Station Orientation
@@ -4879,10 +4913,18 @@ STR_SAVEGAME_NAME_DEFAULT :{COMPANY}, {STR
STR_SAVEGAME_NAME_SPECTATOR :Spectator, {1:STRING1}
# Viewport strings
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})
STR_VIEWPORT_TOWN_POP :{WHITE}{TOWN} ({COMMA})
STR_VIEWPORT_TOWN_POP_EXCELLENT_RATING :{WHITE}{TOWN} {GREEN}({COMMA})
STR_VIEWPORT_TOWN :{WHITE}{TOWN}
STR_VIEWPORT_TOWN_TINY_BLACK :{TINY_FONT}{BLACK}{TOWN}
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}
STR_VIEWPORT_TOWN_TINY_WHITE :{TINY_FONT}{WHITE}{TOWN}
STR_VIEWPORT_TOWN_TINY_EXCELLENT_RATING :{TINY_FONT}{GREEN}{TOWN}
STR_VIEWPORT_SIGN_SMALL_BLACK :{TINY_FONT}{BLACK}{SIGN}
STR_VIEWPORT_SIGN_SMALL_WHITE :{TINY_FONT}{WHITE}{SIGN}
@@ -4968,3 +5010,247 @@ STR_PLANE :{BLACK}{PLANE}
STR_SHIP :{BLACK}{SHIP}
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
### 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} {BLACK}Next: {ORANGE}{COMMA} {BLACK}RH: {ORANGE}{COMMA} {BLACK}Flag {ORANGE}{NUM} {BLACK}FB: {ORANGE}{NUM} {BLACK}month{P "" s}
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}UR: {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_RESET2 :{BLACK}Reset
STR_XI_WATCH :Watch
STR_XI_SUSPEND :{BLACK}Suspend
STR_XI_SUSPEND2 :{BLACK}Suspend
STR_XI_RESUME :{BLACK}Resume
STR_XI_RESUME2 :{BLACK}Resume
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}<days> <reason>
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_ADVERTISEMENT_ZONES :{BLACK}Advertisement
STR_ZONING_TOWN_GROWTH_TILES :{BLACK}Town growth tiles
# 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}NS{NUM}
STR_TOOLBAR_COMMANDS_NS_TOOLTIP :{BLACK}Join NS{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}<Name> <password>
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_NOVAPOLIS :{BLACK}Novapolis
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})
STR_TOWN_DIRECTORY_CITY_COLOUR :{YELLOW}{TOWN}{BLACK} ({COMMA})
STR_OLD_DEPOT_TRAINT_LENGTH :Old depot length format: {STRING2}
STR_SMALLMAP_TOWN_LARGE :{TINY_FONT}{YELLOW}{TOWN}
STR_ORDER_DIST :{NUM}, {NUM}
#server list
STR_NETWORK_SELECT_NOVA :{BLACK}Novapolis
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_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}

View File

@@ -107,7 +107,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
w->SetDirty();
if (w->IsWidgetLowered(widget)) {
if (w->IsWidgetLowered(widget) && mode == _thd.place_mode) {
ResetObjectToPlace();
return false;
}
@@ -227,6 +227,7 @@ enum {
GHK_TOGGLE_INVISIBILITY = GHK_TOGGLE_TRANSPARENCY + 9,
GHK_TRANSPARENCY_TOOLBAR = GHK_TOGGLE_INVISIBILITY + 8,
GHK_TRANSPARANCY,
GHK_BORROW_ALL,
GHK_CHAT,
GHK_CHAT_ALL,
GHK_CHAT_COMPANY,
@@ -393,6 +394,10 @@ struct MainWindow : Window
ResetRestoreAllTransparency();
break;
case GHK_BORROW_ALL:
DoCommandP(0, 0, 1, CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY));
break;
#ifdef ENABLE_NETWORK
case GHK_CHAT: // smart chat; send to team if any, otherwise to all
if (_networking) {
@@ -465,6 +470,11 @@ struct MainWindow : Window
InvalidateWindowData(WC_MAIN_TOOLBAR, 0, data, true);
}
virtual void OnMouseOver(Point pt, int widget)
{
if (_game_mode != GM_MENU && _settings_client.gui.enable_extra_tooltips && pt.x != -1) GuiPrepareTooltipsExtra(this);
}
static HotkeyList hotkeys;
};
@@ -511,6 +521,7 @@ static Hotkey global_hotkeys[] = {
Hotkey('8' | WKC_CTRL | WKC_SHIFT, "invisibility_catenary", GHK_TOGGLE_INVISIBILITY + 7),
Hotkey('X' | WKC_CTRL, "transparency_toolbar", GHK_TRANSPARENCY_TOOLBAR),
Hotkey('X', "toggle_transparency", GHK_TRANSPARANCY),
Hotkey(WKC_NONE, "borrow_all", GHK_BORROW_ALL),
#ifdef ENABLE_NETWORK
Hotkey(_ghk_chat_keys, "chat", GHK_CHAT),
Hotkey(_ghk_chat_all_keys, "chat_all", GHK_CHAT_ALL),

View File

@@ -110,6 +110,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
InitializeEconomy();
ResetObjectToPlace();
ClearRailPlacementEndpoints();
GamelogReset();
GamelogStartAction(GLAT_START);

View File

@@ -33,6 +33,14 @@
#include "safeguards.h"
#include "house.h"
#include "town_map.h"
#include "station_base.h"
#include "viewport_func.h"
#include "industry.h"
void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip);
/** Method to open the OSK. */
enum OskActivation {
OSKA_DISABLED, ///< The OSK shall not be activated at all.
@@ -164,6 +172,7 @@ public:
td.airport_tile_name = STR_NULL;
td.rail_speed = 0;
td.road_speed = 0;
td.population = 0;
td.grf = NULL;
@@ -293,6 +302,13 @@ public:
line_nr++;
}
/* 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++;
}
assert(line_nr < LAND_INFO_CENTERED_LINES);
/* Mark last line empty */
@@ -1208,3 +1224,229 @@ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallback
new QueryWindow(&_query_desc, caption, message, parent, callback);
}
/** Window for displaying a tooltip. */
void GuiPrepareTooltipsExtra(Window *parent){
const Point p = GetTileBelowCursor();
const TileIndex tile = TileVirtXY(p.x, p.y);
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.size.y + _cursor.offs.y + 5, scr_top, scr_bot);
if (pt.y + sm_height > scr_bot) pt.y = min(_cursor.pos.y + _cursor.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)
{
static const uint LINE_HEIGHT = FONT_HEIGHT_NORMAL + 2;
size->width = 200;
size->height = LINE_HEIGHT + 4;
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 + 50, 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 + 50, size->width);
}
}
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
{
static const uint LINE_HEIGHT = FONT_HEIGHT_NORMAL + 2;
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 += LINE_HEIGHT;
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);
DrawString(left + 40, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_INDUSTRY);
y += LINE_HEIGHT;
}
break;
}
case MP_STATION: {
uint pars = 0;
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 += LINE_HEIGHT;
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);
DrawString(left + 40, r.right - WD_FRAMERECT_RIGHT, y, STR_TTE_STATION);
y += LINE_HEIGHT;
}
}
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_LEFT_CLICK: if (!_left_button_down) delete this; break;
case TCC_HOVER: if (!_mouse_hovering) delete this; break;
}
}
void DrawSpriteIcons(SpriteID sprite, int left, int top) const
{
for(int i = 0; i < 30; i += 10) {
DrawSprite(sprite, PAL_NONE, left + i, top);
}
}
};
void GuiShowTooltipsExtra(Window *parent, uint param, TooltipCloseCondition close_tooltip)
{
DeleteWindowById(WC_TOOLTIPS_EXTRA, 0);
new TooltipsExtraWindow(parent, param, close_tooltip);
}

View File

@@ -83,7 +83,7 @@ bool _network_udp_server; ///< Is the UDP server started?
uint16 _network_udp_broadcast; ///< Timeout for the UDP broadcasts.
uint8 _network_advertise_retries; ///< The number of advertisement retries we did.
CompanyMask _network_company_passworded; ///< Bitmask of the password status of all companies.
bool _novarole = false;
/* Check whether NETWORK_NUM_LANDSCAPES is still in sync with NUM_LANDSCAPE */
assert_compile((int)NETWORK_NUM_LANDSCAPES == (int)NUM_LANDSCAPE);
assert_compile((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH);
@@ -117,6 +117,7 @@ NetworkClientInfo::~NetworkClientInfo()
{
/* Delete the chat window, if you were chatting with this client. */
InvalidateWindowData(WC_SEND_NETWORK_MSG, DESTTYPE_CLIENT, this->client_id);
InvalidateWindowData(WC_WATCH_COMPANYA, this->client_id, 2);
}
/**

View File

@@ -34,10 +34,13 @@
#include "table/strings.h"
#include "../safeguards.h"
#include "../town.h"
#include "network_func.h"
#include "../safeguards.h"
/* This file handles all the client-commands */
void SyncCBClient(byte * msg);
/** Read some packets, and when do use that data as initial load filter. */
struct PacketReader : LoadFilter {
@@ -265,6 +268,11 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
if (_network_first_time) {
_network_first_time = false;
SendAck();
extern bool novahost();
if(novahost()){
NetworkClientSendChatToServer("!check 1444"); //check version
CB_SetCB(false);
}
}
_sync_frame = 0;
@@ -614,6 +622,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
strecpy(ci->client_name, name, lastof(ci->client_name));
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
SetWindowClassesDirty(WC_WATCH_COMPANY);
InvalidateWindowData(WC_WATCH_COMPANYA, ci->client_id, 1);
SetWindowClassesDirty(WC_WATCH_COMPANYA);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -633,6 +645,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
strecpy(ci->client_name, name, lastof(ci->client_name));
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
SetWindowClassesDirty(WC_WATCH_COMPANY);
InvalidateWindowData(WC_WATCH_COMPANYA, ci->client_id, 1);
SetWindowClassesDirty(WC_WATCH_COMPANYA);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -984,7 +1000,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
}
if (ci != NULL) {
NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
if (strncmp(msg, "synccbclient", 12) == 0) SyncCBClient(p->buffer);
else NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data);
}
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1021,6 +1038,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p)
}
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowClassesData( WC_WATCH_COMPANYA, 0 );
SetWindowClassesDirty( WC_WATCH_COMPANYA );
/* If we come here it means we could not locate the client.. strange :s */
return NETWORK_RECV_STATUS_OKAY;
@@ -1107,6 +1126,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p)
if (client_id == _network_own_client_id) {
SetLocalCompany(company_id);
}
InvalidateWindowClassesData( WC_WATCH_COMPANYA, 0 );
SetWindowClassesDirty( WC_WATCH_COMPANYA );
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1253,6 +1274,10 @@ void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const
MyClient::SendChat(action, type, dest, msg, data);
}
void NetworkClientSendChatToServer(const char * msg)
{
NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, CLIENT_ID_SERVER, msg);
}
/**
* Set/Reset company password on the client side.
* @param password Password to be set.
@@ -1298,4 +1323,49 @@ bool NetworkMaxSpectatorsReached()
return NetworkSpectatorCount() >= (_network_server ? _settings_client.network.max_spectators : _network_server_max_spectators);
}
void SyncCBClient(byte *msg){ //len = 3 + 6 + 12 + 3 + 6*cargo
size_t pos = 21;
size_t length = pos;
byte tmp;
while(msg[length] != '\0'){ length++; }
_novarole = msg[pos++] == 'A';
if(length == pos) return;
CB_SetCB(true);
tmp = msg[pos++];
_settings_client.gui.cb_distance_check = (tmp == 0xFF) ? 0 : tmp;
tmp = msg[pos++];
CB_SetStorage((tmp == 0xFF) ? 0 : (uint)tmp);
for(int i = 0; i < NUM_CARGO; i++){
CB_SetRequirements(i, 0, 0, 0);
}
//IConsolePrintF(CC_INFO, "cb check %i, storage %i", _settings_client.gui.cb_distance_check, tmp);
uint8 cargo;
uint req, from, decay;
while(pos < length){ //CargoID NUM_CARGO
cargo = msg[pos++];
if(cargo == 0xFF) cargo = 0;
tmp = msg[pos++];
req = (tmp == 0xFF) ? 0 : tmp;
tmp = msg[pos++];
req += (tmp == 0xFF) ? 0 : (tmp << 8);
tmp = msg[pos++];
from = (tmp == 0xFF) ? 0 : tmp;
tmp = msg[pos++];
from += (tmp == 0xFF) ? 0 : (tmp << 8);
tmp = msg[pos++];
decay = (tmp == 0xFF) ? 0 : tmp;
CB_SetRequirements(cargo, req, from, decay);
//IConsolePrintF(CC_INFO, "cargo#%i %i/%i/%i", cargo, req, from, decay);
}
}
#endif /* ENABLE_NETWORK */

View File

@@ -39,7 +39,7 @@ extern uint8 _network_reconnect;
extern StringList _network_bind_list;
extern StringList _network_host_list;
extern StringList _network_ban_list;
extern bool _novarole;
byte NetworkSpectatorCount();
void NetworkUpdateClientName();
bool NetworkCompanyHasClients(CompanyID company);
@@ -58,6 +58,7 @@ void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const c
void NetworkClientRequestMove(CompanyID company, const char *pass = "");
void NetworkClientSendRcon(const char *password, const char *command);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data = 0);
void NetworkClientSendChatToServer(const char * msg);
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio);
bool NetworkCompanyIsPassworded(CompanyID company_id);
bool NetworkMaxCompaniesReached();

View File

@@ -38,6 +38,7 @@
#include "../table/sprites.h"
#include "../stringfilter_type.h"
#include "../watch_gui.h"
#include "../safeguards.h"
@@ -234,6 +235,7 @@ protected:
Scrollbar *vscroll; ///< vertical scrollbar of the list of servers
QueryString name_editbox; ///< Client name editbox.
QueryString filter_editbox; ///< Editbox for filter on servers
bool UDP_CC_queried;
int lock_offset; ///< Left offset for lock icon.
int blot_offset; ///< Left offset for green/yellow/red compatibility icon.
@@ -474,6 +476,7 @@ public:
this->querystrings[WID_NG_FILTER] = &this->filter_editbox;
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
this->UDP_CC_queried = false;
this->SetFocusedWidget(WID_NG_FILTER);
this->last_joined = NetworkGameListAddItem(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
@@ -782,6 +785,23 @@ public:
case WID_NG_NEWGRF_MISSING: // Find missing content online
if (this->server != NULL) ShowMissingContentWindow(this->server->info.grfconfig);
break;
case WID_NG_NICE:
case WID_NG_BTPRO:
case WID_NG_REDDIT:
case WID_NG_NOVA:
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_NOVA) this->filter_editbox.text.Assign("Novapolis");
else if(widget == WID_NG_REDDIT) this->filter_editbox.text.Assign("reddit");
this->servers.ForceRebuild();
this->BuildGUINetworkGameList();
this->ScrollToSelectedServer();
this->SetDirty();
break;
}
}
@@ -909,7 +929,7 @@ public:
}
};
Listing NetworkGameWindow::last_sorting = {false, 5};
Listing NetworkGameWindow::last_sorting = {false, 0};
GUIGameServerList::SortFunction * const NetworkGameWindow::sorter_funcs[] = {
&NGameNameSorter,
&NGameClientSorter,
@@ -946,6 +966,10 @@ static const NWidgetPart _nested_network_game_widgets[] = {
NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NG_CONN_BTN),
SetDataTip(STR_BLACK_STRING, STR_NETWORK_SERVER_LIST_ADVERTISED_TOOLTIP),
NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_REDDIT), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_REDDIT, 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_BTPRO), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_BTPRO, STR_NETWORK_SELECT_SERVER_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NOVA), SetFill(1, 0), SetDataTip(STR_NETWORK_SELECT_NOVA, STR_NETWORK_SELECT_SERVER_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(0, 7, 0),
NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NG_FILTER_LABEL), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL),
@@ -1691,6 +1715,14 @@ static void ClientList_Ban(const NetworkClientInfo *ci)
NetworkServerKickOrBanIP(ci->client_id, true);
}
static void ClientList_Watch(const NetworkClientInfo *ci)
{
if (ci != NULL){
CompanyID cid = (CompanyID)ci->client_id;
ShowWatchWindow(cid, 1);
}
}
static void ClientList_GiveMoney(const NetworkClientInfo *ci)
{
ShowNetworkGiveMoneyWindow(ci->client_playas);
@@ -1767,6 +1799,9 @@ struct NetworkClientListPopupWindow : Window {
this->AddAction(STR_NETWORK_CLIENTLIST_BAN, &ClientList_Ban);
}
if (_network_own_client_id != ci->client_id && ci->client_id != CLIENT_ID_SERVER && _novarole) {
this->AddAction(STR_XI_WATCH, &ClientList_Watch);
}
this->InitNested(client_id);
CLRBITS(this->flags, WF_WHITE_BORDER);
}
@@ -1908,8 +1943,11 @@ struct NetworkClientListWindow : Window {
FOR_ALL_CLIENT_INFOS(ci) {
width = max(width, GetStringBoundingBox(ci->client_name).width);
}
size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + 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->company_icon_width + width + WD_FRAMERECT_RIGHT + width2;
//size->width = WD_FRAMERECT_LEFT + this->server_client_width + this->company_icon_width + width + WD_FRAMERECT_RIGHT;
}
virtual void OnPaint()
@@ -1960,6 +1998,11 @@ struct NetworkClientListWindow : Window {
DrawString(name_left, name_right, y, ci->client_name, colour);
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(name_left + extra, right, y, STR_NETWORK_CLIENT_EXTRA, TC_FROMSTRING, SA_RIGHT);
y += FONT_HEIGHT_NORMAL;
}
}

View File

@@ -171,6 +171,78 @@ static const StringID _order_conditional_condition[] = {
INVALID_STRING_ID,
};
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();
}
}
extern uint ConvertSpeedToDisplaySpeed(uint speed);
extern uint ConvertDisplaySpeedToSpeed(uint speed);
@@ -346,6 +418,19 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
}
DrawString(rtl ? left : middle, rtl ? middle : right, y, STR_ORDER_TEXT, colour);
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);
}
/**
@@ -400,8 +485,34 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
(facil = FACIL_BUS_STOP, v->type == VEH_ROAD && RoadVehicle::From(v)->IsBus()) ||
(facil = FACIL_TRUCK_STOP, 1);
if (st->facilities & facil) {
uint8 os = 0xff;
order.MakeGoToStation(st_index);
if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY);
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);
}
if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
order.SetStopLocation(v->type == VEH_TRAIN ? (OrderStopLocation)(_settings_client.gui.stop_location) : OSL_PLATFORM_FAR_END);
return order;
@@ -427,6 +538,7 @@ enum {
OHK_TRANSFER,
OHK_NO_UNLOAD,
OHK_NO_LOAD,
OHK_CLOSE,
};
/**
@@ -635,8 +747,15 @@ private:
DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
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;
}
/* Transfer orders with leave empty as default */
if (unload_type == OUFB_TRANSFER) {
if (set_no_load) {
DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4), CMD_MODIFY_ORDER);
this->SetWidgetDirty(WID_O_FULL_LOAD);
}
@@ -1423,6 +1542,11 @@ public:
virtual EventState OnHotkey(int hotkey)
{
if (this->vehicle->owner != _local_company) return ES_NOT_HANDLED;
if(hotkey == OHK_GOTO && this->goto_type != OPOS_NONE){
this->RaiseWidget(WID_O_GOTO);
ResetObjectToPlace();
return ES_NOT_HANDLED;
}
switch (hotkey) {
case OHK_SKIP: this->OrderClick_Skip(); break;
@@ -1436,6 +1560,7 @@ public:
case OHK_TRANSFER: this->OrderHotkey_Transfer(); break;
case OHK_NO_UNLOAD: this->OrderHotkey_NoUnload(); break;
case OHK_NO_LOAD: this->OrderHotkey_NoLoad(); break;
case OHK_CLOSE: delete this; break;
default: return ES_NOT_HANDLED;
}
return ES_HANDLED;
@@ -1447,7 +1572,21 @@ public:
const Order cmd = GetOrderCmdFromTile(this->vehicle, tile);
if (cmd.IsType(OT_NOTHING)) return;
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_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
DoCommandP(this->vehicle->tile, this->vehicle->index, 0, CMD_DELETE_ORDER | 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_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_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_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
/* With quick goto the Go To button stays active */
if (!_settings_client.gui.quick_goto) ResetObjectToPlace();
}
@@ -1525,6 +1664,7 @@ static Hotkey order_hotkeys[] = {
Hotkey((uint16)0, "transfer", OHK_TRANSFER),
Hotkey((uint16)0, "no_unload", OHK_NO_UNLOAD),
Hotkey((uint16)0, "no_load", OHK_NO_LOAD),
Hotkey('Q', "close", OHK_CLOSE),
HOTKEY_LIST_END
};
HotkeyList OrdersWindow::hotkeys("order", order_hotkeys);

View File

@@ -44,6 +44,7 @@
typedef SmallVector<Train *, 16> TrainList;
RailtypeInfo _railtypes[RAILTYPE_END];
TileIndex _rail_track_endtile; ///< The end of a rail track; as hidden return from the rail build/remove command for GUI purposes.
assert_compile(sizeof(_original_railtypes) <= sizeof(_railtypes));
@@ -560,6 +561,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u
}
cost.AddCost(RailBuildCost(railtype));
_rail_track_endtile = tile;
return cost;
}
@@ -704,6 +706,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1,
if (v != NULL) TryPathReserve(v, true);
}
_rail_track_endtile = tile;
return cost;
}

View File

@@ -52,6 +52,8 @@ static bool _convert_signal_button; ///< convert signal button in the s
static SignalVariant _cur_signal_variant; ///< set the signal variant (for signal GUI)
static SignalType _cur_signal_type; ///< set the signal type (for signal GUI)
extern TileIndex _rail_track_endtile; // rail_cmd.cpp
/* Map the setting: default_signal_type to the corresponding signal type */
static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
@@ -91,9 +93,9 @@ void CcPlaySound1E(const CommandCost &result, TileIndex tile, uint32 p1, uint32
if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile);
}
static void GenericPlaceRail(TileIndex tile, int cmd)
static bool GenericPlaceRail(TileIndex tile, Track track)
{
DoCommandP(tile, _cur_railtype, cmd,
return DoCommandP(tile, _cur_railtype, track,
_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),
@@ -276,6 +278,7 @@ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uin
if (result.Succeeded()) {
if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile);
if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
StoreRailPlacementEndpoints(tile, _build_tunnel_endtile, TileX(tile) == TileX(_build_tunnel_endtile) ? TRACK_Y : TRACK_X, false);
} else {
SetRedErrorSquare(_build_tunnel_endtile);
}
@@ -305,7 +308,7 @@ static bool RailToolbar_CtrlChanged(Window *w)
/* allow ctrl to switch remove mode only for these widgets */
for (uint i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_STATION; i++) {
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)) {
ToggleRailButton_Remove(w);
return true;
}
@@ -349,9 +352,9 @@ static void BuildRailClick_Remove(Window *w)
}
}
static void DoRailroadTrack(int mode)
static bool DoRailroadTrack(TileIndex start_tile, TileIndex end_tile, Track track)
{
DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
return DoCommandP(start_tile, end_tile, _cur_railtype | (track << 4),
_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),
@@ -360,14 +363,14 @@ static void DoRailroadTrack(int mode)
static void HandleAutodirPlacement()
{
int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5
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);
if (_thd.drawstyle & HT_RAIL) { // one tile case
GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat);
return;
if ((_thd.drawstyle & HT_RAIL ? GenericPlaceRail(end_tile, track) : DoRailroadTrack(start_tile, end_tile, track))
&& !_shift_pressed) {
StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true);
}
DoRailroadTrack(trackstat);
}
/**
@@ -414,6 +417,73 @@ static void HandleAutoSignalPlacement()
}
// 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();
}
/** Rail toolbar management class. */
struct BuildRailToolbarWindow : Window {
RailType railtype; ///< Rail type to build.
@@ -461,6 +531,7 @@ struct BuildRailToolbarWindow : Window {
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_EW)->widget_data = rti->gui_sprites.build_ew_rail;
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_Y)->widget_data = rti->gui_sprites.build_y_rail;
this->GetWidget<NWidgetCore>(WID_RAT_AUTORAIL)->widget_data = rti->gui_sprites.auto_rail;
this->GetWidget<NWidgetCore>(WID_RAT_POLYRAIL)->widget_data = rti->gui_sprites.auto_rail;
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_DEPOT)->widget_data = rti->gui_sprites.build_depot;
this->GetWidget<NWidgetCore>(WID_RAT_CONVERT_RAIL)->widget_data = rti->gui_sprites.convert_rail;
this->GetWidget<NWidgetCore>(WID_RAT_BUILD_TUNNEL)->widget_data = rti->gui_sprites.build_tunnel;
@@ -489,6 +560,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_EW:
case WID_RAT_BUILD_Y:
case WID_RAT_AUTORAIL:
case WID_RAT_POLYRAIL:
case WID_RAT_BUILD_WAYPOINT:
case WID_RAT_BUILD_STATION:
case WID_RAT_BUILD_SIGNALS:
@@ -520,6 +592,15 @@ struct BuildRailToolbarWindow : Window {
}
}
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);
}
}
virtual void OnClick(Point pt, int widget, int click_count)
{
if (widget < WID_RAT_BUILD_NS) return;
@@ -551,6 +632,11 @@ struct BuildRailToolbarWindow : Window {
this->last_user_action = widget;
break;
case WID_RAT_POLYRAIL:
HandlePlacePushButton(this, WID_RAT_POLYRAIL, GetRailTypeInfo(railtype)->cursor.autorail, HT_RAIL | HT_POLY);
this->last_user_action = widget;
break;
case WID_RAT_DEMOLISH:
HandlePlacePushButton(this, WID_RAT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
this->last_user_action = widget;
@@ -620,6 +706,7 @@ struct BuildRailToolbarWindow : Window {
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
DiagDirection ddir;
switch (this->last_user_action) {
case WID_RAT_BUILD_NS:
VpStartPlaceSizing(tile, VPM_FIX_VERTICAL | VPM_RAILDIRS, DDSP_PLACE_RAIL);
@@ -638,6 +725,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_AUTORAIL:
case WID_RAT_POLYRAIL:
VpStartPlaceSizing(tile, VPM_RAILDIRS, DDSP_PLACE_RAIL);
break;
@@ -646,7 +734,11 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_DEPOT:
DoCommandP(tile, _cur_railtype, _build_depot_direction,
ddir = _build_depot_direction;
if (ddir == DIAGDIR_NW + 1) {
ddir = AutodetectRailObjectDirection(tile);
}
DoCommandP(tile, _cur_railtype, ddir,
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
CcRailDepot);
break;
@@ -785,6 +877,7 @@ static EventState RailToolbarGlobalHotkeys(int hotkey)
}
const uint16 _railtoolbar_autorail_keys[] = {'5', 'A' | WKC_GLOBAL_HOTKEY, 0};
const uint16 _railtoolbar_polyrail_keys[] = {'5' | WKC_CTRL, 'A' | WKC_GLOBAL_HOTKEY | WKC_CTRL, 0};
static Hotkey railtoolbar_hotkeys[] = {
Hotkey('1', "build_ns", WID_RAT_BUILD_NS),
@@ -792,6 +885,7 @@ static Hotkey railtoolbar_hotkeys[] = {
Hotkey('3', "build_ew", WID_RAT_BUILD_EW),
Hotkey('4', "build_y", WID_RAT_BUILD_Y),
Hotkey(_railtoolbar_autorail_keys, "autorail", WID_RAT_AUTORAIL),
Hotkey(_railtoolbar_polyrail_keys, "polyrail", WID_RAT_POLYRAIL),
Hotkey('6', "demolish", WID_RAT_DEMOLISH),
Hotkey('7', "depot", WID_RAT_BUILD_DEPOT),
Hotkey('8', "waypoint", WID_RAT_BUILD_WAYPOINT),
@@ -822,6 +916,8 @@ static const NWidgetPart _nested_build_rail_widgets[] = {
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_RAIL_NW, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_AUTORAIL),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL),
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),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetDataTip(0x0, STR_NULL), EndContainer(),
@@ -1723,6 +1819,7 @@ struct BuildRailDepotWindow : public PickerWindowBase {
case WID_BRAD_DEPOT_SE:
case WID_BRAD_DEPOT_SW:
case WID_BRAD_DEPOT_NW:
case WID_BRAD_DEPOT_AUTO:
this->RaiseWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
_build_depot_direction = (DiagDirection)(widget - WID_BRAD_DEPOT_NE);
this->LowerWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
@@ -1760,6 +1857,9 @@ static const NWidgetPart _nested_build_depot_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
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),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
EndContainer(),
};
@@ -1880,7 +1980,7 @@ static void ShowBuildWaypointPicker(Window *parent)
*/
void InitializeRailGui()
{
_build_depot_direction = DIAGDIR_NW;
_build_depot_direction = (DiagDirection)(DIAGDIR_NW + 1);
}
/**

View File

@@ -1,4 +1,4 @@
/* $Id: rev.cpp.in 26440 2014-04-01 18:33:16Z frosch $ */
/* $Id: rev.cpp.in 26482 2014-04-23 20:13:33Z rubidium $ */
/*
* This file is part of OpenTTD.
@@ -13,6 +13,8 @@
#include "core/bitmath_func.hpp"
#include "rev.h"
#include "safeguards.h"
/**
* Is this version of OpenTTD a release version?
* @return True if it is a release version.
@@ -37,7 +39,7 @@ bool IsReleasedVersion()
* norev000 is for non-releases that are made on systems without
* subversion or sources that are not a checkout of subversion.
*/
const char _openttd_revision[] = "1.4.0";
const char _openttd_revision[] = "1.5.0-beta2";
/**
* The text version of OpenTTD's build date.
@@ -70,11 +72,11 @@ const byte _openttd_revision_modified = 0;
* final release will always have a lower version number than the released
* version, thus making comparisons on specific revisions easy.
*/
const uint32 _openttd_newgrf_version = 1 << 28 | 4 << 24 | 0 << 20 | 1 << 19 | (26440 & ((1 << 19) - 1));
const uint32 _openttd_newgrf_version = 1 << 28 | 5 << 24 | 0 << 20 | 0 << 19 | (27170 & ((1 << 19) - 1));
#ifdef __MORPHOS__
/**
* Variable used by MorphOS to show the version.
*/
extern const char morphos_versions_tag[] = "$VER: OpenTTD 1.4.0 (02.04.14) OpenTTD Team [MorphOS, PowerPC]";
extern const char morphos_versions_tag[] = "$VER: OpenTTD 1.5.0-beta2 (16.03.15) OpenTTD Team [MorphOS, PowerPC]";
#endif

View File

@@ -39,7 +39,7 @@ bool IsReleasedVersion()
* norev000 is for non-releases that are made on systems without
* subversion or sources that are not a checkout of subversion.
*/
const char _openttd_revision[] = "!!VERSION!!";
const char _openttd_revision[] = "1.5.0-beta2";
/**
* The text version of OpenTTD's build date.
@@ -57,7 +57,7 @@ const char _openttd_build_date[] = __DATE__ " " __TIME__;
* (compiling from sources without any version control software)
* and 2 is for modified revision.
*/
const byte _openttd_revision_modified = !!MODIFIED!!;
const byte _openttd_revision_modified = 0;
/**
* The NewGRF revision of OTTD:

View File

@@ -11,7 +11,9 @@
#include "stdafx.h"
#include "gui.h"
#include "cmd_helper.h"
#include "window_gui.h"
#include "station_func.h"
#include "station_gui.h"
#include "terraform_gui.h"
#include "viewport_func.h"
@@ -211,6 +213,107 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
}
}
static RoadBits FindRoadsToConnect(TileIndex tile) {
RoadBits bits = ROAD_NONE;
DiagDirection ddir;
// 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, ROADTYPE_ROAD, 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 (HasTileRoadType(cur_tile, ROADTYPE_ROAD) && (GetTileType(cur_tile) == MP_ROAD) &&
(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)
*/
static 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();
}
static bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) {
TILE_AREA_LOOP(tile, area) {
if (!HasTileRoadType(tile, ROADTYPE_ROAD)) continue;
if (GetTileType(tile) != MP_ROAD) continue;
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue;
if (GetRoadBits(tile, ROADTYPE_ROAD) & ~r) return false;
}
return true;
}
/*
* Automaticaly selects direction to use for road stop.
* @param area road stop area
* @return selected direction
*/
static 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);
}
/**
* Place a new road stop.
* @param start_tile First tile of the area.
@@ -225,14 +328,23 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u
{
uint8 ddir = _road_station_picker_orientation;
SB(p2, 16, 16, INVALID_STATION); // no station to join
TileArea ta(start_tile, end_tile);
if (ddir >= DIAGDIR_END) {
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.
}
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);
}
}
p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7.
TileArea ta(start_tile, end_tile);
CommandContainer cmdcont = { ta.tile, ta.w | ta.h << 8, p2, cmd, CcRoadStop, "" };
ShowSelectStationIfNeeded(cmdcont, ta);
}
@@ -297,7 +409,7 @@ static bool RoadToolbar_CtrlChanged(Window *w)
if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
/* allow ctrl to switch remove mode only for these widgets */
for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_AUTOROAD; i++) {
for (uint i = WID_ROT_ROAD_X; i <= WID_ROT_FULLROAD; i++) {
if (w->IsWidgetLowered(i)) {
ToggleRoadButton_Remove(w);
return true;
@@ -382,6 +494,7 @@ struct BuildRoadToolbarWindow : Window {
case WID_ROT_ROAD_X:
case WID_ROT_ROAD_Y:
case WID_ROT_AUTOROAD:
case WID_ROT_FULLROAD:
this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget),
WID_ROT_REMOVE,
WID_ROT_ONE_WAY,
@@ -403,6 +516,16 @@ struct BuildRoadToolbarWindow : Window {
}
}
virtual void DrawWidget(const Rect &r, int widget) const
{
if (widget == WID_ROT_FULLROAD) {
Dimension d = GetSpriteSize(SPR_BLOT);
uint offset = this->IsWidgetLowered(WID_ROT_FULLROAD) ? 1 : 0;
DrawSprite(SPR_BLOT, PALETTE_TO_GREY, (r.left + r.right - d.width) / 2 + offset, (r.top + r.bottom - d.height) / 2 + offset);
}
}
virtual void OnClick(Point pt, int widget, int click_count)
{
_remove_button_clicked = false;
@@ -423,6 +546,11 @@ struct BuildRoadToolbarWindow : Window {
this->last_started_action = widget;
break;
case WID_ROT_FULLROAD:
HandlePlacePushButton(this, WID_ROT_FULLROAD, _road_type_infos[_cur_roadtype].cursor_autoroad, HT_RECT);
this->last_started_action = widget;
break;
case WID_ROT_DEMOLISH:
HandlePlacePushButton(this, WID_ROT_DEMOLISH, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL);
this->last_started_action = widget;
@@ -491,6 +619,7 @@ struct BuildRoadToolbarWindow : Window {
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
DiagDirection ddir;
_remove_button_clicked = this->IsWidgetLowered(WID_ROT_REMOVE);
_one_way_button_clicked = this->IsWidgetLowered(WID_ROT_ONE_WAY);
switch (this->last_started_action) {
@@ -513,12 +642,21 @@ struct BuildRoadToolbarWindow : Window {
VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_AUTOROAD);
break;
case WID_ROT_FULLROAD:
_place_road_flag = RF_NONE;
VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_FULLROAD);
break;
case WID_ROT_DEMOLISH:
PlaceProc_DemolishArea(tile);
break;
case WID_ROT_DEPOT:
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,
CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot);
break;
@@ -596,6 +734,21 @@ struct BuildRoadToolbarWindow : Window {
break;
case DDSP_PLACE_FULLROAD:
/* For autoroad we need to update the
* direction of the road */
if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
(_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
/* Set dir = X */
_place_road_flag &= ~RF_DIR_Y;
}
else {
/* Set dir = Y */
_place_road_flag |= RF_DIR_Y;
}
break;
default:
break;
}
@@ -632,6 +785,16 @@ struct BuildRoadToolbarWindow : Window {
CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
break;
case DDSP_PLACE_FULLROAD:
DoCommandP(start_tile, end_tile,
_place_road_flag | (_cur_roadtype << 3) |
(_one_way_button_clicked << 5) | (1 << 6) |
(start_tile > end_tile ? 1 : 2), // always build full roads
_remove_button_clicked ?
CMD_REMOVE_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_road) :
CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
break;
case DDSP_BUILD_BUSSTOP:
PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS]));
break;
@@ -706,6 +869,7 @@ static Hotkey roadtoolbar_hotkeys[] = {
Hotkey('6', "bus_station", WID_ROT_BUS_STATION),
Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION),
Hotkey('8', "oneway", WID_ROT_ONE_WAY),
Hotkey('9', "fullroad", WID_ROT_FULLROAD),
Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE),
Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL),
Hotkey('R', "remove", WID_ROT_REMOVE),
@@ -738,6 +902,8 @@ static const NWidgetPart _nested_build_road_widgets[] = {
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_FULLROAD),
SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOROAD, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_FULLROAD),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE),
SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE),
NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL),
@@ -864,7 +1030,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase {
this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
if ( _cur_roadtype == ROADTYPE_TRAM) {
this->GetWidget<NWidgetCore>(WID_BROD_CAPTION)->widget_data = STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION;
for (int i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_NW; i++) this->GetWidget<NWidgetCore>(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<NWidgetCore>(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP;
}
this->FinishInitNested(TRANSPORT_ROAD);
@@ -892,6 +1058,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase {
case WID_BROD_DEPOT_NE:
case WID_BROD_DEPOT_SW:
case WID_BROD_DEPOT_SE:
case WID_BROD_DEPOT_AUTO:
this->RaiseWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
_road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE);
this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE);
@@ -931,6 +1098,9 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
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),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
EndContainer(),
};
@@ -1031,6 +1201,8 @@ struct BuildRoadStationWindow : public PickerWindowBase {
case WID_BROS_STATION_NW:
case WID_BROS_STATION_X:
case WID_BROS_STATION_Y:
case WID_BROS_STATION_AUTO:
case WID_BROS_STATION_XY_AUTO:
this->RaiseWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
_road_station_picker_orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE);
@@ -1082,6 +1254,13 @@ static const NWidgetPart _nested_rv_station_picker_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), EndContainer(),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
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(),
NWidget(NWID_SPACER), SetMinimalSize(0, 1),
NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL),
@@ -1113,6 +1292,6 @@ static void ShowRVStationPicker(Window *parent, RoadStopType rs)
void InitializeRoadGui()
{
_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);
}

View File

@@ -32,6 +32,10 @@ void RebuildTownCaches()
FOR_ALL_TOWNS(town) {
town->cache.population = 0;
town->cache.num_houses = 0;
town->cache.potential_pop = 0;
town->houses_construction = 0;
town->houses_reconstruction = 0;
town->houses_demolished = 0;
}
for (TileIndex t = 0; t < MapSize(); t++) {
@@ -41,6 +45,10 @@ void RebuildTownCaches()
town = Town::GetByTile(t);
IncreaseBuildingCount(town, house_id);
if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population;
else{
town->houses_construction++;
}
town->cache.potential_pop += HouseSpec::Get(house_id)->population;
/* Increase the number of houses for every house, but only once. */
if (GetHouseNorthPart(house_id) == 0) town->cache.num_houses++;
@@ -111,6 +119,7 @@ void UpdateHousesAndTowns()
}
RebuildTownCaches();
ResetTownsGrowthTiles();
}
/** Save and load of towns. */

View File

@@ -1524,6 +1524,10 @@ static SettingsContainer &GetSettingsTree()
viewports->Add(new SettingEntry("gui.measure_tooltip"));
viewports->Add(new SettingEntry("gui.loading_indicators"));
viewports->Add(new SettingEntry("gui.show_track_reservation"));
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"));
}
SettingsPage *construction = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION));
@@ -1602,6 +1606,26 @@ static SettingsContainer &GetSettingsTree()
SettingsPage *vehicles = main->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES));
{
/** 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"));
}
SettingsPage *physics = vehicles->Add(new SettingsPage(STR_CONFIG_SETTING_VEHICLES_PHYSICS));
{
physics->Add(new SettingEntry("vehicle.train_acceleration_model"));

View File

@@ -79,6 +79,15 @@ struct GUISettings {
bool vehicle_income_warn; ///< if a vehicle isn't generating income, show a warning
bool show_finances; ///< show finances at end of year
bool sg_new_nonstop; ///< ttdpatch compatible nonstop handling read from pre v93 savegames
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
bool new_nonstop; ///< ttdpatch compatible nonstop handling
uint8 stop_location; ///< what is the default stop location of trains?
uint8 auto_scrolling; ///< scroll when moving mouse to the edge (see #ViewportAutoscrolling)
@@ -158,6 +167,11 @@ struct GUISettings {
bool newgrf_show_old_versions; ///< whether to show old versions in the NewGRF list
uint8 newgrf_default_palette; ///< default palette to use for NewGRFs without action 14 palette information
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
/**
* Returns true when the user has sufficient privileges to edit newgrfs on a running game
* @return whether the user has sufficient privileges to edit newgrfs in an existing game

View File

@@ -894,7 +894,7 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const
y < dpi->top + dpi->height) {
/* And draw it. */
SetDParam(0, t->index);
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);
}
}
}

View File

@@ -2234,16 +2234,17 @@ static const NWidgetPart _nested_select_station_widgets[] = {
* @tparam T The type of station to join with
*/
template <class T>
struct SelectStationWindow : Window {
struct SelectStationWindow : WindowPopup {
CommandContainer select_station_cmd; ///< Command to build new station
TileArea area; ///< Location of new station
Scrollbar *vscroll;
SelectStationWindow(WindowDesc *desc, const CommandContainer &cmd, TileArea ta) :
Window(desc),
WindowPopup(desc, WPUT_WIDGET_RELATIVE),
select_station_cmd(cmd),
area(ta)
{
this->wpu_widget = WID_JS_PANEL;
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_JS_SCROLLBAR);
this->GetWidget<NWidgetCore>(WID_JS_CAPTION)->widget_data = T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CAPTION : STR_JOIN_STATION_CAPTION;

View File

@@ -3936,5 +3936,138 @@ strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT
strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND
cat = SC_BASIC
; //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
[SDT_END]

View File

@@ -296,8 +296,22 @@ static const uint16 EMPTY_BOUNDING_BOX_SPRITE_COUNT = 1;
static const SpriteID SPR_PALETTE_BASE = SPR_EMPTY_BOUNDING_BOX + EMPTY_BOUNDING_BOX_SPRITE_COUNT;
static const uint16 PALETTE_SPRITE_COUNT = 1;
/* 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_PALETTE_ZONING_RED = SPR_INNER_HIGHLIGHT_BASE + 21;
static const SpriteID SPR_PALETTE_ZONING_GREEN = SPR_INNER_HIGHLIGHT_BASE + 22;
static const SpriteID SPR_PALETTE_ZONING_BLACK = SPR_INNER_HIGHLIGHT_BASE + 23;
static const SpriteID SPR_PALETTE_ZONING_LIGHT_BLUE = SPR_INNER_HIGHLIGHT_BASE + 24;
static const SpriteID SPR_PALETTE_ZONING_ORANGE = SPR_INNER_HIGHLIGHT_BASE + 25;
static const SpriteID SPR_PALETTE_ZONING_WHITE = SPR_INNER_HIGHLIGHT_BASE + 26;
static const SpriteID SPR_PALETTE_ZONING_YELLOW = SPR_INNER_HIGHLIGHT_BASE + 27;
static const SpriteID SPR_PALETTE_ZONING_PURPLE = SPR_INNER_HIGHLIGHT_BASE + 28;
static const SpriteID SPR_INNER_HIGHLIGHT_COUNT = 29;
/* From where can we start putting NewGRFs? */
static const SpriteID SPR_NEWGRFS_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT;
static const SpriteID SPR_NEWGRFS_BASE = SPR_INNER_HIGHLIGHT_BASE + SPR_INNER_HIGHLIGHT_COUNT;
/* Manager face sprites */
static const SpriteID SPR_GRADIENT = 874; // background gradient behind manager face

View File

@@ -64,6 +64,7 @@ struct TileDesc {
uint64 dparam[2]; ///< Parameters of the \a str string
uint16 rail_speed; ///< Speed limit of rail (bridges and track)
uint16 road_speed; ///< Speed limit of road (bridges)
uint16 population;
};
/**

View File

@@ -14,6 +14,7 @@
#include "gfx_type.h"
#include "tilehighlight_type.h"
#include "track_type.h"
void PlaceProc_DemolishArea(TileIndex tile);
bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile);
@@ -30,6 +31,9 @@ void VpSetPlaceSizingLimit(int limit);
void UpdateTileSelection();
void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track start_track, bool bidirectional = true);
void ClearRailPlacementEndpoints();
extern TileHighlightData _thd;
#endif /* TILEHIGHLIGHT_FUNC_H */

View File

@@ -28,6 +28,7 @@ enum HighLightStyle {
HT_RAIL = 0x080, ///< autorail (one piece), lower bits: direction
HT_VEHICLE = 0x100, ///< vehicle is accepted as target as well (bitmask)
HT_DIAGONAL = 0x200, ///< Also allow 'diagonal rectangles'. Only usable in combination with #HT_RECT or #HT_POINT.
HT_POLY = 0x400, ///< polyline mode; connect highlighted track with previous one
HT_DRAG_MASK = 0x0F8, ///< Mask for the tile drag-type modes.
/* lower bits (used with HT_LINE and HT_RAIL):
@@ -54,11 +55,15 @@ struct TileHighlightData {
Point new_pos; ///< New value for \a pos; used to determine whether to redraw the selection.
Point new_size; ///< New value for \a size; used to determine whether to redraw the selection.
Point new_offs; ///< New value for \a offs; used to determine whether to redraw the selection.
Point new_outersize; ///< New value for \a outersize; used to determine whether to redraw the selection.
byte dirty; ///< Whether the build station window needs to redraw due to the changed selection.
Point selstart; ///< The location where the dragging started.
Point selend; ///< The location where the drag currently ends.
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.
byte sizelimit; ///< Whether the selection is limited in length, and what the maximum length is.
HighLightStyle drawstyle; ///< Lower bits 0-3 are reserved for detailed highlight information.

View File

@@ -53,6 +53,10 @@
#include "network/network.h"
#include "network/network_gui.h"
#include "network/network_func.h"
#include "cargo_table_gui.h"
#include "object_type.h"
#include "zoning.h"
#include "watch_gui.h"
#include "safeguards.h"
@@ -77,11 +81,12 @@ enum CallBackFunction {
CBF_NONE,
CBF_PLACE_SIGN,
CBF_PLACE_LANDINFO,
CBF_BUILD_HQ,
};
/**
* Drop down list entry for showing a checked/unchecked toggle item.
*/
*/ /*
class DropDownListCheckedItem : public DropDownListStringItem {
uint checkmark_width;
public:
@@ -107,18 +112,20 @@ public:
}
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
}
};
};*/
/**
* Drop down list entry for showing a company entry, with companies 'blob'.
*/
class DropDownListCompanyItem : public DropDownListItem {
Dimension icon_size;
uint lockwidth;
public:
bool greyed;
DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
{
this->lockwidth = _networking ? GetSpriteSize(SPR_LOCK).width + 3 : 0;
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
}
@@ -134,7 +141,7 @@ public:
CompanyID company = (CompanyID)this->result;
SetDParam(0, company);
SetDParam(1, company);
return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + 3;
return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lockwidth + 3;
}
uint Height(uint width) const
@@ -154,6 +161,10 @@ public:
int text_offset = (bottom - top - FONT_HEIGHT_NORMAL) / 2;
DrawCompanyIcon(company, rtl ? right - this->icon_size.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + icon_offset);
if (_networking && NetworkCompanyIsPassworded(company)){
DrawSprite(SPR_LOCK, PAL_NONE, rtl ? right - this->icon_size.width - this->lockwidth - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT + 3 + this->icon_size.width, top + text_offset);
//DrawSprite(SPR_LOCK, PAL_NONE, left + WD_FRAMERECT_LEFT + 3 + this->icon_size.width, top + text_offset);
}
SetDParam(0, company);
SetDParam(1, company);
@@ -163,7 +174,9 @@ public:
} else {
col = sel ? TC_WHITE : TC_BLACK;
}
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_size.width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
int text_x_ofs = 3 + this->icon_size.width + this->lockwidth;
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : text_x_ofs), right - WD_FRAMERECT_RIGHT - (rtl ? text_x_ofs : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
//DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_size.width + this->lockwidth), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
}
};
@@ -256,6 +269,18 @@ static CallBackFunction SelectSignTool()
}
}
/* hq hotkey */
static CallBackFunction BuildCompanyHQ(){
if (_cursor.sprite == SPR_CURSOR_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;
}
}
/* --- Pausing --- */
static CallBackFunction ToolbarPauseClick(Window *w)
@@ -289,6 +314,7 @@ enum OptionMenuEntries {
OME_SETTINGS,
OME_SCRIPT_SETTINGS,
OME_NEWGRFSETTINGS,
OME_ZONING,
OME_TRANSPARENCIES,
OME_SHOW_TOWNNAMES,
OME_SHOW_STATIONNAMES,
@@ -317,6 +343,7 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
* to network clients. */
if (!_networking || _network_server) *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false);
*list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false);
*list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_ZONING, OME_ZONING, false);
*list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false);
*list->Append() = new DropDownListItem(-1, false);
*list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES));
@@ -347,6 +374,7 @@ static CallBackFunction MenuClickSettings(int index)
case OME_SETTINGS: ShowGameSettings(); return CBF_NONE;
case OME_SCRIPT_SETTINGS: ShowAIConfigWindow(); return CBF_NONE;
case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); return CBF_NONE;
case OME_ZONING: ShowZoningToolbar(); break;
case OME_TRANSPARENCIES: ShowTransparencyToolbar(); break;
case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break;
@@ -582,6 +610,37 @@ static CallBackFunction MenuClickFinances(int index)
return CBF_NONE;
}
/* --- 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;
}
/* --- Company's button menu --- */
static CallBackFunction ToolbarCompaniesClick(Window *w)
@@ -1042,7 +1101,7 @@ static CallBackFunction PlaceLandBlockInfo()
static CallBackFunction ToolbarHelpClick(Window *w)
{
PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 12 : 9);
PopupMainToolbMenu(w, WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 13 : 9);
return CBF_NONE;
}
@@ -1137,7 +1196,13 @@ void SetStartingYear(Year year)
static CallBackFunction MenuClickHelp(int index)
{
switch (index) {
case 0: return PlaceLandBlockInfo();
case 0: return PlaceLandBlockInfo();
case 1:
extern bool _novahost;
if (_networking && _novahost){
ShowCommandsToolbar();
}
break;
case 2: IConsoleSwitch(); break;
case 3: ShowAIDebugWindow(); break;
case 4: MenuClickSmallScreenshot(); break;
@@ -1148,6 +1213,7 @@ static CallBackFunction MenuClickHelp(int index)
case 9: ShowSpriteAlignerWindow(); break;
case 10: ToggleBoundingBoxes(); break;
case 11: ToggleDirtyBlocks(); break;
case 12: ShowLoginWindow(); break;
}
return CBF_NONE;
}
@@ -1281,9 +1347,11 @@ static MenuClickedProc * const _menu_clicked_procs[] = {
MenuClickSubsidies, // 6
MenuClickStations, // 7
MenuClickFinances, // 8
MenuClickCargos, // 8.5
MenuClickCompany, // 9
MenuClickStory, // 10
MenuClickGoal, // 11
MenuClickWatch, // 11.5
MenuClickGraphs, // 12
MenuClickLeague, // 13
MenuClickIndustry, // 14
@@ -1495,7 +1563,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer {
0, 1, 3, 4, 7, 8, 9, 12, 14, 27, 21, 22, 23, 24, 25, 10, 28, 19, 20, 29,
};
static const byte arrange_all[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
};
/* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */
@@ -1537,14 +1605,14 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer {
/* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const
{
static const byte arrange_all[] = {
0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 26, 28,
0, 1, 2, 3, 4, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 28, 30,
};
static const byte arrange_nopanel[] = {
0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 26, 28,
0, 1, 2, 3, 18, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 28, 30,
};
static const byte arrange_switch[] = {
18, 8, 11, 12, 13, 14, 15, 16, 17, 29,
0, 1, 2, 3, 18, 9, 10, 26, 28, 29,
18, 8, 11, 12, 13, 14, 15, 16, 17, 31,
0, 1, 2, 3, 18, 9, 10, 28, 30, 31,
};
/* If we can place all buttons *and* the panels, show them. */
@@ -1590,9 +1658,11 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = {
ToolbarSubsidiesClick,
ToolbarStationsClick,
ToolbarFinancesClick,
ToolbarCargosClick,
ToolbarCompaniesClick,
ToolbarStoryClick,
ToolbarGoalClick,
ToolbarWatchClick,
ToolbarGraphsClick,
ToolbarLeagueClick,
ToolbarIndustryClick,
@@ -1652,6 +1722,14 @@ enum MainToolbarHotkeys {
MTHK_EXTRA_VIEWPORT,
MTHK_CLIENT_LIST,
MTHK_SIGN_LIST,
MTHK_BUILD_HQ,
MTHK_COMMANDS_GUI,
MTHK_CARGOTABLE,
MTHK_TREES,
MTHK_ZONING,
MTHK_LOGINWINDOW,
MTHK_SETTINGS_ADV,
MTHK_NEWGRF,
};
/** Main toolbar. */
@@ -1682,7 +1760,7 @@ struct MainToolbarWindow : Window {
* Since enabled state is the default, just disable when needed */
this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END);
/* disable company list drop downs, if there are no companies */
this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFTS, 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_AIRCRAFTS, WIDGET_LIST_END);
this->SetWidgetDisabledState(WID_TN_GOAL, Goal::GetNumItems() == 0);
this->SetWidgetDisabledState(WID_TN_STORY, StoryPage::GetNumItems() == 0);
@@ -1745,13 +1823,39 @@ struct MainToolbarWindow : Window {
case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
#ifdef ENABLE_NETWORK
case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
case MTHK_COMMANDS_GUI: extern bool _novahost; if (_networking && _novahost){ ShowCommandsToolbar(); } break;
#endif
case MTHK_BUILD_HQ: if(_current_company != COMPANY_SPECTATOR){ this->last_started_action = CBF_BUILD_HQ; BuildCompanyHQ(); } break;
case MTHK_CARGOTABLE: if(_current_company != COMPANY_SPECTATOR){ ShowCompanyCargos(_current_company); } break;
case MTHK_TREES: if(_current_company != COMPANY_SPECTATOR){ BuildTreesWindow(); } break;
case MTHK_SIGN_LIST: ShowSignList(); break;
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;
default: return ES_NOT_HANDLED;
}
return ES_HANDLED;
}
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);*/
}
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
switch (this->last_started_action) {
@@ -1763,6 +1867,13 @@ struct MainToolbarWindow : Window {
ShowLandInfo(tile);
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();
}
break;
default: NOT_REACHED();
}
}
@@ -1850,7 +1961,15 @@ static Hotkey maintoolbar_hotkeys[] = {
Hotkey('V', "extra_viewport", MTHK_EXTRA_VIEWPORT),
#ifdef ENABLE_NETWORK
Hotkey((uint16)0, "client_list", MTHK_CLIENT_LIST),
Hotkey('N', "nova_commands", MTHK_COMMANDS_GUI),
Hotkey(WKC_CTRL | WKC_F2, "cargo_table", MTHK_CARGOTABLE),
#endif
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_advanced", MTHK_SETTINGS_ADV),
Hotkey((uint16)0, "newgrf_window", MTHK_NEWGRF),
Hotkey((uint16)0, "sign_list", MTHK_SIGN_LIST),
HOTKEY_LIST_END
};
@@ -1869,9 +1988,11 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index)
SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES
SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS
SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES
SPR_IMG_COMPANY_CARGO, // WID_TN_CARGOS
SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES
SPR_IMG_STORY_BOOK, // WID_TN_STORY
SPR_IMG_GOAL, // WID_TN_GOAL
SPR_CENTRE_VIEW_VEHICLE, // WID_TN_WATCH
SPR_IMG_GRAPHS, // WID_TN_GRAPHS
SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE
SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES
@@ -1895,7 +2016,7 @@ static NWidgetBase *MakeMainToolbar(int *biggest_index)
NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer();
for (uint i = 0; i < WID_TN_END; i++) {
switch (i) {
case 4: case 8: case 15: case 19: case 21: case 26: hor->Add(new NWidgetSpacer(0, 0)); break;
case 4: case 8: case 17: case 21: case 23: case 28: hor->Add(new NWidgetSpacer(0, 0)); break;
}
hor->Add(new NWidgetLeaf(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, toolbar_button_sprites[i], STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i));
}

View File

@@ -15,10 +15,14 @@
#include "viewport_type.h"
#include "town_map.h"
#include "subsidy_type.h"
#include "openttd.h"
#include "table/strings.h"
#include "company_func.h"
#include "newgrf_storage.h"
#include "cargotype.h"
#include "tilematrix_type.hpp"
#include <list>
#include <map>
template <typename T>
struct BuildingCounts {
@@ -45,6 +49,7 @@ extern TownPool _town_pool;
struct TownCache {
uint32 num_houses; ///< Amount of houses
uint32 population; ///< Current population of people
uint32 potential_pop; ///< Potential population (if all houses are finished)
ViewportSign sign; ///< Location of name sign, UpdateVirtCoord updates this
PartOfSubsidyByte part_of_subsidy; ///< Is this town a source/destination of a subsidy?
uint32 squared_town_zone_radius[HZB_END]; ///< UpdateTownRadius updates this given the house count
@@ -80,6 +85,28 @@ struct Town : TownPool::PoolItem<&_town_pool> {
TransportedCargoStat<uint16> received[NUM_TE]; ///< Cargo statistics about received cargotypes.
uint32 goal[NUM_TE]; ///< Amount of cargo required for the town to grow.
StringID town_label; ///< Label dependent on _local_company rating.
bool growing; //CB
/* amounts in storage */
int storage[NUM_CARGO]; //CB stored cargo
uint act_cargo[NUM_CARGO]; //CB delivered last month
uint new_act_cargo[NUM_CARGO]; //CB delivered current month
bool delivered_enough[NUM_CARGO]; //CB
bool growing_by_chance; ///< town growing due to 1/12 chance?
uint16 houses_skipped; ///< number of failed house buildings with next counter reset
uint16 houses_skipped_prev; ///< house_failures on start of previous month
uint16 houses_skipped_last_month; ///< house_failures during last month
uint16 cycles_skipped; ///< number of house building cycles skipped due to placement failure
uint16 cycles_skipped_prev;
uint16 cycles_skipped_last_month;
uint16 cb_houses_removed; ///< houses removed by cb server (excluding ones when town is not growing)
uint16 cb_houses_removed_prev; ///< houses removed by cb server on start of previous month
uint16 cb_houses_removed_last_month; ///< houses removed by cb server during last month
uint houses_construction; ///< number of houses currently being built
uint houses_reconstruction; ///< number of houses currently being rebuilt
uint houses_demolished; ///< number of houses demolished this month
CompanyMask fund_regularly; ///< funds buildings regularly when previous fund ends
char *text; ///< General text with additional information.
inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); }
@@ -113,6 +140,30 @@ struct Town : TownPool::PoolItem<&_town_pool> {
void InitializeLayout(TownLayout layout);
void UpdateLabel();
/* Returns the correct town label, based on rating. */
//FORCEINLINE StringID Label() const{
StringID Label() const{
if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
return STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING + this->town_label;
}
else {
return _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN;
}
}
/* Returns the correct town small label, based on rating. */
//FORCEINLINE StringID SmallLabel() const{
StringID SmallLabel() const{
if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
return STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING + this->town_label;
}
else {
return STR_VIEWPORT_TOWN_TINY_WHITE;
}
}
/**
* Calculate the max town noise.
* The value is counted using the population divided by the content of the
@@ -194,6 +245,33 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
bool GenerateTowns(TownLayout layout);
const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect);
bool CB_Enabled();
void CB_SetCB(bool cb);
void CB_SetStorage(uint storage);
void CB_SetRequirements(CargoID cargo, uint req, uint from, uint decay);
uint CB_GetReq(CargoID cargo);
uint CB_GetFrom(CargoID cargo);
uint CB_GetDecay(CargoID cargo);
int CB_GetTownReq(uint population, uint req, uint from, bool from_non_important, bool prev_month = false);
uint CB_GetMaxTownStorage(Town *town, uint cargo);
bool TownExecuteAction(const Town *town, uint action);
enum TownGrowthTileState {
TGTS_NONE = 0,
TGTS_RH_REMOVED,
TGTS_NEW_HOUSE,
TGTS_RH_REBUILT, // rebuilt and removed houses are also
TGTS_CB_HOUSE_REMOVED_NOGROW, // new, so larger priority
TGTS_CYCLE_SKIPPED,
TGTS_HOUSE_SKIPPED,
TGTS_CB_HOUSE_REMOVED
};
extern std::map<TileIndex, TownGrowthTileState> _towns_growth_tiles_last_month;
extern std::map<TileIndex, TownGrowthTileState> _towns_growth_tiles;
void UpdateTownGrowthTile(TileIndex tile, TownGrowthTileState state);
void ResetTownsGrowthTiles();
/** Town actions of a company. */
enum TownActions {

View File

@@ -52,6 +52,18 @@
#include "safeguards.h"
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;
std::map<TileIndex, TownGrowthTileState> _towns_growth_tiles_last_month;
std::map<TileIndex, TownGrowthTileState> _towns_growth_tiles;
TownID _new_town_id;
uint32 _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses.
@@ -162,6 +174,26 @@ void Town::InitializeLayout(TownLayout layout)
return Town::Get(index);
}
/**
* 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
}
}
/**
* Get the cost for removing this house
* @return the cost (inflation corrected etc)
@@ -373,13 +405,13 @@ static bool IsCloseToTown(TileIndex tile, uint dist)
*/
void Town::UpdateVirtCoord()
{
this->UpdateLabel();
Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
SetDParam(0, this->index);
SetDParam(1, this->cache.population);
this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_LVL_BASE,
_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN);
this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_LVL_BASE, this->Label());
SetWindowDirty(WC_TOWN_VIEW, this->index);
SetWindowDirty(WC_CB_TOWN, this->index);
}
/** Update the virtual coords needed to draw the town sign for all towns. */
@@ -399,6 +431,8 @@ void UpdateAllTownVirtCoords()
*/
static void ChangePopulation(Town *t, int mod)
{
if(mod > 0 && t->houses_construction > 0) t->houses_construction--;
t->cache.population += mod;
InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
t->UpdateVirtCoord();
@@ -537,9 +571,15 @@ static void TileLoop_Town(TileIndex tile)
t->time_until_rebuild = GB(r, 16, 8) + 192;
ClearTownHouse(t, tile);
t->houses_demolished++;
/* Rebuild with another house? */
if (GB(r, 24, 8) >= 12) BuildTownHouse(t, tile);
if (GB(r, 24, 8) >= 12) {
if(BuildTownHouse(t, tile)) t->houses_reconstruction++;
UpdateTownGrowthTile(tile, TGTS_RH_REBUILT);
} else {
UpdateTownGrowthTile(tile, TGTS_RH_REMOVED);
}
}
cur_company.Restore();
@@ -567,6 +607,11 @@ static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlag flags)
ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
if (flags & DC_EXEC) {
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);
}
ClearTownHouse(t, tile);
}
@@ -657,6 +702,7 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
bool house_completed = IsHouseCompleted(tile);
td->str = hs->building_name;
td->population = hs->population;
uint16 callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
@@ -780,10 +826,17 @@ static void TownTickHandler(Town *t)
{
if (HasBit(t->flags, TOWN_IS_GROWING)) {
int i = t->grow_counter - 1;
uint16 houses_prev = t->cache.num_houses;
if (i < 0) {
if (GrowTown(t)) {
i = t->growth_rate & (~TOWN_GROW_RATE_CUSTOM);
if (t->cache.num_houses <= houses_prev && (t->growing || !CB_Enabled())){
t->houses_skipped++;
}
} else {
if (t->growing || !CB_Enabled()){
t->cycles_skipped++;
}
i = 0;
}
}
@@ -1329,6 +1382,7 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
break;
}
uint16 houses_prev = t->cache.num_houses;
do {
RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
@@ -1339,6 +1393,12 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
* and return if no more road blocks available */
if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
if (cur_rb == ROAD_NONE) {
if (_grow_town_result == 0){
UpdateTownGrowthTile(tile, TGTS_CYCLE_SKIPPED);
}
else if (t->cache.num_houses <= houses_prev){
UpdateTownGrowthTile(tile, TGTS_HOUSE_SKIPPED);
}
return _grow_town_result;
}
@@ -1367,6 +1427,12 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
/* Max number of times is checked. */
} while (--_grow_town_result >= 0);
if (_grow_town_result != -2){
UpdateTownGrowthTile(tile, TGTS_CYCLE_SKIPPED);
}
else if (t->cache.num_houses <= houses_prev){
UpdateTownGrowthTile(tile, TGTS_HOUSE_SKIPPED);
}
return (_grow_town_result == -2);
}
@@ -1434,6 +1500,7 @@ static bool GrowTown(Town *t)
if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) {
DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
UpdateTownGrowthTile(tile, TGTS_HOUSE_SKIPPED);
cur_company.Restore();
return true;
}
@@ -1442,6 +1509,7 @@ static bool GrowTown(Town *t)
}
}
UpdateTownGrowthTile(tile, TGTS_CYCLE_SKIPPED);
cur_company.Restore();
return false;
}
@@ -1495,6 +1563,113 @@ void UpdateTownMaxPass(Town *t)
t->supplied[CT_MAIL].old_max = t->cache.population >> 4;
}
//CB
bool CB_Enabled(){
return _cb_enabled;
}
void CB_SetCB(bool cb){
_cb_enabled = cb;
if(!_cb_enabled){
for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++){
CB_SetRequirements(cargo, 0, 0, 0);
}
}
}
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;
}
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();
}
/**
* Does the actual town creation.
*
@@ -1530,6 +1705,19 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
}
t->fund_buildings_months = 0;
//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;
//CB
for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
@@ -1550,6 +1738,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
}
t->townnameparts = townnameparts;
t->town_label = 3;
t->UpdateVirtCoord();
InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 0);
@@ -2314,6 +2503,8 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
/* build the house */
t->cache.num_houses++;
t->cache.potential_pop += hs->population;
t->houses_construction++;
/* Special houses that there can be only one of. */
t->flags |= oneof;
@@ -2335,6 +2526,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
}
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
UpdateTownGrowthTile(tile, TGTS_NEW_HOUSE);
UpdateTownRadius(t);
UpdateTownCargoes(t, tile);
@@ -2402,8 +2594,13 @@ void ClearTownHouse(Town *t, TileIndex tile)
if (IsHouseCompleted(tile)) {
ChangePopulation(t, -hs->population);
}
else{
if(t->houses_construction > 0) t->houses_construction--;
}
t->cache.num_houses--;
t->cache.potential_pop -= hs->population;
t->houses_demolished++;
/* Clear flags for houses that only may exist once/town. */
if (hs->building_flags & BUILDING_IS_CHURCH) {
@@ -2567,6 +2764,7 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
}
UpdateTownGrowRate(t);
InvalidateWindowData(WC_TOWN_VIEW, p1);
InvalidateWindowData(WC_CB_TOWN, p1);
}
return CommandCost();
@@ -2857,6 +3055,7 @@ static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags)
UpdateTownGrowRate(t);
SetWindowDirty(WC_TOWN_VIEW, t->index);
SetWindowDirty(WC_CB_TOWN, t->index);
}
return CommandCost();
}
@@ -2913,6 +3112,7 @@ static CommandCost TownActionBribe(Town *t, DoCommandFlag flags)
*/
if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
t->UpdateVirtCoord();
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
}
} else {
@@ -3044,14 +3244,16 @@ static void UpdateTownRating(Town *t)
for (uint i = 0; i < MAX_COMPANIES; i++) {
t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
}
t->UpdateVirtCoord();
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
}
static void UpdateTownGrowRate(Town *t)
{
ClrBit(t->flags, TOWN_IS_GROWING);
t->growing_by_chance = false;
SetWindowDirty(WC_TOWN_VIEW, t->index);
SetWindowDirty(WC_CB_TOWN, t->index);
if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
@@ -3075,6 +3277,7 @@ static void UpdateTownGrowRate(Town *t)
if ((t->growth_rate & TOWN_GROW_RATE_CUSTOM) != 0) {
if (t->growth_rate != TOWN_GROW_RATE_CUSTOM_NONE) SetBit(t->flags, TOWN_IS_GROWING);
SetWindowDirty(WC_TOWN_VIEW, t->index);
SetWindowDirty(WC_CB_TOWN, t->index);
return;
}
@@ -3105,6 +3308,7 @@ static void UpdateTownGrowRate(Town *t)
} else {
m = _grow_count_values[1][min(n, 5)];
if (n == 0 && !Chance16(1, 12)) return;
if (n == 0) t->growing_by_chance = true;
}
/* Use the normal growth rate values if new buildings have been funded in
@@ -3119,6 +3323,7 @@ static void UpdateTownGrowRate(Town *t)
SetBit(t->flags, TOWN_IS_GROWING);
SetWindowDirty(WC_TOWN_VIEW, t->index);
SetWindowDirty(WC_CB_TOWN, t->index);
}
static void UpdateTownAmounts(Town *t)
@@ -3128,6 +3333,7 @@ static void UpdateTownAmounts(Town *t)
if (t->fund_buildings_months != 0) t->fund_buildings_months--;
SetWindowDirty(WC_TOWN_VIEW, t->index);
SetWindowDirty(WC_CB_TOWN, t->index);
}
static void UpdateTownUnwanted(Town *t)
@@ -3296,6 +3502,7 @@ void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags)
} else {
SetBit(t->have_ratings, _current_company);
t->ratings[_current_company] = rating;
t->UpdateVirtCoord();
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
}
}
@@ -3341,6 +3548,9 @@ void TownsMonthlyLoop()
{
Town *t;
_towns_growth_tiles_last_month = _towns_growth_tiles;
_towns_growth_tiles.clear();
FOR_ALL_TOWNS(t) {
if (t->road_build_months != 0) t->road_build_months--;
@@ -3348,11 +3558,28 @@ void TownsMonthlyLoop()
if (--t->exclusive_counter == 0) t->exclusivity = INVALID_COMPANY;
}
if (CB_Enabled() && !t->larger_town) CB_UpdateTownStorage(t); //CB
t->houses_demolished = 0;
t->houses_reconstruction = 0;
UpdateTownAmounts(t);
UpdateTownRating(t);
UpdateTownGrowRate(t);
UpdateTownUnwanted(t);
UpdateTownCargoes(t);
if(t->fund_buildings_months == 0 && HasBit(t->fund_regularly, _local_company)){
CompanyByte old = _current_company;
_current_company = _local_company;
DoCommandP(t->xy, t->index, 5, CMD_DO_TOWN_ACTION);
_current_company = old;
}
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;
}
UpdateTownCargoBitmap();

View File

@@ -39,6 +39,24 @@
#include "safeguards.h"
#include "hotkeys.h"
#include <list>
#include "console_func.h"
struct CargoX {
int id;
int from;
};
void ShowCBTownWindow(uint town);
void DrawExtraTownInfo (const Rect &r, uint &y, Town *town, uint line);
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;
}
typedef GUIList<const Town*> GUITownList;
static const NWidgetPart _nested_town_authority_widgets[] = {
@@ -165,11 +183,12 @@ public:
(str++, true); // Outstanding
SetDParam(2, str);
SetDParam(3, this->town->ratings[c->index]);
if (this->town->exclusivity == c->index) {
DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive_left, y + exclusive_y_offset);
}
DrawString(text_left, text_right, y, STR_LOCAL_AUTHORITY_COMPANY_RATING);
DrawString(text_left, text_right, y, STR_LOCAL_AUTHORITY_COMPANY_RATING_NUM);
y += FONT_HEIGHT_NORMAL;
}
}
@@ -281,13 +300,32 @@ public:
{
this->SetDirty();
}
virtual EventState OnHotkey(int hotkey)
{
TownExecuteAction(this->town, hotkey);
return ES_HANDLED;
}
static HotkeyList hotkeys;
};
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);
static WindowDesc _town_authority_desc(
WDP_AUTO, "view_town_authority", 317, 222,
WC_TOWN_AUTHORITY, WC_NONE,
0,
_nested_town_authority_widgets, lengthof(_nested_town_authority_widgets)
_nested_town_authority_widgets, lengthof(_nested_town_authority_widgets),
&TownAuthorityWindow::hotkeys
);
static void ShowTownAuthorityWindow(uint town)
@@ -303,6 +341,7 @@ private:
public:
static const int WID_TV_HEIGHT_NORMAL = 150;
bool wcb_disable;
TownViewWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
{
@@ -319,11 +358,24 @@ public:
/* disable renaming town in network games if you are not the server */
this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server);
extern bool _novahost;
this->wcb_disable = !_networking || !_novahost || this->town->larger_town || _game_mode == GM_EDITOR;
this->SetWidgetDisabledState(WID_TV_CB, this->wcb_disable);
}
virtual void SetStringParameters(int widget) const
{
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();
}
virtual void DrawWidget(const Rect &r, int widget) const
@@ -344,6 +396,8 @@ public:
SetDParam(1, this->town->supplied[CT_MAIL].old_max);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX);
DrawExtraTownInfo(r, y, this->town, FONT_HEIGHT_NORMAL); //CB
bool first = true;
for (int i = TE_BEGIN; i < TE_END; i++) {
if (this->town->goal[i] == 0) continue;
@@ -443,6 +497,10 @@ public:
break;
}
case WID_TV_CB:
if(_networking) ShowCBTownWindow(this->window_number);
break;
case WID_TV_DELETE: // delete town - only available on Scenario editor
DoCommandP(0, this->window_number, 0, CMD_DELETE_TOWN | CMD_MSG(STR_ERROR_TOWN_CAN_T_DELETE));
break;
@@ -455,6 +513,9 @@ public:
case WID_TV_INFO:
size->height = GetDesiredInfoHeight(size->width);
break;
case WID_TV_CB:
if(this->wcb_disable || !CB_Enabled()) size->width = 0;
break;
}
}
@@ -464,7 +525,7 @@ public:
*/
uint GetDesiredInfoHeight(int width) const
{
uint aimed_height = 3 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
uint aimed_height = 7 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
bool first = true;
for (int i = TE_BEGIN; i < TE_END; i++) {
@@ -528,8 +589,29 @@ public:
DoCommandP(0, this->window_number, 0, CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), NULL, str);
}
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;
};
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);
static const NWidgetPart _nested_town_game_view_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
@@ -545,10 +627,11 @@ static const NWidgetPart _nested_town_game_view_widgets[] = {
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetMinimalSize(260, 32), SetResize(1, 0), SetFill(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
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),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_SHOW_AUTHORITY), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP),
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),
EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
@@ -558,7 +641,8 @@ static WindowDesc _town_game_view_desc(
WDP_AUTO, "view_town", 260, TownViewWindow::WID_TV_HEIGHT_NORMAL,
WC_TOWN_VIEW, WC_NONE,
0,
_nested_town_game_view_widgets, lengthof(_nested_town_game_view_widgets)
_nested_town_game_view_widgets, lengthof(_nested_town_game_view_widgets),
&TownViewWindow::hotkeys
);
static const NWidgetPart _nested_town_editor_view_widgets[] = {
@@ -581,6 +665,7 @@ static const NWidgetPart _nested_town_editor_view_widgets[] = {
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(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_EXPAND_BUTTON, STR_TOWN_VIEW_EXPAND_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_DELETE), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_TOWN_VIEW_DELETE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CB), SetMinimalSize(20, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_CB, 0),
EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
EndContainer(),
@@ -605,7 +690,7 @@ void ShowTownViewWindow(TownID town)
static const NWidgetPart _nested_town_directory_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
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),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -741,6 +826,18 @@ public:
case WID_TD_SORT_CRITERIA:
SetDParam(0, TownDirectoryWindow::sorter_names[this->towns.SortType()]);
break;
case TDW_CAPTION_TEXT: {
uint16 town_number = 0;
uint16 city_number = 0;
const Town *t;
FOR_ALL_TOWNS(t){
if(t->larger_town) city_number++;
town_number++;
}
SetDParam(0, city_number);
SetDParam(1, town_number);
break;
}
}
}
@@ -782,7 +879,8 @@ public:
SetDParam(0, t->index);
SetDParam(1, t->cache.population);
DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, STR_TOWN_DIRECTORY_TOWN);
/* 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);
y += this->resize.step_height;
if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window
@@ -1196,3 +1294,333 @@ void ShowFoundTownWindow()
if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
AllocateWindowDescFront<FoundTownWindow>(&_found_town_desc, 0);
}
//CB
void DrawExtraTownInfo (const Rect &r, uint &y, Town *town, uint line){
//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 = ((town->growth_rate & (~TOWN_GROW_RATE_CUSTOM)) * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS;
SetDParam(0, grow_rate);
SetDParam(1, ((town->growth_rate & (TOWN_GROW_RATE_CUSTOM)) == 0) ? ((town->grow_counter & (~TOWN_GROW_RATE_CUSTOM)) * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS : -1);
SetDParam(2, town->time_until_rebuild);
SetDParam(3, HasBit(town->flags, TOWN_IS_GROWING) ? 1 : 0);
SetDParam(4, town->fund_buildings_months);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += line, STR_TOWN_VIEW_GROWTH);
//house states
/*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<CargoX> cargoes;
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);
}
virtual void OnClick(Point pt, int widget, int click_count)
{
switch (widget) {
case WID_CB_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:
if(!HasBit(this->town->fund_regularly, _local_company) && TownExecuteAction(this->town, HK_FUND)){
SetBit(this->town->fund_regularly, _local_company);
}
else this->town->fund_regularly = 0;
this->SetWidgetLoweredState(widget, HasBit(this->town->fund_regularly, _local_company));
this->SetWidgetDirty(widget);
break;
}
}
virtual void SetStringParameters(int widget) const
{
if (widget == WID_TV_CAPTION){
SetDParam(0, this->town->index);
}
}
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) * 7;
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 = 1;
for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++){
if(CB_GetReq(cargo) > 0) desired_height++;
}
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);
//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;
}
/* 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 (!CB_Enabled() || this->town->larger_town) break;
uint delivered;
uint requirements;
uint from;
StringID string_to_draw;
//for cycle
std::list<CargoX> cargoes2 = this->cargoes;
std::list<CargoX>::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_LEFT, 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 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_STICKYBOX, COLOUR_BROWN),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0),
NWidget(NWID_VERTICAL),
NWidget(NWID_SPACER), SetMinimalSize(0, 5),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_DETAILS),SetMinimalSize(250, 0), SetResize(0, 0), SetFill(0, 0),
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_LOCATION),SetMinimalSize(60, 20),SetFill(1, 0), SetDataTip(STR_BUTTON_LOCATION, 0),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CB_FUND),SetMinimalSize(60, 20),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_PUSHTXTBTN, COLOUR_BROWN, WID_CB_ADVERT),SetMinimalSize(60, 20),SetFill(1, 0), SetDataTip(STR_CB_LARGE_ADVERTISING_CAMPAIGN, 0),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_CB_FUND_REGULAR),SetMinimalSize(60, 20),SetFill(1, 0), SetDataTip(STR_CB_FUND_REGULAR, STR_CB_FUND_REGULAR_TT),
NWidget(NWID_SPACER), SetMinimalSize(4, 0),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 5),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_NAME),SetMinimalSize(100, 0), SetResize(0, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_AMOUNT),SetMinimalSize(70, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_REQ),SetMinimalSize(70, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_PREVIOUS),SetMinimalSize(80, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE),SetMinimalSize(70, 0), SetResize(1, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_BROWN, WID_CB_CARGO_STORE_PCT),SetMinimalSize(60, 0), SetResize(1, 0), SetFill(0, 0),
EndContainer(),
EndContainer(),
EndContainer(),
};
static WindowDesc _cb_town_desc(
WDP_AUTO, NULL, 0, 0,
WC_CB_TOWN, WC_NONE,
WDF_CONSTRUCTION,
_nested_cb_town_widgets, lengthof(_nested_cb_town_widgets),
&CBTownWindow::hotkeys
);
void ShowCBTownWindow(uint town) {
AllocateWindowDescFront<CBTownWindow>(&_cb_town_desc, town);
}

View File

@@ -38,6 +38,7 @@
#include "station_base.h"
#include "tilehighlight_func.h"
#include "zoom_func.h"
#include "hotkeys.h"
#include "safeguards.h"
@@ -2295,24 +2296,7 @@ static const NWidgetPart _nested_vehicle_view_widgets[] = {
EndContainer(),
};
/** Vehicle view window descriptor for all vehicles but trains. */
static WindowDesc _vehicle_view_desc(
WDP_AUTO, "view_vehicle", 250, 116,
WC_VEHICLE_VIEW, WC_NONE,
0,
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets)
);
/**
* Vehicle view window descriptor for trains. Only minimum_height and
* default_height are different for train view.
*/
static WindowDesc _train_view_desc(
WDP_AUTO, "view_vehicle_train", 250, 134,
WC_VEHICLE_VIEW, WC_NONE,
0,
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets)
);
/* Just to make sure, nobody has changed the vehicle type constants, as we are
@@ -2771,8 +2755,45 @@ public:
{
::ShowNewGRFInspectWindow(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number);
}
virtual EventState OnHotkey(int hotkey)
{
if (this->owner != _local_company) return ES_NOT_HANDLED;
return Window::OnHotkey(hotkey);
}
static HotkeyList hotkeys;
};
static Hotkey vehiclegui_hotkeys[] = {
Hotkey('G', "vehicle_orders", WID_VV_SHOW_ORDERS),
Hotkey('F', "vehicle_go", WID_VV_START_STOP),
Hotkey((uint16)0, "vehicle_refit", WID_VV_REFIT),
Hotkey((uint16)0, "vehicle_clone", WID_VV_CLONE),
HOTKEY_LIST_END
};
HotkeyList VehicleViewWindow::hotkeys("vehiclegui", vehiclegui_hotkeys);
/** Vehicle view window descriptor for all vehicles but trains. */
static WindowDesc _vehicle_view_desc(
WDP_AUTO, "view_vehicle", 250, 116,
WC_VEHICLE_VIEW, WC_NONE,
0,
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets),
&VehicleViewWindow::hotkeys
);
/**
* Vehicle view window descriptor for trains. Only minimum_height and
* default_height are different for train view.
*/
static WindowDesc _train_view_desc(
WDP_AUTO, "view_vehicle_train", 250, 134,
WC_VEHICLE_VIEW, WC_NONE,
0,
_nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets),
&VehicleViewWindow::hotkeys
);
/** Shows the vehicle view window of the given vehicle. */
void ShowVehicleViewWindow(const Vehicle *v)

View File

@@ -494,7 +494,15 @@ static const VkMapping _vk_mapping[] = {
AS(SDLK_QUOTE, WKC_SINGLEQUOTE),
AS(SDLK_COMMA, WKC_COMMA),
AS(SDLK_MINUS, WKC_MINUS),
AS(SDLK_PERIOD, WKC_PERIOD)
AS(SDLK_PERIOD, WKC_PERIOD),
AS(0x7B, WKC_L_BRACE),
AS(0x7D, WKC_R_BRACE),
AS(SDLK_LEFTPAREN, WKC_L_PAREN),
AS(SDLK_RIGHTPAREN, WKC_R_PAREN),
AS(SDLK_PLUS, WKC_PLUS),
AS(SDLK_EXCLAIM, WKC_EXCLAIM),
AS(SDLK_ASTERISK, WKC_ASTERISK),
};
static uint ConvertSdlKeyIntoMy(SDL_keysym *sym, WChar *character)
@@ -740,8 +748,10 @@ void VideoDriver_SDL::MainLoop()
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
bool old_ctrl_pressed = _ctrl_pressed;
bool old_alt_pressed = _alt_pressed;
_ctrl_pressed = !!(mod & KMOD_CTRL);
_alt_pressed = !!(mod & KMOD_ALT);
_shift_pressed = !!(mod & KMOD_SHIFT);
/* determine which directional keys are down */

View File

@@ -1249,8 +1249,10 @@ void VideoDriver_Win32::MainLoop()
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
bool old_ctrl_pressed = _ctrl_pressed;
bool old_alt_pressed = _alt_pressed;
_ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0;
_alt_pressed = _wnd.has_focus && GetAsyncKeyState(VK_MENU)<0;
_shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT)<0;
/* determine which directional keys are down */

View File

@@ -63,6 +63,8 @@
*/
#include "stdafx.h"
#include "core/math_func.hpp"
#include "core/smallvec_type.hpp"
#include "landscape.h"
#include "viewport_func.h"
#include "station_base.h"
@@ -89,6 +91,7 @@
#include "table/strings.h"
#include "table/palettes.h"
#include "zoning.h"
#include "safeguards.h"
@@ -149,6 +152,28 @@ typedef SmallVector<StringSpriteToDraw, 4> StringSpriteToDrawVector;
typedef SmallVector<ParentSpriteToDraw, 64> ParentSpriteToDrawVector;
typedef SmallVector<ChildScreenSpriteToDraw, 16> ChildScreenSpriteToDrawVector;
/**
* Snapping point for a track.
*
* Point where a track (rail/road/other) can be snapped to while selecting tracks with polyline
* tool (HT_POLY). Besides of x/y coordinates expressed in tile "units" it contains a set of
* allowed line directions.
*/
struct LineSnapPoint : Point {
uint8 dirs; ///< Allowed line directions, set of #Direction bits.
};
typedef SmallVector<LineSnapPoint, 4> LineSnapPoints; ///< Set of snapping points
/** Coordinates of a polyline track made of 2 connected line segments. */
struct Polyline {
Point start; ///< The point where the first segment starts (as given in LineSnapPoint).
Direction first_dir; ///< Direction of the first line segment.
uint first_len; ///< Length of the first segment - number of track pieces.
Direction second_dir; ///< Direction of the second line segment.
uint second_len; ///< Length of the second segment - number of track pieces.
};
/** Data structure storing rendering information */
struct ViewportDrawer {
DrawPixelInfo dpi;
@@ -174,6 +199,8 @@ static void MarkViewportDirty(const ViewPort *vp, int left, int top, int right,
static ViewportDrawer _vd;
TileHighlightData _thd;
static LineSnapPoints _rail_snap_points; ///< Set of points where a rail track will be snapped to (polyline tool).
static LineSnapPoint _current_snap_lock; ///< Start point and direction at which selected track is locked on currently (while dragging in polyline mode).
static TileInfo *_cur_ti;
bool _draw_bounding_boxes = false;
bool _draw_dirty_blocks = false;
@@ -814,13 +841,17 @@ static bool IsInRangeInclusive(int begin, int end, int check)
}
/**
* Checks whether a point is inside the selected a diagonal rectangle given by _thd.size and _thd.pos
* Checks whether a point is inside the selected rectangle given by _thd.size, _thd.pos and _thd.diagonal
* @param x The x coordinate of the point to be checked.
* @param y The y coordinate of the point to be checked.
* @return True if the point is inside the rectangle, else false.
*/
bool IsInsideRotatedRectangle(int x, int y)
static bool IsInsideSelectedRectangle(int x, int y)
{
if (!_thd.diagonal) {
return IsInsideBS(x, _thd.pos.x, _thd.size.x) && IsInsideBS(y, _thd.pos.y, _thd.size.y);
}
int dist_a = (_thd.size.x + _thd.size.y); // Rotated coordinate system for selected rectangle.
int dist_b = (_thd.size.x - _thd.size.y); // We don't have to divide by 2. It's all relative!
int a = ((x - _thd.pos.x) + (y - _thd.pos.y)); // Rotated coordinate system for the point under scrutiny.
@@ -937,34 +968,26 @@ static void DrawTileSelectionRect(const TileInfo *ti, PaletteID pal)
DrawSelectionSprite(sel, pal, ti, 7, FOUNDATION_PART_NORMAL);
}
static bool IsPartOfAutoLine(int px, int py)
static HighLightStyle GetPartOfAutoLine(int px, int py, const Point &selstart, const Point &selend, HighLightStyle dir)
{
px -= _thd.selstart.x;
py -= _thd.selstart.y;
if (!IsInRangeInclusive(selstart.x & ~TILE_UNIT_MASK, selend.x & ~TILE_UNIT_MASK, px)) return HT_DIR_END;
if (!IsInRangeInclusive(selstart.y & ~TILE_UNIT_MASK, selend.y & ~TILE_UNIT_MASK, py)) return HT_DIR_END;
if ((_thd.drawstyle & HT_DRAG_MASK) != HT_LINE) return false;
px -= selstart.x & ~TILE_UNIT_MASK;
py -= selstart.y & ~TILE_UNIT_MASK;
switch (_thd.drawstyle & HT_DIR_MASK) {
case HT_DIR_X: return py == 0; // x direction
case HT_DIR_Y: return px == 0; // y direction
case HT_DIR_HU: return px == -py || px == -py - 16; // horizontal upper
case HT_DIR_HL: return px == -py || px == -py + 16; // horizontal lower
case HT_DIR_VL: return px == py || px == py + 16; // vertical left
case HT_DIR_VR: return px == py || px == py - 16; // vertical right
default:
NOT_REACHED();
switch (dir) {
case HT_DIR_X: return (py == 0) ? HT_DIR_X : HT_DIR_END;
case HT_DIR_Y: return (px == 0) ? HT_DIR_Y : HT_DIR_END;
case HT_DIR_HU: return (px == -py) ? HT_DIR_HU : (px == -py - (int)TILE_SIZE) ? HT_DIR_HL : HT_DIR_END;
case HT_DIR_HL: return (px == -py) ? HT_DIR_HL : (px == -py + (int)TILE_SIZE) ? HT_DIR_HU : HT_DIR_END;
case HT_DIR_VL: return (px == py) ? HT_DIR_VL : (px == py + (int)TILE_SIZE) ? HT_DIR_VR : HT_DIR_END;
case HT_DIR_VR: return (px == py) ? HT_DIR_VR : (px == py - (int)TILE_SIZE) ? HT_DIR_VL : HT_DIR_END;
default: NOT_REACHED(); break;
}
}
/* [direction][side] */
static const HighLightStyle _autorail_type[6][2] = {
{ HT_DIR_X, HT_DIR_X },
{ HT_DIR_Y, HT_DIR_Y },
{ HT_DIR_HU, HT_DIR_HL },
{ HT_DIR_HL, HT_DIR_HU },
{ HT_DIR_VL, HT_DIR_VR },
{ HT_DIR_VR, HT_DIR_VL }
};
return HT_DIR_END;
}
#include "table/autorail.h"
@@ -972,18 +995,18 @@ static const HighLightStyle _autorail_type[6][2] = {
* Draws autorail highlights.
*
* @param *ti TileInfo Tile that is being drawn
* @param autorail_type Offset into _AutorailTilehSprite[][]
* @param autorail_type \c HT_DIR_XXX, offset into _AutorailTilehSprite[][]
* @param pal Palette to use, -1 to autodetect
*/
static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type)
static void DrawAutorailSelection(const TileInfo *ti, HighLightStyle autorail_type, PaletteID pal = -1)
{
SpriteID image;
PaletteID pal;
int offset;
FoundationPart foundation_part = FOUNDATION_PART_NORMAL;
Slope autorail_tileh = RemoveHalftileSlope(ti->tileh);
if (IsHalftileSlope(ti->tileh)) {
static const uint _lower_rail[4] = { 5U, 2U, 4U, 3U };
static const HighLightStyle _lower_rail[CORNER_END] = { HT_DIR_VR, HT_DIR_HU, HT_DIR_VL, HT_DIR_HL }; // CORNER_W, CORNER_S, CORNER_E, CORNER_N
Corner halftile_corner = GetHalftileSlopeCorner(ti->tileh);
if (autorail_type != _lower_rail[halftile_corner]) {
foundation_part = FOUNDATION_PART_HALFTILE;
@@ -992,16 +1015,17 @@ static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type)
}
}
assert(autorail_type < HT_DIR_END);
offset = _AutorailTilehSprite[autorail_tileh][autorail_type];
if (offset >= 0) {
image = SPR_AUTORAIL_BASE + offset;
pal = PAL_NONE;
if (pal == (PaletteID)-1) pal = _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE;
} else {
image = SPR_AUTORAIL_BASE - offset;
pal = PALETTE_SEL_TILE_RED;
if (pal == (PaletteID)-1) pal = PALETTE_SEL_TILE_RED;
}
DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti, 7, foundation_part);
DrawSelectionSprite(image, pal, ti, 7, foundation_part);
}
/**
@@ -1014,21 +1038,25 @@ static void DrawTileSelection(const TileInfo *ti)
bool is_redsq = _thd.redsq == ti->tile;
if (is_redsq) DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING);
/* No tile selection active? */
if ((_thd.drawstyle & HT_DRAG_MASK) == HT_NONE) return;
switch (_thd.drawstyle & HT_DRAG_MASK) {
default: break; // No tile selection active?
if (_thd.diagonal) { // We're drawing a 45 degrees rotated (diagonal) rectangle
if (IsInsideRotatedRectangle((int)ti->x, (int)ti->y)) goto draw_inner;
return;
case HT_RECT:
if (!is_redsq) {
if (IsInsideSelectedRectangle(ti->x, ti->y)) {
DrawTileSelectionRect(ti, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE);
} else if (_thd.outersize.x > 0 &&
/* Check if it's inside the outer area? */
IsInsideBS(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
IsInsideBS(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
/* Draw a blue rect. */
DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE);
}
}
break;
/* Inside the inner area? */
if (IsInsideBS(ti->x, _thd.pos.x, _thd.size.x) &&
IsInsideBS(ti->y, _thd.pos.y, _thd.size.y)) {
draw_inner:
if (_thd.drawstyle & HT_RECT) {
if (!is_redsq) DrawTileSelectionRect(ti, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE);
} else if (_thd.drawstyle & HT_POINT) {
case HT_POINT:
if (IsInsideSelectedRectangle(ti->x, ti->y)) {
/* Figure out the Z coordinate for the single dot. */
int z = 0;
FoundationPart foundation_part = FOUNDATION_PART_NORMAL;
@@ -1045,35 +1073,26 @@ draw_inner:
}
}
DrawSelectionSprite(_cur_dpi->zoom <= ZOOM_LVL_DETAIL ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti, z, foundation_part);
} else if (_thd.drawstyle & HT_RAIL) {
/* autorail highlight piece under cursor */
HighLightStyle type = _thd.drawstyle & HT_DIR_MASK;
assert(type < HT_DIR_END);
DrawAutorailSelection(ti, _autorail_type[type][0]);
} else if (IsPartOfAutoLine(ti->x, ti->y)) {
/* autorail highlighting long line */
HighLightStyle dir = _thd.drawstyle & HT_DIR_MASK;
uint side;
if (dir == HT_DIR_X || dir == HT_DIR_Y) {
side = 0;
} else {
TileIndex start = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
side = Delta(Delta(TileX(start), TileX(ti->tile)), Delta(TileY(start), TileY(ti->tile)));
}
break;
DrawAutorailSelection(ti, _autorail_type[dir][side]);
case HT_RAIL:
if (ti->tile == TileVirtXY(_thd.pos.x, _thd.pos.y)) {
assert((_thd.drawstyle & HT_DIR_MASK) < HT_DIR_END);
DrawAutorailSelection(ti, _thd.drawstyle & HT_DIR_MASK);
}
break;
case HT_LINE: {
HighLightStyle type = GetPartOfAutoLine(ti->x, ti->y, _thd.selstart, _thd.selend, _thd.drawstyle & HT_DIR_MASK);
if (type < HT_DIR_END) {
DrawAutorailSelection(ti, type);
} else if ((_thd.drawstyle & HT_POLY) && _thd.dir2 < HT_DIR_END) {
type = GetPartOfAutoLine(ti->x, ti->y, _thd.selstart2, _thd.selend2, _thd.dir2);
if (type < HT_DIR_END) DrawAutorailSelection(ti, type, PALETTE_SEL_TILE_BLUE);
}
return;
break;
}
/* Check if it's inside the outer area? */
if (!is_redsq && _thd.outersize.x > 0 &&
IsInsideBS(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
IsInsideBS(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
/* Draw a blue rect. */
DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE);
return;
}
}
@@ -1200,7 +1219,10 @@ static void ViewportAddLandscape()
_vd.last_foundation_child[1] = NULL;
_tile_type_procs[tile_type]->draw_tile_proc(&tile_info);
if (tile_info.tile != INVALID_TILE) DrawTileSelection(&tile_info);
if (tile_info.tile != INVALID_TILE){
DrawTileZoning(&tile_info);
DrawTileSelection(&tile_info);
}
}
}
}
@@ -1255,8 +1277,9 @@ static void ViewportAddTownNames(DrawPixelInfo *dpi)
const Town *t;
FOR_ALL_TOWNS(t) {
ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &t->cache.sign,
_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN,
STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK,
//_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN,
//STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK,
t->Label(), t->SmallLabel(), STR_VIEWPORT_TOWN_TINY_BLACK,
t->index, t->cache.population);
}
}
@@ -1939,7 +1962,7 @@ static void SetSelectionTilesDirty()
int x_start = _thd.pos.x;
int y_start = _thd.pos.y;
if (_thd.outersize.x != 0) {
if (_thd.outersize.x != 0 || _thd.outersize.y != 0) {
x_size += _thd.outersize.x;
x_start += _thd.offs.x;
y_size += _thd.outersize.y;
@@ -2075,7 +2098,8 @@ static bool CheckClickOnTown(const ViewPort *vp, int x, int y)
const Town *t;
FOR_ALL_TOWNS(t) {
if (CheckClickOnViewportSign(vp, x, y, &t->cache.sign)) {
ShowTownViewWindow(t->index);
if(_ctrl_pressed) TownExecuteAction(t, 4); //build statue
else ShowTownViewWindow(t->index);
return true;
}
}
@@ -2162,7 +2186,7 @@ static void PlaceObject()
}
bool HandleViewportClicked(const ViewPort *vp, int x, int y)
bool HandleViewportClicked(const ViewPort *vp, int x, int y, bool double_click)
{
const Vehicle *v = CheckClickOnVehicle(vp, x, y);
@@ -2170,6 +2194,13 @@ bool HandleViewportClicked(const ViewPort *vp, int x, int y)
if (v != NULL && VehicleClicked(v)) return true;
}
/* Double-clicking finishes current polyline and starts new one. */
if (double_click && _settings_client.gui.polyrail_double_click && (_thd.place_mode & HT_POLY)) {
ClearRailPlacementEndpoints();
SetTileSelectSize(1, 1);
return true;
}
/* Vehicle placement mode already handled above. */
if ((_thd.place_mode & HT_DRAG_MASK) != HT_NONE) {
PlaceObject();
@@ -2186,6 +2217,7 @@ bool HandleViewportClicked(const ViewPort *vp, int x, int y)
if (IsCompanyBuildableVehicleType(v)) {
v = v->First();
if (_ctrl_pressed && v->owner == _local_company) {
if (_settings_client.gui.enable_ctrl_click_start_stop)
StartStopVehicle(v, true);
} else {
ShowVehicleViewWindow(v);
@@ -2298,8 +2330,8 @@ void SetTileSelectSize(int w, int h)
void SetTileSelectBigSize(int ox, int oy, int sx, int sy)
{
_thd.offs.x = ox * TILE_SIZE;
_thd.offs.y = oy * TILE_SIZE;
_thd.new_offs.x = ox * TILE_SIZE;
_thd.new_offs.y = oy * TILE_SIZE;
_thd.new_outersize.x = sx * TILE_SIZE;
_thd.new_outersize.y = sy * TILE_SIZE;
}
@@ -2339,7 +2371,36 @@ Window *TileHighlightData::GetCallbackWnd()
return FindWindowById(this->window_class, this->window_number);
}
static HighLightStyle CalcPolyrailDrawstyle(Point pt, bool dragging);
static inline void CalcNewPolylineOutersize()
{
/* use the 'outersize' to mark the second (blue) part of a polyline selection */
if (_thd.dir2 < HT_DIR_END) {
/* get bounds of the second part */
int outer_x1 = _thd.selstart2.x & ~TILE_UNIT_MASK;
int outer_y1 = _thd.selstart2.y & ~TILE_UNIT_MASK;
int outer_x2 = _thd.selend2.x & ~TILE_UNIT_MASK;
int outer_y2 = _thd.selend2.y & ~TILE_UNIT_MASK;
if (outer_x1 > outer_x2) Swap(outer_x1, outer_x2);
if (outer_y1 > outer_y2) Swap(outer_y1, outer_y2);
/* include the first part */
outer_x1 = min<int>(outer_x1, _thd.new_pos.x);
outer_y1 = min<int>(outer_y1, _thd.new_pos.y);
outer_x2 = max<int>(outer_x2, _thd.new_pos.x + _thd.new_size.x - TILE_SIZE);
outer_y2 = max<int>(outer_y2, _thd.new_pos.y + _thd.new_size.y - TILE_SIZE);
/* write new values */
_thd.new_offs.x = outer_x1 - _thd.new_pos.x;
_thd.new_offs.y = outer_y1 - _thd.new_pos.y;
_thd.new_outersize.x = outer_x2 - outer_x1 + TILE_SIZE - _thd.new_size.x;
_thd.new_outersize.y = outer_y2 - outer_y1 + TILE_SIZE - _thd.new_size.y;
} else {
_thd.new_offs.x = 0;
_thd.new_offs.y = 0;
_thd.new_outersize.x = 0;
_thd.new_outersize.y = 0;
}
}
/**
* Updates tile highlighting for all cases.
@@ -2379,6 +2440,9 @@ void UpdateTileSelection()
_thd.new_size.x += TILE_SIZE;
_thd.new_size.y += TILE_SIZE;
}
if (_thd.place_mode & HT_POLY) {
CalcNewPolylineOutersize();
}
new_drawstyle = _thd.next_drawstyle;
}
} else if ((_thd.place_mode & HT_DRAG_MASK) != HT_NONE) {
@@ -2396,10 +2460,39 @@ void UpdateTileSelection()
y1 += TILE_SIZE / 2;
break;
case HT_RAIL:
case HT_LINE:
/* HT_POLY */
if (_thd.place_mode & HT_POLY) {
if (_rail_snap_points.Length() > 0) {
new_drawstyle = CalcPolyrailDrawstyle(pt, false);
if (new_drawstyle != HT_NONE) {
x1 = _thd.selstart.x & ~TILE_UNIT_MASK;
y1 = _thd.selstart.y & ~TILE_UNIT_MASK;
int x2 = _thd.selend.x & ~TILE_UNIT_MASK;
int y2 = _thd.selend.y & ~TILE_UNIT_MASK;
if (x1 > x2) Swap(x1, x2);
if (y1 > y2) Swap(y1, y2);
_thd.new_pos.x = x1;
_thd.new_pos.y = y1;
_thd.new_size.x = x2 - x1 + TILE_SIZE;
_thd.new_size.y = y2 - y1 + TILE_SIZE;
CalcNewPolylineOutersize();
}
break;
}
_thd.new_offs.x = 0;
_thd.new_offs.y = 0;
_thd.new_outersize.x = 0;
_thd.new_outersize.y = 0;
_thd.dir2 = HT_DIR_END;
}
/* HT_RAIL */
if (_thd.place_mode & HT_RAIL) {
/* Draw one highlighted tile in any direction */
new_drawstyle = GetAutorailHT(pt.x, pt.y);
break;
case HT_LINE:
}
/* HT_LINE */
switch (_thd.place_mode & HT_DIR_MASK) {
case HT_DIR_X: new_drawstyle = HT_LINE | HT_DIR_X; break;
case HT_DIR_Y: new_drawstyle = HT_LINE | HT_DIR_Y; break;
@@ -2418,6 +2511,8 @@ void UpdateTileSelection()
}
_thd.selstart.x = x1 & ~TILE_UNIT_MASK;
_thd.selstart.y = y1 & ~TILE_UNIT_MASK;
_thd.selend.x = x1;
_thd.selend.y = y1;
break;
default:
NOT_REACHED();
@@ -2432,6 +2527,7 @@ void UpdateTileSelection()
if (_thd.drawstyle != new_drawstyle ||
_thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y ||
_thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y ||
_thd.offs.x != _thd.new_offs.x || _thd.offs.y != _thd.new_offs.y ||
_thd.outersize.x != _thd.new_outersize.x ||
_thd.outersize.y != _thd.new_outersize.y ||
_thd.diagonal != new_diagonal) {
@@ -2441,6 +2537,7 @@ void UpdateTileSelection()
_thd.drawstyle = new_drawstyle;
_thd.pos = _thd.new_pos;
_thd.size = _thd.new_size;
_thd.offs = _thd.new_offs;
_thd.outersize = _thd.new_outersize;
_thd.diagonal = new_diagonal;
_thd.dirty = 0xff;
@@ -2490,6 +2587,7 @@ void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDrag
} else if (_thd.place_mode & (HT_RAIL | HT_LINE)) {
_thd.place_mode = HT_SPECIAL | others;
_thd.next_drawstyle = _thd.drawstyle | others;
_current_snap_lock.x = -1;
} else {
_thd.place_mode = HT_SPECIAL | others;
_thd.next_drawstyle = HT_POINT | others;
@@ -2681,7 +2779,31 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t
return (int)(h1 - h0) * TILE_HEIGHT_STEP;
}
static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
static void ShowLengthMeasurement(HighLightStyle style, TileIndex start_tile, TileIndex end_tile, TooltipCloseCondition close_cond = TCC_LEFT_CLICK, bool show_single_tile_length = false)
{
static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
if (_settings_client.gui.measure_tooltip) {
uint distance = DistanceManhattan(start_tile, end_tile) + 1;
byte index = 0;
uint64 params[2];
if (show_single_tile_length || distance != 1) {
int heightdiff = CalcHeightdiff(style, distance, start_tile, end_tile);
/* If we are showing a tooltip for horizontal or vertical drags,
* 2 tiles have a length of 1. To bias towards the ceiling we add
* one before division. It feels more natural to count 3 lengths as 2 */
if ((style & HT_DIR_MASK) != HT_DIR_X && (style & HT_DIR_MASK) != HT_DIR_Y) {
distance = CeilDiv(distance, 2);
}
params[index++] = distance;
if (heightdiff != 0) params[index++] = heightdiff;
}
ShowMeasurementTooltips(measure_strings_length[index], index, params, close_cond);
}
}
/**
* Check for underflowing the map.
@@ -2712,6 +2834,162 @@ static void CheckOverflow(int &test, int &other, int max, int mult)
test = max;
}
static const uint X_DIRS = (1 << DIR_NE) | (1 << DIR_SW);
static const uint Y_DIRS = (1 << DIR_SE) | (1 << DIR_NW);
static const uint HORZ_DIRS = (1 << DIR_W) | (1 << DIR_E);
static const uint VERT_DIRS = (1 << DIR_N) | (1 << DIR_S);
Trackdir PointDirToTrackdir(const Point &pt, Direction dir)
{
Trackdir ret;
if (IsDiagonalDirection(dir)) {
ret = DiagDirToDiagTrackdir(DirToDiagDir(dir));
} else {
int x = pt.x & TILE_UNIT_MASK;
int y = pt.y & TILE_UNIT_MASK;
int ns = x + y;
int we = y - x;
if (HasBit(HORZ_DIRS, dir)) {
ret = TrackDirectionToTrackdir(ns < (int)TILE_SIZE ? TRACK_UPPER : TRACK_LOWER, dir);
} else {
ret = TrackDirectionToTrackdir(we < 0 ? TRACK_LEFT : TRACK_RIGHT, dir);
}
}
return ret;
}
static bool FindPolyline(const Point &pt, const LineSnapPoint &start, Polyline *ret)
{
/* relative coordinats of the mouse point (offset against the snap point) */
int x = pt.x - start.x;
int y = pt.y - start.y;
int we = y - x;
int ns = x + y;
/* in-tile alignment of the snap point (there are two variants: [0, 8] or [8, 0]) */
uint align_x = start.x & TILE_UNIT_MASK;
uint align_y = start.y & TILE_UNIT_MASK;
assert((align_x == TILE_SIZE / 2 && align_y == 0 && !(start.dirs & X_DIRS)) || (align_x == 0 && align_y == TILE_SIZE / 2 && !(start.dirs & Y_DIRS)));
/* absolute distance between points (in tiles) */
uint d_x = abs(RoundDivSU(x < 0 ? x - align_y : x + align_y, TILE_SIZE));
uint d_y = abs(RoundDivSU(y < 0 ? y - align_x : y + align_x, TILE_SIZE));
uint d_ns = abs(RoundDivSU(ns, TILE_SIZE));
uint d_we = abs(RoundDivSU(we, TILE_SIZE));
/* Find on which quadrant is the mouse point (reltively to the snap point).
* Numeration (clockwise like in Direction):
* ortho diag
* \ 2 / 2 | 3
* \ / --+---> [we]
* 1 X 3 1 | 0
* / \ v
* [x] 0 [y] [ns] */
uint ortho_quadrant = 2 * (x < 0) + ((x < 0) != (y < 0)); // implicit cast: false/true --> 0/1
uint diag_quadrant = 2 * (ns < 0) + ((ns < 0) != (we < 0));
/* direction from the snap point to the mouse point */
Direction ortho_line_dir = ChangeDir(DIR_S, (DirDiff)(2 * ortho_quadrant)); // DIR_S is the middle of the ortho quadrant no. 0
Direction diag_line_dir = ChangeDir(DIR_SE, (DirDiff)(2 * diag_quadrant)); // DIR_SE is the middle of the diag quadrant no. 0
if (!HasBit(start.dirs, ortho_line_dir) && !HasBit(start.dirs, diag_line_dir)) return false;
/* length of booth segments of auto line (choosing orthogonal direction first) */
uint ortho_len = 0, ortho_len2 = 0;
if (HasBit(start.dirs, ortho_line_dir)) {
bool is_len_even = (align_x != 0) ? d_x >= d_y : d_x <= d_y;
ortho_len = 2 * min(d_x, d_y) - (int)is_len_even;
assert((int)ortho_len >= 0);
if (d_ns == 0 || d_we == 0) { // just single segment?
ortho_len++;
} else {
ortho_len2 = abs((int)d_x - (int)d_y) + (int)is_len_even;
}
}
/* length of booth segments of auto line (choosing diagonal direction first) */
uint diag_len = 0, diag_len2 = 0;
if (HasBit(start.dirs, diag_line_dir)) {
if (d_x == 0 || d_y == 0) { // just single segment?
diag_len = d_x + d_y;
} else {
diag_len = min(d_ns, d_we);
diag_len2 = d_x + d_y - diag_len;
}
}
/* choose the best variant */
if (ortho_len != 0 && diag_len != 0) {
/* in the first place, choose this line whose first segment ends up closer
* to the mouse point (thus the second segment is shorter) */
int cmp = ortho_len2 - diag_len2;
/* if equeal, choose the shorter line */
if (cmp == 0) cmp = ortho_len - diag_len;
/* finally look at small "units" and choose the line which is closer to the mouse point */
if (cmp == 0) cmp = min(abs(we), abs(ns)) - min(abs(x), abs(y));
/* based on comparison, disable one of variants */
if (cmp > 0) {
ortho_len = 0;
} else {
diag_len = 0;
}
}
/* store results */
if (ortho_len != 0) {
ret->first_dir = ortho_line_dir;
ret->first_len = ortho_len;
ret->second_dir = (ortho_len2 != 0) ? diag_line_dir : INVALID_DIR;
ret->second_len = ortho_len2;
} else if (diag_len != 0) {
ret->first_dir = diag_line_dir;
ret->first_len = diag_len;
ret->second_dir = (diag_len2 != 0) ? ortho_line_dir : INVALID_DIR;
ret->second_len = diag_len2;
} else {
return false;
}
ret->start = start;
return true;
}
/**
* Calculate squared euclidean distance between two points.
* @param a the first point
* @param b the second point
* @return |b - a| ^ 2
*/
static inline uint SqrDist(const Point &a, const Point &b)
{
return (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y);
}
static LineSnapPoint *FindBestPolyline(const Point &pt, LineSnapPoint *snap_points, uint num_points, Polyline *ret)
{
while (num_points > 0) {
/* run a single bubble sort loop to find the closest snap point (push it to the and of the array) */
uint prev_dist = SqrDist(snap_points[0], pt);
for (uint i = 1; i < num_points; i++) {
uint next_dist = SqrDist(snap_points[i], pt);
if (prev_dist < next_dist) {
Swap(snap_points[i], snap_points[i - 1]);
} else {
prev_dist = next_dist;
}
}
/* try to fit a line */
if (FindPolyline(pt, snap_points[num_points - 1], ret)) return &snap_points[num_points - 1];
/* repeat procedure for the rest of snap points */
--num_points;
}
return NULL;
}
/** while dragging */
static void CalcRaildirsDrawstyle(int x, int y, int method)
{
@@ -2898,32 +3176,78 @@ static void CalcRaildirsDrawstyle(int x, int y, int method)
}
}
if (_settings_client.gui.measure_tooltip) {
TileIndex t0 = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
TileIndex t1 = TileVirtXY(x, y);
uint distance = DistanceManhattan(t0, t1) + 1;
byte index = 0;
uint64 params[2];
if (distance != 1) {
int heightdiff = CalcHeightdiff(b, distance, t0, t1);
/* If we are showing a tooltip for horizontal or vertical drags,
* 2 tiles have a length of 1. To bias towards the ceiling we add
* one before division. It feels more natural to count 3 lengths as 2 */
if ((b & HT_DIR_MASK) != HT_DIR_X && (b & HT_DIR_MASK) != HT_DIR_Y) {
distance = CeilDiv(distance, 2);
}
params[index++] = distance;
if (heightdiff != 0) params[index++] = heightdiff;
}
ShowMeasurementTooltips(measure_strings_length[index], index, params);
}
_thd.selend.x = x;
_thd.selend.y = y;
_thd.next_drawstyle = b;
ShowLengthMeasurement(b, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y));
}
static HighLightStyle CalcPolyrailDrawstyle(Point pt, bool dragging)
{
/* find the best track */
Polyline line;
HighLightStyle ret = HT_LINE | HT_POLY;
if (!dragging) {
_current_snap_lock.x = -1;
if (FindBestPolyline(pt, _rail_snap_points.Begin(), _rail_snap_points.Length(), &line) == NULL) ret = HT_NONE; // no match
} else if (_current_snap_lock.x != -1) {
if (FindBestPolyline(pt, &_current_snap_lock, 1, &line) == NULL) ret = HT_NONE; // no match
} else {
const LineSnapPoint *snap_point = FindBestPolyline(pt, _rail_snap_points.Begin(), _rail_snap_points.Length(), &line);
if (snap_point == NULL) {
ret = HT_NONE; // no match
} else {
_current_snap_lock = *snap_point;
_current_snap_lock.dirs &= (1 << line.first_dir) | (1 << ReverseDir(line.first_dir)); // lock direction
}
}
if (ret == HT_NONE) {
_thd.selstart.x = -1;
_thd.selend.x = -1;
_thd.selstart2.x = -1;
_thd.selend2.x = -1;
_thd.dir2 = HT_DIR_END;
return ret;
}
TileIndexDiffC first_dir = TileIndexDiffCByDir(line.first_dir);
_thd.selstart.x = line.start.x;
_thd.selstart.y = line.start.y;
_thd.selend.x = _thd.selstart.x + line.first_len * first_dir.x * (IsDiagonalDirection(line.first_dir) ? TILE_SIZE : TILE_SIZE / 2);
_thd.selend.y = _thd.selstart.y + line.first_len * first_dir.y * (IsDiagonalDirection(line.first_dir) ? TILE_SIZE : TILE_SIZE / 2);
_thd.selstart2.x = _thd.selend.x;
_thd.selstart2.y = _thd.selend.y;
_thd.selstart.x += first_dir.x;
_thd.selstart.y += first_dir.y;
_thd.selend.x -= first_dir.x;
_thd.selend.y -= first_dir.y;
Trackdir seldir = PointDirToTrackdir(_thd.selstart, line.first_dir);
_thd.selstart.x &= ~TILE_UNIT_MASK;
_thd.selstart.y &= ~TILE_UNIT_MASK;
ret |= (HighLightStyle)TrackdirToTrack(seldir);
if (line.second_len != 0) {
TileIndexDiffC second_dir = TileIndexDiffCByDir(line.second_dir);
_thd.selend2.x = _thd.selstart2.x + line.second_len * second_dir.x * (IsDiagonalDirection(line.second_dir) ? TILE_SIZE : TILE_SIZE / 2);
_thd.selend2.y = _thd.selstart2.y + line.second_len * second_dir.y * (IsDiagonalDirection(line.second_dir) ? TILE_SIZE : TILE_SIZE / 2);
_thd.selstart2.x += second_dir.x;
_thd.selstart2.y += second_dir.y;
_thd.selend2.x -= second_dir.x;
_thd.selend2.y -= second_dir.y;
Trackdir seldir2 = PointDirToTrackdir(_thd.selstart2, line.second_dir);
_thd.selstart2.x &= ~TILE_UNIT_MASK;
_thd.selstart2.y &= ~TILE_UNIT_MASK;
_thd.dir2 = (HighLightStyle)TrackdirToTrack(seldir2);
} else {
_thd.dir2 = HT_DIR_END;
}
ShowLengthMeasurement(ret, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), TCC_HOVER, true);
return ret;
}
/**
@@ -2943,6 +3267,12 @@ void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method)
return;
}
if ((_thd.place_mode & HT_POLY) && _rail_snap_points.Length() > 0) {
Point pt = { x, y };
_thd.next_drawstyle = CalcPolyrailDrawstyle(pt, true);
return;
}
/* Special handling of drag in any (8-way) direction */
if (method & (VPM_RAILDIRS | VPM_SIGNALDIRS)) {
_thd.selend.x = x;
@@ -2995,27 +3325,12 @@ calc_heightdiff_single_direction:;
x = sx + Clamp(x - sx, -limit, limit);
y = sy + Clamp(y - sy, -limit, limit);
}
if (_settings_client.gui.measure_tooltip) {
TileIndex t0 = TileVirtXY(sx, sy);
TileIndex t1 = TileVirtXY(x, y);
uint distance = DistanceManhattan(t0, t1) + 1;
byte index = 0;
uint64 params[2];
if (distance != 1) {
/* With current code passing a HT_LINE style to calculate the height
* difference is enough. However if/when a point-tool is created
* with this method, function should be called with new_style (below)
* instead of HT_LINE | style case HT_POINT is handled specially
* new_style := (_thd.next_drawstyle & HT_RECT) ? HT_LINE | style : _thd.next_drawstyle; */
int heightdiff = CalcHeightdiff(HT_LINE | style, 0, t0, t1);
params[index++] = distance;
if (heightdiff != 0) params[index++] = heightdiff;
}
ShowMeasurementTooltips(measure_strings_length[index], index, params);
}
ShowLengthMeasurement(HT_LINE | style, TileVirtXY(sx, sy), TileVirtXY(x, y));
break;
case VPM_X_AND_Y_LIMITED: // Drag an X by Y constrained rect area.
@@ -3126,7 +3441,7 @@ EventState VpHandlePlaceSizingDrag()
} else if (_thd.select_method & VPM_SIGNALDIRS) {
_thd.place_mode = HT_RECT | others;
} else if (_thd.select_method & VPM_RAILDIRS) {
_thd.place_mode = (_thd.select_method & ~VPM_RAILDIRS) ? _thd.next_drawstyle : (HT_RAIL | others);
_thd.place_mode = (_thd.select_method & ~VPM_RAILDIRS ? _thd.next_drawstyle : HT_RAIL) | others;
} else {
_thd.place_mode = HT_POINT | others;
}
@@ -3193,6 +3508,69 @@ void ResetObjectToPlace()
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
}
static LineSnapPoint LineSnapPointAtRailTrackEndpoint(TileIndex tile, DiagDirection exit_dir, bool bidirectional)
{
LineSnapPoint ret;
ret.x = (TILE_SIZE / 2) * (uint)(2 * TileX(tile) + TileIndexDiffCByDiagDir(exit_dir).x + 1);
ret.y = (TILE_SIZE / 2) * (uint)(2 * TileY(tile) + TileIndexDiffCByDiagDir(exit_dir).y + 1);
ret.dirs = 0;
SetBit(ret.dirs, DiagDirToDir(exit_dir));
SetBit(ret.dirs, ChangeDir(DiagDirToDir(exit_dir), DIRDIFF_45LEFT));
SetBit(ret.dirs, ChangeDir(DiagDirToDir(exit_dir), DIRDIFF_45RIGHT));
if (bidirectional) ret.dirs |= ROR<uint8>(ret.dirs, DIRDIFF_REVERSE);
return ret;
}
/**
* Store the position of lastly built rail track; for highlighting purposes.
*
* In "polyline" highlighting mode, the stored end point will be used as a snapping point for new
* tracks allowing to place multi-segment polylines.
*
* @param start_tile tile where the track starts
* @param end_tile tile where the track ends
* @param start_track track piece on the start_tile
* @param bidirectional_exit whether to allow to highlight next track in any direction; otherwise new track will have to fallow the stored one (usefull when placing tunnels and bridges)
*/
void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track start_track, bool bidirectional_exit)
{
if (start_tile != INVALID_TILE && end_tile != INVALID_TILE) {
/* calculate trackdirs at booth ends of the track */
Trackdir exit_trackdir_at_start = TrackToTrackdir(start_track);
Trackdir exit_trackdir_at_end = ReverseTrackdir(TrackToTrackdir(start_track));
if (start_tile != end_tile) { // multi-tile case
/* determine proper direction (pointing outside of the track) */
uint distance = DistanceManhattan(start_tile, end_tile);
if (distance > DistanceManhattan(TileAddByDiagDir(start_tile, TrackdirToExitdir(exit_trackdir_at_start)), end_tile)) {
Swap(exit_trackdir_at_start, exit_trackdir_at_end);
}
/* determine proper track on the end tile - switch between upper/lower or left/right based on the length */
if (distance % 2 != 0) exit_trackdir_at_end = NextTrackdir(exit_trackdir_at_end);
}
LineSnapPoint snap_start = LineSnapPointAtRailTrackEndpoint(start_tile, TrackdirToExitdir(exit_trackdir_at_start), bidirectional_exit);
LineSnapPoint snap_end = LineSnapPointAtRailTrackEndpoint(end_tile, TrackdirToExitdir(exit_trackdir_at_end), bidirectional_exit);
/* Find if we already had these coordinates before. */
LineSnapPoint *snap;
for (snap = _rail_snap_points.Begin(); snap != _rail_snap_points.End(); snap++) {
/* Coordinates found - remove the snap point as it was already used. */
if (snap->x == snap_start.x && snap->y == snap_start.y) snap_start.dirs = 0;
if (snap->x == snap_end.x && snap->y == snap_end.y) snap_end.dirs = 0;
}
/* Create new snap point set. */
_rail_snap_points.Clear();
if (snap_start.dirs != 0) *_rail_snap_points.Append() = snap_start;
if (snap_end.dirs != 0) *_rail_snap_points.Append() = snap_end;
}
}
void ClearRailPlacementEndpoints()
{
_rail_snap_points.Clear();
}
Point GetViewportStationMiddle(const ViewPort *vp, const Station *st)
{
int x = TileX(st->xy) * TILE_SIZE;

View File

@@ -59,7 +59,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie
void StartSpriteCombine();
void EndSpriteCombine();
bool HandleViewportClicked(const ViewPort *vp, int x, int y);
bool HandleViewportClicked(const ViewPort *vp, int x, int y, bool double_click);
void SetRedErrorSquare(TileIndex tile);
void SetTileSelectSize(int w, int h);
void SetTileSelectBigSize(int ox, int oy, int sx, int sy);

View File

@@ -154,6 +154,11 @@ public:
/* Only handle zoom message if intended for us (msg ZOOM_IN/ZOOM_OUT) */
HandleZoomMessage(this, this->viewport, WID_EV_ZOOM_IN, WID_EV_ZOOM_OUT);
}
virtual void OnMouseOver(Point pt, int widget)
{
if (_settings_client.gui.enable_extra_tooltips && pt.x != -1) GuiPrepareTooltipsExtra(this);
}
};
static WindowDesc _extra_view_port_desc(

View File

@@ -116,6 +116,7 @@ enum ViewportDragDropSelectionProcess {
DDSP_PLACE_ROAD_X_DIR, ///< Road placement (X axis)
DDSP_PLACE_ROAD_Y_DIR, ///< Road placement (Y axis)
DDSP_PLACE_AUTOROAD, ///< Road placement (auto)
DDSP_PLACE_FULLROAD, ///< Road placement (auto, full roads)
DDSP_BUILD_BUSSTOP, ///< Road stop placement (buses)
DDSP_BUILD_TRUCKSTOP, ///< Road stop placement (trucks)
DDSP_REMOVE_BUSSTOP, ///< Road stop removal (buses)

View File

@@ -52,6 +52,10 @@ enum CompanyWidgets {
WID_C_SELECT_MULTIPLAYER, ///< Multiplayer selection panel.
WID_C_COMPANY_PASSWORD, ///< Button to set company password.
WID_C_COMPANY_JOIN, ///< Button to join company.
CW_WIDGET_COMPANY_JOIN2,
CW_WIDGET_COMPANY_RESET,
CW_WIDGET_COMPANY_SUSPEND,
CW_WIDGET_COMPANY_RESUME,
};
/** Widgets of the #CompanyFinancesWindow class. */

View File

@@ -42,7 +42,12 @@ void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool
{
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, this->String(), sel ? TC_WHITE : TC_BLACK);
}
/*
const char * DropDownListCharStringItem::String() const
{
return this->string;
}
*/
/**
* Natural sorting comparator function for DropDownList::sort().
* @param first Left side of comparison.

View File

@@ -16,6 +16,11 @@
#include "../gfx_func.h"
#include "../core/smallvec_type.hpp"
#include "table/strings.h"
#include "../stdafx.h"
#include "../window_gui.h"
#include "../string_func.h"
#include "../strings_func.h"
#include "../window_func.h"
/**
* Base list item class from which others are derived. If placed in a list it
@@ -47,12 +52,46 @@ public:
virtual bool Selectable() const { return true; }
virtual uint Width() const;
//virtual const char * String() const;
virtual void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const;
virtual StringID String() const { return this->string; }
static int CDECL NatSortFunc(const DropDownListItem * const *first, const DropDownListItem * const *second);
};
/**
* Drop down list entry for showing a checked/unchecked toggle item. Use
* DropDownListCheckedItem or DropDownListCharStringCheckedItem depending of
* type of string used (either StringID or const char*).
*/
template <class T, typename S>
class DropDownListCheckedItemT : public T {
uint checkmark_width;
public:
bool checked;
DropDownListCheckedItemT<T,S>(S string, int result, bool masked, bool checked) : T(string, result, masked), checked(checked)
{
this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3;
}
virtual ~DropDownListCheckedItemT<T,S>() {}
virtual uint Width() const
{
return T::Width() + this->checkmark_width;
}
virtual void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
{
bool rtl = _current_text_dir == TD_RTL;
if (this->checked) {
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK);
}
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK);
}
};
#define DropDownListCheckedItem DropDownListCheckedItemT<DropDownListStringItem,StringID>
#define DropDownListCharStringCheckedItem DropDownListCheckedItemT<DropDownListCharStringItem,const char*>
/**
* String list item with parameters.
*/

View File

@@ -29,6 +29,10 @@ enum CompanyValueWidgets {
WID_CV_BACKGROUND, ///< Background of the window.
WID_CV_GRAPH, ///< Graph itself.
WID_CV_RESIZE, ///< Resize button.
WID_CPR2_FOOTER, ///< Footer.
WID_CPR2_ENABLE_CARGOES, ///< Enable cargoes button.
WID_CPR2_DISABLE_CARGOES, ///< Disable cargoes button.
WID_CPR2_CARGO_FIRST, ///< First cargo in the list.
};
/** Widget of the #PerformanceHistoryGraphWindow class. */

View File

@@ -34,6 +34,7 @@ enum IndustryViewWidgets {
enum IndustryDirectoryWidgets {
WID_ID_DROPDOWN_ORDER, ///< Dropdown for the order of the sort.
WID_ID_DROPDOWN_CRITERIA, ///< Dropdown for the criteria of the sort.
WID_ID_DROPDOWN_FILTER, ///< Industry filter
WID_ID_INDUSTRY_LIST, ///< Industry list.
WID_ID_SCROLLBAR, ///< Scrollbar of the list.
};

View File

@@ -51,6 +51,11 @@ enum NetworkGameWidgets {
WID_NG_ADD, ///< 'Add server' button.
WID_NG_START, ///< 'Start server' button.
WID_NG_CANCEL, ///< 'Cancel' button.
WID_NG_NOVA, ///< filter nova
WID_NG_REDDIT, ///< filter reddit
WID_NG_NICE, ///< filter n-ice
WID_NG_BTPRO, ///< filter btpro
};
/** Widgets of the #NetworkStartServerWindow class. */

View File

@@ -21,6 +21,7 @@ enum RailToolbarWidgets {
WID_RAT_BUILD_EW, ///< Build rail along the game view X axis.
WID_RAT_BUILD_Y, ///< Build rail along the game grid Y axis.
WID_RAT_AUTORAIL, ///< Autorail tool.
WID_RAT_POLYRAIL, ///< Polyline rail tool.
WID_RAT_DEMOLISH, ///< Destroy something with dynamite!
WID_RAT_BUILD_DEPOT, ///< Build a depot.
WID_RAT_BUILD_WAYPOINT, ///< Build a waypoint.
@@ -99,10 +100,11 @@ enum BuildSignalWidgets {
/** Widgets of the #BuildRailDepotWindow class. */
enum BuildRailDepotWidgets {
/* Name starts with BRA instead of BR, because of collision with BuildRoadDepotWidgets */
WID_BRAD_DEPOT_NE, ///< Build a depot with the entrance in the north east.
WID_BRAD_DEPOT_SE, ///< Build a depot with the entrance in the south east.
WID_BRAD_DEPOT_SW, ///< Build a depot with the entrance in the south west.
WID_BRAD_DEPOT_NW, ///< Build a depot with the entrance in the north west.
WID_BRAD_DEPOT_NE, ///< Build a depot with the entrance in the north east.
WID_BRAD_DEPOT_SE, ///< Build a depot with the entrance in the south east.
WID_BRAD_DEPOT_SW, ///< Build a depot with the entrance in the south west.
WID_BRAD_DEPOT_NW, ///< Build a depot with the entrance in the north west.
WID_BRAD_DEPOT_AUTO, ///< Build a depot, autoselect entrance.
};
/** Widgets of the #BuildRailWaypointWindow class. */

View File

@@ -17,7 +17,8 @@ enum RoadToolbarWidgets {
/* Name starts with RO instead of R, because of collision with RailToolbarWidgets */
WID_ROT_ROAD_X, ///< Build road in x-direction.
WID_ROT_ROAD_Y, ///< Build road in y-direction.
WID_ROT_AUTOROAD, ///< Autorail.
WID_ROT_AUTOROAD, ///< Autoroad.
WID_ROT_FULLROAD, ///< Auto full road (no half-tiles).
WID_ROT_DEMOLISH, ///< Demolish.
WID_ROT_DEPOT, ///< Build depot.
WID_ROT_BUS_STATION, ///< Build bus station.
@@ -31,27 +32,30 @@ enum RoadToolbarWidgets {
/** Widgets of the #BuildRoadDepotWindow class. */
enum BuildRoadDepotWidgets {
/* Name starts with BRO instead of BR, because of collision with BuildRailDepotWidgets */
WID_BROD_CAPTION, ///< Caption of the window.
WID_BROD_DEPOT_NE, ///< Depot with NE entry.
WID_BROD_DEPOT_SE, ///< Depot with SE entry.
WID_BROD_DEPOT_SW, ///< Depot with SW entry.
WID_BROD_DEPOT_NW, ///< Depot with NW entry.
WID_BROD_CAPTION, ///< Caption of the window.
WID_BROD_DEPOT_NE, ///< Depot with NE entry.
WID_BROD_DEPOT_SE, ///< Depot with SE entry.
WID_BROD_DEPOT_SW, ///< Depot with SW entry.
WID_BROD_DEPOT_NW, ///< Depot with NW entry.
WID_BROD_DEPOT_AUTO, ///< Depot, autodetect entry.
};
/** Widgets of the #BuildRoadStationWindow class. */
enum BuildRoadStationWidgets {
/* Name starts with BRO instead of BR, because of collision with BuildRailStationWidgets */
WID_BROS_CAPTION, ///< Caption of the window.
WID_BROS_BACKGROUND, ///< Background of the window.
WID_BROS_STATION_NE, ///< Terminal station with NE entry.
WID_BROS_STATION_SE, ///< Terminal station with SE entry.
WID_BROS_STATION_SW, ///< Terminal station with SW entry.
WID_BROS_STATION_NW, ///< Terminal station with NW entry.
WID_BROS_STATION_X, ///< Drive-through station in x-direction.
WID_BROS_STATION_Y, ///< Drive-through station in y-direction.
WID_BROS_LT_OFF, ///< Turn off area highlight.
WID_BROS_LT_ON, ///< Turn on area highlight.
WID_BROS_INFO, ///< Station acceptance info.
WID_BROS_CAPTION, ///< Caption of the window.
WID_BROS_BACKGROUND, ///< Background of the window.
WID_BROS_STATION_NE, ///< Terminal station with NE entry.
WID_BROS_STATION_SE, ///< Terminal station with SE entry.
WID_BROS_STATION_SW, ///< Terminal station with SW entry.
WID_BROS_STATION_NW, ///< Terminal station with NW entry.
WID_BROS_STATION_X, ///< Drive-through station in x-direction.
WID_BROS_STATION_Y, ///< Drive-through station in y-direction.
WID_BROS_STATION_AUTO, ///< Terminal station, autoselect entry.
WID_BROS_STATION_XY_AUTO, ///< Drive-through station, autoselect direction.
WID_BROS_LT_OFF, ///< Turn off area highlight.
WID_BROS_LT_ON, ///< Turn on area highlight.
WID_BROS_INFO, ///< Station acceptance info.
};
#endif /* WIDGETS_ROAD_WIDGET_H */

View File

@@ -23,9 +23,11 @@ enum ToolbarNormalWidgets {
WID_TN_SUBSIDIES, ///< Subsidy menu.
WID_TN_STATIONS, ///< Station menu.
WID_TN_FINANCES, ///< Finance menu.
WID_TN_CARGOS, ///< Transported cargo menu
WID_TN_COMPANIES, ///< Company menu.
WID_TN_STORY, ///< Story menu.
WID_TN_GOAL, ///< Goal menu.
WID_TN_WATCH, ///< Watch gui menu
WID_TN_GRAPHS, ///< Graph menu.
WID_TN_LEAGUE, ///< Company league menu.
WID_TN_INDUSTRIES, ///< Industry menu.

View File

@@ -19,6 +19,7 @@ enum TownDirectoryWidgets {
WID_TD_LIST, ///< List of towns.
WID_TD_SCROLLBAR, ///< Scrollbar for the town list.
WID_TD_WORLD_POPULATION, ///< The world's population.
TDW_CAPTION_TEXT,
};
/** Widgets of the #TownAuthorityWindow class. */
@@ -41,6 +42,7 @@ enum TownViewWidgets {
WID_TV_CHANGE_NAME, ///< Change the name of this town.
WID_TV_EXPAND, ///< Expand this town (scenario editor only).
WID_TV_DELETE, ///< Delete this town (scenario editor only).
WID_TV_CB,
};
/** Widgets of the #FoundTownWindow class. */
@@ -62,4 +64,28 @@ enum TownFoundingWidgets {
WID_TF_LAYOUT_RANDOM, ///< Selection for a randomly chosen town layout.
};
enum TownHK {
HK_SADVERT,
HK_MADVERT,
HK_LADVERT,
HK_ROADS,
HK_STATUE,
HK_FUND,
};
enum CBTownWidgets {
WID_CB_LOCATION,
WID_CB_ADVERT,
WID_CB_FUND,
WID_CB_FUND_REGULAR,
WID_CB_DETAILS,
WID_CB_CARGO_NAME,
WID_CB_CARGO_AMOUNT,
WID_CB_CARGO_REQ,
WID_CB_CARGO_PREVIOUS,
WID_CB_CARGO_STORE,
WID_CB_CARGO_STORE_PCT,
WID_CB_CARGO_FROM,
};
#endif /* WIDGETS_TOWN_WIDGET_H */

View File

@@ -11,6 +11,7 @@
#include "stdafx.h"
#include <stdarg.h>
#include <limits>
#include "company_func.h"
#include "gfx_func.h"
#include "console_func.h"
@@ -21,6 +22,7 @@
#include "zoom_func.h"
#include "vehicle_base.h"
#include "window_func.h"
#include "window_gui.h"
#include "tilehighlight_func.h"
#include "network/network.h"
#include "querystring_gui.h"
@@ -1190,6 +1192,7 @@ void ChangeWindowOwner(Owner old_owner, Owner new_owner)
switch (w->window_class) {
case WC_COMPANY_COLOUR:
case WC_FINANCES:
case WC_CARGOS:
case WC_STATION_LIST:
case WC_TRAINS_LIST:
case WC_ROADVEH_LIST:
@@ -2816,7 +2819,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
case MC_DOUBLE_LEFT:
case MC_LEFT:
DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
if (!HandleViewportClicked(vp, x, y) &&
if (!HandleViewportClicked(vp, x, y, click == MC_DOUBLE_LEFT) &&
!(w->flags & WF_DISABLE_VP_SCROLL) &&
_settings_client.gui.left_mouse_btn_scrolling) {
_scrolling_viewport = true;
@@ -3468,3 +3471,55 @@ PickerWindowBase::~PickerWindowBase()
this->window_class = WC_INVALID; // stop the ancestor from freeing the already (to be) child
ResetObjectToPlace();
}
/**
* Sets safe-initial values.
* @param t The type of positioning desired.
*/
WindowPopup::WindowPopup(WindowDesc *desc, WindowPopupType t): Window(desc)
{
this->type = t;
this->wpu_mod_x = -5;
this->wpu_mod_y = -5;
this->wpu_widget = std::numeric_limits<uint>::max();
}
/**
* Compute #WindowPopup origin Point.
*
* @param desc The window's #WindowDesc object
* @param sm_width Window's smallest_x.
* @param sm_height Window's smallest_y. Unused.
* @param window_number Unused.
* @return The origin coordinate of the window.
*/
/*virtual*/ Point WindowPopup::OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
{
int x, y;
switch (this->type) {
case WPUT_CENTERED:
x = _cursor.pos.x - sm_width / 2;
y = _cursor.pos.y - this->window_desc->GetDefaultHeight() / 2;
break;
case WPUT_WIDGET_RELATIVE:
if (this->wpu_widget != std::numeric_limits<uint>::max()) {
NWidgetBase *wid = this->GetWidget<NWidgetBase>(this->wpu_widget);
x = _cursor.pos.x - wid->pos_x + this->wpu_mod_x;
y = _cursor.pos.y - wid->pos_y + this->wpu_mod_y;
break;
}
case WPUT_ORIGIN:
default:
x = _cursor.pos.x + this->wpu_mod_x;
y = _cursor.pos.y + this->wpu_mod_y;
break;
}
Point rv;
rv.x = Clamp(x, 0, _screen.width - sm_width);
rv.y = Clamp(y, GetMainViewTop(), GetMainViewBottom() - this->window_desc->GetDefaultHeight());
return rv;
}

View File

@@ -873,6 +873,7 @@ enum TooltipCloseCondition {
};
void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const uint64 params[] = NULL, TooltipCloseCondition close_tooltip = TCC_HOVER);
void GuiPrepareTooltipsExtra(Window *parent);
/* widget.cpp */
int GetWidgetFromPos(const Window *w, int x, int y);
@@ -905,4 +906,31 @@ void SetFocusedWindow(Window *w);
void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y);
/**
* #WindowPopup positioning types
*/
enum WindowPopupType {
WPUT_ORIGIN = 1, ///< Align with the top-left corner of the window.
WPUT_WIDGET_RELATIVE, ///< Align from a nested widget.
WPUT_CENTERED, ///< Center the widget under the cursor. Ignore modifiers.
};
/**
* Specialized Window bound to open around the cursor's position.
* Its sole purpose is to provide the OnInitialPosition() method
* and an simple interface to control its behaviour.
*/
struct WindowPopup: public Window {
public:
WindowPopup(WindowDesc *desc, WindowPopupType t = WPUT_ORIGIN);
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number);
protected:
uint wpu_widget; ///< The widget to which the computation would be made from when type is #WPUT_WIDGET_RELATIVE.
int wpu_mod_x; ///< The X axis modifier. A negative value would bring the window closer to the left edge of the screen. Default value is -5.
int wpu_mod_y; ///< The Y axis modifier. A negative value would bring the window closer to the top edge of the screen. Default value is -5.
private:
WindowPopupType type;
};
#endif /* WINDOW_GUI_H */

View File

@@ -109,6 +109,7 @@ enum WindowClass {
* - 0 = #ToolTipsWidgets
*/
WC_TOOLTIPS,
WC_TOOLTIPS_EXTRA,
/**
* Query string window; %Window numbers:
@@ -370,6 +371,12 @@ enum WindowClass {
*/
WC_BUILD_OBJECT,
//watch company
WC_WATCH_COMPANY,
//watch company admin version
WC_WATCH_COMPANYA,
/**
* Build vehicle; %Window numbers:
* - #VehicleType = #BuildVehicleWidgets
@@ -516,6 +523,7 @@ enum WindowClass {
* - #CompanyID = #CompanyWidgets
*/
WC_FINANCES,
WC_CARGOS,
/**
* Income graph; %Window numbers:
@@ -681,6 +689,11 @@ enum WindowClass {
*/
WC_SAVE_PRESET,
WC_ZONING_TOOLBAR,
WC_COMMAND_TOOLBAR,
WC_LOGIN_WINDOW,
WC_CB_TOWN,
WC_INVALID = 0xFFFF, ///< Invalid window.
};