Merge branch 'master' into jgrpp

# Conflicts:
#	projects/openttd_vs140.vcxproj.filters
#	projects/openttd_vs141.vcxproj.filters
#	projects/openttd_vs142.vcxproj.filters
#	src/base_consist.h
#	src/company_base.h
#	src/newgrf_config.cpp
#	src/newgrf_config.h
#	src/openttd.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/saveload/station_sl.cpp
#	src/settings.cpp
#	src/signs_base.h
#	src/string.cpp
#	src/string_func.h
#	src/table/misc_settings.ini
#	src/table/settings.h.preamble
#	src/town_cmd.cpp
#	src/vehicle.cpp
#	src/vehicle_cmd.cpp
#	src/video/cocoa/cocoa_v.mm
#	src/video/null_v.cpp
This commit is contained in:
Jonathan G Rennison
2020-05-21 20:19:57 +01:00
162 changed files with 2519 additions and 1448 deletions

View File

@@ -528,6 +528,9 @@ See the comments in the source files in `src/3rdparty/md5` for the complete lice
The implementations of Posix `getaddrinfo` and `getnameinfo` for OS/2 in `src/3rdparty/os2` are distributed partly under the GNU Lesser General Public License 2.1, and partly under the (3-clause) BSD license. The implementations of Posix `getaddrinfo` and `getnameinfo` for OS/2 in `src/3rdparty/os2` are distributed partly under the GNU Lesser General Public License 2.1, and partly under the (3-clause) BSD license.
The exact licensing terms can be found in `src/3rdparty/os2/getaddrinfo.c` resp. `src/3rdparty/os2/getnameinfo.c`. The exact licensing terms can be found in `src/3rdparty/os2/getaddrinfo.c` resp. `src/3rdparty/os2/getnameinfo.c`.
The implementation of C++17 `std::optional` in `src/3rdparty/optional` is licensed under the Boost Software License - Version 1.0.
See `src/3rdparty/optional/LICENSE_1_0.txt` for the complete license text.
## 4.0 Credits ## 4.0 Credits

View File

@@ -65,6 +65,7 @@ output_files() {
if [ ! -e ${FOLDER}/${filename}.md5sum ] || [ ! -e ${FOLDER}/${filename}.sha1sum ] || [ ! -e ${FOLDER}/${filename}.sha256sum ]; then if [ ! -e ${FOLDER}/${filename}.md5sum ] || [ ! -e ${FOLDER}/${filename}.sha1sum ] || [ ! -e ${FOLDER}/${filename}.sha256sum ]; then
echo "ERROR: missing checksum file for ${filename}" 1>&2 echo "ERROR: missing checksum file for ${filename}" 1>&2
error="y" error="y"
shift
continue continue
fi fi

View File

@@ -63,10 +63,14 @@ Sub Lookup(ini_key, str_id, outfile)
For Each file In folder.Files For Each file In folder.Files
If UCase(FSO.GetExtensionName(file.Name)) = "TXT" Then If UCase(FSO.GetExtensionName(file.Name)) = "TXT" Then
Dim f Dim f
Set f = FSO.OpenTextFile(file.Path) Set f = CreateObject("ADODB.Stream")
f.Charset = "utf-8"
f.LineSeparator = 10 ' Assume lines end with \n even for \r\n files
f.Open
f.LoadFromFile(file.Path)
Do Until f.atEndOfStream Do Until f.EOS
line = f.ReadLine() line = Replace(f.ReadText(-2), Chr(13), "") ' Read a line and remove any \r
If InStr(1, line, "##isocode ") = 1 Then If InStr(1, line, "##isocode ") = 1 Then
p = Split(line) p = Split(line)
@@ -80,8 +84,9 @@ Sub Lookup(ini_key, str_id, outfile)
End If End If
i = i + 1 i = i + 1
End If End If
Loop Loop
f.Close
End If End If
Next Next
@@ -89,7 +94,7 @@ Sub Lookup(ini_key, str_id, outfile)
ISort output ISort output
For Each line In output For Each line In output
outfile.Write line & vbCrLf outfile.WriteText line, 1
Next Next
End Sub End Sub
@@ -100,7 +105,9 @@ Dim infile
Set infile = FSO.OpenTextFile(inputfile) Set infile = FSO.OpenTextFile(inputfile)
Dim outfile Dim outfile
Set outfile = FSO.CreateTextFile(outputfile, True) Set outfile = CreateObject("ADODB.Stream")
outfile.Charset = "utf-8"
outfile.Open
Do Until infile.atEndOfStream Do Until infile.atEndOfStream
@@ -109,15 +116,30 @@ Do Until infile.atEndOfStream
If InStr(1, line, "ORIG_EXTRA.GRF ") = 1 Then If InStr(1, line, "ORIG_EXTRA.GRF ") = 1 Then
p = Split(line, "=") p = Split(line, "=")
If Trim(p(1)) = "" Then If Trim(p(1)) = "" Then
outfile.Write("ORIG_EXTRA.GRF = " & GetExtraGrfHash() & vbCrLf) outfile.WriteText "ORIG_EXTRA.GRF = " & GetExtraGrfHash(), 1
Else Else
outfile.Write(line & vbCrLf) outfile.WriteText line, 1
End If End If
ElseIf InStr(1, line, "!! ") = 1 Then ElseIf InStr(1, line, "!! ") = 1 Then
p = Split(line) p = Split(line)
Lookup p(1), p(2), outfile Lookup p(1), p(2), outfile
Else Else
outfile.Write(line & vbCrLf) outfile.WriteText line, 1
End If End If
Loop Loop
' UTF-8 Text ADO Stream includes BOM, so we need to remove it
Dim outfile_noBOM
Set outfile_noBOM = CreateObject("ADODB.Stream")
outfile_noBOM.Type = 1
outfile_noBOM.Open
' Copy Text stream to Binary stream, skiping the BOM
outfile.Position = 3
outfile.CopyTo outfile_noBOM
outfile.Close
' Write the Binary stream
outfile_noBOM.SaveToFile outputfile, 2
outfile_noBOM.Close

View File

@@ -1029,6 +1029,8 @@
<ClInclude Include="..\src\table\water_land.h" /> <ClInclude Include="..\src\table\water_land.h" />
<ClCompile Include="..\src\3rdparty\md5\md5.cpp" /> <ClCompile Include="..\src\3rdparty\md5\md5.cpp" />
<ClInclude Include="..\src\3rdparty\md5\md5.h" /> <ClInclude Include="..\src\3rdparty\md5\md5.h" />
<ClInclude Include="..\src\3rdparty\optional\optional.hpp" />
<ClInclude Include="..\src\3rdparty\optional\ottd_optional.h" />
<ClCompile Include="..\src\script\script_config.cpp" /> <ClCompile Include="..\src\script\script_config.cpp" />
<ClInclude Include="..\src\script\script_config.hpp" /> <ClInclude Include="..\src\script\script_config.hpp" />
<ClInclude Include="..\src\script\script_fatalerror.hpp" /> <ClInclude Include="..\src\script\script_fatalerror.hpp" />

View File

@@ -28,84 +28,87 @@
<Filter Include="MD5"> <Filter Include="MD5">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000008}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000008}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script"> <Filter Include="Compat">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000009}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000009}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Squirrel"> <Filter Include="Script">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000010}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000010}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Squirrel headers"> <Filter Include="Squirrel">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000011}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000011}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="AI Core"> <Filter Include="Squirrel headers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000012}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000012}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="AI API"> <Filter Include="AI Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000013}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000013}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Game API"> <Filter Include="AI API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000014}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000014}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Game Core"> <Filter Include="Game API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000015}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000015}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script API"> <Filter Include="Game Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000016}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000016}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script API Implementation"> <Filter Include="Script API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000017}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000017}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Blitters"> <Filter Include="Script API Implementation">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000018}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000018}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Drivers"> <Filter Include="Blitters">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000019}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000019}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Sprite loaders"> <Filter Include="Drivers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000020}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000020}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="NewGRF"> <Filter Include="Sprite loaders">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000021}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000021}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Map Accessors"> <Filter Include="NewGRF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000022}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000022}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Misc"> <Filter Include="Map Accessors">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000023}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000023}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Network Core"> <Filter Include="Misc">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000024}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000024}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Pathfinder"> <Filter Include="Network Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000025}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000025}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="NPF"> <Filter Include="Pathfinder">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000026}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000026}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="YAPF"> <Filter Include="NPF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000027}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000027}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Video"> <Filter Include="YAPF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000028}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000028}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Music"> <Filter Include="Video">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000029}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000029}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Sound"> <Filter Include="Music">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000030}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000030}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Windows files"> <Filter Include="Sound">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000031}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000031}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Threading"> <Filter Include="Windows files">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000032}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000032}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Btree containers"> <Filter Include="Threading">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000033}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000033}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="MinGW threading"> <Filter Include="Btree containers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000034}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000034}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="MinGW threading">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000035}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\tbtr_template_gui_main.cpp"> <ClCompile Include="..\src\tbtr_template_gui_main.cpp">
@@ -2181,6 +2184,12 @@
<ClInclude Include="..\src\3rdparty\md5\md5.h"> <ClInclude Include="..\src\3rdparty\md5\md5.h">
<Filter>MD5</Filter> <Filter>MD5</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\3rdparty\optional\optional.hpp">
<Filter>Compat</Filter>
</ClInclude>
<ClInclude Include="..\src\3rdparty\optional\ottd_optional.h">
<Filter>Compat</Filter>
</ClInclude>
<ClCompile Include="..\src\script\script_config.cpp"> <ClCompile Include="..\src\script\script_config.cpp">
<Filter>Script</Filter> <Filter>Script</Filter>
</ClCompile> </ClCompile>

View File

@@ -1029,6 +1029,8 @@
<ClInclude Include="..\src\table\water_land.h" /> <ClInclude Include="..\src\table\water_land.h" />
<ClCompile Include="..\src\3rdparty\md5\md5.cpp" /> <ClCompile Include="..\src\3rdparty\md5\md5.cpp" />
<ClInclude Include="..\src\3rdparty\md5\md5.h" /> <ClInclude Include="..\src\3rdparty\md5\md5.h" />
<ClInclude Include="..\src\3rdparty\optional\optional.hpp" />
<ClInclude Include="..\src\3rdparty\optional\ottd_optional.h" />
<ClCompile Include="..\src\script\script_config.cpp" /> <ClCompile Include="..\src\script\script_config.cpp" />
<ClInclude Include="..\src\script\script_config.hpp" /> <ClInclude Include="..\src\script\script_config.hpp" />
<ClInclude Include="..\src\script\script_fatalerror.hpp" /> <ClInclude Include="..\src\script\script_fatalerror.hpp" />

View File

@@ -28,84 +28,87 @@
<Filter Include="MD5"> <Filter Include="MD5">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000008}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000008}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script"> <Filter Include="Compat">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000009}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000009}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Squirrel"> <Filter Include="Script">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000010}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000010}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Squirrel headers"> <Filter Include="Squirrel">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000011}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000011}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="AI Core"> <Filter Include="Squirrel headers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000012}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000012}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="AI API"> <Filter Include="AI Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000013}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000013}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Game API"> <Filter Include="AI API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000014}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000014}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Game Core"> <Filter Include="Game API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000015}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000015}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script API"> <Filter Include="Game Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000016}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000016}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script API Implementation"> <Filter Include="Script API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000017}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000017}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Blitters"> <Filter Include="Script API Implementation">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000018}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000018}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Drivers"> <Filter Include="Blitters">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000019}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000019}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Sprite loaders"> <Filter Include="Drivers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000020}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000020}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="NewGRF"> <Filter Include="Sprite loaders">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000021}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000021}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Map Accessors"> <Filter Include="NewGRF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000022}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000022}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Misc"> <Filter Include="Map Accessors">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000023}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000023}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Network Core"> <Filter Include="Misc">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000024}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000024}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Pathfinder"> <Filter Include="Network Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000025}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000025}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="NPF"> <Filter Include="Pathfinder">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000026}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000026}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="YAPF"> <Filter Include="NPF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000027}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000027}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Video"> <Filter Include="YAPF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000028}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000028}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Music"> <Filter Include="Video">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000029}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000029}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Sound"> <Filter Include="Music">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000030}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000030}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Windows files"> <Filter Include="Sound">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000031}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000031}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Threading"> <Filter Include="Windows files">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000032}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000032}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Btree containers"> <Filter Include="Threading">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000033}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000033}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="MinGW threading"> <Filter Include="Btree containers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000034}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000034}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="MinGW threading">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000035}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\tbtr_template_gui_main.cpp"> <ClCompile Include="..\src\tbtr_template_gui_main.cpp">
@@ -2181,6 +2184,12 @@
<ClInclude Include="..\src\3rdparty\md5\md5.h"> <ClInclude Include="..\src\3rdparty\md5\md5.h">
<Filter>MD5</Filter> <Filter>MD5</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\3rdparty\optional\optional.hpp">
<Filter>Compat</Filter>
</ClInclude>
<ClInclude Include="..\src\3rdparty\optional\ottd_optional.h">
<Filter>Compat</Filter>
</ClInclude>
<ClCompile Include="..\src\script\script_config.cpp"> <ClCompile Include="..\src\script\script_config.cpp">
<Filter>Script</Filter> <Filter>Script</Filter>
</ClCompile> </ClCompile>

View File

@@ -100,7 +100,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Full</Optimization> <Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
@@ -168,7 +168,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -223,7 +223,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Full</Optimization> <Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
@@ -289,7 +289,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -1029,6 +1029,8 @@
<ClInclude Include="..\src\table\water_land.h" /> <ClInclude Include="..\src\table\water_land.h" />
<ClCompile Include="..\src\3rdparty\md5\md5.cpp" /> <ClCompile Include="..\src\3rdparty\md5\md5.cpp" />
<ClInclude Include="..\src\3rdparty\md5\md5.h" /> <ClInclude Include="..\src\3rdparty\md5\md5.h" />
<ClInclude Include="..\src\3rdparty\optional\optional.hpp" />
<ClInclude Include="..\src\3rdparty\optional\ottd_optional.h" />
<ClCompile Include="..\src\script\script_config.cpp" /> <ClCompile Include="..\src\script\script_config.cpp" />
<ClInclude Include="..\src\script\script_config.hpp" /> <ClInclude Include="..\src\script\script_config.hpp" />
<ClInclude Include="..\src\script\script_fatalerror.hpp" /> <ClInclude Include="..\src\script\script_fatalerror.hpp" />

View File

@@ -28,84 +28,87 @@
<Filter Include="MD5"> <Filter Include="MD5">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000008}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000008}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script"> <Filter Include="Compat">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000009}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000009}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Squirrel"> <Filter Include="Script">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000010}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000010}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Squirrel headers"> <Filter Include="Squirrel">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000011}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000011}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="AI Core"> <Filter Include="Squirrel headers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000012}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000012}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="AI API"> <Filter Include="AI Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000013}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000013}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Game API"> <Filter Include="AI API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000014}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000014}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Game Core"> <Filter Include="Game API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000015}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000015}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script API"> <Filter Include="Game Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000016}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000016}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Script API Implementation"> <Filter Include="Script API">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000017}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000017}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Blitters"> <Filter Include="Script API Implementation">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000018}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000018}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Drivers"> <Filter Include="Blitters">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000019}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000019}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Sprite loaders"> <Filter Include="Drivers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000020}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000020}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="NewGRF"> <Filter Include="Sprite loaders">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000021}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000021}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Map Accessors"> <Filter Include="NewGRF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000022}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000022}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Misc"> <Filter Include="Map Accessors">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000023}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000023}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Network Core"> <Filter Include="Misc">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000024}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000024}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Pathfinder"> <Filter Include="Network Core">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000025}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000025}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="NPF"> <Filter Include="Pathfinder">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000026}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000026}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="YAPF"> <Filter Include="NPF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000027}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000027}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Video"> <Filter Include="YAPF">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000028}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000028}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Music"> <Filter Include="Video">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000029}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000029}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Sound"> <Filter Include="Music">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000030}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000030}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Windows files"> <Filter Include="Sound">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000031}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000031}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Threading"> <Filter Include="Windows files">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000032}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000032}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Btree containers"> <Filter Include="Threading">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000033}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000033}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="MinGW threading"> <Filter Include="Btree containers">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000034}</UniqueIdentifier> <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000034}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="MinGW threading">
<UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-000000000035}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\tbtr_template_gui_main.cpp"> <ClCompile Include="..\src\tbtr_template_gui_main.cpp">
@@ -2181,6 +2184,12 @@
<ClInclude Include="..\src\3rdparty\md5\md5.h"> <ClInclude Include="..\src\3rdparty\md5\md5.h">
<Filter>MD5</Filter> <Filter>MD5</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\3rdparty\optional\optional.hpp">
<Filter>Compat</Filter>
</ClInclude>
<ClInclude Include="..\src\3rdparty\optional\ottd_optional.h">
<Filter>Compat</Filter>
</ClInclude>
<ClCompile Include="..\src\script\script_config.cpp"> <ClCompile Include="..\src\script\script_config.cpp">
<Filter>Script</Filter> <Filter>Script</Filter>
</ClCompile> </ClCompile>

View File

@@ -100,7 +100,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Full</Optimization> <Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
@@ -168,7 +168,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -223,7 +223,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Full</Optimization> <Optimization>Full</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
@@ -289,7 +289,7 @@
</HeaderFileName> </HeaderFileName>
</Midl> </Midl>
<ClCompile> <ClCompile>
<AdditionalOptions>/J /Zc:throwingNew /std:c++latest %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/J /Zc:throwingNew /std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

View File

@@ -39,6 +39,7 @@
<Inputs>%(Inputs)</Inputs> <Inputs>%(Inputs)</Inputs>
</CustomBuildStep> </CustomBuildStep>
<ClCompile> <ClCompile>
<AdditionalOptions>/std:c++latest /Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<Optimization>MinSpace</Optimization> <Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<PreprocessorDefinitions>SETTINGSGEN;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>SETTINGSGEN;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@@ -747,6 +747,10 @@ table/water_land.h
3rdparty/md5/md5.cpp 3rdparty/md5/md5.cpp
3rdparty/md5/md5.h 3rdparty/md5/md5.h
# Compat
3rdparty/optional/optional.hpp
3rdparty/optional/ottd_optional.h
# Script # Script
script/script_config.cpp script/script_config.cpp
script/script_config.hpp script/script_config.hpp

23
src/3rdparty/optional/LICENSE_1_0.txt vendored Normal file
View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

1066
src/3rdparty/optional/optional.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

33
src/3rdparty/optional/ottd_optional.h vendored Normal file
View File

@@ -0,0 +1,33 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ottd_optional.h Header to select between native. */
#ifndef OTTD_OPTIONAL_H
#define OTTD_OPTIONAL_H
#if defined(__has_include)
# if __has_include(<version>)
# include <version>
# endif
#endif
#if (__cplusplus >= 201703L) || (defined(__cpp_lib_optional) && __cpp_lib_optional >= 201606L)
/* Native std::optional. */
#include <optional>
namespace opt = std;
#else
/* No std::optional, use local copy instead. */
#include "optional.hpp"
namespace opt = std::experimental;
#endif
#endif /* OTTD_OPTIONAL_H */

View File

@@ -309,7 +309,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
v->cargo_type = e->GetDefaultCargoType(); v->cargo_type = e->GetDefaultCargoType();
u->cargo_type = CT_MAIL; u->cargo_type = CT_MAIL;
v->name = nullptr; v->name.clear();
v->last_station_visited = INVALID_STATION; v->last_station_visited = INVALID_STATION;
v->last_loading_station = INVALID_STATION; v->last_loading_station = INVALID_STATION;

View File

@@ -14,10 +14,6 @@
#include "safeguards.h" #include "safeguards.h"
BaseConsist::~BaseConsist()
{
free(this->name);
}
/** /**
* Copy properties of other BaseConsist. * Copy properties of other BaseConsist.
@@ -27,8 +23,7 @@ void BaseConsist::CopyConsistPropertiesFrom(const BaseConsist *src)
{ {
if (this == src) return; if (this == src) return;
free(this->name); this->name = src->name;
this->name = src->name != nullptr ? stredup(src->name) : nullptr;
this->current_order_time = src->current_order_time; this->current_order_time = src->current_order_time;
this->lateness_counter = src->lateness_counter; this->lateness_counter = src->lateness_counter;

View File

@@ -13,10 +13,11 @@
#include "order_type.h" #include "order_type.h"
#include "date_type.h" #include "date_type.h"
#include "timetable.h" #include "timetable.h"
#include <string>
/** Various front vehicle properties that are preserved when autoreplacing, using order-backup or switching front engines within a consist. */ /** Various front vehicle properties that are preserved when autoreplacing, using order-backup or switching front engines within a consist. */
struct BaseConsist { struct BaseConsist {
char *name; ///< Name of vehicle std::string name; ///< Name of vehicle
/* Used for timetabling. */ /* Used for timetabling. */
uint32 current_order_time; ///< How many ticks have passed since this order started. uint32 current_order_time; ///< How many ticks have passed since this order started.
@@ -32,8 +33,7 @@ struct BaseConsist {
uint16 vehicle_flags; ///< Used for gradual loading and other miscellaneous things (@see VehicleFlags enum) uint16 vehicle_flags; ///< Used for gradual loading and other miscellaneous things (@see VehicleFlags enum)
BaseConsist() : name(nullptr) {} virtual ~BaseConsist() {}
virtual ~BaseConsist();
void CopyConsistPropertiesFrom(const BaseConsist *src); void CopyConsistPropertiesFrom(const BaseConsist *src);
}; };

View File

@@ -15,6 +15,7 @@
#include "gfx_type.h" #include "gfx_type.h"
#include "textfile_type.h" #include "textfile_type.h"
#include "textfile_gui.h" #include "textfile_gui.h"
#include <unordered_map>
/* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */ /* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
struct IniFile; struct IniFile;
@@ -46,7 +47,7 @@ struct MD5File {
*/ */
template <class T, size_t Tnum_files, bool Tsearch_in_tars> template <class T, size_t Tnum_files, bool Tsearch_in_tars>
struct BaseSet { struct BaseSet {
typedef SmallMap<const char *, const char *> TranslatedStrings; typedef std::unordered_map<std::string, std::string> TranslatedStrings;
/** Number of files in this set */ /** Number of files in this set */
static const size_t NUM_FILES = Tnum_files; static const size_t NUM_FILES = Tnum_files;
@@ -57,7 +58,7 @@ struct BaseSet {
/** Internal names of the files in this set. */ /** Internal names of the files in this set. */
static const char * const *file_names; static const char * const *file_names;
const char *name; ///< The name of the base set std::string name; ///< The name of the base set
TranslatedStrings description; ///< Description of the base set TranslatedStrings description; ///< Description of the base set
uint32 shortname; ///< Four letter short variant of the name uint32 shortname; ///< Four letter short variant of the name
uint32 version; ///< The version of this base set uint32 version; ///< The version of this base set
@@ -72,13 +73,6 @@ struct BaseSet {
/** Free everything we allocated */ /** Free everything we allocated */
~BaseSet() ~BaseSet()
{ {
free(this->name);
for (auto &pair : this->description) {
free(pair.first);
free(pair.second);
}
for (uint i = 0; i < NUM_FILES; i++) { for (uint i = 0; i < NUM_FILES; i++) {
free(this->files[i].filename); free(this->files[i].filename);
free(this->files[i].missing_warning); free(this->files[i].missing_warning);
@@ -116,20 +110,19 @@ struct BaseSet {
* @param isocode the isocode to search for * @param isocode the isocode to search for
* @return the description * @return the description
*/ */
const char *GetDescription(const char *isocode = nullptr) const const char *GetDescription(const std::string &isocode) const
{ {
if (isocode != nullptr) { if (!isocode.empty()) {
/* First the full ISO code */ /* First the full ISO code */
for (const auto &pair : this->description) { auto desc = this->description.find(isocode);
if (strcmp(pair.first, isocode) == 0) return pair.second; if (desc != this->description.end()) return desc->second.c_str();
}
/* Then the first two characters */ /* Then the first two characters */
for (const auto &pair : this->description) { desc = this->description.find(isocode.substr(0, 2));
if (strncmp(pair.first, isocode, 2) == 0) return pair.second; if (desc != this->description.end()) return desc->second.c_str();
}
} }
/* Then fall back */ /* Then fall back */
return this->description.front().second; return this->description.at(std::string{}).c_str();
} }
/** /**
@@ -183,7 +176,7 @@ protected:
static const char *GetExtension(); static const char *GetExtension();
public: public:
/** The set as saved in the config file. */ /** The set as saved in the config file. */
static const char *ini_set; static std::string ini_set;
/** /**
* Determine the graphics pack that has to be used. * Determine the graphics pack that has to be used.
@@ -203,7 +196,7 @@ public:
static Tbase_set *GetAvailableSets(); static Tbase_set *GetAvailableSets();
static bool SetSet(const char *name); static bool SetSet(const std::string &name);
static char *GetSetsList(char *p, const char *last); static char *GetSetsList(char *p, const char *last);
static int GetNumSets(); static int GetNumSets();
static int GetIndexOfUsedSet(); static int GetIndexOfUsedSet();
@@ -219,7 +212,7 @@ public:
static bool HasSet(const ContentInfo *ci, bool md5sum); static bool HasSet(const ContentInfo *ci, bool md5sum);
}; };
template <class Tbase_set> /* static */ const char *BaseMedia<Tbase_set>::ini_set; template <class Tbase_set> /* static */ std::string BaseMedia<Tbase_set>::ini_set;
template <class Tbase_set> /* static */ const Tbase_set *BaseMedia<Tbase_set>::used_set; template <class Tbase_set> /* static */ const Tbase_set *BaseMedia<Tbase_set>::used_set;
template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::available_sets; template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::available_sets;
template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::duplicate_sets; template <class Tbase_set> /* static */ Tbase_set *BaseMedia<Tbase_set>::duplicate_sets;

View File

@@ -21,7 +21,7 @@
*/ */
#define fetch_metadata(name) \ #define fetch_metadata(name) \
item = metadata->GetItem(name, false); \ item = metadata->GetItem(name, false); \
if (item == nullptr || StrEmpty(item->value)) { \ if (item == nullptr || !item->value.has_value() || item->value->empty()) { \
DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \ DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \
DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename); \ DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename); \
return false; \ return false; \
@@ -42,28 +42,28 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
IniItem *item; IniItem *item;
fetch_metadata("name"); fetch_metadata("name");
this->name = stredup(item->value); this->name = *item->value;
fetch_metadata("description"); fetch_metadata("description");
this->description[stredup("")] = stredup(item->value); this->description[std::string{}] = *item->value;
/* Add the translations of the descriptions too. */ /* Add the translations of the descriptions too. */
for (const IniItem *item = metadata->item; item != nullptr; item = item->next) { for (const IniItem *item = metadata->item; item != nullptr; item = item->next) {
if (strncmp("description.", item->name, 12) != 0) continue; if (item->name.compare(0, 12, "description.") != 0) continue;
this->description[stredup(item->name + 12)] = stredup(item->value); this->description[item->name.substr(12)] = item->value.value_or("");
} }
fetch_metadata("shortname"); fetch_metadata("shortname");
for (uint i = 0; item->value[i] != '\0' && i < 4; i++) { for (uint i = 0; item->value.value()[i] != '\0' && i < 4; i++) {
this->shortname |= ((uint8)item->value[i]) << (i * 8); this->shortname |= ((uint8)item->value.value()[i]) << (i * 8);
} }
fetch_metadata("version"); fetch_metadata("version");
this->version = atoi(item->value); this->version = atoi(item->value->c_str());
item = metadata->GetItem("fallback", false); item = metadata->GetItem("fallback", false);
this->fallback = (item != nullptr && strcmp(item->value, "0") != 0 && strcmp(item->value, "false") != 0); this->fallback = (item != nullptr && item->value && item->value.value() != "0" && item->value.value() != "false");
/* For each of the file types we want to find the file, MD5 checksums and warning messages. */ /* For each of the file types we want to find the file, MD5 checksums and warning messages. */
IniGroup *files = ini->GetGroup("files"); IniGroup *files = ini->GetGroup("files");
@@ -73,13 +73,12 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
MD5File *file = &this->files[i]; MD5File *file = &this->files[i];
/* Find the filename first. */ /* Find the filename first. */
item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false); item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false);
if (item == nullptr || (item->value == nullptr && !allow_empty_filename)) { if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename); DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
return false; return false;
} }
const char *filename = item->value; if (!item->value.has_value()) {
if (filename == nullptr) {
file->filename = nullptr; file->filename = nullptr;
/* If we list no file, that file must be valid */ /* If we list no file, that file must be valid */
this->valid_files++; this->valid_files++;
@@ -87,15 +86,16 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
continue; continue;
} }
const char *filename = item->value->c_str();
file->filename = str_fmt("%s%s", path, filename); file->filename = str_fmt("%s%s", path, filename);
/* Then find the MD5 checksum */ /* Then find the MD5 checksum */
item = md5s->GetItem(filename, false); item = md5s->GetItem(filename, false);
if (item == nullptr || item->value == nullptr) { if (item == nullptr || !item->value.has_value()) {
DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename); DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename);
return false; return false;
} }
char *c = item->value; const char *c = item->value->c_str();
for (uint i = 0; i < sizeof(file->hash) * 2; i++, c++) { for (uint i = 0; i < sizeof(file->hash) * 2; i++, c++) {
uint j; uint j;
if ('0' <= *c && *c <= '9') { if ('0' <= *c && *c <= '9') {
@@ -118,11 +118,11 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
/* Then find the warning message when the file's missing */ /* Then find the warning message when the file's missing */
item = origin->GetItem(filename, false); item = origin->GetItem(filename, false);
if (item == nullptr) item = origin->GetItem("default", false); if (item == nullptr) item = origin->GetItem("default", false);
if (item == nullptr) { if (item == nullptr || !item->value.has_value()) {
DEBUG(grf, 1, "No origin warning message specified for: %s", filename); DEBUG(grf, 1, "No origin warning message specified for: %s", filename);
file->missing_warning = stredup(""); file->missing_warning = stredup("");
} else { } else {
file->missing_warning = stredup(item->value); file->missing_warning = stredup(item->value->c_str());
} }
file->check_result = T::CheckMD5(file, BASESET_DIR); file->check_result = T::CheckMD5(file, BASESET_DIR);
@@ -170,7 +170,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
if (set->FillSetDetails(ini, path, filename)) { if (set->FillSetDetails(ini, path, filename)) {
Tbase_set *duplicate = nullptr; Tbase_set *duplicate = nullptr;
for (Tbase_set *c = BaseMedia<Tbase_set>::available_sets; c != nullptr; c = c->next) { for (Tbase_set *c = BaseMedia<Tbase_set>::available_sets; c != nullptr; c = c->next) {
if (strcmp(c->name, set->name) == 0 || c->shortname == set->shortname) { if (c->name == set->name || c->shortname == set->shortname) {
duplicate = c; duplicate = c;
break; break;
} }
@@ -179,7 +179,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
/* The more complete set takes precedence over the version number. */ /* The more complete set takes precedence over the version number. */
if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) || if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
duplicate->valid_files > set->valid_files) { duplicate->valid_files > set->valid_files) {
DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name, set->version, DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name.c_str(), set->version,
duplicate->valid_files > set->valid_files ? "less valid files" : "lower version"); duplicate->valid_files > set->valid_files ? "less valid files" : "lower version");
set->next = BaseMedia<Tbase_set>::duplicate_sets; set->next = BaseMedia<Tbase_set>::duplicate_sets;
BaseMedia<Tbase_set>::duplicate_sets = set; BaseMedia<Tbase_set>::duplicate_sets = set;
@@ -195,7 +195,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
* version number until a new game is started which isn't a big problem */ * version number until a new game is started which isn't a big problem */
if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set; if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set;
DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name, duplicate->version, DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name.c_str(), duplicate->version,
duplicate->valid_files < set->valid_files ? "less valid files" : "lower version"); duplicate->valid_files < set->valid_files ? "less valid files" : "lower version");
duplicate->next = BaseMedia<Tbase_set>::duplicate_sets; duplicate->next = BaseMedia<Tbase_set>::duplicate_sets;
BaseMedia<Tbase_set>::duplicate_sets = duplicate; BaseMedia<Tbase_set>::duplicate_sets = duplicate;
@@ -209,7 +209,7 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
ret = true; ret = true;
} }
if (ret) { if (ret) {
DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name, set->version); DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name.c_str(), set->version);
} }
} else { } else {
delete set; delete set;
@@ -226,18 +226,18 @@ bool BaseMedia<Tbase_set>::AddFile(const char *filename, size_t basepath_length,
* @return true if it could be loaded * @return true if it could be loaded
*/ */
template <class Tbase_set> template <class Tbase_set>
/* static */ bool BaseMedia<Tbase_set>::SetSet(const char *name) /* static */ bool BaseMedia<Tbase_set>::SetSet(const std::string &name)
{ {
extern void CheckExternalFiles(); extern void CheckExternalFiles();
if (StrEmpty(name)) { if (name.empty()) {
if (!BaseMedia<Tbase_set>::DetermineBestSet()) return false; if (!BaseMedia<Tbase_set>::DetermineBestSet()) return false;
CheckExternalFiles(); CheckExternalFiles();
return true; return true;
} }
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) { for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
if (strcmp(name, s->name) == 0) { if (name == s->name) {
BaseMedia<Tbase_set>::used_set = s; BaseMedia<Tbase_set>::used_set = s;
CheckExternalFiles(); CheckExternalFiles();
return true; return true;
@@ -257,7 +257,7 @@ template <class Tbase_set>
{ {
p += seprintf(p, last, "List of " SET_TYPE " sets:\n"); p += seprintf(p, last, "List of " SET_TYPE " sets:\n");
for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) { for (const Tbase_set *s = BaseMedia<Tbase_set>::available_sets; s != nullptr; s = s->next) {
p += seprintf(p, last, "%18s: %s", s->name, s->GetDescription()); p += seprintf(p, last, "%18s: %s", s->name.c_str(), s->GetDescription({}));
int invalid = s->GetNumInvalid(); int invalid = s->GetNumInvalid();
if (invalid != 0) { if (invalid != 0) {
int missing = s->GetNumMissing(); int missing = s->GetNumMissing();
@@ -376,11 +376,11 @@ template <class Tbase_set>
* @param set_type the type of the BaseSet to instantiate * @param set_type the type of the BaseSet to instantiate
*/ */
#define INSTANTIATE_BASE_MEDIA_METHODS(repl_type, set_type) \ #define INSTANTIATE_BASE_MEDIA_METHODS(repl_type, set_type) \
template const char *repl_type::ini_set; \ template std::string repl_type::ini_set; \
template const char *repl_type::GetExtension(); \ template const char *repl_type::GetExtension(); \
template bool repl_type::AddFile(const char *filename, size_t pathlength, const char *tar_filename); \ template bool repl_type::AddFile(const char *filename, size_t pathlength, const char *tar_filename); \
template bool repl_type::HasSet(const struct ContentInfo *ci, bool md5sum); \ template bool repl_type::HasSet(const struct ContentInfo *ci, bool md5sum); \
template bool repl_type::SetSet(const char *name); \ template bool repl_type::SetSet(const std::string &name); \
template char *repl_type::GetSetsList(char *p, const char *last); \ template char *repl_type::GetSetsList(char *p, const char *last); \
template int repl_type::GetNumSets(); \ template int repl_type::GetNumSets(); \
template int repl_type::GetIndexOfUsedSet(); \ template int repl_type::GetIndexOfUsedSet(); \

View File

@@ -56,7 +56,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign
byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted. byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
char *name; ///< Custom name std::string name; ///< Custom name
StringID string_id; ///< Default name (town area) of station StringID string_id; ///< Default name (town area) of station
mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the station, if not using a custom name mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the station, if not using a custom name
@@ -113,7 +113,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
inline const char *GetCachedName() const inline const char *GetCachedName() const
{ {
if (this->name != nullptr) return this->name; if (!this->name.empty()) return this->name.c_str();
if (this->cached_name.empty()) this->FillCachedName(); if (this->cached_name.empty()) this->FillCachedName();
return this->cached_name.c_str(); return this->cached_name.c_str();
} }

View File

@@ -22,10 +22,10 @@
*/ */
class BlitterFactory { class BlitterFactory {
private: private:
const char *name; ///< The name of the blitter factory. const std::string name; ///< The name of the blitter factory.
const char *description; ///< The description of the blitter. const std::string description; ///< The description of the blitter.
typedef std::map<const char *, BlitterFactory *, StringCompare> Blitters; ///< Map of blitter factories. typedef std::map<std::string, BlitterFactory *> Blitters; ///< Map of blitter factories.
/** /**
* Get the map with currently known blitters. * Get the map with currently known blitters.
@@ -58,7 +58,7 @@ protected:
* @pre There is no blitter registered with this name. * @pre There is no blitter registered with this name.
*/ */
BlitterFactory(const char *name, const char *description, bool usable = true) : BlitterFactory(const char *name, const char *description, bool usable = true) :
name(stredup(name)), description(stredup(description)) name(name), description(description)
{ {
if (usable) { if (usable) {
/* /*
@@ -78,9 +78,6 @@ public:
{ {
GetBlitters().erase(this->name); GetBlitters().erase(this->name);
if (GetBlitters().empty()) delete &GetBlitters(); if (GetBlitters().empty()) delete &GetBlitters();
free(this->name);
free(this->description);
} }
/** /**
@@ -88,7 +85,7 @@ public:
* @param name the blitter to select. * @param name the blitter to select.
* @post Sets the blitter so GetCurrentBlitter() returns it too. * @post Sets the blitter so GetCurrentBlitter() returns it too.
*/ */
static Blitter *SelectBlitter(const char *name) static Blitter *SelectBlitter(const std::string &name)
{ {
BlitterFactory *b = GetBlitterFactory(name); BlitterFactory *b = GetBlitterFactory(name);
if (b == nullptr) return nullptr; if (b == nullptr) return nullptr;
@@ -97,7 +94,7 @@ public:
delete *GetActiveBlitter(); delete *GetActiveBlitter();
*GetActiveBlitter() = newb; *GetActiveBlitter() = newb;
DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", newb->GetName()); DEBUG(driver, 1, "Successfully %s blitter '%s'", name.empty() ? "probed" : "loaded", newb->GetName());
return newb; return newb;
} }
@@ -106,7 +103,7 @@ public:
* @param name the blitter factory to select. * @param name the blitter factory to select.
* @return The blitter factory, or nullptr when there isn't one with the wanted name. * @return The blitter factory, or nullptr when there isn't one with the wanted name.
*/ */
static BlitterFactory *GetBlitterFactory(const char *name) static BlitterFactory *GetBlitterFactory(const std::string &name)
{ {
#if defined(DEDICATED) #if defined(DEDICATED)
const char *default_blitter = "null"; const char *default_blitter = "null";
@@ -116,12 +113,12 @@ public:
const char *default_blitter = "8bpp-optimized"; const char *default_blitter = "8bpp-optimized";
#endif #endif
if (GetBlitters().size() == 0) return nullptr; if (GetBlitters().size() == 0) return nullptr;
const char *bname = (StrEmpty(name)) ? default_blitter : name; const char *bname = name.empty() ? default_blitter : name.c_str();
Blitters::iterator it = GetBlitters().begin(); Blitters::iterator it = GetBlitters().begin();
for (; it != GetBlitters().end(); it++) { for (; it != GetBlitters().end(); it++) {
BlitterFactory *b = (*it).second; BlitterFactory *b = (*it).second;
if (strcasecmp(bname, b->name) == 0) { if (strcasecmp(bname, b->name.c_str()) == 0) {
return b; return b;
} }
} }
@@ -148,7 +145,7 @@ public:
Blitters::iterator it = GetBlitters().begin(); Blitters::iterator it = GetBlitters().begin();
for (; it != GetBlitters().end(); it++) { for (; it != GetBlitters().end(); it++) {
BlitterFactory *b = (*it).second; BlitterFactory *b = (*it).second;
p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription()); p += seprintf(p, last, "%18s: %s\n", b->name.c_str(), b->GetDescription().c_str());
} }
p += seprintf(p, last, "\n"); p += seprintf(p, last, "\n");
@@ -158,7 +155,7 @@ public:
/** /**
* Get the long, human readable, name for the Blitter-class. * Get the long, human readable, name for the Blitter-class.
*/ */
const char *GetName() const const std::string &GetName() const
{ {
return this->name; return this->name;
} }
@@ -166,7 +163,7 @@ public:
/** /**
* Get a nice description of the blitter-class. * Get a nice description of the blitter-class.
*/ */
const char *GetDescription() const const std::string &GetDescription() const
{ {
return this->description; return this->description;
} }
@@ -177,7 +174,7 @@ public:
virtual Blitter *CreateInstance() = 0; virtual Blitter *CreateInstance() = 0;
}; };
extern char *_ini_blitter; extern std::string _ini_blitter;
extern bool _blitter_autodetected; extern bool _blitter_autodetected;
#endif /* BLITTER_FACTORY_HPP */ #endif /* BLITTER_FACTORY_HPP */

View File

@@ -16,6 +16,7 @@
#include "tile_type.h" #include "tile_type.h"
#include "settings_type.h" #include "settings_type.h"
#include "group.h" #include "group.h"
#include <string>
/** Statistics about the economy. */ /** Statistics about the economy. */
struct CompanyEconomyEntry { struct CompanyEconomyEntry {
@@ -56,11 +57,11 @@ extern CompanyPool _company_pool;
struct CompanyProperties { struct CompanyProperties {
uint32 name_2; ///< Parameter of #name_1. uint32 name_2; ///< Parameter of #name_1.
StringID name_1; ///< Name of the company if the user did not change it. StringID name_1; ///< Name of the company if the user did not change it.
char *name; ///< Name of the company if the user changed it. std::string name; ///< Name of the company if the user changed it.
StringID president_name_1; ///< Name of the president if the user did not change it. StringID president_name_1; ///< Name of the president if the user did not change it.
uint32 president_name_2; ///< Parameter of #president_name_1 uint32 president_name_2; ///< Parameter of #president_name_1
char *president_name; ///< Name of the president if the user changed it. std::string president_name; ///< Name of the president if the user changed it.
CompanyManagerFace face; ///< Face description of the president. CompanyManagerFace face; ///< Face description of the president.
@@ -102,17 +103,11 @@ struct CompanyProperties {
// TODO: Change some of these member variables to use relevant INVALID_xxx constants // TODO: Change some of these member variables to use relevant INVALID_xxx constants
CompanyProperties() CompanyProperties()
: name_2(0), name_1(0), name(nullptr), president_name_1(0), president_name_2(0), president_name(nullptr), : name_2(0), name_1(0), president_name_1(0), president_name_2(0),
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0), face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0), location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), is_ai(false) {} terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), is_ai(false) {}
~CompanyProperties()
{
free(this->name);
free(this->president_name);
}
}; };
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties { struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {

View File

@@ -359,7 +359,7 @@ static void GenerateCompanyName(Company *c)
StringID str; StringID str;
uint32 strp; uint32 strp;
if (t->name == nullptr && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) { if (t->name.empty() && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) {
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START; str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START;
strp = t->townnameparts; strp = t->townnameparts;
@@ -1062,7 +1062,7 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1,
static bool IsUniqueCompanyName(const char *name) static bool IsUniqueCompanyName(const char *name)
{ {
for (const Company *c : Company::Iterate()) { for (const Company *c : Company::Iterate()) {
if (c->name != nullptr && strcmp(c->name, name) == 0) return false; if (!c->name.empty() && c->name == name) return false;
} }
return true; return true;
@@ -1088,8 +1088,11 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
Company *c = Company::Get(_current_company); Company *c = Company::Get(_current_company);
free(c->name); if (reset) {
c->name = reset ? nullptr : stredup(text); c->name.clear();
} else {
c->name = text;
}
MarkWholeScreenDirty(); MarkWholeScreenDirty();
CompanyAdminUpdate(c); CompanyAdminUpdate(c);
} }
@@ -1105,7 +1108,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
static bool IsUniquePresidentName(const char *name) static bool IsUniquePresidentName(const char *name)
{ {
for (const Company *c : Company::Iterate()) { for (const Company *c : Company::Iterate()) {
if (c->president_name != nullptr && strcmp(c->president_name, name) == 0) return false; if (!c->president_name.empty() && c->president_name == name) return false;
} }
return true; return true;
@@ -1131,14 +1134,13 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
Company *c = Company::Get(_current_company); Company *c = Company::Get(_current_company);
free(c->president_name);
if (reset) { if (reset) {
c->president_name = nullptr; c->president_name.clear();
} else { } else {
c->president_name = stredup(text); c->president_name = text;
if (c->name_1 == STR_SV_UNNAMED && c->name == nullptr) { if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) {
char buf[80]; char buf[80];
seprintf(buf, lastof(buf), "%s Transport", text); seprintf(buf, lastof(buf), "%s Transport", text);

View File

@@ -11,40 +11,26 @@
#define SMALLMAP_TYPE_HPP #define SMALLMAP_TYPE_HPP
#include "smallvec_type.hpp" #include "smallvec_type.hpp"
#include <utility>
/** /**
* Simple pair of data. Both types have to be POD ("Plain Old Data")! * Implementation of simple mapping class.
* @tparam T Key type. * It has inherited accessors from std::vector().
* @tparam U Value type.
*/
template <typename T, typename U>
struct SmallPair {
T first;
U second;
/** Initializes this Pair with data */
inline SmallPair(const T &first, const U &second) : first(first), second(second) { }
SmallPair() = default;
};
/**
* Implementation of simple mapping class. Both types have to be POD ("Plain Old Data")!
* It has inherited accessors from SmallVector().
* @tparam T Key type. * @tparam T Key type.
* @tparam U Value type. * @tparam U Value type.
* @tparam S Unit of allocation. * @tparam S Unit of allocation.
* *
* @see SmallVector * @see std::vector
*/ */
template <typename T, typename U> template <typename T, typename U>
struct SmallMap : std::vector<SmallPair<T, U> > { struct SmallMap : std::vector<std::pair<T, U> > {
typedef ::SmallPair<T, U> Pair; typedef std::pair<T, U> Pair;
typedef Pair *iterator; typedef Pair *iterator;
typedef const Pair *const_iterator; typedef const Pair *const_iterator;
/** Creates new SmallMap. Data are initialized in SmallVector constructor */ /** Creates new SmallMap. Data are initialized in std::vector constructor */
inline SmallMap() { } inline SmallMap() { }
/** Data are freed in SmallVector destructor */ /** Data are freed in std::vector destructor */
inline ~SmallMap() { } inline ~SmallMap() { }
/** /**

View File

@@ -199,15 +199,15 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const
" Video driver: %s\n" " Video driver: %s\n"
" Pathfinder: %s %s %s\n\n", " Pathfinder: %s %s %s\n\n",
BlitterFactory::GetCurrentBlitter() == nullptr ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(), BlitterFactory::GetCurrentBlitter() == nullptr ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(),
BaseGraphics::GetUsedSet() == nullptr ? "none" : BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet() == nullptr ? "none" : BaseGraphics::GetUsedSet()->name.c_str(),
BaseGraphics::GetUsedSet() == nullptr ? UINT32_MAX : BaseGraphics::GetUsedSet()->version, BaseGraphics::GetUsedSet() == nullptr ? UINT32_MAX : BaseGraphics::GetUsedSet()->version,
_current_language == nullptr ? "none" : _current_language->file, _current_language == nullptr ? "none" : _current_language->file,
MusicDriver::GetInstance() == nullptr ? "none" : MusicDriver::GetInstance()->GetName(), MusicDriver::GetInstance() == nullptr ? "none" : MusicDriver::GetInstance()->GetName(),
BaseMusic::GetUsedSet() == nullptr ? "none" : BaseMusic::GetUsedSet()->name, BaseMusic::GetUsedSet() == nullptr ? "none" : BaseMusic::GetUsedSet()->name.c_str(),
BaseMusic::GetUsedSet() == nullptr ? UINT32_MAX : BaseMusic::GetUsedSet()->version, BaseMusic::GetUsedSet() == nullptr ? UINT32_MAX : BaseMusic::GetUsedSet()->version,
_networking ? (_network_server ? "server" : "client") : "no", _networking ? (_network_server ? "server" : "client") : "no",
SoundDriver::GetInstance() == nullptr ? "none" : SoundDriver::GetInstance()->GetName(), SoundDriver::GetInstance() == nullptr ? "none" : SoundDriver::GetInstance()->GetName(),
BaseSounds::GetUsedSet() == nullptr ? "none" : BaseSounds::GetUsedSet()->name, BaseSounds::GetUsedSet() == nullptr ? "none" : BaseSounds::GetUsedSet()->name.c_str(),
BaseSounds::GetUsedSet() == nullptr ? UINT32_MAX : BaseSounds::GetUsedSet()->version, BaseSounds::GetUsedSet() == nullptr ? UINT32_MAX : BaseSounds::GetUsedSet()->version,
VideoDriver::GetInstance() == nullptr ? "none" : VideoDriver::GetInstance()->GetName(), VideoDriver::GetInstance() == nullptr ? "none" : VideoDriver::GetInstance()->GetName(),
pathfinder_name(_settings_game.pf.pathfinder_for_trains), pathfinder_name(_settings_game.pf.pathfinder_for_roadvehs), pathfinder_name(_settings_game.pf.pathfinder_for_ships) pathfinder_name(_settings_game.pf.pathfinder_for_trains), pathfinder_name(_settings_game.pf.pathfinder_for_roadvehs), pathfinder_name(_settings_game.pf.pathfinder_for_ships)

View File

@@ -8,9 +8,11 @@
/** @file dedicated.cpp Forking support for dedicated servers. */ /** @file dedicated.cpp Forking support for dedicated servers. */
#include "stdafx.h" #include "stdafx.h"
#include "fileio_func.h"
#include <string>
char *_log_file = nullptr; ///< File to reroute output of a forked OpenTTD to std::string _log_file; ///< File to reroute output of a forked OpenTTD to
FILE *_log_fd = nullptr; ///< File to reroute output of a forked OpenTTD to std::unique_ptr<FILE, FileDeleter> _log_fd; ///< File to reroute output of a forked OpenTTD to
#if defined(UNIX) #if defined(UNIX)
@@ -38,17 +40,17 @@ void DedicatedFork()
case 0: { // We're the child case 0: { // We're the child
/* Open the log-file to log all stuff too */ /* Open the log-file to log all stuff too */
_log_fd = fopen(_log_file, "a"); _log_fd.reset(fopen(_log_file.c_str(), "a"));
if (_log_fd == nullptr) { if (!_log_fd) {
perror("Unable to open logfile"); perror("Unable to open logfile");
exit(1); exit(1);
} }
/* Redirect stdout and stderr to log-file */ /* Redirect stdout and stderr to log-file */
if (dup2(fileno(_log_fd), fileno(stdout)) == -1) { if (dup2(fileno(_log_fd.get()), fileno(stdout)) == -1) {
perror("Rerouting stdout"); perror("Rerouting stdout");
exit(1); exit(1);
} }
if (dup2(fileno(_log_fd), fileno(stderr)) == -1) { if (dup2(fileno(_log_fd.get()), fileno(stderr)) == -1) {
perror("Rerouting stderr"); perror("Rerouting stderr");
exit(1); exit(1);
} }

View File

@@ -154,7 +154,7 @@ protected:
&& order->GetDestination() == this->station) { && order->GetDestination() == this->station) {
this->vehicles.push_back(v); this->vehicles.push_back(v);
if (v->name == nullptr) { if (v->name.empty()) {
if (v->unitnumber > unitnumber_max[v->type]) unitnumber_max[v->type] = v->unitnumber; if (v->unitnumber > unitnumber_max[v->type]) unitnumber_max[v->type] = v->unitnumber;
} else { } else {
SetDParam(0, (uint64)(v->index)); SetDParam(0, (uint64)(v->index));

View File

@@ -28,8 +28,6 @@ INSTANTIATE_POOL_METHODS(Depot)
*/ */
Depot::~Depot() Depot::~Depot()
{ {
free(this->name);
if (CleaningPool()) return; if (CleaningPool()) return;
if (!IsDepotTile(this->xy) || GetDepotIndex(this->xy) != this->index) { if (!IsDepotTile(this->xy) || GetDepotIndex(this->xy) != this->index) {

View File

@@ -18,7 +18,7 @@ extern DepotPool _depot_pool;
struct Depot : DepotPool::PoolItem<&_depot_pool> { struct Depot : DepotPool::PoolItem<&_depot_pool> {
Town *town; Town *town;
char *name; std::string name;
TileIndex xy; TileIndex xy;
uint16 town_cn; ///< The N-1th depot for this town (consecutive number) uint16 town_cn; ///< The N-1th depot for this town (consecutive number)

View File

@@ -29,7 +29,7 @@
static bool IsUniqueDepotName(const char *name) static bool IsUniqueDepotName(const char *name)
{ {
for (const Depot *d : Depot::Iterate()) { for (const Depot *d : Depot::Iterate()) {
if (d->name != nullptr && strcmp(d->name, name) == 0) return false; if (!d->name.empty() && d->name == name) return false;
} }
return true; return true;
@@ -60,13 +60,11 @@ CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
free(d->name);
if (reset) { if (reset) {
d->name = nullptr; d->name.clear();
MakeDefaultName(d); MakeDefaultName(d);
} else { } else {
d->name = stredup(text); d->name = text;
} }
/* Update the orders and depot */ /* Update the orders and depot */

View File

@@ -13,19 +13,21 @@
#include "music/music_driver.hpp" #include "music/music_driver.hpp"
#include "video/video_driver.hpp" #include "video/video_driver.hpp"
#include "string_func.h" #include "string_func.h"
#include <string>
#include <sstream>
#include "safeguards.h" #include "safeguards.h"
char *_ini_videodriver; ///< The video driver a stored in the configuration file. std::string _ini_videodriver; ///< The video driver a stored in the configuration file.
std::vector<Dimension> _resolutions; ///< List of resolutions. std::vector<Dimension> _resolutions; ///< List of resolutions.
Dimension _cur_resolution; ///< The current resolution. Dimension _cur_resolution; ///< The current resolution.
bool _rightclick_emulate; ///< Whether right clicking is emulated. bool _rightclick_emulate; ///< Whether right clicking is emulated.
char *_ini_sounddriver; ///< The sound driver a stored in the configuration file. std::string _ini_sounddriver; ///< The sound driver a stored in the configuration file.
char *_ini_musicdriver; ///< The music driver a stored in the configuration file. std::string _ini_musicdriver; ///< The music driver a stored in the configuration file.
char *_ini_blitter; ///< The blitter as stored in the configuration file. std::string _ini_blitter; ///< The blitter as stored in the configuration file.
bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user? bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user?
/** /**
@@ -34,19 +36,15 @@ bool _blitter_autodetected; ///< Was the blitter autodetected or specif
* @param name The parameter name we're looking for. * @param name The parameter name we're looking for.
* @return The parameter value. * @return The parameter value.
*/ */
const char *GetDriverParam(const char * const *parm, const char *name) const char *GetDriverParam(const StringList &parm, const char *name)
{ {
size_t len; if (parm.empty()) return nullptr;
if (parm == nullptr) return nullptr; size_t len = strlen(name);
for (auto &p : parm) {
len = strlen(name); if (p.compare(0, len, name) == 0) {
for (; *parm != nullptr; parm++) { if (p.length() == len) return "";
const char *p = *parm; if (p[len] == '=') return p.c_str() + len + 1;
if (strncmp(p, name, len) == 0) {
if (p[len] == '=') return p + len + 1;
if (p[len] == '\0') return p + len;
} }
} }
return nullptr; return nullptr;
@@ -58,7 +56,7 @@ const char *GetDriverParam(const char * const *parm, const char *name)
* @param name The parameter name we're looking for. * @param name The parameter name we're looking for.
* @return The parameter value. * @return The parameter value.
*/ */
bool GetDriverParamBool(const char * const *parm, const char *name) bool GetDriverParamBool(const StringList &parm, const char *name)
{ {
return GetDriverParam(parm, name) != nullptr; return GetDriverParam(parm, name) != nullptr;
} }
@@ -70,7 +68,7 @@ bool GetDriverParamBool(const char * const *parm, const char *name)
* @param def The default value if the parameter doesn't exist. * @param def The default value if the parameter doesn't exist.
* @return The parameter value. * @return The parameter value.
*/ */
int GetDriverParamInt(const char * const *parm, const char *name, int def) int GetDriverParamInt(const StringList &parm, const char *name, int def)
{ {
const char *p = GetDriverParam(parm, name); const char *p = GetDriverParam(parm, name);
return p != nullptr ? atoi(p) : def; return p != nullptr ? atoi(p) : def;
@@ -82,12 +80,12 @@ int GetDriverParamInt(const char * const *parm, const char *name, int def)
* @param type the type of driver to select * @param type the type of driver to select
* @post Sets the driver so GetCurrentDriver() returns it too. * @post Sets the driver so GetCurrentDriver() returns it too.
*/ */
void DriverFactoryBase::SelectDriver(const char *name, Driver::Type type) void DriverFactoryBase::SelectDriver(const std::string &name, Driver::Type type)
{ {
if (!DriverFactoryBase::SelectDriverImpl(name, type)) { if (!DriverFactoryBase::SelectDriverImpl(name, type)) {
StrEmpty(name) ? name.empty() ?
usererror("Failed to autoprobe %s driver", GetDriverTypeName(type)) : usererror("Failed to autoprobe %s driver", GetDriverTypeName(type)) :
usererror("Failed to select requested %s driver '%s'", GetDriverTypeName(type), name); usererror("Failed to select requested %s driver '%s'", GetDriverTypeName(type), name.c_str());
} }
} }
@@ -98,11 +96,11 @@ void DriverFactoryBase::SelectDriver(const char *name, Driver::Type type)
* @post Sets the driver so GetCurrentDriver() returns it too. * @post Sets the driver so GetCurrentDriver() returns it too.
* @return True upon success, otherwise false. * @return True upon success, otherwise false.
*/ */
bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type) bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type type)
{ {
if (GetDrivers().size() == 0) return false; if (GetDrivers().size() == 0) return false;
if (StrEmpty(name)) { if (name.empty()) {
/* Probe for this driver, but do not fall back to dedicated/null! */ /* Probe for this driver, but do not fall back to dedicated/null! */
for (int priority = 10; priority > 0; priority--) { for (int priority = 10; priority > 0; priority--) {
Drivers::iterator it = GetDrivers().begin(); Drivers::iterator it = GetDrivers().begin();
@@ -117,7 +115,7 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type)
Driver *newd = d->CreateInstance(); Driver *newd = d->CreateInstance();
*GetActiveDriver(type) = newd; *GetActiveDriver(type) = newd;
const char *err = newd->Start(nullptr); const char *err = newd->Start({});
if (err == nullptr) { if (err == nullptr) {
DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name); DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
delete oldd; delete oldd;
@@ -131,23 +129,15 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type)
} }
usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type)); usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
} else { } else {
char *parm;
char buffer[256];
const char *parms[32];
/* Extract the driver name and put parameter list in parm */ /* Extract the driver name and put parameter list in parm */
strecpy(buffer, name, lastof(buffer)); std::istringstream buffer(name);
parm = strchr(buffer, ':'); std::string dname;
parms[0] = nullptr; std::getline(buffer, dname, ':');
if (parm != nullptr) {
uint np = 0; std::string param;
/* Tokenize the parm. */ std::vector<std::string> parms;
do { while (std::getline(buffer, param, ',')) {
*parm++ = '\0'; parms.push_back(param);
if (np < lengthof(parms) - 1) parms[np++] = parm;
while (*parm != '\0' && *parm != ',') parm++;
} while (*parm == ',');
parms[np] = nullptr;
} }
/* Find this driver */ /* Find this driver */
@@ -159,7 +149,7 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type)
if (d->type != type) continue; if (d->type != type) continue;
/* Check driver name */ /* Check driver name */
if (strcasecmp(buffer, d->name) != 0) continue; if (strcasecmp(dname.c_str(), d->name) != 0) continue;
/* Found our driver, let's try it */ /* Found our driver, let's try it */
Driver *newd = d->CreateInstance(); Driver *newd = d->CreateInstance();
@@ -175,7 +165,7 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type)
*GetActiveDriver(type) = newd; *GetActiveDriver(type) = newd;
return true; return true;
} }
usererror("No such %s driver: %s\n", GetDriverTypeName(type), buffer); usererror("No such %s driver: %s\n", GetDriverTypeName(type), dname.c_str());
} }
} }
@@ -221,9 +211,7 @@ DriverFactoryBase::DriverFactoryBase(Driver::Type type, int priority, const char
strecpy(buf, GetDriverTypeName(type), lastof(buf)); strecpy(buf, GetDriverTypeName(type), lastof(buf));
strecpy(buf + 5, name, lastof(buf)); strecpy(buf + 5, name, lastof(buf));
const char *longname = stredup(buf); std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(buf, this));
std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(longname, this));
assert(P.second); assert(P.second);
} }
@@ -240,10 +228,6 @@ DriverFactoryBase::~DriverFactoryBase()
Drivers::iterator it = GetDrivers().find(buf); Drivers::iterator it = GetDrivers().find(buf);
assert(it != GetDrivers().end()); assert(it != GetDrivers().end());
const char *longname = (*it).first;
GetDrivers().erase(it); GetDrivers().erase(it);
free(longname);
if (GetDrivers().empty()) delete &GetDrivers(); if (GetDrivers().empty()) delete &GetDrivers();
} }

View File

@@ -12,11 +12,12 @@
#include "core/enum_type.hpp" #include "core/enum_type.hpp"
#include "core/string_compare_type.hpp" #include "core/string_compare_type.hpp"
#include "string_type.h"
#include <map> #include <map>
const char *GetDriverParam(const char * const *parm, const char *name); const char *GetDriverParam(const StringList &parm, const char *name);
bool GetDriverParamBool(const char * const *parm, const char *name); bool GetDriverParamBool(const StringList &parm, const char *name);
int GetDriverParamInt(const char * const *parm, const char *name, int def); int GetDriverParamInt(const StringList &parm, const char *name, int def);
/** A driver for communicating with the user. */ /** A driver for communicating with the user. */
class Driver { class Driver {
@@ -26,7 +27,7 @@ public:
* @param parm Parameters passed to the driver. * @param parm Parameters passed to the driver.
* @return nullptr if everything went okay, otherwise an error message. * @return nullptr if everything went okay, otherwise an error message.
*/ */
virtual const char *Start(const char * const *parm) = 0; virtual const char *Start(const StringList &parm) = 0;
/** /**
* Stop this driver. * Stop this driver.
@@ -66,7 +67,7 @@ private:
const char *name; ///< The name of the drivers of this factory. const char *name; ///< The name of the drivers of this factory.
const char *description; ///< The description of this driver. const char *description; ///< The description of this driver.
typedef std::map<const char *, DriverFactoryBase *, StringCompare> Drivers; ///< Type for a map of drivers. typedef std::map<std::string, DriverFactoryBase *> Drivers; ///< Type for a map of drivers.
/** /**
* Get the map with drivers. * Get the map with drivers.
@@ -99,7 +100,7 @@ private:
return driver_type_name[type]; return driver_type_name[type];
} }
static bool SelectDriverImpl(const char *name, Driver::Type type); static bool SelectDriverImpl(const std::string &name, Driver::Type type);
protected: protected:
DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description); DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description);
@@ -118,7 +119,7 @@ public:
} }
} }
static void SelectDriver(const char *name, Driver::Type type); static void SelectDriver(const std::string &name, Driver::Type type);
static char *GetDriversInfo(char *p, const char *last); static char *GetDriversInfo(char *p, const char *last);
/** /**

View File

@@ -68,7 +68,6 @@ assert_compile(lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_i
const uint EngineOverrideManager::NUM_DEFAULT_ENGINES = _engine_counts[VEH_TRAIN] + _engine_counts[VEH_ROAD] + _engine_counts[VEH_SHIP] + _engine_counts[VEH_AIRCRAFT]; const uint EngineOverrideManager::NUM_DEFAULT_ENGINES = _engine_counts[VEH_TRAIN] + _engine_counts[VEH_ROAD] + _engine_counts[VEH_SHIP] + _engine_counts[VEH_AIRCRAFT];
Engine::Engine() : Engine::Engine() :
name(nullptr),
overrides_count(0), overrides_count(0),
overrides(nullptr) overrides(nullptr)
{ {
@@ -141,7 +140,6 @@ Engine::Engine(VehicleType type, EngineID base)
Engine::~Engine() Engine::~Engine()
{ {
UnloadWagonOverrides(this); UnloadWagonOverrides(this);
free(this->name);
} }
/** /**
@@ -1079,7 +1077,7 @@ void EnginesMonthlyLoop()
static bool IsUniqueEngineName(const char *name) static bool IsUniqueEngineName(const char *name)
{ {
for (const Engine *e : Engine::Iterate()) { for (const Engine *e : Engine::Iterate()) {
if (e->name != nullptr && strcmp(e->name, name) == 0) return false; if (!e->name.empty() && e->name == name) return false;
} }
return true; return true;
@@ -1107,12 +1105,10 @@ CommandCost CmdRenameEngine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
free(e->name);
if (reset) { if (reset) {
e->name = nullptr; e->name.clear();
} else { } else {
e->name = stredup(text); e->name = text;
} }
MarkWholeScreenDirty(); MarkWholeScreenDirty();

View File

@@ -19,7 +19,7 @@ typedef Pool<Engine, EngineID, 64, 64000> EnginePool;
extern EnginePool _engine_pool; extern EnginePool _engine_pool;
struct Engine : EnginePool::PoolItem<&_engine_pool> { struct Engine : EnginePool::PoolItem<&_engine_pool> {
char *name; ///< Custom name of engine. std::string name; ///< Custom name of engine.
Date intro_date; ///< Date of introduction of the engine. Date intro_date; ///< Date of introduction of the engine.
Date age; Date age;
uint16 reliability; ///< Current reliability of the engine. uint16 reliability; ///< Current reliability of the engine.

View File

@@ -1251,8 +1251,9 @@ void DeterminePaths(const char *exe)
free(tmp); free(tmp);
} }
extern char *_log_file; extern std::string _log_file;
_log_file = str_fmt("%sopenttd.log", _personal_dir); _log_file = _personal_dir;
_log_file += "openttd.log";
} }
/** /**

View File

@@ -159,4 +159,12 @@ public:
} }
}; };
/** Helper to manage a FILE with a \c std::unique_ptr. */
struct FileDeleter {
void operator()(FILE *f)
{
if (f) fclose(f);
}
};
#endif /* FILEIO_FUNC_H */ #endif /* FILEIO_FUNC_H */

View File

@@ -548,9 +548,9 @@ public:
for (auto &pair : _load_check_data.companies) { for (auto &pair : _load_check_data.companies) {
SetDParam(0, pair.first + 1); SetDParam(0, pair.first + 1);
const CompanyProperties &c = *pair.second; const CompanyProperties &c = *pair.second;
if (c.name != nullptr) { if (!c.name.empty()) {
SetDParam(1, STR_JUST_RAW_STRING); SetDParam(1, STR_JUST_RAW_STRING);
SetDParamStr(2, c.name); SetDParamStr(2, c.name.c_str());
} else { } else {
SetDParam(1, c.name_1); SetDParam(1, c.name_1);
SetDParam(2, c.name_2); SetDParam(2, c.name_2);

View File

@@ -94,13 +94,13 @@ SpriteFontCache::~SpriteFontCache()
this->ClearGlyphToSpriteMap(); this->ClearGlyphToSpriteMap();
} }
SpriteID SpriteFontCache::GetUnicodeGlyph(GlyphID key) SpriteID SpriteFontCache::GetUnicodeGlyph(WChar key)
{ {
if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) return 0; if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) return 0;
return this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)]; return this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)];
} }
void SpriteFontCache::SetUnicodeGlyph(GlyphID key, SpriteID sprite) void SpriteFontCache::SetUnicodeGlyph(WChar key, SpriteID sprite)
{ {
if (this->glyph_to_spriteid_map == nullptr) this->glyph_to_spriteid_map = CallocT<SpriteID*>(256); if (this->glyph_to_spriteid_map == nullptr) this->glyph_to_spriteid_map = CallocT<SpriteID*>(256);
if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT<SpriteID>(256); if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT<SpriteID>(256);
@@ -209,7 +209,7 @@ protected:
int req_size; ///< Requested font size. int req_size; ///< Requested font size.
int used_size; ///< Used font size. int used_size; ///< Used font size.
typedef SmallMap<uint32, SmallPair<size_t, const void*> > FontTable; ///< Table with font table cache typedef SmallMap<uint32, std::pair<size_t, const void*> > FontTable; ///< Table with font table cache
FontTable font_tables; ///< Cached font tables. FontTable font_tables; ///< Cached font tables.
/** Container for information about a glyph. */ /** Container for information about a glyph. */
@@ -438,7 +438,7 @@ const void *TrueTypeFontCache::GetFontTable(uint32 tag, size_t &length)
const void *result = this->InternalGetFontTable(tag, length); const void *result = this->InternalGetFontTable(tag, length);
this->font_tables.Insert(tag, SmallPair<size_t, const void *>(length, result)); this->font_tables.Insert(tag, std::pair<size_t, const void *>(length, result));
return result; return result;
} }

View File

@@ -58,47 +58,27 @@ void NORETURN CDECL strgen_fatal(const char *s, ...)
throw std::exception(); throw std::exception();
} }
/**
* Create a new container for language strings.
* @param language The language name.
* @param end If not nullptr, terminate \a language at this position.
*/
LanguageStrings::LanguageStrings(const char *language, const char *end)
{
this->language = stredup(language, end != nullptr ? end - 1 : nullptr);
}
/** Free everything. */
LanguageStrings::~LanguageStrings()
{
free(this->language);
}
/** /**
* Read all the raw language strings from the given file. * Read all the raw language strings from the given file.
* @param file The file to read from. * @param file The file to read from.
* @return The raw strings, or nullptr upon error. * @return The raw strings, or nullptr upon error.
*/ */
std::unique_ptr<LanguageStrings> ReadRawLanguageStrings(const char *file) LanguageStrings ReadRawLanguageStrings(const std::string &file)
{ {
try {
size_t to_read; size_t to_read;
FILE *fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read); FILE *fh = FioFOpenFile(file.c_str(), "rb", GAME_DIR, &to_read);
if (fh == nullptr) return nullptr; if (fh == nullptr) return LanguageStrings();
FileCloser fhClose(fh); FileCloser fhClose(fh);
const char *langname = strrchr(file, PATHSEPCHAR); auto pos = file.rfind(PATHSEPCHAR);
if (langname == nullptr) { if (pos == std::string::npos) return LanguageStrings();
langname = file; std::string langname = file.substr(pos + 1);
} else {
langname++;
}
/* Check for invalid empty filename */ /* Check for invalid empty filename */
if (*langname == '.' || *langname == 0) return nullptr; if (langname.empty() || langname.front() == '.') return LanguageStrings();
std::unique_ptr<LanguageStrings> ret(new LanguageStrings(langname, strchr(langname, '.'))); LanguageStrings ret(langname.substr(0, langname.find('.')));
char buffer[2048]; char buffer[2048];
while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) { while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) {
@@ -109,7 +89,7 @@ std::unique_ptr<LanguageStrings> ReadRawLanguageStrings(const char *file)
while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--; while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--;
buffer[i] = '\0'; buffer[i] = '\0';
ret->lines.emplace_back(buffer, i); ret.lines.emplace_back(buffer, i);
if (len > to_read) { if (len > to_read) {
to_read = 0; to_read = 0;
@@ -119,9 +99,6 @@ std::unique_ptr<LanguageStrings> ReadRawLanguageStrings(const char *file)
} }
return ret; return ret;
} catch (...) {
return nullptr;
}
} }
@@ -138,7 +115,7 @@ struct StringListReader : StringReader {
* @param translation Are we reading a translation? * @param translation Are we reading a translation?
*/ */
StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation) : StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation) :
StringReader(data, strings.language, master, translation), p(strings.lines.begin()), end(strings.lines.end()) StringReader(data, strings.language.c_str(), master, translation), p(strings.lines.begin()), end(strings.lines.end())
{ {
} }
@@ -215,12 +192,11 @@ struct StringNameWriter : HeaderWriter {
class LanguageScanner : protected FileScanner { class LanguageScanner : protected FileScanner {
private: private:
GameStrings *gs; GameStrings *gs;
char *exclude; std::string exclude;
public: public:
/** Initialise */ /** Initialise */
LanguageScanner(GameStrings *gs, const char *exclude) : gs(gs), exclude(stredup(exclude)) {} LanguageScanner(GameStrings *gs, const std::string &exclude) : gs(gs), exclude(exclude) {}
~LanguageScanner() { free(exclude); }
/** /**
* Scan. * Scan.
@@ -232,10 +208,10 @@ public:
bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override
{ {
if (strcmp(filename, exclude) == 0) return true; if (exclude == filename) return true;
auto ls = ReadRawLanguageStrings(filename); auto ls = ReadRawLanguageStrings(filename);
if (ls == nullptr) return false; if (!ls.IsValid()) return false;
gs->raw_strings.push_back(std::move(ls)); gs->raw_strings.push_back(std::move(ls));
return true; return true;
@@ -249,17 +225,16 @@ public:
GameStrings *LoadTranslations() GameStrings *LoadTranslations()
{ {
const GameInfo *info = Game::GetInfo(); const GameInfo *info = Game::GetInfo();
char filename[512]; std::string basename(info->GetMainScript());
strecpy(filename, info->GetMainScript(), lastof(filename)); auto e = basename.rfind(PATHSEPCHAR);
char *e = strrchr(filename, PATHSEPCHAR); if (e == std::string::npos) return nullptr;
if (e == nullptr) return nullptr; basename.erase(e + 1);
e++; // Make 'e' point after the PATHSEPCHAR
strecpy(e, "lang" PATHSEP "english.txt", lastof(filename)); std::string filename = basename + "lang" PATHSEP "english.txt";
if (!FioCheckFileExists(filename, GAME_DIR)) return nullptr; if (!FioCheckFileExists(filename.c_str() , GAME_DIR)) return nullptr;
auto ls = ReadRawLanguageStrings(filename); auto ls = ReadRawLanguageStrings(filename);
if (ls == nullptr) return nullptr; if (!ls.IsValid()) return nullptr;
GameStrings *gs = new GameStrings(); GameStrings *gs = new GameStrings();
try { try {
@@ -267,8 +242,7 @@ GameStrings *LoadTranslations()
/* Scan for other language files */ /* Scan for other language files */
LanguageScanner scanner(gs, filename); LanguageScanner scanner(gs, filename);
strecpy(e, "lang" PATHSEP, lastof(filename)); std::string ldir = basename + "lang" PATHSEP;
size_t len = strlen(filename);
const char *tar_filename = info->GetTarFile(); const char *tar_filename = info->GetTarFile();
TarList::iterator iter; TarList::iterator iter;
@@ -281,14 +255,14 @@ GameStrings *LoadTranslations()
if (tar->second.tar_filename != iter->first) continue; if (tar->second.tar_filename != iter->first) continue;
/* Check the path and extension. */ /* Check the path and extension. */
if (tar->first.size() <= len || tar->first.compare(0, len, filename) != 0) continue; if (tar->first.size() <= ldir.size() || tar->first.compare(0, ldir.size(), ldir) != 0) continue;
if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue; if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue;
scanner.AddFile(tar->first.c_str(), 0, tar_filename); scanner.AddFile(tar->first.c_str(), 0, tar_filename);
} }
} else { } else {
/* Scan filesystem */ /* Scan filesystem */
scanner.Scan(filename); scanner.Scan(ldir.c_str());
} }
gs->Compile(); gs->Compile();
@@ -303,7 +277,7 @@ GameStrings *LoadTranslations()
void GameStrings::Compile() void GameStrings::Compile()
{ {
StringData data(32); StringData data(32);
StringListReader master_reader(data, *this->raw_strings[0], true, false); StringListReader master_reader(data, this->raw_strings[0], true, false);
master_reader.ParseFile(); master_reader.ParseFile();
if (_errors != 0) throw std::exception(); if (_errors != 0) throw std::exception();
@@ -314,12 +288,12 @@ void GameStrings::Compile()
for (const auto &p : this->raw_strings) { for (const auto &p : this->raw_strings) {
data.FreeTranslation(); data.FreeTranslation();
StringListReader translation_reader(data, *p, false, strcmp(p->language, "english") != 0); StringListReader translation_reader(data, p, false, p.language != "english");
translation_reader.ParseFile(); translation_reader.ParseFile();
if (_errors != 0) throw std::exception(); if (_errors != 0) throw std::exception();
this->compiled_strings.emplace_back(new LanguageStrings(p->language)); this->compiled_strings.emplace_back(p.language);
TranslationWriter writer(this->compiled_strings.back()->lines); TranslationWriter writer(this->compiled_strings.back().lines);
writer.WriteLang(data); writer.WriteLang(data);
} }
} }
@@ -387,11 +361,11 @@ void ReconsiderGameScriptLanguage()
language++; language++;
for (auto &p : _current_data->compiled_strings) { for (auto &p : _current_data->compiled_strings) {
if (strcmp(p->language, language) == 0) { if (p.language == language) {
_current_data->cur_language = p; _current_data->cur_language = &p;
return; return;
} }
} }
_current_data->cur_language = _current_data->compiled_strings[0]; _current_data->cur_language = &_current_data->compiled_strings[0];
} }

View File

@@ -18,23 +18,34 @@ void ReconsiderGameScriptLanguage();
/** Container for the raw (unencoded) language strings of a language. */ /** Container for the raw (unencoded) language strings of a language. */
struct LanguageStrings { struct LanguageStrings {
const char *language; ///< Name of the language (base filename). std::string language; ///< Name of the language (base filename). Empty string if invalid.
StringList lines; ///< The lines of the file to pass into the parser/encoder. StringList lines; ///< The lines of the file to pass into the parser/encoder.
LanguageStrings(const char *language, const char *end = nullptr); LanguageStrings() {}
~LanguageStrings(); LanguageStrings(const std::string &lang) : language(lang) {}
LanguageStrings(const LanguageStrings &other) : language(other.language), lines(other.lines) {}
LanguageStrings(LanguageStrings &&other) : language(std::move(other.language)), lines(std::move(other.lines)) {}
bool IsValid() const { return !this->language.empty(); }
}; };
/** Container for all the game strings. */ /** Container for all the game strings. */
struct GameStrings { struct GameStrings {
uint version; ///< The version of the language strings. uint version; ///< The version of the language strings.
std::shared_ptr<LanguageStrings> cur_language; ///< The current (compiled) language. LanguageStrings *cur_language; ///< The current (compiled) language.
std::vector<std::unique_ptr<LanguageStrings>> raw_strings; ///< The raw strings per language, first must be English/the master language!. std::vector<LanguageStrings> raw_strings; ///< The raw strings per language, first must be English/the master language!.
std::vector<std::shared_ptr<LanguageStrings>> compiled_strings; ///< The compiled strings per language, first must be English/the master language!. std::vector<LanguageStrings> compiled_strings; ///< The compiled strings per language, first must be English/the master language!.
StringList string_names; ///< The names of the compiled strings. StringList string_names; ///< The names of the compiled strings.
void Compile(); void Compile();
GameStrings() = default;
GameStrings(const GameStrings &) = delete;
GameStrings(GameStrings &&) = delete;
GameStrings &operator=(const GameStrings &) = delete;
GameStrings &operator=(GameStrings &&) = delete;
}; };
#endif /* GAME_TEXT_HPP */ #endif /* GAME_TEXT_HPP */

View File

@@ -114,7 +114,7 @@ int DrawString(int left, int right, int top, StringID str, TextColour colour = T
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL); int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL); int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
void DrawCharCentered(uint32 c, int x, int y, TextColour colour); void DrawCharCentered(WChar c, int x, int y, TextColour colour);
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE); void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE);
void GfxFillPolygon(const std::vector<Point> &shape, int colour, FillRectMode mode = FILLRECT_OPAQUE); void GfxFillPolygon(const std::vector<Point> &shape, int colour, FillRectMode mode = FILLRECT_OPAQUE);
@@ -168,7 +168,7 @@ void SortResolutions();
bool ToggleFullScreen(bool fs); bool ToggleFullScreen(bool fs);
/* gfx.cpp */ /* gfx.cpp */
byte GetCharacterWidth(FontSize size, uint32 key); byte GetCharacterWidth(FontSize size, WChar key);
byte GetDigitWidth(FontSize size = FS_NORMAL); byte GetDigitWidth(FontSize size = FS_NORMAL);
void GetBroadestDigit(uint *front, uint *next, FontSize size = FS_NORMAL); void GetBroadestDigit(uint *front, uint *next, FontSize size = FS_NORMAL);

View File

@@ -134,7 +134,7 @@ void CheckExternalFiles()
const GraphicsSet *used_set = BaseGraphics::GetUsedSet(); const GraphicsSet *used_set = BaseGraphics::GetUsedSet();
DEBUG(grf, 1, "Using the %s base graphics set", used_set->name); DEBUG(grf, 1, "Using the %s base graphics set", used_set->name.c_str());
static const size_t ERROR_MESSAGE_LENGTH = 256; static const size_t ERROR_MESSAGE_LENGTH = 256;
static const size_t MISSING_FILE_MESSAGE_LENGTH = 128; static const size_t MISSING_FILE_MESSAGE_LENGTH = 128;
@@ -149,7 +149,7 @@ void CheckExternalFiles()
if (used_set->GetNumInvalid() != 0) { if (used_set->GetNumInvalid() != 0) {
/* Not all files were loaded successfully, see which ones */ /* Not all files were loaded successfully, see which ones */
add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", used_set->name); add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", used_set->name.c_str());
for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) { for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) {
MD5File::ChecksumResult res = GraphicsSet::CheckMD5(&used_set->files[i], BASESET_DIR); MD5File::ChecksumResult res = GraphicsSet::CheckMD5(&used_set->files[i], BASESET_DIR);
if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning); if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning);
@@ -159,7 +159,7 @@ void CheckExternalFiles()
const SoundsSet *sounds_set = BaseSounds::GetUsedSet(); const SoundsSet *sounds_set = BaseSounds::GetUsedSet();
if (sounds_set->GetNumInvalid() != 0) { if (sounds_set->GetNumInvalid() != 0) {
add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", sounds_set->name); add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of README.md.\n\nThe following files are corrupted or missing:\n", sounds_set->name.c_str());
assert_compile(SoundsSet::NUM_FILES == 1); assert_compile(SoundsSet::NUM_FILES == 1);
/* No need to loop each file, as long as there is only a single /* No need to loop each file, as long as there is only a single
@@ -503,11 +503,11 @@ bool GraphicsSet::FillSetDetails(IniFile *ini, const char *path, const char *ful
IniItem *item; IniItem *item;
fetch_metadata("palette"); fetch_metadata("palette");
this->palette = (*item->value == 'D' || *item->value == 'd') ? PAL_DOS : PAL_WINDOWS; this->palette = (item->value.value()[0] == 'D' || item->value.value()[0] == 'd') ? PAL_DOS : PAL_WINDOWS;
/* Get optional blitter information. */ /* Get optional blitter information. */
item = metadata->GetItem("blitter", false); item = metadata->GetItem("blitter", false);
this->blitter = (item != nullptr && *item->value == '3') ? BLT_32BPP : BLT_8BPP; this->blitter = (item != nullptr && item->value.value()[0] == '3') ? BLT_32BPP : BLT_8BPP;
} }
return ret; return ret;
} }

View File

@@ -16,6 +16,7 @@
#include "vehicle_type.h" #include "vehicle_type.h"
#include "engine_type.h" #include "engine_type.h"
#include "livery.h" #include "livery.h"
#include <string>
typedef Pool<Group, GroupID, 16, 64000> GroupPool; typedef Pool<Group, GroupID, 16, 64000> GroupPool;
extern GroupPool _group_pool; ///< Pool of groups. extern GroupPool _group_pool; ///< Pool of groups.
@@ -63,7 +64,7 @@ struct GroupStatistics {
/** Group data. */ /** Group data. */
struct Group : GroupPool::PoolItem<&_group_pool> { struct Group : GroupPool::PoolItem<&_group_pool> {
char *name; ///< Group Name std::string name; ///< Group Name
Owner owner; ///< Group Owner Owner owner; ///< Group Owner
VehicleType vehicle_type; ///< Vehicle type of the group VehicleType vehicle_type; ///< Vehicle type of the group
@@ -76,7 +77,6 @@ struct Group : GroupPool::PoolItem<&_group_pool> {
GroupID parent; ///< Parent group GroupID parent; ///< Parent group
Group(CompanyID owner = INVALID_COMPANY); Group(CompanyID owner = INVALID_COMPANY);
~Group();
}; };

View File

@@ -298,11 +298,6 @@ Group::Group(Owner owner)
this->folded = false; this->folded = false;
} }
Group::~Group()
{
free(this->name);
}
/** /**
* Create a new vehicle group. * Create a new vehicle group.
@@ -436,10 +431,12 @@ CommandCost CmdAlterGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
/* Delete the old name */
free(g->name);
/* Assign the new one */ /* Assign the new one */
g->name = reset ? nullptr : stredup(text); if (reset) {
g->name.clear();
} else {
g->name = text;
}
} }
} else { } else {
/* Set group parent */ /* Set group parent */

View File

@@ -292,7 +292,7 @@ void HotkeyList::Load(IniFile *ini)
IniItem *item = group->GetItem(hotkey->name, false); IniItem *item = group->GetItem(hotkey->name, false);
if (item != nullptr) { if (item != nullptr) {
hotkey->keycodes.clear(); hotkey->keycodes.clear();
if (item->value != nullptr) ParseHotkeys(hotkey, item->value); if (item->value.has_value()) ParseHotkeys(hotkey, item->value->c_str());
} }
} }
} }

View File

@@ -12,9 +12,11 @@
#include "ini_type.h" #include "ini_type.h"
#include "string_func.h" #include "string_func.h"
#include "fileio_func.h" #include "fileio_func.h"
#include <fstream>
#if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) #if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500)
# include <unistd.h> # include <unistd.h>
# include <fcntl.h>
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@@ -45,31 +47,33 @@ bool IniFile::SaveToDisk(const char *filename)
* that file. This to prevent that when OpenTTD crashes during the save * that file. This to prevent that when OpenTTD crashes during the save
* you end up with a truncated configuration file. * you end up with a truncated configuration file.
*/ */
char file_new[MAX_PATH]; std::string file_new{ filename };
file_new.append(".new");
strecpy(file_new, filename, lastof(file_new)); std::ofstream os(OTTD2FS(file_new.c_str()));
strecat(file_new, ".new", lastof(file_new)); if (os.fail()) return false;
FILE *f = fopen(file_new, "w");
if (f == nullptr) return false;
for (const IniGroup *group = this->group; group != nullptr; group = group->next) { for (const IniGroup *group = this->group; group != nullptr; group = group->next) {
if (group->comment) fputs(group->comment, f); os << group->comment << "[" << group->name << "]\n";
fprintf(f, "[%s]\n", group->name);
for (const IniItem *item = group->item; item != nullptr; item = item->next) { for (const IniItem *item = group->item; item != nullptr; item = item->next) {
if (item->comment != nullptr) fputs(item->comment, f); os << item->comment;
/* protect item->name with quotes if needed */ /* protect item->name with quotes if needed */
if (strchr(item->name, ' ') != nullptr || if (item->name.find(' ') != std::string::npos ||
item->name[0] == '[') { item->name[0] == '[') {
fprintf(f, "\"%s\"", item->name); os << "\"" << item->name << "\"";
} else { } else {
fprintf(f, "%s", item->name); os << item->name;
} }
fprintf(f, " = %s\n", item->value == nullptr ? "" : item->value); os << " = " << item->value.value_or("") << "\n";
} }
} }
if (this->comment) fputs(this->comment, f); os << this->comment;
os.flush();
os.close();
if (os.fail()) return false;
/* /*
* POSIX (and friends) do not guarantee that when a file is closed it is * POSIX (and friends) do not guarantee that when a file is closed it is
@@ -78,11 +82,10 @@ bool IniFile::SaveToDisk(const char *filename)
* (modification date etc.) is not important to us; only the real data is. * (modification date etc.) is not important to us; only the real data is.
*/ */
#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
int ret = fdatasync(fileno(f)); int f = open(file_new.c_str(), O_RDWR);
fclose(f); int ret = fdatasync(f);
close(f);
if (ret != 0) return false; if (ret != 0) return false;
#else
fclose(f);
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
@@ -91,7 +94,7 @@ bool IniFile::SaveToDisk(const char *filename)
/* Allocate space for one more \0 character. */ /* Allocate space for one more \0 character. */
TCHAR tfilename[MAX_PATH + 1], tfile_new[MAX_PATH + 1]; TCHAR tfilename[MAX_PATH + 1], tfile_new[MAX_PATH + 1];
_tcsncpy(tfilename, OTTD2FS(filename), MAX_PATH); _tcsncpy(tfilename, OTTD2FS(filename), MAX_PATH);
_tcsncpy(tfile_new, OTTD2FS(file_new), MAX_PATH); _tcsncpy(tfile_new, OTTD2FS(file_new.c_str()), MAX_PATH);
/* SHFileOperation wants a double '\0' terminated string. */ /* SHFileOperation wants a double '\0' terminated string. */
tfilename[MAX_PATH - 1] = '\0'; tfilename[MAX_PATH - 1] = '\0';
tfile_new[MAX_PATH - 1] = '\0'; tfile_new[MAX_PATH - 1] = '\0';
@@ -107,8 +110,8 @@ bool IniFile::SaveToDisk(const char *filename)
shfopt.pTo = tfilename; shfopt.pTo = tfilename;
SHFileOperation(&shfopt); SHFileOperation(&shfopt);
#else #else
if (rename(file_new, filename) < 0) { if (rename(file_new.c_str(), filename) < 0) {
DEBUG(misc, 0, "Renaming %s to %s failed; configuration not saved", file_new, filename); DEBUG(misc, 0, "Renaming %s to %s failed; configuration not saved", file_new.c_str(), filename);
} }
#endif #endif

View File

@@ -19,12 +19,10 @@
* Construct a new in-memory item of an Ini file. * Construct a new in-memory item of an Ini file.
* @param parent the group we belong to * @param parent the group we belong to
* @param name the name of the item * @param name the name of the item
* @param last the last element of the name of the item
*/ */
IniItem::IniItem(IniGroup *parent, const char *name, const char *last) : next(nullptr), value(nullptr), comment(nullptr) IniItem::IniItem(IniGroup *parent, const std::string &name) : next(nullptr)
{ {
this->name = stredup(name, last); this->name = str_validate(name);
str_validate(this->name, this->name + strlen(this->name));
*parent->last_item = this; *parent->last_item = this;
parent->last_item = &this->next; parent->last_item = &this->next;
@@ -33,10 +31,6 @@ IniItem::IniItem(IniGroup *parent, const char *name, const char *last) : next(nu
/** Free everything we loaded. */ /** Free everything we loaded. */
IniItem::~IniItem() IniItem::~IniItem()
{ {
free(this->name);
free(this->value);
free(this->comment);
delete this->next; delete this->next;
} }
@@ -46,20 +40,21 @@ IniItem::~IniItem()
*/ */
void IniItem::SetValue(const char *value) void IniItem::SetValue(const char *value)
{ {
free(this->value); if (value == nullptr) {
this->value = stredup(value); this->value.reset();
} else {
this->value.emplace(value);
}
} }
/** /**
* Construct a new in-memory group of an Ini file. * Construct a new in-memory group of an Ini file.
* @param parent the file we belong to * @param parent the file we belong to
* @param name the name of the group * @param name the name of the group
* @param last the last element of the name of the group
*/ */
IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : next(nullptr), type(IGT_VARIABLES), item(nullptr), comment(nullptr) IniGroup::IniGroup(IniLoadFile *parent, const std::string &name) : next(nullptr), type(IGT_VARIABLES), item(nullptr)
{ {
this->name = stredup(name, last); this->name = str_validate(name);
str_validate(this->name, this->name + strlen(this->name));
this->last_item = &this->item; this->last_item = &this->item;
*parent->last_group = this; *parent->last_group = this;
@@ -67,7 +62,7 @@ IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : ne
if (parent->list_group_names != nullptr) { if (parent->list_group_names != nullptr) {
for (uint i = 0; parent->list_group_names[i] != nullptr; i++) { for (uint i = 0; parent->list_group_names[i] != nullptr; i++) {
if (strcmp(this->name, parent->list_group_names[i]) == 0) { if (this->name == parent->list_group_names[i]) {
this->type = IGT_LIST; this->type = IGT_LIST;
return; return;
} }
@@ -75,7 +70,7 @@ IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : ne
} }
if (parent->seq_group_names != nullptr) { if (parent->seq_group_names != nullptr) {
for (uint i = 0; parent->seq_group_names[i] != nullptr; i++) { for (uint i = 0; parent->seq_group_names[i] != nullptr; i++) {
if (strcmp(this->name, parent->seq_group_names[i]) == 0) { if (this->name == parent->seq_group_names[i]) {
this->type = IGT_SEQUENCE; this->type = IGT_SEQUENCE;
return; return;
} }
@@ -86,9 +81,6 @@ IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : ne
/** Free everything we loaded. */ /** Free everything we loaded. */
IniGroup::~IniGroup() IniGroup::~IniGroup()
{ {
free(this->name);
free(this->comment);
delete this->item; delete this->item;
delete this->next; delete this->next;
} }
@@ -100,16 +92,16 @@ IniGroup::~IniGroup()
* @param create whether to create an item when not found or not. * @param create whether to create an item when not found or not.
* @return the requested item or nullptr if not found. * @return the requested item or nullptr if not found.
*/ */
IniItem *IniGroup::GetItem(const char *name, bool create) IniItem *IniGroup::GetItem(const std::string &name, bool create)
{ {
for (IniItem *item = this->item; item != nullptr; item = item->next) { for (IniItem *item = this->item; item != nullptr; item = item->next) {
if (strcmp(item->name, name) == 0) return item; if (item->name == name) return item;
} }
if (!create) return nullptr; if (!create) return nullptr;
/* otherwise make a new one */ /* otherwise make a new one */
return new IniItem(this, name, nullptr); return new IniItem(this, name);
} }
/** /**
@@ -129,7 +121,6 @@ void IniGroup::Clear()
*/ */
IniLoadFile::IniLoadFile(const char * const *list_group_names, const char * const *seq_group_names) : IniLoadFile::IniLoadFile(const char * const *list_group_names, const char * const *seq_group_names) :
group(nullptr), group(nullptr),
comment(nullptr),
list_group_names(list_group_names), list_group_names(list_group_names),
seq_group_names(seq_group_names) seq_group_names(seq_group_names)
{ {
@@ -139,7 +130,6 @@ IniLoadFile::IniLoadFile(const char * const *list_group_names, const char * cons
/** Free everything we loaded. */ /** Free everything we loaded. */
IniLoadFile::~IniLoadFile() IniLoadFile::~IniLoadFile()
{ {
free(this->comment);
delete this->group; delete this->group;
} }
@@ -147,26 +137,21 @@ IniLoadFile::~IniLoadFile()
* Get the group with the given name. If it doesn't exist * Get the group with the given name. If it doesn't exist
* and \a create_new is \c true create a new group. * and \a create_new is \c true create a new group.
* @param name name of the group to find. * @param name name of the group to find.
* @param len the maximum length of said name (\c 0 means length of the string).
* @param create_new Allow creation of group if it does not exist. * @param create_new Allow creation of group if it does not exist.
* @return The requested group if it exists or was created, else \c nullptr. * @return The requested group if it exists or was created, else \c nullptr.
*/ */
IniGroup *IniLoadFile::GetGroup(const char *name, size_t len, bool create_new) IniGroup *IniLoadFile::GetGroup(const std::string &name, bool create_new)
{ {
if (len == 0) len = strlen(name);
/* does it exist already? */ /* does it exist already? */
for (IniGroup *group = this->group; group != nullptr; group = group->next) { for (IniGroup *group = this->group; group != nullptr; group = group->next) {
if (!strncmp(group->name, name, len) && group->name[len] == 0) { if (group->name == name) return group;
return group;
}
} }
if (!create_new) return nullptr; if (!create_new) return nullptr;
/* otherwise make a new one */ /* otherwise make a new one */
IniGroup *group = new IniGroup(this, name, name + len - 1); IniGroup *group = new IniGroup(this, name);
group->comment = stredup("\n"); group->comment = "\n";
return group; return group;
} }
@@ -182,7 +167,7 @@ void IniLoadFile::RemoveGroup(const char *name)
/* does it exist already? */ /* does it exist already? */
for (group = this->group; group != nullptr; prev = group, group = group->next) { for (group = this->group; group != nullptr; prev = group, group = group->next) {
if (strncmp(group->name, name, len) == 0) { if (group->name.compare(0, len, name) == 0) {
break; break;
} }
} }
@@ -266,17 +251,17 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir, std::s
e--; e--;
} }
s++; // skip [ s++; // skip [
group = new IniGroup(this, s, e - 1); group = new IniGroup(this, std::string(s, e - s));
if (comment_size != 0) { if (comment_size != 0) {
group->comment = stredup(comment, comment + comment_size - 1); group->comment.assign(comment, comment_size);
comment_size = 0; comment_size = 0;
} }
} else if (group != nullptr) { } else if (group != nullptr) {
if (group->type == IGT_SEQUENCE) { if (group->type == IGT_SEQUENCE) {
/* A sequence group, use the line as item name without further interpretation. */ /* A sequence group, use the line as item name without further interpretation. */
IniItem *item = new IniItem(group, buffer, e - 1); IniItem *item = new IniItem(group, std::string(buffer, e - buffer));
if (comment_size) { if (comment_size) {
item->comment = stredup(comment, comment + comment_size - 1); item->comment.assign(comment, comment_size);
comment_size = 0; comment_size = 0;
} }
continue; continue;
@@ -292,9 +277,9 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir, std::s
} }
/* it's an item in an existing group */ /* it's an item in an existing group */
IniItem *item = new IniItem(group, s, t - 1); IniItem *item = new IniItem(group, std::string(s, t - s));
if (comment_size != 0) { if (comment_size != 0) {
item->comment = stredup(comment, comment + comment_size - 1); item->comment.assign(comment, comment_size);
comment_size = 0; comment_size = 0;
} }
@@ -310,8 +295,11 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir, std::s
*e = '\0'; *e = '\0';
/* If the value was not quoted and empty, it must be nullptr */ /* If the value was not quoted and empty, it must be nullptr */
item->value = (!quoted && e == t) ? nullptr : stredup(t); if (!quoted && e == t) {
if (item->value != nullptr) str_validate(item->value, item->value + strlen(item->value)); item->value.reset();
} else {
item->value = str_validate(std::string(t));
}
} else { } else {
/* it's an orphan item */ /* it's an orphan item */
this->ReportFileError("ini: '", buffer, "' outside of group"); this->ReportFileError("ini: '", buffer, "' outside of group");
@@ -319,7 +307,7 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir, std::s
} }
if (comment_size > 0) { if (comment_size > 0) {
this->comment = stredup(comment, comment + comment_size - 1); this->comment.assign(comment, comment_size);
comment_size = 0; comment_size = 0;
} }

View File

@@ -11,6 +11,8 @@
#define INI_TYPE_H #define INI_TYPE_H
#include "fileio_type.h" #include "fileio_type.h"
#include <string>
#include "3rdparty/optional/ottd_optional.h"
#include <string> #include <string>
@@ -24,11 +26,11 @@ enum IniGroupType {
/** A single "line" in an ini file. */ /** A single "line" in an ini file. */
struct IniItem { struct IniItem {
IniItem *next; ///< The next item in this group IniItem *next; ///< The next item in this group
char *name; ///< The name of this item std::string name; ///< The name of this item
char *value; ///< The value of this item opt::optional<std::string> value; ///< The value of this item
char *comment; ///< The comment associated with this item std::string comment; ///< The comment associated with this item
IniItem(struct IniGroup *parent, const char *name, const char *last = nullptr); IniItem(struct IniGroup *parent, const std::string &name);
~IniItem(); ~IniItem();
void SetValue(const char *value); void SetValue(const char *value);
@@ -40,13 +42,13 @@ struct IniGroup {
IniGroupType type; ///< type of group IniGroupType type; ///< type of group
IniItem *item; ///< the first item in the group IniItem *item; ///< the first item in the group
IniItem **last_item; ///< the last item in the group IniItem **last_item; ///< the last item in the group
char *name; ///< name of group std::string name; ///< name of group
char *comment; ///< comment for group std::string comment; ///< comment for group
IniGroup(struct IniLoadFile *parent, const char *name, const char *last = nullptr); IniGroup(struct IniLoadFile *parent, const std::string &name);
~IniGroup(); ~IniGroup();
IniItem *GetItem(const char *name, bool create); IniItem *GetItem(const std::string &name, bool create);
void Clear(); void Clear();
}; };
@@ -54,14 +56,14 @@ struct IniGroup {
struct IniLoadFile { struct IniLoadFile {
IniGroup *group; ///< the first group in the ini IniGroup *group; ///< the first group in the ini
IniGroup **last_group; ///< the last group in the ini IniGroup **last_group; ///< the last group in the ini
char *comment; ///< last comment in file std::string comment; ///< last comment in file
const char * const *list_group_names; ///< nullptr terminated list with group names that are lists const char * const *list_group_names; ///< nullptr terminated list with group names that are lists
const char * const *seq_group_names; ///< nullptr terminated list with group names that are sequences. const char * const *seq_group_names; ///< nullptr terminated list with group names that are sequences.
IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr); IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr);
virtual ~IniLoadFile(); virtual ~IniLoadFile();
IniGroup *GetGroup(const char *name, size_t len = 0, bool create_new = true); IniGroup *GetGroup(const std::string &name, bool create_new = true);
void RemoveGroup(const char *name); void RemoveGroup(const char *name);
void LoadFromDisk(const char *filename, Subdirectory subdir, std::string *save = nullptr); void LoadFromDisk(const char *filename, Subdirectory subdir, std::string *save = nullptr);

View File

@@ -935,6 +935,7 @@ STR_GAME_OPTIONS_CURRENCY_MXN :Mexicaanse peso
STR_GAME_OPTIONS_CURRENCY_NTD :Nieuwe Taiwanse dollar (NTD) STR_GAME_OPTIONS_CURRENCY_NTD :Nieuwe Taiwanse dollar (NTD)
STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY) STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY)
STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD)
STR_GAME_OPTIONS_CURRENCY_INR :Indiase rupee (INR)
############ end of currency region ############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Wegvoertuigen STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Wegvoertuigen

View File

@@ -3605,6 +3605,7 @@ STR_REPLACE_WAGONS :Gerbong
STR_REPLACE_ALL_RAILTYPE :Semua kereta STR_REPLACE_ALL_RAILTYPE :Semua kereta
STR_REPLACE_HELP_RAILTYPE :{BLACK}Pilih jenis kereta yang anda inginkan untuk diganti STR_REPLACE_HELP_RAILTYPE :{BLACK}Pilih jenis kereta yang anda inginkan untuk diganti
STR_REPLACE_HELP_ROADTYPE :{BLACK}Pilih jenis jalan yang anda inginkan untuk diganti
STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Menampilkan kendaraan terpilih di sisi kiri yang akan diganti, jika ada STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Menampilkan kendaraan terpilih di sisi kiri yang akan diganti, jika ada
STR_REPLACE_RAIL_VEHICLES :Kereta STR_REPLACE_RAIL_VEHICLES :Kereta
STR_REPLACE_ELRAIL_VEHICLES :Kereta Listrik STR_REPLACE_ELRAIL_VEHICLES :Kereta Listrik

View File

@@ -244,6 +244,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Aizvērt
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Loga virsraksts - vilkt to, lai pārvietotu logu STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Loga virsraksts - vilkt to, lai pārvietotu logu
STR_TOOLTIP_SHADE :{BLACK}Aizēnot logu - rādīt tikai virsrakstu STR_TOOLTIP_SHADE :{BLACK}Aizēnot logu - rādīt tikai virsrakstu
STR_TOOLTIP_DEBUG :{BLACK}Rādīt NewGRF atkļūdošanas informāciju STR_TOOLTIP_DEBUG :{BLACK}Rādīt NewGRF atkļūdošanas informāciju
STR_TOOLTIP_DEFSIZE :{BLACK}Mainīt loga izmēru uz tā noklusējuma izmēru. Ctrl+klikšķis, lai saglabātu esošo izmēru kā noklusējuma
STR_TOOLTIP_STICKY :{BLACK}Atzīmēt šo logu kā neaizveramu ar "Aizvērt visus logus" taustiņu. Ctrl+klikšķis, lai saglabātu stāvokli kā noklusējumu STR_TOOLTIP_STICKY :{BLACK}Atzīmēt šo logu kā neaizveramu ar "Aizvērt visus logus" taustiņu. Ctrl+klikšķis, lai saglabātu stāvokli kā noklusējumu
STR_TOOLTIP_RESIZE :{BLACK}Klikšķināt un vilkt, lai mainītu šī loga lielumu STR_TOOLTIP_RESIZE :{BLACK}Klikšķināt un vilkt, lai mainītu šī loga lielumu
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Pārslēgties starp lielu/mazu loga izmēru STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Pārslēgties starp lielu/mazu loga izmēru
@@ -361,6 +362,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Ainavas
STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Pilsētu radīšana STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Pilsētu radīšana
STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Ražotņu radīšana STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Ražotņu radīšana
STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Ceļu būvēšana STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Ceļu būvēšana
STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramvaju sliežu ceļu būvniecība
STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Stādīt kokus. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Stādīt kokus. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu
STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Novietot zīmi STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Novietot zīmi
STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Novietot objektu. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Novietot objektu. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu
@@ -651,6 +653,7 @@ STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLA
STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}--
STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM}
STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------
STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Mūzika nav pieejama
STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}"
STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Celiņš STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Celiņš
STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Nosaukums STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Nosaukums
@@ -884,10 +887,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC
# Extra view window # Extra view window
STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Skatvieta {COMMA} STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Skatvieta {COMMA}
STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopēt uz skatvietu STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Mainīt skatvietu
STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopēt galvenā skata atrašanās vietu uz šo skatvietu STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopēt galvenā skata atrašanās vietu uz šo skatvietu
STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Kopēt no skatvietas STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Mainīt galveno skatu
STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Ielīmēt šīs skatvietas atrašanās vietu uz galveno skatu STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopēt šīs skatvietas atrašanās vietu uz galveno skatu
# Game options window # Game options window
STR_GAME_OPTIONS_CAPTION :{WHITE}Spēles opcijas STR_GAME_OPTIONS_CAPTION :{WHITE}Spēles opcijas
@@ -933,6 +936,7 @@ STR_GAME_OPTIONS_CURRENCY_RUB :Jaunais Krievij
STR_GAME_OPTIONS_CURRENCY_MXN :Meksikas peso (MXN) STR_GAME_OPTIONS_CURRENCY_MXN :Meksikas peso (MXN)
STR_GAME_OPTIONS_CURRENCY_NTD :Jaunais Taivānas dolārs (NTD) STR_GAME_OPTIONS_CURRENCY_NTD :Jaunais Taivānas dolārs (NTD)
STR_GAME_OPTIONS_CURRENCY_CNY :Ķīnas juaņa (CNY) STR_GAME_OPTIONS_CURRENCY_CNY :Ķīnas juaņa (CNY)
STR_GAME_OPTIONS_CURRENCY_HKD :Honkongas dolārs (HKD)
STR_GAME_OPTIONS_CURRENCY_INR :Indijas rūpija (INR) STR_GAME_OPTIONS_CURRENCY_INR :Indijas rūpija (INR)
############ end of currency region ############ end of currency region
@@ -997,6 +1001,7 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Divkāršs
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Četrkāršs STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Četrkāršs
STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Fonta izmērs STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Fonta izmērs
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Izvēlieties saskarnes fonta izmēru
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normāls STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normāls
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Divkāršs izmērs STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Divkāršs izmērs
@@ -1016,6 +1021,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP :{BLACK}Atlasīt
STR_GAME_OPTIONS_BASE_MUSIC_STATUS :{RED}{NUM} bojāt{P s i u} fail{P s i u} STR_GAME_OPTIONS_BASE_MUSIC_STATUS :{RED}{NUM} bojāt{P s i u} fail{P s i u}
STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :{BLACK}Papildinformācija par pamata mūzikas kopu STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :{BLACK}Papildinformācija par pamata mūzikas kopu
STR_ERROR_RESOLUTION_LIST_FAILED :{WHITE}Neizdevās saņemt sarakstu ar atbalstītajām izšķirtspējām
STR_ERROR_FULLSCREEN_FAILED :{WHITE}Pilnekrāna spēles iestatīšana neizdevās STR_ERROR_FULLSCREEN_FAILED :{WHITE}Pilnekrāna spēles iestatīšana neizdevās
# Custom currency window # Custom currency window
@@ -1133,6 +1139,7 @@ STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Spēles iestat
STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Uzņēmuma iestatījumi (tiek iekļauti saglabājumos, ietekmē tikai jaunās spēles) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Uzņēmuma iestatījumi (tiek iekļauti saglabājumos, ietekmē tikai jaunās spēles)
STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Uzņēmuma iestatījumi (tiek iekļauti saglabājumā, ietekmē tikai pašreizējo uzņēmumu) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Uzņēmuma iestatījumi (tiek iekļauti saglabājumā, ietekmē tikai pašreizējo uzņēmumu)
STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Rādīt visus meklēšanas rezultātus, iestatot{}{SILVER}Kategoriju {BLACK}uz {WHITE}{STRING} STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Rādīt visus meklēšanas rezultātus, iestatot{}{SILVER}Kategoriju {BLACK}uz {WHITE}{STRING}
STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}Rādīt visus meklēšanas rezultātus, iestatot{}{SILVER}Veidu {BLACK}uz {WHITE}Visi iestatījumu veidi
STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Rādīt visus meklēšanas rezultātus, iestatot{}{SILVER}Kategorija {BLACK}uz {WHITE}{STRING} {BLACK}un {SILVER}Tips {BLACK}uz {WHITE}Visi iestatījumu veidi STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Rādīt visus meklēšanas rezultātus, iestatot{}{SILVER}Kategorija {BLACK}uz {WHITE}{STRING} {BLACK}un {SILVER}Tips {BLACK}uz {WHITE}Visi iestatījumu veidi
STR_CONFIG_SETTINGS_NONE :{WHITE}-Nav- STR_CONFIG_SETTINGS_NONE :{WHITE}-Nav-
@@ -1157,17 +1164,21 @@ STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksimālais ai
STR_CONFIG_SETTING_INTEREST_RATE :Procentu likme: {STRING} STR_CONFIG_SETTING_INTEREST_RATE :Procentu likme: {STRING}
STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Aizdevumu procentu likme; ja ieslēgts, ietekmē arī inflāciju STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Aizdevumu procentu likme; ja ieslēgts, ietekmē arī inflāciju
STR_CONFIG_SETTING_RUNNING_COSTS :Kārtējās izmaksas: {STRING} STR_CONFIG_SETTING_RUNNING_COSTS :Kārtējās izmaksas: {STRING}
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Iestaties uzturēšanas un ekspluatācijas izmaksu līmeni transportlīdzekļiem un infrastruktūrai
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Būvēšanas ātrums: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Būvēšanas ātrums: {STRING}
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :MI (mākslīgā intelekta) būvniecības darbību daudzuma ierobežošana STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :MI (mākslīgā intelekta) būvniecības darbību daudzuma ierobežošana
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Transportlīdzekļu bojāšanās: {STRING} STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Transportlīdzekļu bojāšanās: {STRING}
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Nosaka, cik bieži var salūzt nepietiekami apkalpoti transportlīdzekļi
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Subsīdiju reizinātājs: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Subsīdiju reizinātājs: {STRING}
STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Iestatīt, cik daudz maksāt par subsidētajiem savienojumiem STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Iestatīt, cik daudz maksāt par subsidētajiem savienojumiem
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Būvēšanas izmaksas: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Būvēšanas izmaksas: {STRING}
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Iestatīt būvēšanas un pirkumu izmaksas STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Iestatīt būvēšanas un pirkumu izmaksas
STR_CONFIG_SETTING_RECESSIONS :Lejupslīde: {STRING} STR_CONFIG_SETTING_RECESSIONS :Lejupslīde: {STRING}
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Ja ieslēgts, ik pa laikam var gadīties recesijas. To laikā visa ražošana būtiski samazinās (tā atgriežas sākotnējā līmenī pēc recesijas beigām).
STR_CONFIG_SETTING_TRAIN_REVERSING :Neatļaut vilcienu apgriešanos stacijās: {STRING} STR_CONFIG_SETTING_TRAIN_REVERSING :Neatļaut vilcienu apgriešanos stacijās: {STRING}
STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Ja ieslēgts, stacijās vilcieni negriezīsies pretējā virzienā, pat ja braucot tādā veidā tie atrastu īsāku ceļu un nākamo pieturu; izņēmums ir gala stacijas STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Ja ieslēgts, stacijās vilcieni negriezīsies pretējā virzienā, pat ja braucot tādā veidā tie atrastu īsāku ceļu un nākamo pieturu; izņēmums ir gala stacijas
STR_CONFIG_SETTING_DISASTERS :Katastrofas: {STRING} STR_CONFIG_SETTING_DISASTERS :Katastrofas: {STRING}
STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Pārslēgt katastrofas, kas laiku pa laikam var bloķēt vai iznīcināt transportlīdzekļus un infrastruktūru
STR_CONFIG_SETTING_CITY_APPROVAL :Pilsētu domju attieksme pret platības pārstrukturēšanu: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL :Pilsētu domju attieksme pret platības pārstrukturēšanu: {STRING}
STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Izvēlieties, cik lielā mērā trokšņi un vides bojājumi ietekmē uzņēmuma reitingu un turpmākās būvniecības darbības viņu teritorijā STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Izvēlieties, cik lielā mērā trokšņi un vides bojājumi ietekmē uzņēmuma reitingu un turpmākās būvniecības darbības viņu teritorijā
@@ -1178,6 +1189,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Atļaut ainavas
STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Atļauj ainavas veidošanu zem ekām un ceļiem bez to nojaukšanas STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Atļauj ainavas veidošanu zem ekām un ceļiem bez to nojaukšanas
STR_CONFIG_SETTING_CATCHMENT :Atļaut realistiskākas, palielinātas apkalpojamās platības: {STRING} STR_CONFIG_SETTING_CATCHMENT :Atļaut realistiskākas, palielinātas apkalpojamās platības: {STRING}
STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Atšķirīga lieluma apkalpojamās platības dažādu veidu stacijām un lidostām STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Atšķirīga lieluma apkalpojamās platības dažādu veidu stacijām un lidostām
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Uzņēmumu stacijas var apkalpot industrijas, kurām ir pievienotas neitrālas stacijas: {STRING}
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Ja ieslēgts, industrijas ar pievienotām stacijām (piemēram, naftas ieguves platformas) var apkalpot arī netālu esošās uzņēmumumam piederošās stacijas. Ja izslēgts, šīs industrijas var apkalpot tikai to pašu stacijas. Tuvumā esošās uzņēmumu stacijas nevarēs tās apkalpot, un pievienotās stacijas neapkalpos preču veidus, kas nav atbilstošas attiecīgajai industrijai.
STR_CONFIG_SETTING_EXTRADYNAMITE :Atļaut pilsētai piederošo ceļu, tiltu un tuneļu nojaukšanu: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE :Atļaut pilsētai piederošo ceļu, tiltu un tuneļu nojaukšanu: {STRING}
STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Padara vieglāku pilsētai piederošas infrastruktūras un ēku nojaukšanu STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Padara vieglāku pilsētai piederošas infrastruktūras un ēku nojaukšanu
STR_CONFIG_SETTING_TRAIN_LENGTH :Maksimālais vilcienu garums: {STRING} STR_CONFIG_SETTING_TRAIN_LENGTH :Maksimālais vilcienu garums: {STRING}
@@ -1194,8 +1207,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Slīpu lauciņu
STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_PERCENTAGE :{COMMA}%
STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Nogāžu stāvums autotransporta līdzekļiem: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Nogāžu stāvums autotransporta līdzekļiem: {STRING}
STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Slīpu lauciņu nogāžu stāvums autotransporta līdzekļiem. Augstākas vērtības apgrūtina uzbraukšanu uzkalnā STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Slīpu lauciņu nogāžu stāvums autotransporta līdzekļiem. Augstākas vērtības apgrūtina uzbraukšanu uzkalnā
STR_CONFIG_SETTING_FORBID_90_DEG :Aizliegt vilcieniem un kuģiem veikt 90 grādu pagriezienus: {STRING} STR_CONFIG_SETTING_FORBID_90_DEG :Aizliegt vilcieniem veikt 90° pagriezienus: {STRING}
STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 grādu pagriezieni rodas, ja horizontālam sliežu ceļa posmam tieši seko vertikāls sliežu ceļa posms uz blakus esošā lauciņa. Tādējādi vilciens, šķērsojot lauciņu malas, veic 90 grādu pagriezienu, nevis parasto 45 grādu kā citām sliežu ceļu kombinācijām. Tas attiecas arī uz kuģu pagrieziena lenķiem STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 grādu pagriezieni rodas, ja horizontālam sliežu ceļa posmam tieši seko vertikāls sliežu ceļa posms uz blakus esošā lauciņa. Tādējādi vilciens, šķērsojot lauciņu malas, veic 90 grādu pagriezienu, nevis parasto 45 grādu kā citām sliežu ceļu kombinācijām. Tas attiecas arī uz kuģu pagrieziena leņķiem. Tas arī attiecas uz kuģu pagriešanās rādiusu.
STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Atļaut savienot stacijas, kas neatrodas tieši blakus: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Atļaut savienot stacijas, kas neatrodas tieši blakus: {STRING}
STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Atļaut pievienot staciju daļas, tām nesaskaroties ar jau esošajām. Novietojot jaunās daļas, ir nepieciešams nospiest Ctrl+klikšķis STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Atļaut pievienot staciju daļas, tām nesaskaroties ar jau esošajām. Novietojot jaunās daļas, ir nepieciešams nospiest Ctrl+klikšķis
STR_CONFIG_SETTING_INFLATION :Inflācija: {STRING} STR_CONFIG_SETTING_INFLATION :Inflācija: {STRING}
@@ -1240,7 +1253,7 @@ STR_CONFIG_SETTING_BRIBE_HELPTEXT :Lauj uzņēmumi
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Atļaut pirkt pārvadājumu izņēmuma tiesības: {STRING} STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Atļaut pirkt pārvadājumu izņēmuma tiesības: {STRING}
STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Ja uzņēmums pērk pārvadājumu izņēmuma tiesības pilsētā, pretinieku stacijas (pasažieru un kravas) veselu gadu nesaņems nekādu kravu STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Ja uzņēmums pērk pārvadājumu izņēmuma tiesības pilsētā, pretinieku stacijas (pasažieru un kravas) veselu gadu nesaņems nekādu kravu
STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Atļaut ēku finansēšanu: {STRING} STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Atļaut ēku finansēšanu: {STRING}
STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Atļauj uzņēmumiem dot naudu pilsētām jaunu ēku finansēšanai STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Atļauj uzņēmumiem dot naudu apdzīvotām vietām jaunu ēku finansēšanai
STR_CONFIG_SETTING_ALLOW_FUND_ROAD :Atļaut finansēt vietējo ceļu atjaunošanu: {STRING} STR_CONFIG_SETTING_ALLOW_FUND_ROAD :Atļaut finansēt vietējo ceļu atjaunošanu: {STRING}
STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Atļaut uzņēmumiem dot pilsētām naudu ceļu rekonstrukcijai, lai kaitētu ceļu pakalpojumiem pilsētās STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Atļaut uzņēmumiem dot pilsētām naudu ceļu rekonstrukcijai, lai kaitētu ceļu pakalpojumiem pilsētās
STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Atļaut pārsūtīt naudu citiem uzņēmumiem: {STRING} STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Atļaut pārsūtīt naudu citiem uzņēmumiem: {STRING}
@@ -1251,8 +1264,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Lidmašīnu āt
STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Iestatīt lidmašīnu nosacīto ātrumu salīdzinājumā ar citu veidu transportlīdzekļiem, lai samazinātu lidaparātu ienākumus STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Iestatīt lidmašīnu nosacīto ātrumu salīdzinājumā ar citu veidu transportlīdzekļiem, lai samazinātu lidaparātu ienākumus
STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA}
STR_CONFIG_SETTING_PLANE_CRASHES :Lidmašīnu avāriju daudzums: {STRING} STR_CONFIG_SETTING_PLANE_CRASHES :Lidmašīnu avāriju daudzums: {STRING}
STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Iestatīt lidaparātu avāriju notikšanas iespējamību STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Iestatīt nejaušu lidaparātu avāriju iespējamību.{}* Lielām lidmašīnām vienmēr ir risks avarēt, kad piezemējas mazās lidostās
STR_CONFIG_SETTING_PLANE_CRASHES_NONE :neviena STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nav*
STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :samazināts STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :samazināts
STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :parasts STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :parasts
STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Atļaut caurbraucamas pieturvietas uz pilsētai piederošiem ceļiem: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Atļaut caurbraucamas pieturvietas uz pilsētai piederošiem ceļiem: {STRING}
@@ -1308,11 +1321,12 @@ STR_CONFIG_SETTING_LAND_GENERATOR :Zemes radītāj
STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :Sākotnējais ģenerators ir atkarīgs no bāzes grafikas kopas, un veido fiksētas ainavas formas. TerraGenesis ir uz Perlina trokšņa balstīts ģenerators ar smalkākiem vadības iestatījumiem. STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :Sākotnējais ģenerators ir atkarīgs no bāzes grafikas kopas, un veido fiksētas ainavas formas. TerraGenesis ir uz Perlina trokšņa balstīts ģenerators ar smalkākiem vadības iestatījumiem.
STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Sākotnējais STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :Sākotnējais
STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis
STR_CONFIG_SETTING_TERRAIN_TYPE :Reljefa veids: {STRING}
STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Tikai TerraGenesis) Ainavas kalnainība STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Tikai TerraGenesis) Ainavas kalnainība
STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industriju blīvums: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industriju blīvums: {STRING}
STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Iestatiet, cik industrijas jāģenerē un kāds līmenis jāuztur spēles laikā STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Iestatiet, cik industrijas jāģenerē un kāds līmenis jāuztur spēles laikā
STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maksimālais attālums no kartes malas naftas pārstrādes rūpnīcām: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Naftas industriju maksimālais attālums no kartes malas: {STRING}
STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Naftas pārstrādes rūpnīcas ir būvējamas tikai kartes malu tuvumā, salu kartēm tas ir pie krasta STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limits, cik tālu no kartes malām drīkst taisīt naftas pārstrādes rūpnīcas un un naftas ieguves platformas. Uz salu kartēm tas nodrošina, ka šīs konstrukcijas tiek būvētas piekrastēs. Uz kartēm, kas ir lielākas par 256 lauciņiem šī vērtība tiek palielināta.
STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Sniega līnijas augstums: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Sniega līnijas augstums: {STRING}
STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Noteikt, kādā augstumā sākas subarktiskā ainava. Sniegs arī ietekmē industriju rašanos un apdzīvoto vietu pieaugšanas prasības STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Noteikt, kādā augstumā sākas subarktiskā ainava. Sniegs arī ietekmē industriju rašanos un apdzīvoto vietu pieaugšanas prasības
STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Apvidus nelīdzenums: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Apvidus nelīdzenums: {STRING}
@@ -1331,6 +1345,7 @@ STR_CONFIG_SETTING_TREE_PLACER_NONE :Nav
STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Sākotnējais STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Sākotnējais
STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Uzlabotais STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Uzlabotais
STR_CONFIG_SETTING_ROAD_SIDE :Autotransporta līdzekļi: {STRING} STR_CONFIG_SETTING_ROAD_SIDE :Autotransporta līdzekļi: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Izvēlieties braukšanas pusi
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Augstumu kartes pagriešana: {STRING} STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Augstumu kartes pagriešana: {STRING}
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Pret pulksteņa rādītāja virzienu STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Pret pulksteņa rādītāja virzienu
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE :Pulksteņa rādītāja virzienā STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE :Pulksteņa rādītāja virzienā
@@ -1353,8 +1368,10 @@ STR_CONFIG_SETTING_SCROLLMODE :Skatvietas riti
STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Uzvedība, kad ritina karti STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Uzvedība, kad ritina karti
STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pārvietot skatvietu ar labo peles pogu, peles pozīcija ir fiksēta STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pārvietot skatvietu ar labo peles pogu, peles pozīcija ir fiksēta
STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pārvietot karti ar labo peles pogu, peles pozīcija ir fiksēta STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pārvietot karti ar labo peles pogu, peles pozīcija ir fiksēta
STR_CONFIG_SETTING_SCROLLMODE_RMB :Pārvietot karti ar labo peles pogu
STR_CONFIG_SETTING_SCROLLMODE_LMB :Pārvietot karti ar kreiso peles pogu STR_CONFIG_SETTING_SCROLLMODE_LMB :Pārvietot karti ar kreiso peles pogu
STR_CONFIG_SETTING_SMOOTH_SCROLLING :Plūdena skatvietas ritināšana: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :Plūdena skatvietas ritināšana: {STRING}
STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Noteikt, kā galvenais skats ritina uz norādīto pozīciju, kad klikšķina uz mazās kartes vai kad dod komandu ritināt uz noteiktu kartes objektu. Ja ieslēgs, skatvieta ritinās gludi. Ja izslēgts, skats pārlec uz izvēlēto punktu.
STR_CONFIG_SETTING_MEASURE_TOOLTIP :Rādīt mērījumu rīkjoslu, izmantojot dažādus būvniecības rīkus: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :Rādīt mērījumu rīkjoslu, izmantojot dažādus būvniecības rīkus: {STRING}
STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Rāda lauciņu attālumus un augstuma starpības, ar vilkšanu veicot būvniecības darbības STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Rāda lauciņu attālumus un augstuma starpības, ar vilkšanu veicot būvniecības darbības
STR_CONFIG_SETTING_LIVERIES :Rādīt uzņēmuma identitātes krāsas: {STRING} STR_CONFIG_SETTING_LIVERIES :Rādīt uzņēmuma identitātes krāsas: {STRING}
@@ -1384,6 +1401,7 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Komanda+klikš
STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klikšķis STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klikšķis
STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Izslēgta STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Izslēgta
STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Aizvērt logu ar labo klikšķi: {STRING}
STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Labais klikšķis logā aizver logu. Izslēdz paskaidres parādīšanu ar labo klikšķi! STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Labais klikšķis logā aizver logu. Izslēdz paskaidres parādīšanu ar labo klikšķi!
STR_CONFIG_SETTING_AUTOSAVE :Automātiskā saglabāšana: {STRING} STR_CONFIG_SETTING_AUTOSAVE :Automātiskā saglabāšana: {STRING}
@@ -1477,6 +1495,7 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Cik daudz atmi
STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB
STR_CONFIG_SETTING_SERVINT_ISPERCENT :Apkopju starplaiki procentos: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT :Apkopju starplaiki procentos: {STRING}
STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Izvēlieties, vai transportlīdzekļu apkopi veikt pēc fiksēta laika kopš iepriekšējās apkopes vai, kad uzticamība nokrīt zem kāda noteiktas daļas no maksimālās uzticamības
STR_CONFIG_SETTING_SERVINT_TRAINS :Vilcienu apkopju noklusējuma starplaiks: {STRING} STR_CONFIG_SETTING_SERVINT_TRAINS :Vilcienu apkopju noklusējuma starplaiks: {STRING}
STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Izvēlēties jaunajiem sliežu transportlīdzekļiem apkopju noklusējuma starplaiku, ja tiem tas nav noteikts STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Izvēlēties jaunajiem sliežu transportlīdzekļiem apkopju noklusējuma starplaiku, ja tiem tas nav noteikts
STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}dien{P 0 a as u}/% STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}dien{P 0 a as u}/%
@@ -1533,6 +1552,7 @@ STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Krāsaini avī
STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Gads kad sāk drukāt krāsainas avīzes. Pirms šā gada tās ir melnbaltas STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Gads kad sāk drukāt krāsainas avīzes. Pirms šā gada tās ir melnbaltas
STR_CONFIG_SETTING_STARTING_YEAR :Sākuma gads: {STRING} STR_CONFIG_SETTING_STARTING_YEAR :Sākuma gads: {STRING}
STR_CONFIG_SETTING_ENDING_YEAR :Vērtēšanas beigu gads: {STRING} STR_CONFIG_SETTING_ENDING_YEAR :Vērtēšanas beigu gads: {STRING}
STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Spēles beigas gads (tiek izmantots rezultāta noteikšanai). Šī gada beigās uzņēmuma rezultāti tiek ierakstīti un uz ekrāna tiek parādīti labākie rezultāti, bet spēlētāji var turpināt spēlēt arī pēc šī datuma.{}Ja tas ir norādīts pirms spēles sākuma datuma, labākie rezultāti nekad netiek parādīti.
STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM}
STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nekad STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nekad
STR_CONFIG_SETTING_SMOOTH_ECONOMY :Atļaut vienmērīgas izmaiņas ekonomikā: {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY :Atļaut vienmērīgas izmaiņas ekonomikā: {STRING}
@@ -1621,12 +1641,12 @@ STR_CONFIG_SETTING_TOWN_GROWTH_SLOW :mazs
STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :vidējs STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :vidējs
STR_CONFIG_SETTING_TOWN_GROWTH_FAST :liels STR_CONFIG_SETTING_TOWN_GROWTH_FAST :liels
STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :ļoti liels STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :ļoti liels
STR_CONFIG_SETTING_LARGER_TOWNS :Pilsētu daļa kas kļūs par lielpilsētām: {STRING} STR_CONFIG_SETTING_LARGER_TOWNS :Apdzīvotu vietu proporcija, kas kļūs par pilsētām: {STRING}
STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Pilsētu daudzums kas kļūs par lielpilsētām, tādēļ s sākumā ir lielākas un attīstās ātrāk STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Apdzīvotu vietu daudzums kas kļūs par pilsētām; tādēļ apdzīvota vieta, kas sākumā ir lielāka, augs straujāk
STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 pret {COMMA} STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 pret {COMMA}
STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :neviena STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :neviena
STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Lielpilsētu sākuma lieluma reizinātājs: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Pilsētu sākuma lieluma reizinātājs: {STRING}
STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Lielpilsētu vidējais lielums attiecībā pret parastām pilsētām spēles sākumā STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Pilsētu vidējais lielums attiecībā pret parastām apdzīvotām vietām spēles sākumā
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Atjaunināt sadales grafu ik pa {STRING}{NBSP}dien{P 0:2 ai ām ām} STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Atjaunināt sadales grafu ik pa {STRING}{NBSP}dien{P 0:2 ai ām ām}
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Laiks starp secīgām saišu grafa pārrēķināšanām. Katra pārrēķināšana izskaitļo plānos vienai grafa komponentei. Tas nozīmē, ka šim iestatījumam vērtība X nenozīmē, ka viss grafs tiks atjaunināts ir pēc X dienām. Tikai dažas komponentes tiks pārrēķinātas. Jo mazāka iestatītā vērtība, jo vairāk laika CPU pavadīs rēķinot. Jo lielāka iestatītā vērtība, jo ilgāk nevarēs sākties kravu izplatīšana jaunos maršrutos. STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Laiks starp secīgām saišu grafa pārrēķināšanām. Katra pārrēķināšana izskaitļo plānos vienai grafa komponentei. Tas nozīmē, ka šim iestatījumam vērtība X nenozīmē, ka viss grafs tiks atjaunināts ir pēc X dienām. Tikai dažas komponentes tiks pārrēķinātas. Jo mazāka iestatītā vērtība, jo vairāk laika CPU pavadīs rēķinot. Jo lielāka iestatītā vērtība, jo ilgāk nevarēs sākties kravu izplatīšana jaunos maršrutos.
@@ -1644,10 +1664,12 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :APSARGĀJAMĀ k
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Izplatīšanas modelis citām kravu klasēm: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Izplatīšanas modelis citām kravu klasēm: {STRING}
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetriska" nozīmē, ka patvaļīgu kravas daudzumu var nosūtīt abos virzienos."manuāli" nozīmē, ka šīm kravām netiks veikta automātiska izplatīšana. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetriska" nozīmē, ka patvaļīgu kravas daudzumu var nosūtīt abos virzienos."manuāli" nozīmē, ka šīm kravām netiks veikta automātiska izplatīšana.
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Sadales precizitāte: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Sadales precizitāte: {STRING}
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Jo lielāku vērtību iestatīsiet, jo vairāk CPU laika aizies saišu grafa aprēķināšanai. Ja tas aizņem pārāk daudz laika, jūs varētu pamanīt spēles iebremzēšanos. Ja iestatīsiet pārāk mazu, izplatīšana būs neprecīza un jūs varētu pamanīt, ka krava tiek nosūtīta uz negaidītām vietām.
STR_CONFIG_SETTING_DEMAND_DISTANCE :Attāluma ietekme uz pieprasījumu: {STRING} STR_CONFIG_SETTING_DEMAND_DISTANCE :Attāluma ietekme uz pieprasījumu: {STRING}
STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Ja iestatīsiet šo vērtību lielāku kā 0, attālums starp kravas izcelsmes staciju A un iespējamo galastaciju B ietekmēs sūtāmās kravas apjomu. Jo tālāk no stacijas A ir stacija B, jo mazāk kravas tiks nosūtīts. Jo augstāka vērtība, jo mazāk kravas tiks nosūtīts uz tālo staciju un vairāk kravu uz tuvo staciju. STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Ja iestatīsiet šo vērtību lielāku kā 0, attālums starp kravas izcelsmes staciju A un iespējamo galastaciju B ietekmēs sūtāmās kravas apjomu. Jo tālāk no stacijas A ir stacija B, jo mazāk kravas tiks nosūtīts. Jo augstāka vērtība, jo mazāk kravas tiks nosūtīts uz tālo staciju un vairāk kravu uz tuvo staciju.
STR_CONFIG_SETTING_DEMAND_SIZE :Atpakaļceļa kravas daudzums simetriskajā režīmā: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE :Atpakaļceļa kravas daudzums simetriskajā režīmā: {STRING}
STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Uzstādod šo mazāk par 100% liks simetriskajai sadalei izturēties vairāk kā asimetriskajai. Mazāk kravas ar varu tiks sūtīts atpakaļ ja noteikts daudzums tiks sūtīts uz piestātni. Ja jūs uzstādīsiet to uz 0% simetriskā sadale izturēsies tā pat kā asimetriskā. STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Uzstādod šo mazāk par 100% liks simetriskajai sadalei izturēties vairāk kā asimetriskajai. Mazāk kravas ar varu tiks sūtīts atpakaļ ja noteikts daudzums tiks sūtīts uz piestātni. Ja jūs uzstādīsiet to uz 0% simetriskā sadale izturēsies tā pat kā asimetriskā.
STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Īso ceļu piesātinājums pirms sākt izmantot augstas ietilpības ceļus: {STRING}
STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Nereti starp divām stacijām ir vairāki ceļi. Kravu sadale vispirms piesātinās īsāko maršrutu, pēc tam izmantos nākamo īsāko maršrutu līdz tas būs piesātināts, un tā tālāk. Piesātinājumu nosaka novērtējot ietilpību un plānoto izmantojumu. Kad visi ceļi ir piesātināti un vēl ir palicis pieprasījumus, tas pārslogos visus ceļus, dodot priekšroku ceļiem ar lielāko ietilpību. Algoritms visbiežāk nepareizi novērtēs ietilpību. Šis iestatījums jums atļaus norādīt, līdz cik procentiem īsākais ceļš ir jāpiesātina pirmajā piegājienā pirms izvēlēties garāku ceļu. Iestatiet to uz mazāk kā 100%, lai izvairītos no pārpildītām stacijām, ja kapacitāte ir pārvērtēta. STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Nereti starp divām stacijām ir vairāki ceļi. Kravu sadale vispirms piesātinās īsāko maršrutu, pēc tam izmantos nākamo īsāko maršrutu līdz tas būs piesātināts, un tā tālāk. Piesātinājumu nosaka novērtējot ietilpību un plānoto izmantojumu. Kad visi ceļi ir piesātināti un vēl ir palicis pieprasījumus, tas pārslogos visus ceļus, dodot priekšroku ceļiem ar lielāko ietilpību. Algoritms visbiežāk nepareizi novērtēs ietilpību. Šis iestatījums jums atļaus norādīt, līdz cik procentiem īsākais ceļš ir jāpiesātina pirmajā piegājienā pirms izvēlēties garāku ceļu. Iestatiet to uz mazāk kā 100%, lai izvairītos no pārpildītām stacijām, ja kapacitāte ir pārvērtēta.
STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Ātruma mērvienības: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Ātruma mērvienības: {STRING}
@@ -1803,8 +1825,8 @@ STR_OSNAME_SUNOS :SunOS
# Abandon game # Abandon game
STR_ABANDON_GAME_CAPTION :{WHITE}Pamest spēli STR_ABANDON_GAME_CAPTION :{WHITE}Pamest spēli
STR_ABANDON_GAME_QUERY :{YELLOW}Vai jūs tiešām vēlaties pamest šo spēli? STR_ABANDON_GAME_QUERY :{YELLOW}Vai tiešām vēlaties pamest šo spēli?
STR_ABANDON_SCENARIO_QUERY :{YELLOW}Vai esat pārliecināts, ka vēlaties pamest šo scenāriju? STR_ABANDON_SCENARIO_QUERY :{YELLOW}Vai tiešām vēlaties pamest šo scenāriju?
# Cheat window # Cheat window
STR_CHEATS :{WHITE}Blēdības STR_CHEATS :{WHITE}Blēdības
@@ -2132,7 +2154,7 @@ STR_NETWORK_CHAT_ALL :[Visiem] {STRIN
STR_NETWORK_CHAT_OSKTITLE :{BLACK}Ievadīt tekstu tīkla tērzēšanai STR_NETWORK_CHAT_OSKTITLE :{BLACK}Ievadīt tekstu tīkla tērzēšanai
# Network messages # Network messages
STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Neviena tīkla iekārta nav atrasta vai kompilēta bez ENABLE_NETWORK STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nav atrasta neviena tīkla ierīce
STR_NETWORK_ERROR_NOSERVER :{WHITE}Nevar atrast nevienu tīkla spēli STR_NETWORK_ERROR_NOSERVER :{WHITE}Nevar atrast nevienu tīkla spēli
STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Serveris neatbild uz pieprasījumu STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Serveris neatbild uz pieprasījumu
STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Nevar pieslēgties sakarā ar NewGRF neatbilstību STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Nevar pieslēgties sakarā ar NewGRF neatbilstību
@@ -2386,9 +2408,9 @@ STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Kombinē
STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Ceļa signāls (luksofors){}Ceļa signāls ļauj vairāk kā vienam vilcienam iebraukt signāla blokā vienlaicīgi, ja vien vilciens var rezervēt drošu apstāšanās punktu. Parastiem ceļa signāliem var pabraukt garām no aizmugures STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Ceļa signāls (luksofors){}Ceļa signāls ļauj vairāk kā vienam vilcienam iebraukt signāla blokā vienlaicīgi, ja vien vilciens var rezervēt drošu apstāšanās punktu. Parastiem ceļa signāliem var pabraukt garām no aizmugures
STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Vienvirziena ceļa signālierīce (elektriska){}Ceļa signāls ļauj iebraukt signāla blokā vairāk kā vienam vilcienam vienlaicīgi, ja vien vilciens var rezervēt drošu apstāšanās punktu. Vienvirziena ceļa signālierīcēm nevar pabraukt garām no aizmugures STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Vienvirziena ceļa signālierīce (elektriska){}Ceļa signāls ļauj iebraukt signāla blokā vairāk kā vienam vilcienam vienlaicīgi, ja vien vilciens var rezervēt drošu apstāšanās punktu. Vienvirziena ceļa signālierīcēm nevar pabraukt garām no aizmugures
STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signālierīču pārveidotājs{}Kad ieslēgts, klikšķis uz jau esošas signālierīces pārveidos to uz norādīto signāla tipu un variantu. Ctrl+klikšķis pārslēgs pašreizējo variantu. Shift+klikšķis rāda pārveidošanas tāmes vērtību STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signālierīču pārveidotājs{}Kad ieslēgts, klikšķis uz jau esošas signālierīces pārveidos to uz norādīto signāla tipu un variantu. Ctrl+klikšķis pārslēgs pašreizējo variantu. Shift+klikšķis rāda pārveidošanas tāmes vērtību
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Vilkt signālu biežumu STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Vilkto signālu attālums
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Samazināt signālierīču attālumu STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Samazināt signālierīču attālumu
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Palielināt signālierīču biežumu STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Palielināt signālierīču atstatumu
# Bridge selection window # Bridge selection window
STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Izvēlēties dzelzceļa tiltu STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Izvēlēties dzelzceļa tiltu
@@ -2426,6 +2448,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Būvēt
STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Būvēt tramvaju tuneli. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Būvēt tramvaju tuneli. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Pārslēgties starp ceļa būvēšanas/nojaukšanas režīmiem STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Pārslēgties starp ceļa būvēšanas/nojaukšanas režīmiem
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Pārslēgt būvēt/novākt tramvaju būvei STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Pārslēgt būvēt/novākt tramvaju būvei
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Pārveidot/uzlabot ceļa veidu. Shift pārslēdz būvēšanu/izmaksu novērtējumu rādīšanu
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Pārveidot/uzlabot tramvaju veidu. Shift pārslēdz būvēšanu/izmaksu novērtējumu rādīšanu STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Pārveidot/uzlabot tramvaju veidu. Shift pārslēdz būvēšanu/izmaksu novērtējumu rādīšanu
STR_ROAD_NAME_ROAD :Ceļš STR_ROAD_NAME_ROAD :Ceļš
@@ -2477,7 +2500,7 @@ STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Lidostas
STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}{NUM}. izkārtojums STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}{NUM}. izkārtojums
STR_AIRPORT_SMALL :Maza STR_AIRPORT_SMALL :Maza
STR_AIRPORT_CITY :Lielpilsēta STR_AIRPORT_CITY :Pilsēta
STR_AIRPORT_METRO :Metropolitēns STR_AIRPORT_METRO :Metropolitēns
STR_AIRPORT_INTERNATIONAL :Starptautiskā lidosta STR_AIRPORT_INTERNATIONAL :Starptautiskā lidosta
STR_AIRPORT_COMMUTER :Ikdienas satiksme STR_AIRPORT_COMMUTER :Ikdienas satiksme
@@ -2553,8 +2576,8 @@ STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON :{BLACK}Vidējs
STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON :{BLACK}Liels STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON :{BLACK}Liels
STR_FOUND_TOWN_SIZE_RANDOM :{BLACK}Nejaušs STR_FOUND_TOWN_SIZE_RANDOM :{BLACK}Nejaušs
STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Izvēlēties pilsētas izmērus STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Izvēlēties pilsētas izmērus
STR_FOUND_TOWN_CITY :{BLACK}Lielpilsēta STR_FOUND_TOWN_CITY :{BLACK}Pilsēta
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Lielpilsētas attīstās ātrāk kā pilsētas{}Atkarībā no iestatījumiem, dibināšanas brīdī s ir lielākas STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Pilsētas aug straujāk kā parastas apdzīvotās vietas{}Atkarībā no iestatījumiem, dibināšanas brīdī pilsētas ir lielākas
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Pilsētas ceļu izskats: STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Pilsētas ceļu izskats:
STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}Atlasīt šajā pilsētā lietojamo ceļu izkārtojumu STR_FOUND_TOWN_SELECT_TOWN_ROAD_LAYOUT :{BLACK}Atlasīt šajā pilsētā lietojamo ceļu izkārtojumu
@@ -2616,6 +2639,7 @@ STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Pieņem
STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING})
STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Sliežu veids: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Sliežu veids: {LTBLUE}{STRING}
STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Ceļu tips: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Ceļu tips: {LTBLUE}{STRING}
STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tramvaja veids: {LTBLUE}{STRING}
STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Sliežu ātruma ierobežojums: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Sliežu ātruma ierobežojums: {LTBLUE}{VELOCITY}
STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Ceļa ātruma ierobežojums: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Ceļa ātruma ierobežojums: {LTBLUE}{VELOCITY}
STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tramvaja ātruma ierobežojums: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tramvaja ātruma ierobežojums: {LTBLUE}{VELOCITY}
@@ -2629,29 +2653,29 @@ STR_LAI_CLEAR_DESCRIPTION_FIELDS :Lauki
STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Apsnigusi zeme STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Apsnigusi zeme
STR_LAI_CLEAR_DESCRIPTION_DESERT :Tuksnesis STR_LAI_CLEAR_DESCRIPTION_DESERT :Tuksnesis
STR_LAI_RAIL_DESCRIPTION_TRACK :Dzelzceļš sliedes STR_LAI_RAIL_DESCRIPTION_TRACK :Dzelzceļa sliedes
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Dzelzceļš ceļš ar bloķēšanas signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS :Dzelzceļa sliedes ar bloku signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Dzelzceļš sliedes ar pirmssignālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS :Dzelzceļa sliedes ar pirmssignālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Dzelzceļš sliedes ar izejas signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS :Dzelzceļa sliedes ar izejas signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Dzelzceļš sliedes ar kombinētajām signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS :Dzelzceļa sliedes ar kombinētajām signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Dzelzceļš sliedes ar ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS :Dzelzceļa sliedes ar ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Dzelzceļš sliedes ar vienvirziena ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS :Dzelzceļa sliedes ar vienvirziena ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Dzelzceļš sliedes ar bloka un pirmssignālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS :Dzelzceļa sliedes ar bloku un pirmssignālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Dzelzceļš sliedes ar bloka un izejas signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS :Dzelzceļa sliedes ar bloku un izejas signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Dzelzceļš sliedes ar bloka un kombinētajām signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS :Dzelzceļa sliedes ar bloku un kombinētajām signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Dzelzceļš sliedes ar bloka un ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS :Dzelzceļa sliedes ar bloku un ceļu signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Dzelzceļš sliedes ar bloka un vienvirziena ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS :Dzelzceļa sliedes ar bloka un vienvirziena ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Dzelzceļš sliedes ar izejas un pirmssignālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS :Dzelzceļa sliedes ar izejas un pirmssignālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Dzelzceļš sliedes ar kombinētajām un pirmssignālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS :Dzelzceļa sliedes ar kombinētajām un pirmssignālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Dzelzceļš sliedes ar ceļu un pirmssignālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS :Dzelzceļa sliedes ar ceļu un pirmssignālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Dzelzceļš sliedes ar vienvirziena ceļu un pirmssignālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS :Dzelzceļa sliedes ar vienvirziena un pirmssignālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Dzelzceļš sliedes ar izejas un kombinētajām signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS :Dzelzceļa sliedes ar izejas un kombinētajām signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Dzelzceļš sliedes ar izejas un ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS :Dzelzceļa sliedes ar izejas un ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Dzelzceļš sliedes ar izejas un vienvirziena ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :Dzelzceļa sliedes ar izejas un vienvirziena ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Dzelzceļš sliedes ar kombinētajām un ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :Dzelzceļa sliedes ar kombinētajām un ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Dzelzceļš sliedes ar kombinētajām un vienvirziena ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Dzelzceļa sliedes ar kombinētajām un vienvirziena ceļa signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Dzelzceļš sliedes ar ceļa un vienvirziena ceļa signālierīcēm STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Dzelzceļa sliedes ar ceļu un vienvirziena ceļu signālierīcēm
STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Dzelzceļš vilcienu depo STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Dzelzceļa vilcienu depo
STR_LAI_ROAD_DESCRIPTION_ROAD :Ceļš STR_LAI_ROAD_DESCRIPTION_ROAD :Ceļš
STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Ceļš ar ielu apgaismojumu STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Ceļš ar ielu apgaismojumu
@@ -2723,7 +2747,8 @@ STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE}
STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Simulācijas ātrums: {STRING} STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Simulācijas ātrums: {STRING}
STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Spēles tikšķu skaits, ko simulēt vienā sekundē. STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Spēles tikšķu skaits, ko simulēt vienā sekundē.
STR_FRAMERATE_RATE_BLITTER :{BLACK}Grafikas kadru ātrums: {STRING} STR_FRAMERATE_RATE_BLITTER :{BLACK}Grafikas kadru ātrums: {STRING}
STR_FRAMERATE_SPEED_FACTOR :{WHITE}pašreizējās spēles ātruma pakāpe: {DECIMAL}x STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Sekundē renderēto video kadru skaits.
STR_FRAMERATE_SPEED_FACTOR :{BLACK}Pašreizējās spēles ātruma pakāpe: {DECIMAL}×
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Cik ātri spēle šobrīd iet salīdzinot ar standarta ātrumu. STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Cik ātri spēle šobrīd iet salīdzinot ar standarta ātrumu.
STR_FRAMERATE_CURRENT :{WHITE}Pašreizējais STR_FRAMERATE_CURRENT :{WHITE}Pašreizējais
STR_FRAMERATE_AVERAGE :{WHITE}Vidējais STR_FRAMERATE_AVERAGE :{WHITE}Vidējais
@@ -2749,6 +2774,7 @@ STR_FRAMERATE_GL_SHIPS :{BLACK} Kuģu
STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Lidaparātu tikšķi: STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Lidaparātu tikšķi:
STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Pasaules tikšķi: STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Pasaules tikšķi:
STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Saišu grafika aizture: STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Saišu grafika aizture:
STR_FRAMERATE_DRAWING :{BLACK}Grafikas renderēšana:
STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Pasaules skatvietas: STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Pasaules skatvietas:
STR_FRAMERATE_VIDEO :{BLACK}Video izvade: STR_FRAMERATE_VIDEO :{BLACK}Video izvade:
STR_FRAMERATE_SOUND :{BLACK}Skaņas miksēšana: STR_FRAMERATE_SOUND :{BLACK}Skaņas miksēšana:
@@ -2761,6 +2787,7 @@ STR_FRAMETIME_CAPTION_GAMELOOP :Spēles cikls
STR_FRAMETIME_CAPTION_GL_ECONOMY : Kravu iekraušana un izkraušana STR_FRAMETIME_CAPTION_GL_ECONOMY : Kravu iekraušana un izkraušana
STR_FRAMETIME_CAPTION_GL_TRAINS :Vilcienu tikšķi STR_FRAMETIME_CAPTION_GL_TRAINS :Vilcienu tikšķi
STR_FRAMETIME_CAPTION_GL_ROADVEHS :Autotransporta tikšķi STR_FRAMETIME_CAPTION_GL_ROADVEHS :Autotransporta tikšķi
STR_FRAMETIME_CAPTION_GL_SHIPS :Kuģu tikšķi
STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Lidaparātu tikšķi STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Lidaparātu tikšķi
STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Pasaules tikšķi STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Pasaules tikšķi
STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Saišu grafa aizture STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Saišu grafa aizture
@@ -2918,6 +2945,8 @@ STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum:
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palete: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palete: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Noklusējuma (D) STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Noklusējuma (D)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Noklusējuma (D) / 32 bpp STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Noklusējuma (D) / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Mantotais (W)
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Mantotais (W) / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parametri: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parametri: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :Nav STR_NEWGRF_SETTINGS_PARAMETER_NONE :Nav
@@ -2965,9 +2994,11 @@ STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Iet pie
STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Iepriekšējais gariņš STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Iepriekšējais gariņš
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Iet pie iepriekšējā parastā gariņa, izlaižot visus pseido/pārkrāsotos/fonta gariņus STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Iet pie iepriekšējā parastā gariņa, izlaižot visus pseido/pārkrāsotos/fonta gariņus
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Atlasītā gariņa attēlojums. To attēlojot, izkārtojums netiek ievērots STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Atlasītā gariņa attēlojums. To attēlojot, izkārtojums netiek ievērots
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Pārvietot gariņu, lai mainītu X un Y vērtības STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Pārvietot gariņu, lai mainītu X un Y vērtības. Ctrl+klikšķis, lai vienā piegājienā pārvietotu gariņu par astoņām vienībām
STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Atiestatīt relatīvi STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Atiestatīt relatīvi
STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Pāriestatīt paršreizējo relatīvo nobīdi
STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X nobīde: {NUM}, Y nobīde: {NUM} (absolūta) STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X nobīde: {NUM}, Y nobīde: {NUM} (absolūta)
STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X nobīde: {NUM}, Y nobīde: {NUM} (relatīvi)
STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Paņemt gariņu STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Paņemt gariņu
STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Paņemt gariņu no jebkuras vietas ekrānā STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Paņemt gariņu no jebkuras vietas ekrānā
@@ -3033,6 +3064,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF '
STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}'{1:ENGINE}' kravas pielāgošanas informācija pēc izbūves atšķiras no pārdošanas sarakstā norādītās. Tas var liegt automātiskai atjaunošanai/aizvietošanai pareizi pielāgot kravas STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}'{1:ENGINE}' kravas pielāgošanas informācija pēc izbūves atšķiras no pārdošanas sarakstā norādītās. Tas var liegt automātiskai atjaunošanai/aizvietošanai pareizi pielāgot kravas
STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' izraisīja bezgalīgu ražošanas izsaukumu ciklu STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' izraisīja bezgalīgu ražošanas izsaukumu ciklu
STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Izsaukums {1:HEX} atgrieza nezināmu vai nederīgu rezultātu {2:HEX} STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Izsaukums {1:HEX} atgrieza nezināmu vai nederīgu rezultātu {2:HEX}
STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}“{1:STRING}” atgrieza nederīgu kravas veidu ražošanas atgriezeniskajā funkcijā punktā {2:HEX}
# 'User removed essential NewGRFs'-placeholders for stuff without specs # 'User removed essential NewGRFs'-placeholders for stuff without specs
STR_NEWGRF_INVALID_CARGO :<nederīga krava> STR_NEWGRF_INVALID_CARGO :<nederīga krava>
@@ -3073,7 +3105,7 @@ STR_TOWN_POPULATION :{BLACK}Pasaules
# Town view window # Town view window
STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN}
STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (lielpilsēta) STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (pilsēta)
STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Iedzīvotāji: {ORANGE}{COMMA}{BLACK} Mājas: {ORANGE}{COMMA} STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Iedzīvotāji: {ORANGE}{COMMA}{BLACK} Mājas: {ORANGE}{COMMA}
STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} iepriekšējā mēnesī: {ORANGE}{COMMA}{BLACK} maks.: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} iepriekšējā mēnesī: {ORANGE}{COMMA}{BLACK} maks.: {ORANGE}{COMMA}
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Krava nepieciešama pilsētas attīstībai: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Krava nepieciešama pilsētas attīstībai:
@@ -3101,6 +3133,7 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Pārdēvēt pil
# Town local authority window # Town local authority window
STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} pašvaldība STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} pašvaldība
STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zona STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zona
STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Rādīt zonu pašvaldības robežās
STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transporta uzņēmumu vērtējumi: STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transporta uzņēmumu vērtējumi:
STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING}
STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Pieejamās darbības: STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Pieejamās darbības:
@@ -3180,6 +3213,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klikšķ
# Story book window # Story book window
STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Stāstu grāmata STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Stāstu grāmata
STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Globālā stāstu grāmata STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Globālā stāstu grāmata
STR_STORY_BOOK_SPECTATOR :Globālā stāstu grāmata
STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_TITLE :{YELLOW}{STRING}
STR_STORY_BOOK_GENERIC_PAGE_ITEM :{NUM} lapa STR_STORY_BOOK_GENERIC_PAGE_ITEM :{NUM} lapa
STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Pārlēkt uz specifisku lapu spiežot to zemāk esošajā sarakstā. STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Pārlēkt uz specifisku lapu spiežot to zemāk esošajā sarakstā.
@@ -3373,6 +3407,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC
STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Ražotnes STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Ražotnes
STR_INDUSTRY_DIRECTORY_NONE :{G=m}{ORANGE}- Neviens - STR_INDUSTRY_DIRECTORY_NONE :{G=m}{ORANGE}- Neviens -
STR_INDUSTRY_DIRECTORY_NONE.kas :{ORANGE}- Neviena - STR_INDUSTRY_DIRECTORY_NONE.kas :{ORANGE}- Neviena -
STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} (pārvadāti {COMMA}%){BLACK}
STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY}
STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING}
STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING}
@@ -3387,7 +3422,7 @@ STR_INDUSTRY_DIRECTORY_FILTER_NONE :Nav
# Industry view # Industry view
STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY}
STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Iepriekšējā mēnesī saražots: STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Iepriekšējā mēnesī saražots:
STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} (aizvests {COMMA}%) STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} (pārvadāti {COMMA}%)
STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrēt galveno skatu uz ražotni. Ctrl+klikšķis atvērs skatu uz ražotni jaunā skatlaukā STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrēt galveno skatu uz ražotni. Ctrl+klikšķis atvērs skatu uz ražotni jaunā skatlaukā
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Ražošanas līmenis: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Ražošanas līmenis: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Nozare ir paziņojusi par nenovēršamu slēgšanu! STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Nozare ir paziņojusi par nenovēršamu slēgšanu!
@@ -3396,6 +3431,7 @@ STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Pieprasa
STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Ražo: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Ražo: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING}
STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Pieprasa:
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}
STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} gaida{STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} gaida{STRING}
@@ -3466,6 +3502,7 @@ STR_GROUP_RENAME_CAPTION :{BLACK}Pārdēv
STR_GROUP_PROFIT_THIS_YEAR :Ienākumi šajā gadā: STR_GROUP_PROFIT_THIS_YEAR :Ienākumi šajā gadā:
STR_GROUP_PROFIT_LAST_YEAR :Peļņa pērn: STR_GROUP_PROFIT_LAST_YEAR :Peļņa pērn:
STR_GROUP_OCCUPANCY :Pašreizējais lietojums:
STR_GROUP_OCCUPANCY_VALUE :{NUM}% STR_GROUP_OCCUPANCY_VALUE :{NUM}%
# Build vehicle window # Build vehicle window
@@ -3485,6 +3522,7 @@ STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Jauns lidaparā
############ range for vehicle availability ends ############ range for vehicle availability ends
STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Svars: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Svars: {GOLD}{WEIGHT_SHORT}
STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} (Pielāgošanas izmaksas: {GOLD}{CURRENCY_LONG}{BLACK}) Svars: {GOLD}{WEIGHT_SHORT}
STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Ātrums: {GOLD}{VELOCITY}{BLACK} Jauda: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Ātrums: {GOLD}{VELOCITY}{BLACK} Jauda: {GOLD}{POWER}
STR_PURCHASE_INFO_SPEED :{BLACK}Ātrums: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED :{BLACK}Ātrums: {GOLD}{VELOCITY}
STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Ātrums okeānā: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Ātrums okeānā: {GOLD}{VELOCITY}
@@ -3657,6 +3695,7 @@ STR_ENGINE_PREVIEW_SHIP :kuģis
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Svars: {WEIGHT_SHORT}{}Ātrums: {VELOCITY} Jauda: {POWER}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā{}Ietilpība: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Svars: {WEIGHT_SHORT}{}Ātrums: {VELOCITY} Jauda: {POWER}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā{}Ietilpība: {CARGO_LONG}
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Svars: {WEIGHT_SHORT}{}Ātrums: {VELOCITY} Jauda: {POWER} Maks. spēks: {6:FORCE}{}Kārtējās izmaksas: {4:CURRENCY_LONG} gadā{}Ietilpība: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Svars: {WEIGHT_SHORT}{}Ātrums: {VELOCITY} Jauda: {POWER} Maks. spēks: {6:FORCE}{}Kārtējās izmaksas: {4:CURRENCY_LONG} gadā{}Ietilpība: {5:CARGO_LONG}
STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Ietilpība: {CARGO_LONG}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Ietilpība: {CARGO_LONG}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING}{}Ietilpība: {CARGO_LONG}, {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG} gadā
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING}{}Ietilpība: {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING}{}Ietilpība: {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING} Attālums: {COMMA} lauciņi{}Ietilpība: {CARGO_LONG}, {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING} Attālums: {COMMA} lauciņi{}Ietilpība: {CARGO_LONG}, {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING} Attālums: {COMMA} lauciņi{}Ietilpība: {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING} Attālums: {COMMA} lauciņi{}Ietilpība: {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā
@@ -3669,7 +3708,9 @@ STR_REPLACE_VEHICLE_SHIP :Kuģis
STR_REPLACE_VEHICLE_AIRCRAFT :Lidaparāts STR_REPLACE_VEHICLE_AIRCRAFT :Lidaparāts
STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}Lietošanā esošie transportlīdzekļi STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}Lietošanā esošie transportlīdzekļi
STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP :{BLACK}Kolonna ar jums piederošajiem transportlīdzekļiem
STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES :{YELLOW}Pieejamie transportlīdzekļi STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES :{YELLOW}Pieejamie transportlīdzekļi
STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP :{BLACK}Kolonna ar transportlīdzekļiem, kurus var aizvietot
STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Izvēlēties lokomotīves veidu, kuru vēlaties mainīt STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Izvēlēties lokomotīves veidu, kuru vēlaties mainīt
STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Izvēlēties jaunu lokomotīves veidu, kuru vēlaties lietot kreisajā pusē atlasītās lokomotīves vietā STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Izvēlēties jaunu lokomotīves veidu, kuru vēlaties lietot kreisajā pusē atlasītās lokomotīves vietā
@@ -3691,6 +3732,7 @@ STR_REPLACE_ALL_RAILTYPE :Visi dzelzceļa
STR_REPLACE_ALL_ROADTYPE :Visi ceļu transportlīdzekļi STR_REPLACE_ALL_ROADTYPE :Visi ceļu transportlīdzekļi
STR_REPLACE_HELP_RAILTYPE :{BLACK}Izvēlēties sliežu veidu, kuram vēlaties nomainīt lokomotīves STR_REPLACE_HELP_RAILTYPE :{BLACK}Izvēlēties sliežu veidu, kuram vēlaties nomainīt lokomotīves
STR_REPLACE_HELP_ROADTYPE :{BLACK}Izvēlēties ceļu veidu, kuram vēlaties nomainīt dzinējus
STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Parāda kura lokomotīve no kreisajā pusē atlasītajām tiek nomainīta, ja vien kāda ir STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Parāda kura lokomotīve no kreisajā pusē atlasītajām tiek nomainīta, ja vien kāda ir
STR_REPLACE_RAIL_VEHICLES :Sliežu transportlīdzekļi STR_REPLACE_RAIL_VEHICLES :Sliežu transportlīdzekļi
STR_REPLACE_ELRAIL_VEHICLES :Elektrificētā dzelzceļa transportlīdzekļi STR_REPLACE_ELRAIL_VEHICLES :Elektrificētā dzelzceļa transportlīdzekļi
@@ -3784,6 +3826,8 @@ STR_VEHICLE_INFO_AGE :{COMMA} gad{P s
STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} gad{P s i u} ({COMMA}) STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} gad{P s i u} ({COMMA})
STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Maks. ātrums: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Maks. ātrums: {LTBLUE}{VELOCITY}
STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Maks. ātrums: {LTBLUE}{VELOCITY} {BLACK}Lidaparāta veids: {LTBLUE}{STRING}
STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Maks. ātrums: {LTBLUE}{VELOCITY} {BLACK}Lidaparāta veids: {LTBLUE}{STRING} {BLACK}Attālums: {LTBLUE}{COMMA} lauciņi
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Svars: {LTBLUE}{WEIGHT_SHORT} {BLACK}Jauda: {LTBLUE}{POWER}{BLACK} Maks. ātrums: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Svars: {LTBLUE}{WEIGHT_SHORT} {BLACK}Jauda: {LTBLUE}{POWER}{BLACK} Maks. ātrums: {LTBLUE}{VELOCITY}
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Svars: {LTBLUE}{WEIGHT_SHORT} {BLACK}Jauda: {LTBLUE}{POWER}{BLACK} Maks. ātrums: {LTBLUE}{VELOCITY} {BLACK}Maks. spēks: {LTBLUE}{FORCE} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Svars: {LTBLUE}{WEIGHT_SHORT} {BLACK}Jauda: {LTBLUE}{POWER}{BLACK} Maks. ātrums: {LTBLUE}{VELOCITY} {BLACK}Maks. spēks: {LTBLUE}{FORCE}
@@ -4197,6 +4241,7 @@ STR_FEEDER :{YELLOW}Pārska
STR_FEEDER_INCOME_TINY :{TINY_FONT}{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {GREEN}Ienākumi: {CURRENCY_LONG} STR_FEEDER_INCOME_TINY :{TINY_FONT}{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {GREEN}Ienākumi: {CURRENCY_LONG}
STR_FEEDER_INCOME :{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {GREEN}Ienākumi: {CURRENCY_LONG} STR_FEEDER_INCOME :{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {GREEN}Ienākumi: {CURRENCY_LONG}
STR_FEEDER_COST_TINY :{TINY_FONT}{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {RED}Izmaksas: {CURRENCY_LONG} STR_FEEDER_COST_TINY :{TINY_FONT}{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {RED}Izmaksas: {CURRENCY_LONG}
STR_FEEDER_COST :{YELLOW}Pārkraušana: {CURRENCY_LONG}{WHITE} / {RED}Izmaksas: {CURRENCY_LONG}
STR_MESSAGE_ESTIMATED_COST :{WHITE}Plānotās izmaksas: {CURRENCY_LONG} STR_MESSAGE_ESTIMATED_COST :{WHITE}Plānotās izmaksas: {CURRENCY_LONG}
STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Plānotie ienākumi: {CURRENCY_LONG} STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Plānotie ienākumi: {CURRENCY_LONG}
@@ -4448,6 +4493,7 @@ STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Šeit ne
STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... tur nav ceļa STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... tur nav ceļa
STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... tur nav tramvaju sliežu ceļa STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... tur nav tramvaju sliežu ceļa
STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Šeit nevar mainīt ceļa veidu... STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Šeit nevar mainīt ceļa veidu...
STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Šeit nevar pārveidot tramvaja veidu...
STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Nav piemērota ceļa STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Nav piemērota ceļa
STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Nav piemērotu tramvaju STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Nav piemērotu tramvaju
STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... nesavietojams ceļš STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... nesavietojams ceļš
@@ -4504,6 +4550,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nevar iz
STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nevar izdzēst šo grupu... STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nevar izdzēst šo grupu...
STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Nevar pārdēvēt grupu... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Nevar pārdēvēt grupu...
STR_ERROR_GROUP_CAN_T_SET_PARENT :nevar iestatīt vecāku grupu... STR_ERROR_GROUP_CAN_T_SET_PARENT :nevar iestatīt vecāku grupu...
STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... grupu hierarhijās cikli nav atļauti
STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nevar noņemt no šīs grupas visus transportlīdzekļus... STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nevar noņemt no šīs grupas visus transportlīdzekļus...
STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nevar pievienot transportlīdzekļus šai grupai... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nevar pievienot transportlīdzekļus šai grupai...
STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nevar pievienot koplietojamos transportlīdzekļus šai grupai... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nevar pievienot koplietojamos transportlīdzekļus šai grupai...

View File

@@ -1063,7 +1063,7 @@ STR_GAME_OPTIONS_CURRENCY_NLG :Нидерла
STR_GAME_OPTIONS_CURRENCY_NOK :Норвежская крона (NOK) STR_GAME_OPTIONS_CURRENCY_NOK :Норвежская крона (NOK)
STR_GAME_OPTIONS_CURRENCY_PLN :Польский злотый (PLN) STR_GAME_OPTIONS_CURRENCY_PLN :Польский злотый (PLN)
STR_GAME_OPTIONS_CURRENCY_RON :Румынский лей (RON) STR_GAME_OPTIONS_CURRENCY_RON :Румынский лей (RON)
STR_GAME_OPTIONS_CURRENCY_RUR :Российский рубль (RUR) STR_GAME_OPTIONS_CURRENCY_RUR :Российский рубль (старый) (RUR)
STR_GAME_OPTIONS_CURRENCY_SIT :Словенский толар (SIT) STR_GAME_OPTIONS_CURRENCY_SIT :Словенский толар (SIT)
STR_GAME_OPTIONS_CURRENCY_SEK :Шведская крона (SEK) STR_GAME_OPTIONS_CURRENCY_SEK :Шведская крона (SEK)
STR_GAME_OPTIONS_CURRENCY_TRY :Турецкая лира (TRY) STR_GAME_OPTIONS_CURRENCY_TRY :Турецкая лира (TRY)
@@ -1076,11 +1076,12 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Южноафр
STR_GAME_OPTIONS_CURRENCY_CUSTOM :Своя... STR_GAME_OPTIONS_CURRENCY_CUSTOM :Своя...
STR_GAME_OPTIONS_CURRENCY_GEL :Грузинский лари (GEL) STR_GAME_OPTIONS_CURRENCY_GEL :Грузинский лари (GEL)
STR_GAME_OPTIONS_CURRENCY_IRR :Иранский риал (IRR) STR_GAME_OPTIONS_CURRENCY_IRR :Иранский риал (IRR)
STR_GAME_OPTIONS_CURRENCY_RUB :Российский новый рубль (RUR) STR_GAME_OPTIONS_CURRENCY_RUB :Российский рубль (RUR)
STR_GAME_OPTIONS_CURRENCY_MXN :Мексиканский песо (MXN) STR_GAME_OPTIONS_CURRENCY_MXN :Мексиканский песо (MXN)
STR_GAME_OPTIONS_CURRENCY_NTD :Новый тайваньский доллар (NTD) STR_GAME_OPTIONS_CURRENCY_NTD :Новый тайваньский доллар (NTD)
STR_GAME_OPTIONS_CURRENCY_CNY :Китайский юань (CNY) STR_GAME_OPTIONS_CURRENCY_CNY :Китайский юань (CNY)
STR_GAME_OPTIONS_CURRENCY_HKD :Гонконгский доллар (HKD) STR_GAME_OPTIONS_CURRENCY_HKD :Гонконгский доллар (HKD)
STR_GAME_OPTIONS_CURRENCY_INR :Индийская рупия (INR)
############ end of currency region ############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Движение автомобилей STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Движение автомобилей

View File

@@ -225,9 +225,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m
STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m
# Common window strings # Common window strings
STR_LIST_FILTER_TITLE :{BLACK}Filtrar palabras: STR_LIST_FILTER_TITLE :{BLACK}Filtrar texto:
STR_LIST_FILTER_OSKTITLE :{BLACK}Indicar una palabra a filtrar STR_LIST_FILTER_OSKTITLE :{BLACK}Indicar texto a filtrar
STR_LIST_FILTER_TOOLTIP :{BLACK}Indicar una palabra clave para filtrar la lista STR_LIST_FILTER_TOOLTIP :{BLACK}Indicar un texto clave para filtrar la lista
STR_TOOLTIP_GROUP_ORDER :{BLACK}Elegir orden de grupo STR_TOOLTIP_GROUP_ORDER :{BLACK}Elegir orden de grupo
STR_TOOLTIP_SORT_ORDER :{BLACK}Elegir orden descendiente o ascendiente STR_TOOLTIP_SORT_ORDER :{BLACK}Elegir orden descendiente o ascendiente
@@ -1109,7 +1109,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No se en
# Settings tree window # Settings tree window
STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Configuración STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Configuración
STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar palabras: STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar texto:
STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Desplegar todo STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Desplegar todo
STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Plegar todo STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Plegar todo
STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(sin explicación disponible) STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(sin explicación disponible)
@@ -1163,7 +1163,7 @@ STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Máxima cantida
STR_CONFIG_SETTING_INTEREST_RATE :Porcentaje de interés: {STRING} STR_CONFIG_SETTING_INTEREST_RATE :Porcentaje de interés: {STRING}
STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Porcentaje de interés de los préstamos; controla también la inflación, en caso de estar activada STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Porcentaje de interés de los préstamos; controla también la inflación, en caso de estar activada
STR_CONFIG_SETTING_RUNNING_COSTS :Costos de operación: {STRING} STR_CONFIG_SETTING_RUNNING_COSTS :Costos de operación: {STRING}
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Nivel de los costos de mantenimiento y operación de vehículos e infraestructura STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Nivel de costos de mantenimiento y operación de vehículos e infraestructura
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidad de construcción: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidad de construcción: {STRING}
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Restringir la velocidad de las acciones de construcción de jugadores no humanos STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Restringir la velocidad de las acciones de construcción de jugadores no humanos
STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Averías de vehículos: {STRING} STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Averías de vehículos: {STRING}
@@ -1173,9 +1173,9 @@ STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Establecer cuá
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcción: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcción: {STRING}
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Nivel de costos de construcción y adquisición STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Nivel de costos de construcción y adquisición
STR_CONFIG_SETTING_RECESSIONS :Recesiones: {STRING} STR_CONFIG_SETTING_RECESSIONS :Recesiones: {STRING}
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Si se activa, habrá recesiones cada cierto año. Durante una recesión, toda la producción decaerá considerablemente (se restablecerá al final de la recesión) STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Al activarse, habrá recesiones cada cierto año en las que toda la producción decaerá considerablemente, restableciéndose al final de cada recesión
STR_CONFIG_SETTING_TRAIN_REVERSING :Prohibir a los trenes que cambien de dirección en las estaciones: {STRING} STR_CONFIG_SETTING_TRAIN_REVERSING :Prohibir a los trenes que den reversa en estaciones: {STRING}
STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Si se activa, los trenes no podrán girar al lado opuesto en estaciones intermedias, ni siquiera si al girar hay una ruta más corta a su próximo destino STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Al activarse, los trenes no podrán dar reversa en estaciones intermedias, aun si detrás hay una ruta más corta a su próximo destino
STR_CONFIG_SETTING_DISASTERS :Desastres: {STRING} STR_CONFIG_SETTING_DISASTERS :Desastres: {STRING}
STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Desastres que ocasionalmente pueden bloquear o destruir vehículos o infraestructura STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Desastres que ocasionalmente pueden bloquear o destruir vehículos o infraestructura
STR_CONFIG_SETTING_CITY_APPROVAL :Actitud de los ayuntamientos ante restructuraciones hechas en sus zonas: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL :Actitud de los ayuntamientos ante restructuraciones hechas en sus zonas: {STRING}
@@ -1189,7 +1189,7 @@ STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Modificar el te
STR_CONFIG_SETTING_CATCHMENT :Permitir cambiar el tamaño del área de recolección a una forma más real: {STRING} STR_CONFIG_SETTING_CATCHMENT :Permitir cambiar el tamaño del área de recolección a una forma más real: {STRING}
STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Las áreas de recolección se adecúan a diferentes tamaños, según los tipos de estaciones y aeropuertos STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Las áreas de recolección se adecúan a diferentes tamaños, según los tipos de estaciones y aeropuertos
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Las estaciones privadas pueden dar servicio a industrias con estaciones neutrales: {STRING} STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Las estaciones privadas pueden dar servicio a industrias con estaciones neutrales: {STRING}
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Si se activa, las industrias con estaciones integradas (ej. plataformas petrolíferas) podrán aceptar cargamento de estaciones privadas construidas cerca. Si se desactiva, tales industrias solo recibirán cargamento en sus propias estaciones. No aceptarán cargamento de estaciones de compañías, y la estación integrada no brindará servicio a nada más que su industria STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Al activarse, las industrias con estaciones integradas (ej. plataformas petrolíferas) podrán aceptar carga de estaciones aledañas. Al desactivarse, tales industrias solo recibirán carga en sus propias estaciones y no aceptarán de otras estaciones, ni la estación integrada brindará servicio a nada más que su industria
STR_CONFIG_SETTING_EXTRADYNAMITE :Permitir quitar mayor cantidad de carreteras, puentes y túneles de los pueblos: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE :Permitir quitar mayor cantidad de carreteras, puentes y túneles de los pueblos: {STRING}
STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Hacer más fácil eliminar infraestructura y edificios que sean propiedad de los pueblos STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Hacer más fácil eliminar infraestructura y edificios que sean propiedad de los pueblos
STR_CONFIG_SETTING_TRAIN_LENGTH :Longitud máxima de trenes: {STRING} STR_CONFIG_SETTING_TRAIN_LENGTH :Longitud máxima de trenes: {STRING}
@@ -1242,7 +1242,7 @@ STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :principio
STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :centro STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :centro
STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :fondo STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :fondo
STR_CONFIG_SETTING_AUTOSCROLL :Recorrer vista cuando se mueva el cursor a los bordes: {STRING} STR_CONFIG_SETTING_AUTOSCROLL :Recorrer vista cuando se mueva el cursor a los bordes: {STRING}
STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Si se activa esta opción, las vistas se recorrerán cuando el ratón esté cerca de los bordes de la ventana STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Al activarse, las vistas se desplazarán cuando el ratón se acarque a los bordes de la ventana
STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Desactivado STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Desactivado
STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Vista principal, solo en pantalla completa STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Vista principal, solo en pantalla completa
STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :Vista principal STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :Vista principal
@@ -1273,7 +1273,7 @@ STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir la con
STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Construir paradas de autobuses intermedias en carreteras que sean propiedad de otras empresas STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Construir paradas de autobuses intermedias en carreteras que sean propiedad de otras empresas
STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}No se puede cambiar esta opción si ya existen vehículos STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}No se puede cambiar esta opción si ya existen vehículos
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Mantenimiento de infraestructura: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Mantenimiento de infraestructura: {STRING}
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Cuando se activa, la infraestructura tiene costo de mantenimiento, el cual aumenta en relación con el tamaño de la red de transporte. Esto afecta en mayor medida a las empresas grandes que a las pequeñas STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Al activarse, la infraestructura tiene costo de mantenimiento que aumenta según el tamaño de la red de transporte, de modo que las empresas grandes se afectan más que las pequeñas
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Color inicial de la empresa: {STRING} STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Color inicial de la empresa: {STRING}
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Elegir el color inicial de la empresa STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Elegir el color inicial de la empresa
@@ -1284,7 +1284,7 @@ STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Los tipos de ae
STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Avisar si un vehículo se ha perdido: {STRING} STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Avisar si un vehículo se ha perdido: {STRING}
STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT :Mostrar mensajes indicando aquellos vehículos que no puedan encontrar una ruta a su destino STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT :Mostrar mensajes indicando aquellos vehículos que no puedan encontrar una ruta a su destino
STR_CONFIG_SETTING_ORDER_REVIEW :Analizar órdenes de vehículos: {STRING} STR_CONFIG_SETTING_ORDER_REVIEW :Analizar órdenes de vehículos: {STRING}
STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :Cuando se activa, las órdenes de los vehículos se analizan regularmente y los problemas que se encuentren se informan en una noticia STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :Al activarse, se analizan regularmente las órdenes de los vehículos y los problemas obvios que se detecten se informan en una noticia
STR_CONFIG_SETTING_ORDER_REVIEW_OFF :No STR_CONFIG_SETTING_ORDER_REVIEW_OFF :No
STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :Sí, excepto los vehículos detenidos STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :Sí, excepto los vehículos detenidos
STR_CONFIG_SETTING_ORDER_REVIEW_ON :Todos los vehículos STR_CONFIG_SETTING_ORDER_REVIEW_ON :Todos los vehículos
@@ -1294,8 +1294,8 @@ STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Vehículos siem
STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Todos los modelos de vehículos estarán disponibles para siempre tras haber sido introducidos STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Todos los modelos de vehículos estarán disponibles para siempre tras haber sido introducidos
STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Renovar automáticamente vehículos que se hagan viejos: {STRING} STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Renovar automáticamente vehículos que se hagan viejos: {STRING}
STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Los vehículos próximos al final de su vida útil serán renovados automáticamente, siempre y cuando se cumplan las condiciones de renovación STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Los vehículos próximos al final de su vida útil serán renovados automáticamente, siempre y cuando se cumplan las condiciones de renovación
STR_CONFIG_SETTING_AUTORENEW_MONTHS :Renovar automáticamente el vehículo a {STRING} de su edad máxima STR_CONFIG_SETTING_AUTORENEW_MONTHS :Renovar automáticamente el vehículo cumpla {STRING}
STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Edad relativa en la que un vehículo es considerado para renovarse STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Edad relativa en que un vehículo se considera para renovación
STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA} mes{P 0 "" es} antes STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA} mes{P 0 "" es} antes
STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_AFTER :{COMMA} mes{P 0 "" es} después STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_AFTER :{COMMA} mes{P 0 "" es} después
STR_CONFIG_SETTING_AUTORENEW_MONEY :Costo mínimo requerido para renovación automática: {STRING} STR_CONFIG_SETTING_AUTORENEW_MONEY :Costo mínimo requerido para renovación automática: {STRING}
@@ -1370,7 +1370,7 @@ STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Recorrer mapa c
STR_CONFIG_SETTING_SCROLLMODE_RMB :Recorrer mapa con clic derecho STR_CONFIG_SETTING_SCROLLMODE_RMB :Recorrer mapa con clic derecho
STR_CONFIG_SETTING_SCROLLMODE_LMB :Recorrer mapa con clic izquierdo STR_CONFIG_SETTING_SCROLLMODE_LMB :Recorrer mapa con clic izquierdo
STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desplazamiento de vista suavizado: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desplazamiento de vista suavizado: {STRING}
STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Forma en la que la vista principal se mueve a una ubicación específica al hacer clic en el minimapa o tras una orden de moverse a un objeto determinado del mapa. Si se activa, la vista se mueve de forma suave. Si se desactiva, la vista se mueve instantáneamente al sitio indicado STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Forma en que la vista principal cambia a una ubicación desde el minimapa o tras una orden de ver un objeto determinado del mapa. Al activarse, la vista se mueve suavemente, y al desactivarse, la vista se mueve instantáneamente al sitio indicado
STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar información de medidas al usar las herramientas de construcción: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar información de medidas al usar las herramientas de construcción: {STRING}
STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Mostrar distancias en número de casillas y las diferencias de altura cuando se realicen labores de construcción STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Mostrar distancias en número de casillas y las diferencias de altura cuando se realicen labores de construcción
STR_CONFIG_SETTING_LIVERIES :Mostrar cromáticas por tipo de vehículo: {STRING} STR_CONFIG_SETTING_LIVERIES :Mostrar cromáticas por tipo de vehículo: {STRING}
@@ -1413,7 +1413,7 @@ STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :corto (31-12-20
STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31)
STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Poner el juego en pausa al comenzar una partida: {STRING} STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Poner el juego en pausa al comenzar una partida: {STRING}
STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Si se activa, el juego se detendrá automáticamente al comenzar nuevas partidas para permitir revisar el mapa STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Al activarse, el juego se detendrá automáticamente al comenzar nuevas partidas para permitir revisar el mapa
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Al pausar el juego, permitir: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Al pausar el juego, permitir: {STRING}
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Qué acciones se pueden realizar mientras el juego está en pausa. STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Qué acciones se pueden realizar mientras el juego está en pausa.
STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Ninguna acción STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Ninguna acción
@@ -1460,7 +1460,7 @@ STR_CONFIG_SETTING_SOUND_AMBIENT :Ambiente: {STRI
STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Reproducir sonidos ambientales de terreno, industrias y pueblos STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Reproducir sonidos ambientales de terreno, industrias y pueblos
STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING :Deshabilitar construcción de infraestructura cuando no haya vehículos apropiados disponibles: {STRING} STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING :Deshabilitar construcción de infraestructura cuando no haya vehículos apropiados disponibles: {STRING}
STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING_HELPTEXT :Cuando se activa, solamente se puede construir infraestructura si hay vehículos apropiados disponibles, previniendo un gasto innecesario de tiempo y dinero STR_CONFIG_SETTING_DISABLE_UNSUITABLE_BUILDING_HELPTEXT :Al activarse, hay infraestructura disponible solo si hay vehículos adecuados, evitando gastos de tiempo y dinero en infraestructura inservible
STR_CONFIG_SETTING_MAX_TRAINS :Número máximo de trenes por empresa: {STRING} STR_CONFIG_SETTING_MAX_TRAINS :Número máximo de trenes por empresa: {STRING}
STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Número máximo de trenes que una empresa puede tener STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Número máximo de trenes que una empresa puede tener
STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Número máximo de vehículos de carretera por empresa: {STRING} STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Número máximo de vehículos de carretera por empresa: {STRING}
@@ -1510,7 +1510,7 @@ STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Al activarse, l
STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activar límites de velocidad para vagones: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activar límites de velocidad para vagones: {STRING}
STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Al activarse, se tienen en cuenta los límites de velocidad de los vagones para decidir la máxima velocidad de un tren STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Al activarse, se tienen en cuenta los límites de velocidad de los vagones para decidir la máxima velocidad de un tren
STR_CONFIG_SETTING_DISABLE_ELRAILS :Desactivar ferrocarriles eléctricos: {STRING} STR_CONFIG_SETTING_DISABLE_ELRAILS :Desactivar ferrocarriles eléctricos: {STRING}
STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :Si se activa, no es necesario electrificar las vías férreas para hacer que los trenes eléctricos puedan recorrerlas STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :Al activarse, no es necesario electrificar las vías para que los trenes eléctricos las usen
STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN :Llegada del primer vehículo a una estación del jugador: {STRING} STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN :Llegada del primer vehículo a una estación del jugador: {STRING}
STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT :Mostrar noticia cuando el primer vehículo llegue a una estación del jugador STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT :Mostrar noticia cuando el primer vehículo llegue a una estación del jugador
@@ -1566,11 +1566,11 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Al arrastrar, c
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Distancia de separación entre señales hasta topar con algún obstáculo (otra señal, un desvío, etc.) al instalarlas mediante arrastre con el ratón STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Distancia de separación entre señales hasta topar con algún obstáculo (otra señal, un desvío, etc.) al instalarlas mediante arrastre con el ratón
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} casilla{P 0 "" s} STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} casilla{P 0 "" s}
STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Al arrastrar, mantener distancia fija entre señales: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Al arrastrar, mantener distancia fija entre señales: {STRING}
STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Forma en que se instalan las señales cuando se usa Ctrl+Arrastrar. Si se desactiva, se instalan señales a la entrada de túneles y puentes para evitar tramos largas de vías férreas sin señales. Si se activa, se colocan señales cada cierto número de casillas, haciendo que el alineamiento de señales en vías paralelas sea más sencillo STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Forma en que se instalan señales con Ctrl+Arrastrar. Al desactivarse, se colocan señales cerca de túneles y puentes para evitar tramos largos de vías sin señales. Al activarse, se colocan señales cada tanto de casillas, con lo que alinear señales en vías paralelas es más cil
STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Señales mecánicas por defecto antes de: {STRING} STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Señales mecánicas por defecto antes de: {STRING}
STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Año a partir del cual se usarán señales eléctricas. Antes de ese año se usarán señales mecánicas, las cuales funcionan igual pero tienen distinto aspecto STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Año a partir del cual se usarán señales eléctricas. Antes de ese año se usarán señales mecánicas, las cuales funcionan igual pero tienen distinto aspecto
STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI :Activar interfaz de señales: {STRING} STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI :Activar interfaz de señales: {STRING}
STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT :Mostrar una ventana para elegir los tipos de señales a instalar. Si no se activa, se instalan las señales y se selecciona un tipo determinado mediante Ctrl+Clic, sin que aparezca ninguna interfaz STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT :Mostrar una ventana para elegir qué tipo de señales instalar en lugar de solo ir rotando los tipos mediante Ctrl+Clic y sin ventana
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE :Tipo de señal a instalar por defecto: {STRING} STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE :Tipo de señal a instalar por defecto: {STRING}
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT :Tipo de señal por defecto STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT :Tipo de señal por defecto
STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL :Señales de tramo STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL :Señales de tramo
@@ -2246,7 +2246,7 @@ STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Buscar e
STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Buscar contenido no disponible en el servicio de contenido del juego en sitios web externos no asociados con OpenTTD STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Buscar contenido no disponible en el servicio de contenido del juego en sitios web externos no asociados con OpenTTD
STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}¡Estás saliendo de OpenTTD! STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}¡Estás saliendo de OpenTTD!
STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Los términos y condiciones para descargar contenido de sitios web externos varían.{}Será necesario referirse a tales sitios para saber cómo instalar el contenido en OpenTTD.{}¿Continuar? STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Los términos y condiciones para descargar contenido de sitios web externos varían.{}Será necesario referirse a tales sitios para saber cómo instalar el contenido en OpenTTD.{}¿Continuar?
STR_CONTENT_FILTER_TITLE :{BLACK}Etiqueta o palabras claves STR_CONTENT_FILTER_TITLE :{BLACK}Etiqueta o nombre:
STR_CONTENT_OPEN_URL :{BLACK}Visitar sitio web STR_CONTENT_OPEN_URL :{BLACK}Visitar sitio web
STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visitar el sitio web de este contenido STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visitar el sitio web de este contenido
STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Descargar STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Descargar
@@ -2819,7 +2819,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles
STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible
STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING}
STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING}
STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrar palabras: STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrar texto:
STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobrescribir archivo STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobrescribir archivo
STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}¿Estás seguro de sobrescribir el archivo? STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}¿Estás seguro de sobrescribir el archivo?
@@ -2903,7 +2903,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Informac
STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Archivos NewGRF activos STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Archivos NewGRF activos
STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Archivos NewGRF inactivos STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Archivos NewGRF inactivos
STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Seleccionar perfil: STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Seleccionar perfil:
STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrar palabras: STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrar texto:
STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Cargar perfil STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Cargar perfil
STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Guardar STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Guardar
STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Guardar lista actual como nuevo perfil STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Guardar lista actual como nuevo perfil

View File

@@ -18,6 +18,7 @@
#include "../cargotype.h" #include "../cargotype.h"
#include "../date_func.h" #include "../date_func.h"
#include "linkgraph_type.h" #include "linkgraph_type.h"
#include <utility>
struct SaveLoad; struct SaveLoad;
class LinkGraph; class LinkGraph;
@@ -189,20 +190,20 @@ public:
* to return something that implements operator->, but isn't a pointer * to return something that implements operator->, but isn't a pointer
* from operator->. A fake pointer. * from operator->. A fake pointer.
*/ */
class FakePointer : public SmallPair<NodeID, Tedge_wrapper> { class FakePointer : public std::pair<NodeID, Tedge_wrapper> {
public: public:
/** /**
* Construct a fake pointer from a pair of NodeID and edge. * Construct a fake pointer from a pair of NodeID and edge.
* @param pair Pair to be "pointed" to (in fact shallow-copied). * @param pair Pair to be "pointed" to (in fact shallow-copied).
*/ */
FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {} FakePointer(const std::pair<NodeID, Tedge_wrapper> &pair) : std::pair<NodeID, Tedge_wrapper>(pair) {}
/** /**
* Retrieve the pair by operator->. * Retrieve the pair by operator->.
* @return Pair being "pointed" to. * @return Pair being "pointed" to.
*/ */
SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; } std::pair<NodeID, Tedge_wrapper> *operator->() { return this; }
}; };
public: public:
@@ -267,9 +268,9 @@ public:
* Dereference with operator*. * Dereference with operator*.
* @return Pair of current target NodeID and edge object. * @return Pair of current target NodeID and edge object.
*/ */
SmallPair<NodeID, Tedge_wrapper> operator*() const std::pair<NodeID, Tedge_wrapper> operator*() const
{ {
return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current])); return std::pair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
} }
/** /**

View File

@@ -173,9 +173,9 @@ public:
* @return Pair of the edge currently pointed to and the ID of its * @return Pair of the edge currently pointed to and the ID of its
* other end. * other end.
*/ */
SmallPair<NodeID, Edge> operator*() const std::pair<NodeID, Edge> operator*() const
{ {
return SmallPair<NodeID, Edge>(this->current, Edge(this->base[this->current], this->base_anno[this->current])); return std::pair<NodeID, Edge>(this->current, Edge(this->base[this->current], this->base_anno[this->current]));
} }
/** /**

View File

@@ -135,10 +135,10 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f
this->songinfo[i].filename = filename; // non-owned pointer this->songinfo[i].filename = filename; // non-owned pointer
IniItem *item = catindex->GetItem(_music_file_names[i], false); IniItem *item = catindex->GetItem(_music_file_names[i], false);
if (item != nullptr && !StrEmpty(item->value)) { if (item != nullptr && item->value.has_value() && !item->value->empty()) {
/* Song has a CAT file index, assume it's MPS MIDI format */ /* Song has a CAT file index, assume it's MPS MIDI format */
this->songinfo[i].filetype = MTT_MPSMIDI; this->songinfo[i].filetype = MTT_MPSMIDI;
this->songinfo[i].cat_index = atoi(item->value); this->songinfo[i].cat_index = atoi(item->value->c_str());
char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index); char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index);
if (songname == nullptr) { if (songname == nullptr) {
DEBUG(grf, 1, "Base music set song missing from CAT file: %s/%d", filename, this->songinfo[i].cat_index); DEBUG(grf, 1, "Base music set song missing from CAT file: %s/%d", filename, this->songinfo[i].cat_index);
@@ -161,12 +161,12 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f
while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++; while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++;
item = names->GetItem(trimmed_filename, false); item = names->GetItem(trimmed_filename, false);
if (item != nullptr && !StrEmpty(item->value)) break; if (item != nullptr && item->value.has_value() && !item->value->empty()) break;
} }
if (this->songinfo[i].filetype == MTT_STANDARDMIDI) { if (this->songinfo[i].filetype == MTT_STANDARDMIDI) {
if (item != nullptr && !StrEmpty(item->value)) { if (item != nullptr && item->value.has_value() && !item->value->empty()) {
strecpy(this->songinfo[i].songname, item->value, lastof(this->songinfo[i].songname)); strecpy(this->songinfo[i].songname, item->value->c_str(), lastof(this->songinfo[i].songname));
} else { } else {
DEBUG(grf, 0, "Base music set song name missing: %s", filename); DEBUG(grf, 0, "Base music set song name missing: %s", filename);
return false; return false;
@@ -181,12 +181,12 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f
this->songinfo[i].tracknr = tracknr++; this->songinfo[i].tracknr = tracknr++;
} }
item = timingtrim->GetItem(trimmed_filename, false); item = trimmed_filename != nullptr ? timingtrim->GetItem(trimmed_filename, false) : nullptr;
if (item != nullptr && !StrEmpty(item->value)) { if (item != nullptr && item->value.has_value() && !item->value->empty()) {
const char *endpos = strchr(item->value, ':'); auto endpos = item->value->find(':');
if (endpos != nullptr) { if (endpos != std::string::npos) {
this->songinfo[i].override_start = atoi(item->value); this->songinfo[i].override_start = atoi(item->value->c_str());
this->songinfo[i].override_end = atoi(endpos + 1); this->songinfo[i].override_end = atoi(item->value->c_str() + endpos + 1);
} }
} }
} }

View File

@@ -26,7 +26,7 @@ static MIDI *_midi = nullptr;
*/ */
extern int _allegro_instance_count; extern int _allegro_instance_count;
const char *MusicDriver_Allegro::Start(const char * const *param) const char *MusicDriver_Allegro::Start(const StringList &param)
{ {
if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, nullptr)) { if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, nullptr)) {
DEBUG(driver, 0, "allegro: install_allegro failed '%s'", allegro_error); DEBUG(driver, 0, "allegro: install_allegro failed '%s'", allegro_error);

View File

@@ -15,7 +15,7 @@
/** Allegro's music player. */ /** Allegro's music player. */
class MusicDriver_Allegro : public MusicDriver { class MusicDriver_Allegro : public MusicDriver {
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -24,7 +24,7 @@ static BMidiSynthFile midiSynthFile;
/** Factory for BeOS' midi player. */ /** Factory for BeOS' midi player. */
static FMusicDriver_BeMidi iFMusicDriver_BeMidi; static FMusicDriver_BeMidi iFMusicDriver_BeMidi;
const char *MusicDriver_BeMidi::Start(const char * const *parm) const char *MusicDriver_BeMidi::Start(const StringList &parm)
{ {
return nullptr; return nullptr;
} }

View File

@@ -15,7 +15,7 @@
/** The midi player for BeOS. */ /** The midi player for BeOS. */
class MusicDriver_BeMidi : public MusicDriver { class MusicDriver_BeMidi : public MusicDriver {
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -79,7 +79,7 @@ static void DoSetVolume()
/** /**
* Initialized the MIDI player, including QuickTime initialization. * Initialized the MIDI player, including QuickTime initialization.
*/ */
const char *MusicDriver_Cocoa::Start(const char * const *parm) const char *MusicDriver_Cocoa::Start(const StringList &parm)
{ {
if (NewMusicPlayer(&_player) != noErr) return "failed to create music player"; if (NewMusicPlayer(&_player) != noErr) return "failed to create music player";

View File

@@ -14,7 +14,7 @@
class MusicDriver_Cocoa : public MusicDriver { class MusicDriver_Cocoa : public MusicDriver {
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -1074,7 +1074,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls)
} }
const char *MusicDriver_DMusic::Start(const char * const *parm) const char *MusicDriver_DMusic::Start(const StringList &parm)
{ {
/* Initialize COM */ /* Initialize COM */
if (FAILED(CoInitializeEx(nullptr, COINITBASE_MULTITHREADED))) return "COM initialization failed"; if (FAILED(CoInitializeEx(nullptr, COINITBASE_MULTITHREADED))) return "COM initialization failed";

View File

@@ -17,7 +17,7 @@ class MusicDriver_DMusic : public MusicDriver {
public: public:
virtual ~MusicDriver_DMusic(); virtual ~MusicDriver_DMusic();
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -36,7 +36,7 @@
/** Factory for the midi player that uses external players. */ /** Factory for the midi player that uses external players. */
static FMusicDriver_ExtMidi iFMusicDriver_ExtMidi; static FMusicDriver_ExtMidi iFMusicDriver_ExtMidi;
const char *MusicDriver_ExtMidi::Start(const char * const * parm) const char *MusicDriver_ExtMidi::Start(const StringList &parm)
{ {
if (strcmp(VideoDriver::GetInstance()->GetName(), "allegro") == 0 || if (strcmp(VideoDriver::GetInstance()->GetName(), "allegro") == 0 ||
strcmp(SoundDriver::GetInstance()->GetName(), "allegro") == 0) { strcmp(SoundDriver::GetInstance()->GetName(), "allegro") == 0) {

View File

@@ -22,7 +22,7 @@ private:
void DoStop(); void DoStop();
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -50,7 +50,7 @@ static void RenderMusicStream(int16 *buffer, size_t samples)
fluid_synth_write_s16(_midi.synth, samples, buffer, 0, 2, buffer, 1, 2); fluid_synth_write_s16(_midi.synth, samples, buffer, 0, 2, buffer, 1, 2);
} }
const char *MusicDriver_FluidSynth::Start(const char * const *param) const char *MusicDriver_FluidSynth::Start(const StringList &param)
{ {
std::lock_guard<std::mutex> lock{ _midi.synth_mutex }; std::lock_guard<std::mutex> lock{ _midi.synth_mutex };

View File

@@ -15,7 +15,7 @@
/** Music driver making use of FluidSynth. */ /** Music driver making use of FluidSynth. */
class MusicDriver_FluidSynth : public MusicDriver { class MusicDriver_FluidSynth : public MusicDriver {
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -48,6 +48,6 @@ public:
} }
}; };
extern char *_ini_musicdriver; extern std::string _ini_musicdriver;
#endif /* MUSIC_MUSIC_DRIVER_HPP */ #endif /* MUSIC_MUSIC_DRIVER_HPP */

View File

@@ -15,7 +15,7 @@
/** The music player that does nothing. */ /** The music player that does nothing. */
class MusicDriver_Null : public MusicDriver { class MusicDriver_Null : public MusicDriver {
public: public:
const char *Start(const char * const *param) override { return nullptr; } const char *Start(const StringList &param) override { return nullptr; }
void Stop() override { } void Stop() override { }

View File

@@ -80,7 +80,7 @@ bool MusicDriver_OS2::IsSongPlaying()
return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0;
} }
const char *MusicDriver_OS2::Start(const char * const *parm) const char *MusicDriver_OS2::Start(const StringList &parm)
{ {
return 0; return 0;
} }

View File

@@ -15,7 +15,7 @@
/** OS/2's music player. */ /** OS/2's music player. */
class MusicDriver_OS2 : public MusicDriver { class MusicDriver_OS2 : public MusicDriver {
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -366,7 +366,7 @@ void MusicDriver_Win32::SetVolume(byte vol)
_midi.new_volume = vol; _midi.new_volume = vol;
} }
const char *MusicDriver_Win32::Start(const char * const *parm) const char *MusicDriver_Win32::Start(const StringList &parm)
{ {
DEBUG(driver, 2, "Win32-MIDI: Start: initializing"); DEBUG(driver, 2, "Win32-MIDI: Start: initializing");

View File

@@ -15,7 +15,7 @@
/** The Windows music player. */ /** The Windows music player. */
class MusicDriver_Win32 : public MusicDriver { class MusicDriver_Win32 : public MusicDriver {
public: public:
const char *Start(const char * const *param) override; const char *Start(const StringList &param) override;
void Stop() override; void Stop() override;

View File

@@ -65,7 +65,7 @@ struct MusicSystem {
void BuildPlaylists(); void BuildPlaylists();
void ChangePlaylist(PlaylistChoices pl); void ChangePlaylist(PlaylistChoices pl);
void ChangeMusicSet(const char *set_name); void ChangeMusicSet(const std::string &set_name);
void Shuffle(); void Shuffle();
void Unshuffle(); void Unshuffle();
@@ -167,12 +167,10 @@ void MusicSystem::ChangePlaylist(PlaylistChoices pl)
* Change to named music set, and reset playback. * Change to named music set, and reset playback.
* @param set_name Name of music set to select * @param set_name Name of music set to select
*/ */
void MusicSystem::ChangeMusicSet(const char *set_name) void MusicSystem::ChangeMusicSet(const std::string &set_name)
{ {
BaseMusic::SetSet(set_name); BaseMusic::SetSet(set_name);
BaseMusic::ini_set = set_name;
free(BaseMusic::ini_set);
BaseMusic::ini_set = stredup(set_name);
this->BuildPlaylists(); this->BuildPlaylists();
this->ChangePlaylist(this->selected_playlist); this->ChangePlaylist(this->selected_playlist);
@@ -433,8 +431,7 @@ void MusicLoop()
void ChangeMusicSet(int index) void ChangeMusicSet(int index)
{ {
if (BaseMusic::GetIndexOfUsedSet() == index) return; if (BaseMusic::GetIndexOfUsedSet() == index) return;
const char *name = BaseMusic::GetSet(index)->name; _music.ChangeMusicSet(BaseMusic::GetSet(index)->name);
_music.ChangeMusicSet(name);
} }
/** /**
@@ -464,7 +461,7 @@ struct MusicTrackSelectionWindow : public Window {
SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist); SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist);
break; break;
case WID_MTS_CAPTION: case WID_MTS_CAPTION:
SetDParamStr(0, BaseMusic::GetUsedSet()->name); SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str());
break; break;
} }
} }

View File

@@ -175,21 +175,15 @@ void NetworkAfterNewGRFScan()
/* Don't know the GRF, so mark game incompatible and the (possibly) /* Don't know the GRF, so mark game incompatible and the (possibly)
* already resolved name for this GRF (another server has sent the * already resolved name for this GRF (another server has sent the
* name of the GRF already. */ * name of the GRF already. */
c->name->Release();
c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true); c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true);
c->name->AddRef();
c->status = GCS_NOT_FOUND; c->status = GCS_NOT_FOUND;
/* If we miss a file, we're obviously incompatible. */ /* If we miss a file, we're obviously incompatible. */
item->info.compatible = false; item->info.compatible = false;
} else { } else {
c->filename = f->filename; c->filename = f->filename;
c->name->Release();
c->name = f->name; c->name = f->name;
c->name->AddRef();
c->info->Release();
c->info = f->info; c->info = f->info;
c->info->AddRef();
c->status = GCS_UNKNOWN; c->status = GCS_UNKNOWN;
} }
} }

View File

@@ -511,9 +511,9 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAdd
/* Try to find the GRFTextWrapper for the name of this GRF ID and MD5sum tuple. /* Try to find the GRFTextWrapper for the name of this GRF ID and MD5sum tuple.
* If it exists and not resolved yet, then name of the fake GRF is * If it exists and not resolved yet, then name of the fake GRF is
* overwritten with the name from the reply. */ * overwritten with the name from the reply. */
GRFTextWrapper *unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false); GRFTextWrapper unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
if (unknown_name != nullptr && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) { if (unknown_name && strcmp(GetGRFStringFromGRFText(unknown_name), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
AddGRFTextToList(&unknown_name->text, name); AddGRFTextToList(unknown_name, name);
} }
} }
} }
@@ -526,21 +526,13 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo
/* Don't know the GRF, so mark game incompatible and the (possibly) /* Don't know the GRF, so mark game incompatible and the (possibly)
* already resolved name for this GRF (another server has sent the * already resolved name for this GRF (another server has sent the
* name of the GRF already */ * name of the GRF already */
config->name->Release();
config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true); config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true);
config->name->AddRef();
config->status = GCS_NOT_FOUND; config->status = GCS_NOT_FOUND;
} else { } else {
config->filename = f->filename; config->filename = f->filename;
config->name->Release();
config->name = f->name; config->name = f->name;
config->name->AddRef();
config->info->Release();
config->info = f->info; config->info = f->info;
config->info->AddRef();
config->url->Release();
config->url = f->url; config->url = f->url;
config->url->AddRef();
} }
SetBit(config->flags, GCF_COPY); SetBit(config->flags, GCF_COPY);
} }

View File

@@ -5355,7 +5355,7 @@ static void NewSpriteGroup(ByteReader *buf)
group->num_input = buf->ReadByte(); group->num_input = buf->ReadByte();
if (group->num_input > lengthof(group->subtract_input)) { if (group->num_input > lengthof(group->subtract_input)) {
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
error->data = stredup("too many inputs (max 16)"); error->data = "too many inputs (max 16)";
return; return;
} }
for (uint i = 0; i < group->num_input; i++) { for (uint i = 0; i < group->num_input; i++) {
@@ -5368,7 +5368,7 @@ static void NewSpriteGroup(ByteReader *buf)
group->version = 0xFF; group->version = 0xFF;
} else if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) { } else if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) {
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
error->data = stredup("duplicate input cargo"); error->data = "duplicate input cargo";
return; return;
} }
group->cargo_input[i] = cargo; group->cargo_input[i] = cargo;
@@ -5377,7 +5377,7 @@ static void NewSpriteGroup(ByteReader *buf)
group->num_output = buf->ReadByte(); group->num_output = buf->ReadByte();
if (group->num_output > lengthof(group->add_output)) { if (group->num_output > lengthof(group->add_output)) {
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
error->data = stredup("too many outputs (max 16)"); error->data = "too many outputs (max 16)";
return; return;
} }
for (uint i = 0; i < group->num_output; i++) { for (uint i = 0; i < group->num_output; i++) {
@@ -5388,7 +5388,7 @@ static void NewSpriteGroup(ByteReader *buf)
group->version = 0xFF; group->version = 0xFF;
} else if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) { } else if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) {
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK); GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
error->data = stredup("duplicate output cargo"); error->data = "duplicate output cargo";
return; return;
} }
group->cargo_output[i] = cargo; group->cargo_output[i] = cargo;
@@ -6636,7 +6636,7 @@ static void CfgApply(ByteReader *buf)
static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c) static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
{ {
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c); GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
error->data = stredup(_cur.grfconfig->GetName()); error->data = _cur.grfconfig->GetName();
} }
/* Action 0x07 /* Action 0x07
@@ -6839,11 +6839,11 @@ static void ScanInfo(ByteReader *buf)
/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */ /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM); if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name); AddGRFTextToList(_cur.grfconfig->name, 0x7F, grfid, false, name);
if (buf->HasData()) { if (buf->HasData()) {
const char *info = buf->ReadString(); const char *info = buf->ReadString();
AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info); AddGRFTextToList(_cur.grfconfig->info, 0x7F, grfid, true, info);
} }
/* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */ /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
@@ -7014,10 +7014,10 @@ static void GRFLoadError(ByteReader *buf)
if (buf->HasData()) { if (buf->HasData()) {
const char *message = buf->ReadString(); const char *message = buf->ReadString();
error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, nullptr, SCC_RAW_STRING_POINTER); error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
} else { } else {
grfmsg(7, "GRFLoadError: No custom message supplied."); grfmsg(7, "GRFLoadError: No custom message supplied.");
error->custom_message = stredup(""); error->custom_message.clear();
} }
} else { } else {
error->message = msgstr[message_id]; error->message = msgstr[message_id];
@@ -7029,7 +7029,7 @@ static void GRFLoadError(ByteReader *buf)
error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data); error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
} else { } else {
grfmsg(7, "GRFLoadError: No message data supplied."); grfmsg(7, "GRFLoadError: No message data supplied.");
error->data = stredup(""); error->data.clear();
} }
/* Only two parameter numbers can be used in the string. */ /* Only two parameter numbers can be used in the string. */
@@ -7575,9 +7575,8 @@ static void FeatureTownName(ByteReader *buf)
const char *name = buf->ReadString(); const char *name = buf->ReadString();
char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name); std::string lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name); grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
free(lang_name);
townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
@@ -7619,7 +7618,7 @@ static void FeatureTownName(ByteReader *buf)
townname->partlist[id][i].parts[j].data.id = ref_id; townname->partlist[id][i].parts[j].data.id = ref_id;
} else { } else {
const char *text = buf->ReadString(); const char *text = buf->ReadString();
townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text); townname->partlist[id][i].parts[j].data.text = stredup(TranslateTTDPatchCodes(grfid, 0, false, text).c_str());
grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob); grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
} }
townname->partlist[id][i].parts[j].prob = prob; townname->partlist[id][i].parts[j].prob = prob;
@@ -7891,7 +7890,7 @@ static void TranslateGRFStrings(ByteReader *buf)
char tmp[256]; char tmp[256];
GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp)); GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
error->data = stredup(tmp); error->data = tmp;
return; return;
} }
@@ -7925,21 +7924,21 @@ static void TranslateGRFStrings(ByteReader *buf)
/** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */ /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
static bool ChangeGRFName(byte langid, const char *str) static bool ChangeGRFName(byte langid, const char *str)
{ {
AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str); AddGRFTextToList(_cur.grfconfig->name, langid, _cur.grfconfig->ident.grfid, false, str);
return true; return true;
} }
/** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */ /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
static bool ChangeGRFDescription(byte langid, const char *str) static bool ChangeGRFDescription(byte langid, const char *str)
{ {
AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str); AddGRFTextToList(_cur.grfconfig->info, langid, _cur.grfconfig->ident.grfid, true, str);
return true; return true;
} }
/** Callback function for 'INFO'->'URL_' to set the newgrf url. */ /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
static bool ChangeGRFURL(byte langid, const char *str) static bool ChangeGRFURL(byte langid, const char *str)
{ {
AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str); AddGRFTextToList(_cur.grfconfig->url, langid, _cur.grfconfig->ident.grfid, false, str);
return true; return true;
} }
@@ -8041,14 +8040,14 @@ static GRFParameterInfo *_cur_parameter; ///< The parameter which info is curren
/** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */ /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
static bool ChangeGRFParamName(byte langid, const char *str) static bool ChangeGRFParamName(byte langid, const char *str)
{ {
AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str); AddGRFTextToList(_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
return true; return true;
} }
/** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */ /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
static bool ChangeGRFParamDescription(byte langid, const char *str) static bool ChangeGRFParamDescription(byte langid, const char *str)
{ {
AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str); AddGRFTextToList(_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
return true; return true;
} }
@@ -8249,12 +8248,12 @@ static bool ChangeGRFParamValueNames(ByteReader *buf)
byte langid = buf->ReadByte(); byte langid = buf->ReadByte();
const char *name_string = buf->ReadString(); const char *name_string = buf->ReadString();
SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id); std::pair<uint32, GRFTextList> *val_name = _cur_parameter->value_names.Find(id);
if (val_name != _cur_parameter->value_names.End()) { if (val_name != _cur_parameter->value_names.End()) {
AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string); AddGRFTextToList(val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
} else { } else {
GRFText *list = nullptr; GRFTextList list;
AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string); AddGRFTextToList(list, langid, _cur.grfconfig->ident.grfid, false, name_string);
_cur_parameter->value_names.Insert(id, list); _cur_parameter->value_names.Insert(id, list);
} }

View File

@@ -21,6 +21,7 @@
#include "textfile_gui.h" #include "textfile_gui.h"
#include "thread.h" #include "thread.h"
#include "newgrf_config.h" #include "newgrf_config.h"
#include "newgrf_text.h"
#include "fileio_func.h" #include "fileio_func.h"
#include "fios.h" #include "fios.h"
@@ -35,17 +36,6 @@
#include "safeguards.h" #include "safeguards.h"
/** Create a new GRFTextWrapper. */
GRFTextWrapper::GRFTextWrapper() :
text(nullptr)
{
}
/** Cleanup a GRFTextWrapper object. */
GRFTextWrapper::~GRFTextWrapper()
{
CleanUpGRFText(this->text);
}
/** /**
* Create a new GRFConfig. * Create a new GRFConfig.
@@ -53,15 +43,9 @@ GRFTextWrapper::~GRFTextWrapper()
* is copied so the original string isn't needed after the constructor. * is copied so the original string isn't needed after the constructor.
*/ */
GRFConfig::GRFConfig(const char *filename) : GRFConfig::GRFConfig(const char *filename) :
name(new GRFTextWrapper()),
info(new GRFTextWrapper()),
url(new GRFTextWrapper()),
num_valid_params(lengthof(param)) num_valid_params(lengthof(param))
{ {
if (filename != nullptr) this->filename = stredup(filename); if (filename != nullptr) this->filename = stredup(filename);
this->name->AddRef();
this->info->AddRef();
this->url->AddRef();
} }
/** /**
@@ -87,9 +71,6 @@ GRFConfig::GRFConfig(const GRFConfig &config) :
MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum)); MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
MemCpyT<uint32>(this->param, config.param, lengthof(this->param)); MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
if (config.filename != nullptr) this->filename = stredup(config.filename); if (config.filename != nullptr) this->filename = stredup(config.filename);
this->name->AddRef();
this->info->AddRef();
this->url->AddRef();
if (config.error != nullptr) this->error = new GRFError(*config.error); if (config.error != nullptr) this->error = new GRFError(*config.error);
for (uint i = 0; i < config.param_info.size(); i++) { for (uint i = 0; i < config.param_info.size(); i++) {
if (config.param_info[i] == nullptr) { if (config.param_info[i] == nullptr) {
@@ -109,9 +90,6 @@ GRFConfig::~GRFConfig()
delete this->error; delete this->error;
} }
free(this->full_filename); free(this->full_filename);
this->name->Release();
this->info->Release();
this->url->Release();
for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i]; for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i];
} }
@@ -134,7 +112,7 @@ void GRFConfig::CopyParams(const GRFConfig &src)
*/ */
const char *GRFConfig::GetName() const const char *GRFConfig::GetName() const
{ {
const char *name = GetGRFStringFromGRFText(this->name->text); const char *name = GetGRFStringFromGRFText(this->name);
return StrEmpty(name) ? this->filename : name; return StrEmpty(name) ? this->filename : name;
} }
@@ -144,7 +122,7 @@ const char *GRFConfig::GetName() const
*/ */
const char *GRFConfig::GetDescription() const const char *GRFConfig::GetDescription() const
{ {
return GetGRFStringFromGRFText(this->info->text); return GetGRFStringFromGRFText(this->info);
} }
/** /**
@@ -153,7 +131,7 @@ const char *GRFConfig::GetDescription() const
*/ */
const char *GRFConfig::GetURL() const const char *GRFConfig::GetURL() const
{ {
return GetGRFStringFromGRFText(this->url->text); return GetGRFStringFromGRFText(this->url);
} }
/** Set the default value for all parameters as specified by action14. */ /** Set the default value for all parameters as specified by action14. */
@@ -212,7 +190,8 @@ bool _grf_bug_too_many_strings = false;
*/ */
GRFError::GRFError(StringID severity, StringID message) : GRFError::GRFError(StringID severity, StringID message) :
message(message), message(message),
severity(severity) severity(severity),
param_value()
{ {
} }
@@ -221,30 +200,21 @@ GRFError::GRFError(StringID severity, StringID message) :
* @param error The GRFError object to make a copy of. * @param error The GRFError object to make a copy of.
*/ */
GRFError::GRFError(const GRFError &error) : GRFError::GRFError(const GRFError &error) :
ZeroedMemoryAllocator(),
custom_message(error.custom_message), custom_message(error.custom_message),
data(error.data), data(error.data),
message(error.message), message(error.message),
severity(error.severity) severity(error.severity)
{ {
if (error.custom_message != nullptr) this->custom_message = stredup(error.custom_message);
if (error.data != nullptr) this->data = stredup(error.data);
memcpy(this->param_value, error.param_value, sizeof(this->param_value)); memcpy(this->param_value, error.param_value, sizeof(this->param_value));
} }
GRFError::~GRFError()
{
free(this->custom_message);
free(this->data);
}
/** /**
* Create a new empty GRFParameterInfo object. * Create a new empty GRFParameterInfo object.
* @param nr The newgrf parameter that is changed. * @param nr The newgrf parameter that is changed.
*/ */
GRFParameterInfo::GRFParameterInfo(uint nr) : GRFParameterInfo::GRFParameterInfo(uint nr) :
name(nullptr), name(),
desc(nullptr), desc(),
type(PTYPE_UINT_ENUM), type(PTYPE_UINT_ENUM),
min_value(0), min_value(0),
max_value(UINT32_MAX), max_value(UINT32_MAX),
@@ -252,6 +222,7 @@ GRFParameterInfo::GRFParameterInfo(uint nr) :
param_nr(nr), param_nr(nr),
first_bit(0), first_bit(0),
num_bit(32), num_bit(32),
value_names(),
complete_labels(false) complete_labels(false)
{} {}
@@ -261,8 +232,8 @@ GRFParameterInfo::GRFParameterInfo(uint nr) :
* @param info The GRFParameterInfo object to make a copy of. * @param info The GRFParameterInfo object to make a copy of.
*/ */
GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) : GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) :
name(DuplicateGRFText(info.name)), name(info.name),
desc(DuplicateGRFText(info.desc)), desc(info.desc),
type(info.type), type(info.type),
min_value(info.min_value), min_value(info.min_value),
max_value(info.max_value), max_value(info.max_value),
@@ -270,23 +241,9 @@ GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) :
param_nr(info.param_nr), param_nr(info.param_nr),
first_bit(info.first_bit), first_bit(info.first_bit),
num_bit(info.num_bit), num_bit(info.num_bit),
value_names(info.value_names),
complete_labels(info.complete_labels) complete_labels(info.complete_labels)
{ {
for (uint i = 0; i < info.value_names.size(); i++) {
SmallPair<uint32, GRFText *> *data = info.value_names.data() + i;
this->value_names.Insert(data->first, DuplicateGRFText(data->second));
}
}
/** Cleanup all parameter info. */
GRFParameterInfo::~GRFParameterInfo()
{
CleanUpGRFText(this->name);
CleanUpGRFText(this->desc);
for (uint i = 0; i < this->value_names.size(); i++) {
SmallPair<uint32, GRFText *> *data = this->value_names.data() + i;
CleanUpGRFText(data->second);
}
} }
/** /**
@@ -689,12 +646,8 @@ compatible_grf:
free(c->filename); free(c->filename);
c->filename = stredup(f->filename); c->filename = stredup(f->filename);
memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum)); memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum));
c->name->Release();
c->name = f->name; c->name = f->name;
c->name->AddRef();
c->info->Release();
c->info = f->name; c->info = f->name;
c->info->AddRef();
c->error = nullptr; c->error = nullptr;
c->version = f->version; c->version = f->version;
c->min_loadable_version = f->min_loadable_version; c->min_loadable_version = f->min_loadable_version;
@@ -798,7 +751,7 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length, const
_modal_progress_paint_mutex.lock(); _modal_progress_paint_mutex.lock();
const char *name = nullptr; const char *name = nullptr;
if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name->text); if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name);
if (name == nullptr) name = c->filename; if (name == nullptr) name = c->filename;
UpdateNewGRFScanStatus(this->num_scanned, name); UpdateNewGRFScanStatus(this->num_scanned, name);
@@ -932,8 +885,12 @@ const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8
/** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */ /** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */
struct UnknownGRF : public GRFIdentifier { struct UnknownGRF : public GRFIdentifier {
UnknownGRF *next; ///< The next unknown GRF. GRFTextWrapper name; ///< Name of the GRF.
GRFTextWrapper *name; ///< Name of the GRF.
UnknownGRF() = default;
UnknownGRF(const UnknownGRF &other) = default;
UnknownGRF(UnknownGRF &&other) = default;
UnknownGRF(uint32 grfid, const uint8 *_md5sum) : GRFIdentifier(grfid, _md5sum), name(new GRFTextList) {}
}; };
/** /**
@@ -953,30 +910,24 @@ struct UnknownGRF : public GRFIdentifier {
* and MD5 checksum or nullptr when it does not exist and create is false. * and MD5 checksum or nullptr when it does not exist and create is false.
* This value must NEVER be freed by the caller. * This value must NEVER be freed by the caller.
*/ */
GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create) GRFTextWrapper FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
{ {
UnknownGRF *grf; static std::vector<UnknownGRF> unknown_grfs;
static UnknownGRF *unknown_grfs = nullptr;
for (grf = unknown_grfs; grf != nullptr; grf = grf->next) { for (const auto &grf : unknown_grfs) {
if (grf->grfid == grfid) { if (grf.grfid == grfid) {
if (memcmp(md5sum, grf->md5sum, sizeof(grf->md5sum)) == 0) return grf->name; if (memcmp(md5sum, grf.md5sum, sizeof(grf.md5sum)) == 0) return grf.name;
} }
} }
if (!create) return nullptr; if (!create) return nullptr;
grf = CallocT<UnknownGRF>(1); unknown_grfs.emplace_back(grfid, md5sum);
grf->grfid = grfid; UnknownGRF &grf = unknown_grfs.back();
grf->next = unknown_grfs;
grf->name = new GRFTextWrapper();
grf->name->AddRef();
AddGRFTextToList(&grf->name->text, UNKNOWN_GRF_NAME_PLACEHOLDER); AddGRFTextToList(grf.name, UNKNOWN_GRF_NAME_PLACEHOLDER);
memcpy(grf->md5sum, md5sum, sizeof(grf->md5sum));
unknown_grfs = grf; return grf.name;
return grf->name;
} }
/** /**

View File

@@ -16,6 +16,7 @@
#include "misc/countedptr.hpp" #include "misc/countedptr.hpp"
#include "fileio_type.h" #include "fileio_type.h"
#include "textfile_type.h" #include "textfile_type.h"
#include "newgrf_text.h"
/** GRF config bit flags */ /** GRF config bit flags */
enum GCF_Flags { enum GCF_Flags {
@@ -83,6 +84,16 @@ struct GRFIdentifier {
uint32 grfid; ///< GRF ID (defined by Action 0x08) uint32 grfid; ///< GRF ID (defined by Action 0x08)
uint8 md5sum[16]; ///< MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF) uint8 md5sum[16]; ///< MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
GRFIdentifier() = default;
GRFIdentifier(const GRFIdentifier &other) = default;
GRFIdentifier(GRFIdentifier &&other) = default;
GRFIdentifier(uint32 grfid, const uint8 *md5sum) : grfid(grfid)
{
MemCpyT(this->md5sum, md5sum, lengthof(this->md5sum));
}
GRFIdentifier& operator =(const GRFIdentifier &other) = default;
/** /**
* Does the identification match the provided values? * Does the identification match the provided values?
* @param grfid Expected grfid. * @param grfid Expected grfid.
@@ -98,13 +109,12 @@ struct GRFIdentifier {
}; };
/** Information about why GRF had problems during initialisation */ /** Information about why GRF had problems during initialisation */
struct GRFError : ZeroedMemoryAllocator { struct GRFError {
GRFError(StringID severity, StringID message = 0); GRFError(StringID severity, StringID message = 0);
GRFError(const GRFError &error); GRFError(const GRFError &error);
~GRFError();
char *custom_message; ///< Custom message (if present) std::string custom_message; ///< Custom message (if present)
char *data; ///< Additional data for message and custom_message std::string data; ///< Additional data for message and custom_message
StringID message; ///< Default message StringID message; ///< Default message
StringID severity; ///< Info / Warning / Error / Fatal StringID severity; ///< Info / Warning / Error / Fatal
uint64 param_value[4]; ///< Values of GRF parameters to show for message and custom_message uint64 param_value[4]; ///< Values of GRF parameters to show for message and custom_message
@@ -121,9 +131,8 @@ enum GRFParameterType {
struct GRFParameterInfo { struct GRFParameterInfo {
GRFParameterInfo(uint nr); GRFParameterInfo(uint nr);
GRFParameterInfo(GRFParameterInfo &info); GRFParameterInfo(GRFParameterInfo &info);
~GRFParameterInfo(); GRFTextList name; ///< The name of this parameter
struct GRFText *name; ///< The name of this parameter GRFTextList desc; ///< The description of this parameter
struct GRFText *desc; ///< The description of this parameter
GRFParameterType type; ///< The type of this parameter GRFParameterType type; ///< The type of this parameter
uint32 min_value; ///< The minimal value this parameter can have uint32 min_value; ///< The minimal value this parameter can have
uint32 max_value; ///< The maximal value of this parameter uint32 max_value; ///< The maximal value of this parameter
@@ -131,7 +140,7 @@ struct GRFParameterInfo {
byte param_nr; ///< GRF parameter to store content in byte param_nr; ///< GRF parameter to store content in
byte first_bit; ///< First bit to use in the GRF parameter byte first_bit; ///< First bit to use in the GRF parameter
byte num_bit; ///< Number of bits to use for this parameter byte num_bit; ///< Number of bits to use for this parameter
SmallMap<uint32, struct GRFText *> value_names; ///< Names for each value. SmallMap<uint32, GRFTextList> value_names; ///< Names for each value.
bool complete_labels; ///< True if all values have a label. bool complete_labels; ///< True if all values have a label.
uint32 GetValue(struct GRFConfig *config) const; uint32 GetValue(struct GRFConfig *config) const;
@@ -139,14 +148,6 @@ struct GRFParameterInfo {
void Finalize(); void Finalize();
}; };
/** Reference counted wrapper around a GRFText pointer. */
struct GRFTextWrapper : public SimpleCountedObject {
struct GRFText *text; ///< The actual text
GRFTextWrapper();
~GRFTextWrapper();
};
/** Information about GRF, used in the game and (part of it) in savegames */ /** Information about GRF, used in the game and (part of it) in savegames */
struct GRFConfig : ZeroedMemoryAllocator { struct GRFConfig : ZeroedMemoryAllocator {
GRFConfig(const char *filename = nullptr); GRFConfig(const char *filename = nullptr);
@@ -157,9 +158,9 @@ struct GRFConfig : ZeroedMemoryAllocator {
uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded
char *filename; ///< Filename - either with or without full path char *filename; ///< Filename - either with or without full path
char *full_filename; ///< NOSAVE: Full filename char *full_filename; ///< NOSAVE: Full filename
GRFTextWrapper *name; ///< NOSAVE: GRF name (Action 0x08) GRFTextWrapper name; ///< NOSAVE: GRF name (Action 0x08)
GRFTextWrapper *info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) GRFTextWrapper info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
GRFTextWrapper *url; ///< NOSAVE: URL belonging to this GRF. GRFTextWrapper url; ///< NOSAVE: URL belonging to this GRF.
GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B)
uint32 version; ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown uint32 version; ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown
@@ -237,7 +238,7 @@ void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFC
/** For communication about GRFs over the network */ /** For communication about GRFs over the network */
#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>" #define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create); GRFTextWrapper FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
void UpdateNewGRFScanStatus(uint num, const char *name); void UpdateNewGRFScanStatus(uint num, const char *name);
bool UpdateNewGRFConfigPalette(int32 p1 = 0); bool UpdateNewGRFConfigPalette(int32 p1 = 0);

View File

@@ -842,7 +842,7 @@ GrfSpecFeature GetGrfSpecFeature(VehicleType type)
/** Window used for aligning sprites. */ /** Window used for aligning sprites. */
struct SpriteAlignerWindow : Window { struct SpriteAlignerWindow : Window {
typedef SmallPair<int16, int16> XyOffs; ///< Pair for x and y offsets of the sprite before alignment. First value contains the x offset, second value y offset. typedef std::pair<int16, int16> XyOffs; ///< Pair for x and y offsets of the sprite before alignment. First value contains the x offset, second value y offset.
SpriteID current_sprite; ///< The currently shown sprite. SpriteID current_sprite; ///< The currently shown sprite.
Scrollbar *vscroll; Scrollbar *vscroll;

View File

@@ -50,10 +50,10 @@ void ShowNewGRFError()
/* We only want to show fatal errors */ /* We only want to show fatal errors */
if (c->error == nullptr || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue; if (c->error == nullptr || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue;
SetDParam (0, c->error->custom_message == nullptr ? c->error->message : STR_JUST_RAW_STRING); SetDParam (0, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING);
SetDParamStr(1, c->error->custom_message); SetDParamStr(1, c->error->custom_message.c_str());
SetDParamStr(2, c->filename); SetDParamStr(2, c->filename);
SetDParamStr(3, c->error->data); SetDParamStr(3, c->error->data.c_str());
for (uint i = 0; i < lengthof(c->error->param_value); i++) { for (uint i = 0; i < lengthof(c->error->param_value); i++) {
SetDParam(4 + i, c->error->param_value[i]); SetDParam(4 + i, c->error->param_value[i]);
} }
@@ -66,13 +66,13 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint
{ {
if (c->error != nullptr) { if (c->error != nullptr) {
char message[512]; char message[512];
SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages SetDParamStr(0, c->error->custom_message.c_str()); // is skipped by built-in messages
SetDParamStr(1, c->filename); SetDParamStr(1, c->filename);
SetDParamStr(2, c->error->data); SetDParamStr(2, c->error->data.c_str());
for (uint i = 0; i < lengthof(c->error->param_value); i++) { for (uint i = 0; i < lengthof(c->error->param_value); i++) {
SetDParam(3 + i, c->error->param_value[i]); SetDParam(3 + i, c->error->param_value[i]);
} }
GetString(message, c->error->custom_message == nullptr ? c->error->message : STR_JUST_RAW_STRING, lastof(message)); GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
SetDParamStr(0, message); SetDParamStr(0, message);
y = DrawStringMultiLine(x, right, y, bottom, c->error->severity); y = DrawStringMultiLine(x, right, y, bottom, c->error->severity);
@@ -927,7 +927,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false)); list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false));
for (uint i = 0; i < this->grf_presets.size(); i++) { for (uint i = 0; i < this->grf_presets.size(); i++) {
list.emplace_back(new DropDownListCharStringItem(this->grf_presets[i].c_str(), i, false)); list.emplace_back(new DropDownListCharStringItem(this->grf_presets[i], i, false));
} }
this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window

View File

@@ -749,8 +749,6 @@ bool NewHouseTileLoop(TileIndex tile)
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), t, tile); uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), t, tile);
if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) { if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) {
ClearTownHouse(t, tile); ClearTownHouse(t, tile);
extern void RemoveNearbyStations(Town *t);
RemoveNearbyStations(t);
return false; return false;
} }
} }

View File

@@ -32,6 +32,8 @@
#include "core/alloc_type.hpp" #include "core/alloc_type.hpp"
#include "core/smallmap_type.hpp" #include "core/smallmap_type.hpp"
#include "language.h" #include "language.h"
#include <sstream>
#include <map>
#include "table/strings.h" #include "table/strings.h"
#include "table/control_codes.h" #include "table/control_codes.h"
@@ -64,89 +66,6 @@ enum GRFExtendedLanguages {
GRFLX_UNSPECIFIED = 0x7F, GRFLX_UNSPECIFIED = 0x7F,
}; };
/**
* Element of the linked list.
* Each of those elements represent the string,
* but according to a different lang.
*/
struct GRFText {
public:
/**
* Allocate, and assign a new GRFText with the given text.
* As these strings can have string terminations in them, e.g.
* due to "choice lists" we (sometimes) cannot rely on detecting
* the length by means of strlen. Also, if the length of already
* known not scanning the whole string is more efficient.
* @param langid The language of the text.
* @param text The text to store in the new GRFText.
* @param len The length of the text.
*/
static GRFText *New(byte langid, const char *text, size_t len)
{
return new (len) GRFText(langid, text, len);
}
/**
* Create a copy of this GRFText.
* @param orig the grftext to copy.
* @return an exact copy of the given text.
*/
static GRFText *Copy(GRFText *orig)
{
return GRFText::New(orig->langid, orig->text, orig->len);
}
/**
* Helper allocation function to disallow something.
* Don't allow simple 'news'; they wouldn't have enough memory.
* @param size the amount of space not to allocate.
*/
void *operator new(size_t size)
{
NOT_REACHED();
}
/**
* Free the memory we allocated.
* @param p memory to free.
*/
void operator delete(void *p)
{
free(p);
}
private:
/**
* Actually construct the GRFText.
* @param langid_ The language of the text.
* @param text_ The text to store in this GRFText.
* @param len_ The length of the text to store.
*/
GRFText(byte langid_, const char *text_, size_t len_) : next(nullptr), len(len_), langid(langid_)
{
/* We need to use memcpy instead of strcpy due to
* the possibility of "choice lists" and therefore
* intermediate string terminators. */
memcpy(this->text, text_, len);
}
/**
* Allocate memory for this class.
* @param size the size of the instance
* @param extra the extra memory for the text
* @return the requested amount of memory for both the instance and the text
*/
void *operator new(size_t size, size_t extra)
{
return MallocT<byte>(size + extra);
}
public:
GRFText *next; ///< The next GRFText in this chain.
size_t len; ///< The length of the stored string, used for copying.
byte langid; ///< The language associated with this GRFText.
char text[]; ///< The actual (translated) text.
};
/** /**
* Holder of the above structure. * Holder of the above structure.
@@ -157,7 +76,7 @@ struct GRFTextEntry {
uint32 grfid; uint32 grfid;
uint16 stringid; uint16 stringid;
StringID def_string; StringID def_string;
GRFText *textholder; GRFTextList textholder;
}; };
@@ -196,58 +115,48 @@ int LanguageMap::GetReverseMapping(int openttd_id, bool gender) const
} }
/** Helper structure for mapping choice lists. */ /** Helper structure for mapping choice lists. */
struct UnmappedChoiceList : ZeroedMemoryAllocator { struct UnmappedChoiceList {
/** Clean everything up. */
~UnmappedChoiceList()
{
for (SmallPair<byte, char *> p : this->strings) {
free(p.second);
}
}
/** /**
* Initialise the mapping. * Initialise the mapping.
* @param type The type of mapping. * @param type The type of mapping.
* @param old_d The old begin of the string, i.e. from where to start writing again.
* @param offset The offset to get the plural/gender from. * @param offset The offset to get the plural/gender from.
*/ */
UnmappedChoiceList(StringControlCode type, char *old_d, int offset) : UnmappedChoiceList(StringControlCode type, int offset) :
type(type), old_d(old_d), offset(offset) type(type), offset(offset)
{ {
} }
StringControlCode type; ///< The type of choice list. StringControlCode type; ///< The type of choice list.
char *old_d; ///< The old/original location of the "d" local variable.
int offset; ///< The offset for the plural/gender form. int offset; ///< The offset for the plural/gender form.
/** Mapping of NewGRF supplied ID to the different strings in the choice list. */ /** Mapping of NewGRF supplied ID to the different strings in the choice list. */
SmallMap<byte, char *> strings; std::map<byte, std::stringstream> strings;
/** /**
* Flush this choice list into the old d variable. * Flush this choice list into the destination string.
* @param lm The current language mapping. * @param lm The current language mapping.
* @return The new location of the output string. * @param dest Target to write to.
*/ */
char *Flush(const LanguageMap *lm) void Flush(const LanguageMap *lm, std::ostringstream &dest)
{ {
if (!this->strings.Contains(0)) { if (this->strings.find(0) == this->strings.end()) {
/* In case of a (broken) NewGRF without a default, /* In case of a (broken) NewGRF without a default,
* assume an empty string. */ * assume an empty string. */
grfmsg(1, "choice list misses default value"); grfmsg(1, "choice list misses default value");
this->strings[0] = stredup(""); this->strings[0] = std::stringstream();
} }
char *d = old_d; std::ostreambuf_iterator<char> d(dest);
if (lm == nullptr) { if (lm == nullptr) {
/* In case there is no mapping, just ignore everything but the default. /* In case there is no mapping, just ignore everything but the default.
* A probable cause for this happening is when the language file has * A probable cause for this happening is when the language file has
* been removed by the user and as such no mapping could be made. */ * been removed by the user and as such no mapping could be made. */
size_t len = strlen(this->strings[0]); dest << this->strings[0].rdbuf();
memcpy(d, this->strings[0], len); return;
return d + len;
} }
d += Utf8Encode(d, this->type); Utf8Encode(d, this->type);
if (this->type == SCC_SWITCH_CASE) { if (this->type == SCC_SWITCH_CASE) {
/* /*
@@ -260,33 +169,31 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
int count = 0; int count = 0;
for (uint8 i = 0; i < _current_language->num_cases; i++) { for (uint8 i = 0; i < _current_language->num_cases; i++) {
/* Count the ones we have a mapped string for. */ /* Count the ones we have a mapped string for. */
if (this->strings.Contains(lm->GetReverseMapping(i, false))) count++; if (this->strings.find(lm->GetReverseMapping(i, false)) != this->strings.end()) count++;
} }
*d++ = count; *d++ = count;
for (uint8 i = 0; i < _current_language->num_cases; i++) { for (uint8 i = 0; i < _current_language->num_cases; i++) {
/* Resolve the string we're looking for. */ /* Resolve the string we're looking for. */
int idx = lm->GetReverseMapping(i, false); int idx = lm->GetReverseMapping(i, false);
if (!this->strings.Contains(idx)) continue; if (this->strings.find(idx) == this->strings.end()) continue;
char *str = this->strings[idx]; auto str = this->strings[idx].str();
/* "<CASEn>" */ /* "<CASEn>" */
*d++ = i + 1; *d++ = i + 1;
/* "<LENn>" */ /* "<LENn>": Limit the length of the string to 0xFFFE to leave space for the '\0'. */
size_t len = strlen(str) + 1; size_t len = min<size_t>(0xFFFE, str.size());
*d++ = GB(len, 8, 8); *d++ = GB(len + 1, 8, 8);
*d++ = GB(len, 0, 8); *d++ = GB(len + 1, 0, 8);
/* "<STRINGn>" */ /* "<STRINGn>" */
memcpy(d, str, len); dest.write(str.c_str(), len);
d += len; *d++ = '\0';
} }
/* "<STRINGDEFAULT>" */ /* "<STRINGDEFAULT>" */
size_t len = strlen(this->strings[0]) + 1; dest << this->strings[0].rdbuf() << '\0';
memcpy(d, this->strings[0], len);
d += len;
} else { } else {
if (this->type == SCC_PLURAL_LIST) { if (this->type == SCC_PLURAL_LIST) {
*d++ = lm->plural_form; *d++ = lm->plural_form;
@@ -307,8 +214,8 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
/* "<LENs>" */ /* "<LENs>" */
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1); int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1);
const char *str = this->strings[this->strings.Contains(idx) ? idx : 0]; const auto &str = this->strings[this->strings.find(idx) != this->strings.end() ? idx : 0].str();
size_t len = strlen(str) + 1; size_t len = str.size() + 1;
if (len > 0xFF) grfmsg(1, "choice list string is too long"); if (len > 0xFF) grfmsg(1, "choice list string is too long");
*d++ = GB(len, 0, 8); *d++ = GB(len, 0, 8);
} }
@@ -316,16 +223,14 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
/* "<STRINGs>" */ /* "<STRINGs>" */
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1); int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1);
const char *str = this->strings[this->strings.Contains(idx) ? idx : 0]; const auto &str = this->strings[this->strings.find(idx) != this->strings.end() ? idx : 0].str();
/* Limit the length of the string we copy to 0xFE. The length is written above /* Limit the length of the string we copy to 0xFE. The length is written above
* as a byte and we need room for the final '\0'. */ * as a byte and we need room for the final '\0'. */
size_t len = min<size_t>(0xFE, strlen(str)); size_t len = min<size_t>(0xFE, str.size());
memcpy(d, str, len); dest.write(str.c_str(), len);
d += len;
*d++ = '\0'; *d++ = '\0';
} }
} }
return d;
} }
}; };
@@ -335,47 +240,55 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
* @param language_id The (NewGRF) language ID associated with this string. * @param language_id The (NewGRF) language ID associated with this string.
* @param allow_newlines Whether newlines are allowed in the string or not. * @param allow_newlines Whether newlines are allowed in the string or not.
* @param str The string to translate. * @param str The string to translate.
* @param[out] olen The length of the final string.
* @param byte80 The control code to use as replacement for the 0x80-value. * @param byte80 The control code to use as replacement for the 0x80-value.
* @return The translated string. * @return The translated string.
*/ */
char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const char *str, int *olen, StringControlCode byte80) std::string TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const std::string &str, StringControlCode byte80)
{ {
char *tmp = MallocT<char>(strlen(str) * 10 + 1); // Allocate space to allow for expansion /* Empty input string? Nothing to do here. */
char *d = tmp; if (str.empty()) return str;
std::string::const_iterator src = str.cbegin();
/* Is this an unicode string? */
bool unicode = false; bool unicode = false;
WChar c; WChar marker;
size_t len = Utf8Decode(&c, str); size_t len = Utf8Decode(&marker, &*src);
if (marker == NFO_UTF8_IDENTIFIER) {
unicode = true;
src += len;
}
/* Helper variable for a possible (string) mapping. */ /* Helper variable for a possible (string) mapping. */
UnmappedChoiceList *mapping = nullptr; UnmappedChoiceList *mapping = nullptr;
if (c == NFO_UTF8_IDENTIFIER) { std::ostringstream dest;
unicode = true; std::ostreambuf_iterator<char> d(dest);
str += len; while (src != str.cend()) {
} WChar c;
for (;;) { if (unicode && Utf8EncodedCharLen(*src) != 0) {
if (unicode && Utf8EncodedCharLen(*str) != 0) { c = Utf8Consume(src);
c = Utf8Consume(&str);
/* 'Magic' range of control codes. */ /* 'Magic' range of control codes. */
if (GB(c, 8, 8) == 0xE0) { if (GB(c, 8, 8) == 0xE0) {
c = GB(c, 0, 8); c = GB(c, 0, 8);
} else if (c >= 0x20) { } else if (c >= 0x20) {
if (!IsValidChar(c, CS_ALPHANUMERAL)) c = '?'; if (!IsValidChar(c, CS_ALPHANUMERAL)) c = '?';
d += Utf8Encode(d, c); Utf8Encode(d, c);
continue; continue;
} }
} else { } else {
c = (byte)*str++; c = (byte)*src++;
} }
if (c == '\0') break; if (c == '\0') break;
switch (c) { switch (c) {
case 0x01: case 0x01:
if (str[0] == '\0') goto string_end; if (*src == '\0') goto string_end;
d += Utf8Encode(d, ' '); Utf8Encode(d, ' ');
str++; src++;
break; break;
case 0x0A: break; case 0x0A: break;
case 0x0D: case 0x0D:
@@ -385,56 +298,58 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline
grfmsg(1, "Detected newline in string that does not allow one"); grfmsg(1, "Detected newline in string that does not allow one");
} }
break; break;
case 0x0E: d += Utf8Encode(d, SCC_TINYFONT); break; case 0x0E: Utf8Encode(d, SCC_TINYFONT); break;
case 0x0F: d += Utf8Encode(d, SCC_BIGFONT); break; case 0x0F: Utf8Encode(d, SCC_BIGFONT); break;
case 0x1F: case 0x1F:
if (str[0] == '\0' || str[1] == '\0') goto string_end; if (src[0] == '\0' || src[1] == '\0') goto string_end;
d += Utf8Encode(d, ' '); Utf8Encode(d, ' ');
str += 2; src += 2;
break; break;
case 0x7B: case 0x7B:
case 0x7C: case 0x7C:
case 0x7D: case 0x7D:
case 0x7E: case 0x7E:
case 0x7F: d += Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_SIGNED + c - 0x7B); break; case 0x7F: Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_SIGNED + c - 0x7B); break;
case 0x80: d += Utf8Encode(d, byte80); break; case 0x80: Utf8Encode(d, byte80); break;
case 0x81: { case 0x81:
if (str[0] == '\0' || str[1] == '\0') goto string_end; {
if (src[0] == '\0' || src[1] == '\0') goto string_end;
StringID string; StringID string;
string = ((uint8)*str++); string = ((uint8)* src++);
string |= ((uint8)*str++) << 8; string |= ((uint8)* src++) << 8;
d += Utf8Encode(d, SCC_NEWGRF_STRINL); Utf8Encode(d, SCC_NEWGRF_STRINL);
d += Utf8Encode(d, MapGRFStringID(grfid, string)); Utf8Encode(d, MapGRFStringID(grfid, string));
break; break;
} }
case 0x82: case 0x82:
case 0x83: case 0x83:
case 0x84: d += Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_DATE_LONG + c - 0x82); break; case 0x84: Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_DATE_LONG + c - 0x82); break;
case 0x85: d += Utf8Encode(d, SCC_NEWGRF_DISCARD_WORD); break; case 0x85: Utf8Encode(d, SCC_NEWGRF_DISCARD_WORD); break;
case 0x86: d += Utf8Encode(d, SCC_NEWGRF_ROTATE_TOP_4_WORDS); break; case 0x86: Utf8Encode(d, SCC_NEWGRF_ROTATE_TOP_4_WORDS); break;
case 0x87: d += Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_VOLUME_LONG); break; case 0x87: Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_VOLUME_LONG); break;
case 0x88: d += Utf8Encode(d, SCC_BLUE); break; case 0x88: Utf8Encode(d, SCC_BLUE); break;
case 0x89: d += Utf8Encode(d, SCC_SILVER); break; case 0x89: Utf8Encode(d, SCC_SILVER); break;
case 0x8A: d += Utf8Encode(d, SCC_GOLD); break; case 0x8A: Utf8Encode(d, SCC_GOLD); break;
case 0x8B: d += Utf8Encode(d, SCC_RED); break; case 0x8B: Utf8Encode(d, SCC_RED); break;
case 0x8C: d += Utf8Encode(d, SCC_PURPLE); break; case 0x8C: Utf8Encode(d, SCC_PURPLE); break;
case 0x8D: d += Utf8Encode(d, SCC_LTBROWN); break; case 0x8D: Utf8Encode(d, SCC_LTBROWN); break;
case 0x8E: d += Utf8Encode(d, SCC_ORANGE); break; case 0x8E: Utf8Encode(d, SCC_ORANGE); break;
case 0x8F: d += Utf8Encode(d, SCC_GREEN); break; case 0x8F: Utf8Encode(d, SCC_GREEN); break;
case 0x90: d += Utf8Encode(d, SCC_YELLOW); break; case 0x90: Utf8Encode(d, SCC_YELLOW); break;
case 0x91: d += Utf8Encode(d, SCC_DKGREEN); break; case 0x91: Utf8Encode(d, SCC_DKGREEN); break;
case 0x92: d += Utf8Encode(d, SCC_CREAM); break; case 0x92: Utf8Encode(d, SCC_CREAM); break;
case 0x93: d += Utf8Encode(d, SCC_BROWN); break; case 0x93: Utf8Encode(d, SCC_BROWN); break;
case 0x94: d += Utf8Encode(d, SCC_WHITE); break; case 0x94: Utf8Encode(d, SCC_WHITE); break;
case 0x95: d += Utf8Encode(d, SCC_LTBLUE); break; case 0x95: Utf8Encode(d, SCC_LTBLUE); break;
case 0x96: d += Utf8Encode(d, SCC_GRAY); break; case 0x96: Utf8Encode(d, SCC_GRAY); break;
case 0x97: d += Utf8Encode(d, SCC_DKBLUE); break; case 0x97: Utf8Encode(d, SCC_DKBLUE); break;
case 0x98: d += Utf8Encode(d, SCC_BLACK); break; case 0x98: Utf8Encode(d, SCC_BLACK); break;
case 0x9A: { case 0x9A:
int code = *str++; {
int code = *src++;
switch (code) { switch (code) {
case 0x00: goto string_end; case 0x00: goto string_end;
case 0x01: d += Utf8Encode(d, SCC_NEWGRF_PRINT_QWORD_CURRENCY); break; case 0x01: Utf8Encode(d, SCC_NEWGRF_PRINT_QWORD_CURRENCY); break;
/* 0x02: ignore next colour byte is not supported. It works on the final /* 0x02: ignore next colour byte is not supported. It works on the final
* string and as such hooks into the string drawing routine. At that * string and as such hooks into the string drawing routine. At that
* point many things already happened, such as splitting up of strings * point many things already happened, such as splitting up of strings
@@ -442,35 +357,37 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline
* make the behaviour peculiar, e.g. only happening at specific width * make the behaviour peculiar, e.g. only happening at specific width
* of windows. Or we need to add another pass over the string to just * of windows. Or we need to add another pass over the string to just
* support this. As such it is not implemented in OpenTTD. */ * support this. As such it is not implemented in OpenTTD. */
case 0x03: { case 0x03:
if (str[0] == '\0' || str[1] == '\0') goto string_end; {
uint16 tmp = ((uint8)*str++); if (src[0] == '\0' || src[1] == '\0') goto string_end;
tmp |= ((uint8)*str++) << 8; uint16 tmp = ((uint8)* src++);
d += Utf8Encode(d, SCC_NEWGRF_PUSH_WORD); tmp |= ((uint8)* src++) << 8;
d += Utf8Encode(d, tmp); Utf8Encode(d, SCC_NEWGRF_PUSH_WORD);
Utf8Encode(d, tmp);
break; break;
} }
case 0x04: case 0x04:
if (str[0] == '\0') goto string_end; if (src[0] == '\0') goto string_end;
d += Utf8Encode(d, SCC_NEWGRF_UNPRINT); Utf8Encode(d, SCC_NEWGRF_UNPRINT);
d += Utf8Encode(d, *str++); Utf8Encode(d, *src++);
break; break;
case 0x06: d += Utf8Encode(d, SCC_NEWGRF_PRINT_BYTE_HEX); break; case 0x06: Utf8Encode(d, SCC_NEWGRF_PRINT_BYTE_HEX); break;
case 0x07: d += Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_HEX); break; case 0x07: Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_HEX); break;
case 0x08: d += Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_HEX); break; case 0x08: Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_HEX); break;
/* 0x09, 0x0A are TTDPatch internal use only string codes. */ /* 0x09, 0x0A are TTDPatch internal use only string codes. */
case 0x0B: d += Utf8Encode(d, SCC_NEWGRF_PRINT_QWORD_HEX); break; case 0x0B: Utf8Encode(d, SCC_NEWGRF_PRINT_QWORD_HEX); break;
case 0x0C: d += Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_STATION_NAME); break; case 0x0C: Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_STATION_NAME); break;
case 0x0D: d += Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_WEIGHT_LONG); break; case 0x0D: Utf8Encode(d, SCC_NEWGRF_PRINT_WORD_WEIGHT_LONG); break;
case 0x0E: case 0x0E:
case 0x0F: { case 0x0F:
{
if (str[0] == '\0') goto string_end; if (str[0] == '\0') goto string_end;
const LanguageMap *lm = LanguageMap::GetLanguageMap(grfid, language_id); const LanguageMap *lm = LanguageMap::GetLanguageMap(grfid, language_id);
int index = *str++; int index = *src++;
int mapped = lm != nullptr ? lm->GetMapping(index, code == 0x0E) : -1; int mapped = lm != nullptr ? lm->GetMapping(index, code == 0x0E) : -1;
if (mapped >= 0) { if (mapped >= 0) {
d += Utf8Encode(d, code == 0x0E ? SCC_GENDER_INDEX : SCC_SET_CASE); Utf8Encode(d, code == 0x0E ? SCC_GENDER_INDEX : SCC_SET_CASE);
d += Utf8Encode(d, code == 0x0E ? mapped : mapped + 1); Utf8Encode(d, code == 0x0E ? mapped : mapped + 1);
} }
break; break;
} }
@@ -479,18 +396,16 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline
case 0x11: case 0x11:
if (str[0] == '\0') goto string_end; if (str[0] == '\0') goto string_end;
if (mapping == nullptr) { if (mapping == nullptr) {
if (code == 0x10) str++; // Skip the index if (code == 0x10) src++; // Skip the index
grfmsg(1, "choice list %s marker found when not expected", code == 0x10 ? "next" : "default"); grfmsg(1, "choice list %s marker found when not expected", code == 0x10 ? "next" : "default");
break; break;
} else { } else {
/* Terminate the previous string. */ int index = (code == 0x10 ? *src++ : 0);
*d = '\0'; if (mapping->strings.find(index) != mapping->strings.end()) {
int index = (code == 0x10 ? *str++ : 0);
if (mapping->strings.Contains(index)) {
grfmsg(1, "duplicate choice list string, ignoring"); grfmsg(1, "duplicate choice list string, ignoring");
d++; d++;
} else { } else {
d = mapping->strings[index] = MallocT<char>(strlen(str) * 10 + 1); d = std::ostreambuf_iterator<char>(mapping->strings[index]);
} }
} }
break; break;
@@ -499,26 +414,25 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline
if (mapping == nullptr) { if (mapping == nullptr) {
grfmsg(1, "choice list end marker found when not expected"); grfmsg(1, "choice list end marker found when not expected");
} else { } else {
/* Terminate the previous string. */
*d = '\0';
/* Now we can start flushing everything and clean everything up. */ /* Now we can start flushing everything and clean everything up. */
d = mapping->Flush(LanguageMap::GetLanguageMap(grfid, language_id)); mapping->Flush(LanguageMap::GetLanguageMap(grfid, language_id), dest);
delete mapping; delete mapping;
mapping = nullptr; mapping = nullptr;
d = std::ostreambuf_iterator<char>(dest);
} }
break; break;
case 0x13: case 0x13:
case 0x14: case 0x14:
case 0x15: case 0x15:
if (str[0] == '\0') goto string_end; if (src[0] == '\0') goto string_end;
if (mapping != nullptr) { if (mapping != nullptr) {
grfmsg(1, "choice lists can't be stacked, it's going to get messy now..."); grfmsg(1, "choice lists can't be stacked, it's going to get messy now...");
if (code != 0x14) str++; if (code != 0x14) src++;
} else { } else {
static const StringControlCode mp[] = { SCC_GENDER_LIST, SCC_SWITCH_CASE, SCC_PLURAL_LIST }; static const StringControlCode mp[] = { SCC_GENDER_LIST, SCC_SWITCH_CASE, SCC_PLURAL_LIST };
mapping = new UnmappedChoiceList(mp[code - 0x13], d, code == 0x14 ? 0 : *str++); mapping = new UnmappedChoiceList(mp[code - 0x13], code == 0x14 ? 0 : *src++);
} }
break; break;
@@ -531,11 +445,11 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline
case 0x1C: case 0x1C:
case 0x1D: case 0x1D:
case 0x1E: case 0x1E:
d += Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_DATE_LONG + code - 0x16); Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_DATE_LONG + code - 0x16);
break; break;
case 0x1F: d += Utf8Encode(d, SCC_PUSH_COLOUR); break; case 0x1F: Utf8Encode(d, SCC_PUSH_COLOUR); break;
case 0x20: d += Utf8Encode(d, SCC_POP_COLOUR); break; case 0x20: Utf8Encode(d, SCC_POP_COLOUR); break;
default: default:
grfmsg(1, "missing handler for extended format code"); grfmsg(1, "missing handler for extended format code");
@@ -544,25 +458,25 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline
break; break;
} }
case 0x9E: d += Utf8Encode(d, 0x20AC); break; // Euro case 0x9E: Utf8Encode(d, 0x20AC); break; // Euro
case 0x9F: d += Utf8Encode(d, 0x0178); break; // Y with diaeresis case 0x9F: Utf8Encode(d, 0x0178); break; // Y with diaeresis
case 0xA0: d += Utf8Encode(d, SCC_UP_ARROW); break; case 0xA0: Utf8Encode(d, SCC_UP_ARROW); break;
case 0xAA: d += Utf8Encode(d, SCC_DOWN_ARROW); break; case 0xAA: Utf8Encode(d, SCC_DOWN_ARROW); break;
case 0xAC: d += Utf8Encode(d, SCC_CHECKMARK); break; case 0xAC: Utf8Encode(d, SCC_CHECKMARK); break;
case 0xAD: d += Utf8Encode(d, SCC_CROSS); break; case 0xAD: Utf8Encode(d, SCC_CROSS); break;
case 0xAF: d += Utf8Encode(d, SCC_RIGHT_ARROW); break; case 0xAF: Utf8Encode(d, SCC_RIGHT_ARROW); break;
case 0xB4: d += Utf8Encode(d, SCC_TRAIN); break; case 0xB4: Utf8Encode(d, SCC_TRAIN); break;
case 0xB5: d += Utf8Encode(d, SCC_LORRY); break; case 0xB5: Utf8Encode(d, SCC_LORRY); break;
case 0xB6: d += Utf8Encode(d, SCC_BUS); break; case 0xB6: Utf8Encode(d, SCC_BUS); break;
case 0xB7: d += Utf8Encode(d, SCC_PLANE); break; case 0xB7: Utf8Encode(d, SCC_PLANE); break;
case 0xB8: d += Utf8Encode(d, SCC_SHIP); break; case 0xB8: Utf8Encode(d, SCC_SHIP); break;
case 0xB9: d += Utf8Encode(d, SCC_SUPERSCRIPT_M1); break; case 0xB9: Utf8Encode(d, SCC_SUPERSCRIPT_M1); break;
case 0xBC: d += Utf8Encode(d, SCC_SMALL_UP_ARROW); break; case 0xBC: Utf8Encode(d, SCC_SMALL_UP_ARROW); break;
case 0xBD: d += Utf8Encode(d, SCC_SMALL_DOWN_ARROW); break; case 0xBD: Utf8Encode(d, SCC_SMALL_DOWN_ARROW); break;
default: default:
/* Validate any unhandled character */ /* Validate any unhandled character */
if (!IsValidChar(c, CS_ALPHANUMERAL)) c = '?'; if (!IsValidChar(c, CS_ALPHANUMERAL)) c = '?';
d += Utf8Encode(d, c); Utf8Encode(d, c);
break; break;
} }
} }
@@ -573,33 +487,27 @@ string_end:
delete mapping; delete mapping;
} }
*d = '\0'; return dest.str();
if (olen != nullptr) *olen = d - tmp + 1;
tmp = ReallocT(tmp, d - tmp + 1);
return tmp;
} }
/** /**
* Add a GRFText to a GRFText list. * Add a new text to a GRFText list.
* @param list The list where the text should be added to. * @param list The list where the text should be added to.
* @param text_to_add The GRFText to add to the list. * @param langid The The language of the new text.
* @param text_to_add The text to add to the list.
*/ */
void AddGRFTextToList(GRFText **list, GRFText *text_to_add) static void AddGRFTextToList(GRFTextList &list, byte langid, const std::string &text_to_add)
{ {
GRFText **ptext, *text;
/* Loop through all languages and see if we can replace a string */ /* Loop through all languages and see if we can replace a string */
for (ptext = list; (text = *ptext) != nullptr; ptext = &text->next) { for (auto &text : list) {
if (text->langid == text_to_add->langid) { if (text.langid == langid) {
text_to_add->next = text->next; text.text = text_to_add;
*ptext = text_to_add;
delete text;
return; return;
} }
} }
/* If a string wasn't replaced, then we must append the new string */ /* If a string wasn't replaced, then we must append the new string */
*ptext = text_to_add; list.push_back(GRFText{ langid, text_to_add });
} }
/** /**
@@ -611,14 +519,24 @@ void AddGRFTextToList(GRFText **list, GRFText *text_to_add)
* @param text_to_add The text to add to the list. * @param text_to_add The text to add to the list.
* @note All text-codes will be translated. * @note All text-codes will be translated.
*/ */
void AddGRFTextToList(struct GRFText **list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add) void AddGRFTextToList(GRFTextList &list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add)
{ {
int len; AddGRFTextToList(list, langid, TranslateTTDPatchCodes(grfid, langid, allow_newlines, text_to_add));
char *translatedtext = TranslateTTDPatchCodes(grfid, langid, allow_newlines, text_to_add, &len); }
GRFText *newtext = GRFText::New(langid, translatedtext, len);
free(translatedtext);
AddGRFTextToList(list, newtext); /**
* Add a string to a GRFText list.
* @param list The list where the text should be added to.
* @param langid The language of the new text.
* @param grfid The grfid where this string is defined.
* @param allow_newlines Whether newlines are allowed in this string.
* @param text_to_add The text to add to the list.
* @note All text-codes will be translated.
*/
void AddGRFTextToList(GRFTextWrapper &list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add)
{
if (!list) list.reset(new GRFTextList());
AddGRFTextToList(*list, langid, grfid, allow_newlines, text_to_add);
} }
/** /**
@@ -627,25 +545,10 @@ void AddGRFTextToList(struct GRFText **list, byte langid, uint32 grfid, bool all
* @param list The list where the text should be added to. * @param list The list where the text should be added to.
* @param text_to_add The text to add to the list. * @param text_to_add The text to add to the list.
*/ */
void AddGRFTextToList(struct GRFText **list, const char *text_to_add) void AddGRFTextToList(GRFTextWrapper &list, const char *text_to_add)
{ {
AddGRFTextToList(list, GRFText::New(0x7F, text_to_add, strlen(text_to_add) + 1)); if (!list) list.reset(new GRFTextList());
} AddGRFTextToList(*list, GRFLX_UNSPECIFIED, std::string(text_to_add));
/**
* Create a copy of this GRFText list.
* @param orig The GRFText list to copy.
* @return A duplicate of the given GRFText.
*/
GRFText *DuplicateGRFText(GRFText *orig)
{
GRFText *newtext = nullptr;
GRFText **ptext = &newtext;
for (; orig != nullptr; orig = orig->next) {
*ptext = GRFText::Copy(orig);
ptext = &(*ptext)->next;
}
return newtext;
} }
/** /**
@@ -653,9 +556,6 @@ GRFText *DuplicateGRFText(GRFText *orig)
*/ */
StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string) StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string)
{ {
char *translatedtext;
uint id;
/* When working with the old language scheme (grf_version is less than 7) and /* When working with the old language scheme (grf_version is less than 7) and
* English or American is among the set bits, simply add it as English in * English or American is among the set bits, simply add it as English in
* the new scheme, i.e. as langid = 1. * the new scheme, i.e. as langid = 1.
@@ -674,6 +574,7 @@ StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool ne
} }
} }
uint id;
for (id = 0; id < _num_grf_texts; id++) { for (id = 0; id < _num_grf_texts; id++) {
if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) { if (_grf_text[id].grfid == grfid && _grf_text[id].stringid == stringid) {
break; break;
@@ -686,24 +587,19 @@ StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool ne
return STR_EMPTY; return STR_EMPTY;
} }
int len; std::string newtext = TranslateTTDPatchCodes(grfid, langid_to_add, allow_newlines, text_to_add);
translatedtext = TranslateTTDPatchCodes(grfid, langid_to_add, allow_newlines, text_to_add, &len);
GRFText *newtext = GRFText::New(langid_to_add, translatedtext, len);
free(translatedtext);
/* If we didn't find our stringid and grfid in the list, allocate a new id */ /* If we didn't find our stringid and grfid in the list, allocate a new id */
if (id == _num_grf_texts) _num_grf_texts++; if (id == _num_grf_texts) _num_grf_texts++;
if (_grf_text[id].textholder == nullptr) { if (_grf_text[id].textholder.empty()) {
_grf_text[id].grfid = grfid; _grf_text[id].grfid = grfid;
_grf_text[id].stringid = stringid; _grf_text[id].stringid = stringid;
_grf_text[id].def_string = def_string; _grf_text[id].def_string = def_string;
} }
AddGRFTextToList(&_grf_text[id].textholder, newtext); AddGRFTextToList(_grf_text[id].textholder, langid_to_add, newtext);
grfmsg(3, "Added 0x%X: grfid %08X string 0x%X lang 0x%X string '%s' (%X)", id, grfid, stringid, newtext->langid, newtext->text, MakeStringID(TEXT_TAB_NEWGRF_START, id)); grfmsg(3, "Added 0x%X: grfid %08X string 0x%X lang 0x%X string '%s' (%X)", id, grfid, stringid, langid_to_add, newtext.c_str(), MakeStringID(TEXT_TAB_NEWGRF_START, id));
return MakeStringID(TEXT_TAB_NEWGRF_START, id); return MakeStringID(TEXT_TAB_NEWGRF_START, id);
} }
@@ -728,20 +624,20 @@ StringID GetGRFStringID(uint32 grfid, StringID stringid)
* current language it is returned, otherwise the default translation * current language it is returned, otherwise the default translation
* is returned. If there is neither a default nor a translation for the * is returned. If there is neither a default nor a translation for the
* current language nullptr is returned. * current language nullptr is returned.
* @param text The GRFText to get the string from. * @param text_list The GRFTextList to get the string from.
*/ */
const char *GetGRFStringFromGRFText(const GRFText *text) const char *GetGRFStringFromGRFText(const GRFTextList &text_list)
{ {
const char *default_text = nullptr; const char *default_text = nullptr;
/* Search the list of lang-strings of this stringid for current lang */ /* Search the list of lang-strings of this stringid for current lang */
for (; text != nullptr; text = text->next) { for (const auto &text : text_list) {
if (text->langid == _currentLangID) return text->text; if (text.langid == _currentLangID) return text.text.c_str();
/* If the current string is English or American, set it as the /* If the current string is English or American, set it as the
* fallback language if the specific language isn't available. */ * fallback language if the specific language isn't available. */
if (text->langid == GRFLX_UNSPECIFIED || (default_text == nullptr && (text->langid == GRFLX_ENGLISH || text->langid == GRFLX_AMERICAN))) { if (text.langid == GRFLX_UNSPECIFIED || (default_text == nullptr && (text.langid == GRFLX_ENGLISH || text.langid == GRFLX_AMERICAN))) {
default_text = text->text; default_text = text.text.c_str();
} }
} }
@@ -751,6 +647,18 @@ const char *GetGRFStringFromGRFText(const GRFText *text)
static std::array<std::pair<uint16, const char *>, 16> _grf_string_ptr_log; static std::array<std::pair<uint16, const char *>, 16> _grf_string_ptr_log;
static unsigned int _grf_string_ptr_log_next = 0; static unsigned int _grf_string_ptr_log_next = 0;
/**
* Get a C-string from a GRFText-list. If there is a translation for the
* current language it is returned, otherwise the default translation
* is returned. If there is neither a default nor a translation for the
* current language nullptr is returned.
* @param text The GRFTextList to get the string from.
*/
const char *GetGRFStringFromGRFText(const GRFTextWrapper &text)
{
return text ? GetGRFStringFromGRFText(*text) : nullptr;
}
/** /**
* Get a C-string from a stringid set by a newgrf. * Get a C-string from a stringid set by a newgrf.
*/ */
@@ -797,19 +705,6 @@ bool CheckGrfLangID(byte lang_id, byte grf_version)
return (lang_id == _currentLangID || lang_id == GRFLX_UNSPECIFIED); return (lang_id == _currentLangID || lang_id == GRFLX_UNSPECIFIED);
} }
/**
* Delete all items of a linked GRFText list.
* @param grftext the head of the list to delete
*/
void CleanUpGRFText(GRFText *grftext)
{
while (grftext != nullptr) {
GRFText *grftext2 = grftext->next;
delete grftext;
grftext = grftext2;
}
}
/** /**
* House cleaning. * House cleaning.
* Remove all strings and reset the text counter. * Remove all strings and reset the text counter.
@@ -819,10 +714,9 @@ void CleanUpStrings()
uint id; uint id;
for (id = 0; id < _num_grf_texts; id++) { for (id = 0; id < _num_grf_texts; id++) {
CleanUpGRFText(_grf_text[id].textholder);
_grf_text[id].grfid = 0; _grf_text[id].grfid = 0;
_grf_text[id].stringid = 0; _grf_text[id].stringid = 0;
_grf_text[id].textholder = nullptr; _grf_text[id].textholder.clear();
} }
for (id = 0; id < _grf_string_ptr_log.size(); id++) { for (id = 0; id < _grf_string_ptr_log.size(); id++) {

View File

@@ -14,26 +14,39 @@
#include "strings_type.h" #include "strings_type.h"
#include "core/smallvec_type.hpp" #include "core/smallvec_type.hpp"
#include "table/control_codes.h" #include "table/control_codes.h"
#include <utility>
#include <vector>
#include <string>
/** This character, the thorn ('þ'), indicates a unicode string to NFO. */ /** This character, the thorn ('þ'), indicates a unicode string to NFO. */
static const WChar NFO_UTF8_IDENTIFIER = 0x00DE; static const WChar NFO_UTF8_IDENTIFIER = 0x00DE;
/** A GRF text with associated language ID. */
struct GRFText {
byte langid; ///< The language associated with this GRFText.
std::string text; ///< The actual (translated) text.
};
/** A GRF text with a list of translations. */
typedef std::vector<GRFText> GRFTextList;
/** Reference counted wrapper around a GRFText pointer. */
typedef std::shared_ptr<GRFTextList> GRFTextWrapper;
StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string); StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string);
StringID GetGRFStringID(uint32 grfid, StringID stringid); StringID GetGRFStringID(uint32 grfid, StringID stringid);
const char *GetGRFStringFromGRFText(const struct GRFText *text); const char *GetGRFStringFromGRFText(const GRFTextList &text_list);
const char *GetGRFStringFromGRFText(const GRFTextWrapper &text);
const char *GetGRFStringPtr(uint16 stringid); const char *GetGRFStringPtr(uint16 stringid);
void CleanUpStrings(); void CleanUpStrings();
void SetCurrentGrfLangID(byte language_id); void SetCurrentGrfLangID(byte language_id);
char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const char *str, int *olen = nullptr, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID); std::string TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const std::string &str, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID);
struct GRFText *DuplicateGRFText(struct GRFText *orig); void AddGRFTextToList(GRFTextList &list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add);
void AddGRFTextToList(struct GRFText **list, struct GRFText *text_to_add); void AddGRFTextToList(GRFTextWrapper &list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add);
void AddGRFTextToList(struct GRFText **list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add); void AddGRFTextToList(GRFTextWrapper &list, const char *text_to_add);
void AddGRFTextToList(struct GRFText **list, const char *text_to_add);
void CleanUpGRFText(struct GRFText *grftext);
bool CheckGrfLangID(byte lang_id, byte grf_version); bool CheckGrfLangID(byte lang_id, byte grf_version);
void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values = nullptr); void StartTextRefStackUsage(const struct GRFFile *grffile, byte numEntries, const uint32 *values = nullptr);
void StopTextRefStackUsage(); void StopTextRefStackUsage();
void RewindTextRefStack(); void RewindTextRefStack();
bool UsingNewGRFTextStack(); bool UsingNewGRFTextStack();

View File

@@ -671,17 +671,17 @@ static const OptionData _options[] = {
int openttd_main(int argc, char *argv[]) int openttd_main(int argc, char *argv[])
{ {
SetSelfAsMainThread(); SetSelfAsMainThread();
char *musicdriver = nullptr; std::string musicdriver;
char *sounddriver = nullptr; std::string sounddriver;
char *videodriver = nullptr; std::string videodriver;
char *blitter = nullptr; std::string blitter;
char *graphics_set = nullptr; std::string graphics_set;
char *sounds_set = nullptr; std::string sounds_set;
char *music_set = nullptr; std::string music_set;
Dimension resolution = {0, 0}; Dimension resolution = {0, 0};
/* AfterNewGRFScan sets save_config to true after scanning completed. */ /* AfterNewGRFScan sets save_config to true after scanning completed. */
bool save_config = false; bool save_config = false;
AfterNewGRFScan *scanner = new AfterNewGRFScan(&save_config); std::unique_ptr<AfterNewGRFScan> scanner(new AfterNewGRFScan(&save_config));
bool dedicated = false; bool dedicated = false;
char *debuglog_conn = nullptr; char *debuglog_conn = nullptr;
@@ -701,22 +701,18 @@ int openttd_main(int argc, char *argv[])
int i; int i;
while ((i = mgo.GetOpt()) != -1) { while ((i = mgo.GetOpt()) != -1) {
switch (i) { switch (i) {
case 'I': free(graphics_set); graphics_set = stredup(mgo.opt); break; case 'I': graphics_set = mgo.opt; break;
case 'S': free(sounds_set); sounds_set = stredup(mgo.opt); break; case 'S': sounds_set = mgo.opt; break;
case 'M': free(music_set); music_set = stredup(mgo.opt); break; case 'M': music_set = mgo.opt; break;
case 'm': free(musicdriver); musicdriver = stredup(mgo.opt); break; case 'm': musicdriver = mgo.opt; break;
case 's': free(sounddriver); sounddriver = stredup(mgo.opt); break; case 's': sounddriver = mgo.opt; break;
case 'v': free(videodriver); videodriver = stredup(mgo.opt); break; case 'v': videodriver = mgo.opt; break;
case 'b': free(blitter); blitter = stredup(mgo.opt); break; case 'b': blitter = mgo.opt; break;
case 'D': case 'D':
free(musicdriver); musicdriver = "null";
free(sounddriver); sounddriver = "null";
free(videodriver); videodriver = "dedicated";
free(blitter); blitter = "null";
musicdriver = stredup("null");
sounddriver = stredup("null");
videodriver = stredup("dedicated");
blitter = stredup("null");
dedicated = true; dedicated = true;
SetDebugString("net=6"); SetDebugString("net=6");
if (mgo.opt != nullptr) { if (mgo.opt != nullptr) {
@@ -780,7 +776,7 @@ int openttd_main(int argc, char *argv[])
DeterminePaths(argv[0]); DeterminePaths(argv[0]);
if (StrEmpty(mgo.opt)) { if (StrEmpty(mgo.opt)) {
ret = 1; ret = 1;
goto exit_noshutdown; return ret;
} }
char title[80]; char title[80];
@@ -799,7 +795,7 @@ int openttd_main(int argc, char *argv[])
GetString(buf, _load_check_data.error, lastof(buf)); GetString(buf, _load_check_data.error, lastof(buf));
fprintf(stderr, "%s\n", buf); fprintf(stderr, "%s\n", buf);
} }
goto exit_noshutdown; return ret;
} }
if (i == 'q') { if (i == 'q') {
@@ -807,8 +803,7 @@ int openttd_main(int argc, char *argv[])
} else { } else {
WriteSavegameDebugData(title); WriteSavegameDebugData(title);
} }
return ret;
goto exit_noshutdown;
} }
case 'G': scanner->generation_seed = strtoul(mgo.opt, nullptr, 10); break; case 'G': scanner->generation_seed = strtoul(mgo.opt, nullptr, 10); break;
case 'c': free(_config_file); _config_file = stredup(mgo.opt); break; case 'c': free(_config_file); _config_file = stredup(mgo.opt); break;
@@ -816,7 +811,7 @@ int openttd_main(int argc, char *argv[])
case 'J': _quit_after_days = Clamp(atoi(mgo.opt), 0, INT_MAX); break; case 'J': _quit_after_days = Clamp(atoi(mgo.opt), 0, INT_MAX); break;
case 'Z': { case 'Z': {
CrashLog::VersionInfoLog(); CrashLog::VersionInfoLog();
goto exit_noshutdown; return ret;
} }
case 'h': case 'h':
i = -2; // Force printing of help. i = -2; // Force printing of help.
@@ -837,8 +832,7 @@ int openttd_main(int argc, char *argv[])
BaseSounds::FindSets(); BaseSounds::FindSets();
BaseMusic::FindSets(); BaseMusic::FindSets();
ShowHelp(); ShowHelp();
return ret;
goto exit_noshutdown;
} }
DeterminePaths(argv[0]); DeterminePaths(argv[0]);
@@ -881,24 +875,23 @@ int openttd_main(int argc, char *argv[])
InitWindowSystem(); InitWindowSystem();
BaseGraphics::FindSets(); BaseGraphics::FindSets();
if (graphics_set == nullptr && BaseGraphics::ini_set != nullptr) graphics_set = stredup(BaseGraphics::ini_set); if (graphics_set.empty() && !BaseGraphics::ini_set.empty()) graphics_set = BaseGraphics::ini_set;
if (!BaseGraphics::SetSet(graphics_set)) { if (!BaseGraphics::SetSet(graphics_set)) {
if (!StrEmpty(graphics_set)) { if (!graphics_set.empty()) {
BaseGraphics::SetSet(nullptr); BaseGraphics::SetSet({});
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND);
msg.SetDParamStr(0, graphics_set); msg.SetDParamStr(0, graphics_set.c_str());
ScheduleErrorMessage(msg); ScheduleErrorMessage(msg);
} }
} }
free(graphics_set);
/* Initialize game palette */ /* Initialize game palette */
GfxInitPalettes(); GfxInitPalettes();
DEBUG(misc, 1, "Loading blitter..."); DEBUG(misc, 1, "Loading blitter...");
if (blitter == nullptr && _ini_blitter != nullptr) blitter = stredup(_ini_blitter); if (blitter.empty() && !_ini_blitter.empty()) blitter = _ini_blitter;
_blitter_autodetected = StrEmpty(blitter); _blitter_autodetected = blitter.empty();
/* Activate the initial blitter. /* Activate the initial blitter.
* This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one. * This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one.
* - Never guess anything, if the user specified a blitter. (_blitter_autodetected) * - Never guess anything, if the user specified a blitter. (_blitter_autodetected)
@@ -909,16 +902,14 @@ int openttd_main(int argc, char *argv[])
(_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) || (_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) ||
BlitterFactory::SelectBlitter("32bpp-anim") == nullptr) { BlitterFactory::SelectBlitter("32bpp-anim") == nullptr) {
if (BlitterFactory::SelectBlitter(blitter) == nullptr) { if (BlitterFactory::SelectBlitter(blitter) == nullptr) {
StrEmpty(blitter) ? blitter.empty() ?
usererror("Failed to autoprobe blitter") : usererror("Failed to autoprobe blitter") :
usererror("Failed to select requested blitter '%s'; does it exist?", blitter); usererror("Failed to select requested blitter '%s'; does it exist?", blitter.c_str());
} }
} }
free(blitter);
if (videodriver == nullptr && _ini_videodriver != nullptr) videodriver = stredup(_ini_videodriver); if (videodriver.empty() && !_ini_videodriver.empty()) videodriver = _ini_videodriver;
DriverFactoryBase::SelectDriver(videodriver, Driver::DT_VIDEO); DriverFactoryBase::SelectDriver(videodriver, Driver::DT_VIDEO);
free(videodriver);
InitializeSpriteSorter(); InitializeSpriteSorter();
@@ -942,8 +933,7 @@ int openttd_main(int argc, char *argv[])
if (!HandleBootstrap()) { if (!HandleBootstrap()) {
ShutdownGame(); ShutdownGame();
return ret;
goto exit_bootstrap;
} }
VideoDriver::GetInstance()->ClaimMousePointer(); VideoDriver::GetInstance()->ClaimMousePointer();
@@ -952,38 +942,34 @@ int openttd_main(int argc, char *argv[])
InitializeScreenshotFormats(); InitializeScreenshotFormats();
BaseSounds::FindSets(); BaseSounds::FindSets();
if (sounds_set == nullptr && BaseSounds::ini_set != nullptr) sounds_set = stredup(BaseSounds::ini_set); if (sounds_set.empty() && !BaseSounds::ini_set.empty()) sounds_set = BaseSounds::ini_set;
if (!BaseSounds::SetSet(sounds_set)) { if (!BaseSounds::SetSet(sounds_set)) {
if (StrEmpty(sounds_set) || !BaseSounds::SetSet(nullptr)) { if (sounds_set.empty() || !BaseSounds::SetSet({})) {
usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md."); usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md.");
} else { } else {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND);
msg.SetDParamStr(0, sounds_set); msg.SetDParamStr(0, sounds_set.c_str());
ScheduleErrorMessage(msg); ScheduleErrorMessage(msg);
} }
} }
free(sounds_set);
BaseMusic::FindSets(); BaseMusic::FindSets();
if (music_set == nullptr && BaseMusic::ini_set != nullptr) music_set = stredup(BaseMusic::ini_set); if (music_set.empty() && !BaseMusic::ini_set.empty()) music_set = BaseMusic::ini_set;
if (!BaseMusic::SetSet(music_set)) { if (!BaseMusic::SetSet(music_set)) {
if (StrEmpty(music_set) || !BaseMusic::SetSet(nullptr)) { if (music_set.empty() || !BaseMusic::SetSet({})) {
usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md."); usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md.");
} else { } else {
ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND);
msg.SetDParamStr(0, music_set); msg.SetDParamStr(0, music_set.c_str());
ScheduleErrorMessage(msg); ScheduleErrorMessage(msg);
} }
} }
free(music_set);
if (sounddriver == nullptr && _ini_sounddriver != nullptr) sounddriver = stredup(_ini_sounddriver); if (sounddriver.empty() && !_ini_sounddriver.empty()) sounddriver = _ini_sounddriver;
DriverFactoryBase::SelectDriver(sounddriver, Driver::DT_SOUND); DriverFactoryBase::SelectDriver(sounddriver, Driver::DT_SOUND);
free(sounddriver);
if (musicdriver == nullptr && _ini_musicdriver != nullptr) musicdriver = stredup(_ini_musicdriver); if (musicdriver.empty() && !_ini_musicdriver.empty()) musicdriver = _ini_musicdriver;
DriverFactoryBase::SelectDriver(musicdriver, Driver::DT_MUSIC); DriverFactoryBase::SelectDriver(musicdriver, Driver::DT_MUSIC);
free(musicdriver);
/* Take our initial lock on whatever we might want to do! */ /* Take our initial lock on whatever we might want to do! */
try { try {
@@ -1003,8 +989,7 @@ int openttd_main(int argc, char *argv[])
CheckForMissingGlyphs(); CheckForMissingGlyphs();
/* ScanNewGRFFiles now has control over the scanner. */ /* ScanNewGRFFiles now has control over the scanner. */
ScanNewGRFFiles(scanner); ScanNewGRFFiles(scanner.release());
scanner = nullptr;
VideoDriver::GetInstance()->MainLoop(); VideoDriver::GetInstance()->MainLoop();
@@ -1023,38 +1008,6 @@ int openttd_main(int argc, char *argv[])
/* Reset windowing system, stop drivers, free used memory, ... */ /* Reset windowing system, stop drivers, free used memory, ... */
ShutdownGame(); ShutdownGame();
goto exit_normal;
exit_noshutdown:
/* These three are normally freed before bootstrap. */
free(graphics_set);
free(videodriver);
free(blitter);
exit_bootstrap:
/* These are normally freed before exit, but after bootstrap. */
free(sounds_set);
free(music_set);
free(musicdriver);
free(sounddriver);
exit_normal:
free(BaseGraphics::ini_set);
free(BaseSounds::ini_set);
free(BaseMusic::ini_set);
free(_ini_musicdriver);
free(_ini_sounddriver);
free(_ini_videodriver);
free(_ini_blitter);
delete scanner;
extern FILE *_log_fd;
if (_log_fd != nullptr) {
fclose(_log_fd);
}
return ret; return ret;
} }
@@ -1324,9 +1277,9 @@ void SwitchToMode(SwitchMode new_mode)
case SM_MENU: // Switch to game intro menu case SM_MENU: // Switch to game intro menu
LoadIntroGame(); LoadIntroGame();
if (BaseSounds::ini_set == nullptr && BaseSounds::GetUsedSet()->fallback) { if (BaseSounds::ini_set.empty() && BaseSounds::GetUsedSet()->fallback) {
ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL); ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL);
BaseSounds::ini_set = stredup(BaseSounds::GetUsedSet()->name); BaseSounds::ini_set = BaseSounds::GetUsedSet()->name;
} }
break; break;

View File

@@ -1360,7 +1360,7 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
item->SetDimension(d); item->SetDimension(d);
item->SetParam(0, rti->strings.menu_text); item->SetParam(0, rti->strings.menu_text);
item->SetParam(1, rti->max_speed); item->SetParam(1, rti->max_speed / 2);
list.emplace_back(item); list.emplace_back(item);
} }

View File

@@ -722,20 +722,20 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(SLV_84)) { if (IsSavegameVersionBefore(SLV_84)) {
for (Company *c : Company::Iterate()) { for (Company *c : Company::Iterate()) {
c->name = CopyFromOldName(c->name_1); c->name = CopyFromOldName(c->name_1);
if (c->name != nullptr) c->name_1 = STR_SV_UNNAMED; if (!c->name.empty()) c->name_1 = STR_SV_UNNAMED;
c->president_name = CopyFromOldName(c->president_name_1); c->president_name = CopyFromOldName(c->president_name_1);
if (c->president_name != nullptr) c->president_name_1 = SPECSTR_PRESIDENT_NAME; if (!c->president_name.empty()) c->president_name_1 = SPECSTR_PRESIDENT_NAME;
} }
for (Station *st : Station::Iterate()) { for (Station *st : Station::Iterate()) {
st->name = CopyFromOldName(st->string_id); st->name = CopyFromOldName(st->string_id);
/* generating new name would be too much work for little effect, use the station name fallback */ /* generating new name would be too much work for little effect, use the station name fallback */
if (st->name != nullptr) st->string_id = STR_SV_STNAME_FALLBACK; if (!st->name.empty()) st->string_id = STR_SV_STNAME_FALLBACK;
} }
for (Town *t : Town::Iterate()) { for (Town *t : Town::Iterate()) {
t->name = CopyFromOldName(t->townnametype); t->name = CopyFromOldName(t->townnametype);
if (t->name != nullptr) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name; if (!t->name.empty()) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
} }
} }
@@ -2780,11 +2780,11 @@ bool AfterLoadGame()
* highest possible number to get them numbered in the * highest possible number to get them numbered in the
* order they have in the pool. */ * order they have in the pool. */
for (Waypoint *wp : Waypoint::Iterate()) { for (Waypoint *wp : Waypoint::Iterate()) {
if (wp->name != nullptr) wp->town_cn = UINT16_MAX; if (!wp->name.empty()) wp->town_cn = UINT16_MAX;
} }
for (Waypoint* wp : Waypoint::Iterate()) { for (Waypoint* wp : Waypoint::Iterate()) {
if (wp->name != nullptr) MakeDefaultName(wp); if (!wp->name.empty()) MakeDefaultName(wp);
} }
} }

View File

@@ -240,11 +240,11 @@ void AfterLoadCompanyStats()
static const SaveLoad _company_desc[] = { static const SaveLoad _company_desc[] = {
SLE_VAR(CompanyProperties, name_2, SLE_UINT32), SLE_VAR(CompanyProperties, name_2, SLE_UINT32),
SLE_VAR(CompanyProperties, name_1, SLE_STRINGID), SLE_VAR(CompanyProperties, name_1, SLE_STRINGID),
SLE_CONDSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID), SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID),
SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32), SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32),
SLE_CONDSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, face, SLE_UINT32), SLE_VAR(CompanyProperties, face, SLE_UINT32),
@@ -530,7 +530,7 @@ static void Check_PLYR()
} }
} }
if (cprops->name == nullptr && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) &&
cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED && cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED &&
cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME && cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME &&
cprops->name_1 != SPECSTR_SILLY_NAME) { cprops->name_1 != SPECSTR_SILLY_NAME) {

View File

@@ -23,7 +23,7 @@ static const SaveLoad _depot_desc[] = {
SLEG_CONDVAR(_town_index, SLE_UINT16, SL_MIN_VERSION, SLV_141), SLEG_CONDVAR(_town_index, SLE_UINT16, SL_MIN_VERSION, SLV_141),
SLE_CONDREF(Depot, town, REF_TOWN, SLV_141, SL_MAX_VERSION), SLE_CONDREF(Depot, town, REF_TOWN, SLV_141, SL_MAX_VERSION),
SLE_CONDVAR(Depot, town_cn, SLE_UINT16, SLV_141, SL_MAX_VERSION), SLE_CONDVAR(Depot, town_cn, SLE_UINT16, SLV_141, SL_MAX_VERSION),
SLE_CONDSTR(Depot, name, SLE_STR, 0, SLV_141, SL_MAX_VERSION), SLE_CONDSSTR(Depot, name, SLE_STR, SLV_141, SL_MAX_VERSION),
SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION), SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 5)), SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 5)),
SLE_END() SLE_END()

View File

@@ -39,7 +39,7 @@ static const SaveLoad _engine_desc[] = {
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION), SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION), SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION),
SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION),
SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space
@@ -137,7 +137,7 @@ void CopyTempEngineData()
e->preview_wait = se->preview_wait; e->preview_wait = se->preview_wait;
e->company_avail = se->company_avail; e->company_avail = se->company_avail;
e->company_hidden = se->company_hidden; e->company_hidden = se->company_hidden;
if (se->name != nullptr) e->name = stredup(se->name); e->name = se->name;
} }
ResetTempEngineData(); ResetTempEngineData();

View File

@@ -113,23 +113,23 @@ static void Save_GSDT()
extern GameStrings *_current_data; extern GameStrings *_current_data;
static const char *_game_saveload_string; static std::string _game_saveload_string;
static uint _game_saveload_strings; static uint _game_saveload_strings;
static const SaveLoad _game_language_header[] = { static const SaveLoad _game_language_header[] = {
SLEG_STR(_game_saveload_string, SLE_STR), SLEG_SSTR(_game_saveload_string, SLE_STR),
SLEG_VAR(_game_saveload_strings, SLE_UINT32), SLEG_VAR(_game_saveload_strings, SLE_UINT32),
SLE_END() SLE_END()
}; };
static const SaveLoad _game_language_string[] = { static const SaveLoad _game_language_string[] = {
SLEG_STR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL), SLEG_SSTR(_game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL),
SLE_END() SLE_END()
}; };
static void SaveReal_GSTR(const LanguageStrings *ls) static void SaveReal_GSTR(const LanguageStrings *ls)
{ {
_game_saveload_string = ls->language; _game_saveload_string = ls->language.c_str();
_game_saveload_strings = (uint)ls->lines.size(); _game_saveload_strings = (uint)ls->lines.size();
SlObject(nullptr, _game_language_header); SlObject(nullptr, _game_language_header);
@@ -145,13 +145,13 @@ static void Load_GSTR()
_current_data = new GameStrings(); _current_data = new GameStrings();
while (SlIterateArray() != -1) { while (SlIterateArray() != -1) {
_game_saveload_string = nullptr; _game_saveload_string.clear();
SlObject(nullptr, _game_language_header); SlObject(nullptr, _game_language_header);
std::unique_ptr<LanguageStrings> ls(new LanguageStrings(_game_saveload_string != nullptr ? _game_saveload_string : "")); LanguageStrings ls(_game_saveload_string);
for (uint i = 0; i < _game_saveload_strings; i++) { for (uint i = 0; i < _game_saveload_strings; i++) {
SlObject(nullptr, _game_language_string); SlObject(nullptr, _game_language_string);
ls->lines.emplace_back(_game_saveload_string != nullptr ? _game_saveload_string : ""); ls.lines.emplace_back(_game_saveload_string);
} }
_current_data->raw_strings.push_back(std::move(ls)); _current_data->raw_strings.push_back(std::move(ls));
@@ -174,7 +174,7 @@ static void Save_GSTR()
for (uint i = 0; i < _current_data->raw_strings.size(); i++) { for (uint i = 0; i < _current_data->raw_strings.size(); i++) {
SlSetArrayIndex(i); SlSetArrayIndex(i);
SlAutolength((AutolengthProc *)SaveReal_GSTR, _current_data->raw_strings[i].get()); SlAutolength((AutolengthProc *)SaveReal_GSTR, &_current_data->raw_strings[i]);
} }
} }

View File

@@ -17,7 +17,7 @@
static const SaveLoad _group_desc[] = { static const SaveLoad _group_desc[] = {
SLE_CONDVAR(Group, name, SLE_NAME, SL_MIN_VERSION, SLV_84), SLE_CONDVAR(Group, name, SLE_NAME, SL_MIN_VERSION, SLV_84),
SLE_CONDSTR(Group, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(Group, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_164), // num_vehicle SLE_CONDNULL(2, SL_MIN_VERSION, SLV_164), // num_vehicle
SLE_VAR(Group, owner, SLE_UINT8), SLE_VAR(Group, owner, SLE_UINT8),
SLE_VAR(Group, vehicle_type, SLE_UINT8), SLE_VAR(Group, vehicle_type, SLE_UINT8),

View File

@@ -19,8 +19,8 @@ static const SaveLoad _plan_desc[] = {
SLE_VAR(Plan, visible, SLE_BOOL), SLE_VAR(Plan, visible, SLE_BOOL),
SLE_VAR(Plan, visible_by_all, SLE_BOOL), SLE_VAR(Plan, visible_by_all, SLE_BOOL),
SLE_VAR(Plan, creation_date, SLE_INT32), SLE_VAR(Plan, creation_date, SLE_INT32),
SLE_CONDSTDSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)), SLE_CONDSSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)),
SLE_CONDSTDSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)), SLE_CONDSSSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)),
SLE_END() SLE_END()
}; };

View File

@@ -44,6 +44,7 @@
#include "../fios.h" #include "../fios.h"
#include "../error.h" #include "../error.h"
#include <atomic> #include <atomic>
#include <string>
#include "../tbtr_template_vehicle.h" #include "../tbtr_template_vehicle.h"
@@ -891,7 +892,7 @@ void WriteValue(void *ptr, VarType conv, int64 val)
case SLE_VAR_U32: *(uint32*)ptr = val; break; case SLE_VAR_U32: *(uint32*)ptr = val; break;
case SLE_VAR_I64: *(int64 *)ptr = val; break; case SLE_VAR_I64: *(int64 *)ptr = val; break;
case SLE_VAR_U64: *(uint64*)ptr = val; break; case SLE_VAR_U64: *(uint64*)ptr = val; break;
case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break; case SLE_VAR_NAME: *reinterpret_cast<std::string *>(ptr) = CopyFromOldName(val); break;
case SLE_VAR_NULL: break; case SLE_VAR_NULL: break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
@@ -1110,8 +1111,8 @@ static void SlString(void *ptr, size_t length, VarType conv)
} }
/** /**
* Save/Load a std::string. * Save/Load a \c std::string.
* @param ptr the std::string being manipulated * @param ptr the string being manipulated
* @param conv must be SLE_FILE_STRING * @param conv must be SLE_FILE_STRING
*/ */
static void SlStdString(std::string &str, VarType conv) static void SlStdString(std::string &str, VarType conv)
@@ -1131,11 +1132,15 @@ static void SlStdString(std::string &str, VarType conv)
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK; StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
if ((conv & SLF_ALLOW_CONTROL) != 0) { if ((conv & SLF_ALLOW_CONTROL) != 0) {
settings = settings | SVS_ALLOW_CONTROL_CODE; settings = settings | SVS_ALLOW_CONTROL_CODE;
if (IsSavegameVersionBefore(SLV_169)) {
char *buf = const_cast<char *>(str.c_str());
str.resize(str_fix_scc_encoded(buf, buf + str.size()) - buf);
}
} }
if ((conv & SLF_ALLOW_NEWLINE) != 0) { if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE; settings = settings | SVS_ALLOW_NEWLINE;
} }
str_validate(str, settings); str_validate_inplace(str, settings);
break; break;
} }
case SLA_PTRS: break; case SLA_PTRS: break;
@@ -1692,6 +1697,8 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
case SLE_VAR_I64: case SLE_VAR_I64:
case SLE_VAR_U64: case SLE_VAR_U64:
return sld->size == sizeof(int64); return sld->size == sizeof(int64);
case SLE_VAR_NAME:
return sld->size == sizeof(std::string);
default: default:
return sld->size == sizeof(void *); return sld->size == sizeof(void *);
} }
@@ -1704,6 +1711,7 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
return sld->size == sizeof(void *) || sld->size == sld->length; return sld->size == sizeof(void *) || sld->size == sld->length;
case SL_STDSTR: case SL_STDSTR:
/* These should be all pointers to std::string. */
return sld->size == sizeof(std::string); return sld->size == sizeof(std::string);
default: default:

View File

@@ -620,7 +620,7 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest()) #define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest())
/** /**
* Storage of a std::string in some savegame versions. * Storage of a \c std::string in some savegame versions.
* @param base Name of the class or struct containing the string. * @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base. * @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame. * @param type Storage of the data in memory and in the savegame.
@@ -628,8 +628,8 @@ typedef SaveLoad SaveLoadGlobVarList;
* @param to Last savegame version that has the string. * @param to Last savegame version that has the string.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field * @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/ */
#define SLE_CONDSTDSTR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_STDSTR, base, variable, type, 0, from, to, extver) #define SLE_CONDSSSTR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_STDSTR, base, variable, type, 0, from, to, extver)
#define SLE_CONDSTDSTR(base, variable, type, from, to) SLE_CONDSTDSTR_X(base, variable, type, from, to, SlXvFeatureTest()) #define SLE_CONDSSTR(base, variable, type, from, to) SLE_GENERAL(SL_STDSTR, base, variable, type, 0, from, to)
/** /**
* Storage of a list in some savegame versions. * Storage of a list in some savegame versions.
@@ -726,12 +726,12 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, SL_MIN_VERSION, SL_MAX_VERSION) #define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
/** /**
* Storage of a std::string in every savegame version. * Storage of a \c std::string in every savegame version.
* @param base Name of the class or struct containing the string. * @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base. * @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame. * @param type Storage of the data in memory and in the savegame.
*/ */
#define SLE_STDSTR(base, variable, type) SLE_CONDSTDSTR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) #define SLE_SSTR(base, variable, type) SLE_CONDSSTR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/** /**
* Storage of a list in every savegame version. * Storage of a list in every savegame version.
@@ -841,6 +841,15 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLEG_CONDSTR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_STR, variable, type, length, from, to, extver) #define SLEG_CONDSTR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_STR, variable, type, length, from, to, extver)
#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, SlXvFeatureTest()) #define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a global \c std::string in some savegame versions.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the string.
* @param to Last savegame version that has the string.
*/
#define SLEG_CONDSSTR(variable, type, from, to) SLEG_GENERAL(SL_STDSTR, variable, type, 0, from, to)
/** /**
* Storage of a global list in some savegame versions. * Storage of a global list in some savegame versions.
* @param variable Name of the global variable. * @param variable Name of the global variable.
@@ -902,6 +911,13 @@ typedef SaveLoad SaveLoadGlobVarList;
*/ */
#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION) #define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global \c std::string in every savegame version.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_SSTR(variable, type) SLEG_CONDSSTR(variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/** /**
* Storage of a global list in every savegame version. * Storage of a global list in every savegame version.
* @param variable Name of the global variable. * @param variable Name of the global variable.

View File

@@ -17,7 +17,7 @@
void InitializeOldNames(); void InitializeOldNames();
StringID RemapOldStringID(StringID s); StringID RemapOldStringID(StringID s);
char *CopyFromOldName(StringID id); std::string CopyFromOldName(StringID id);
void ResetOldNames(); void ResetOldNames();
void ResetOldWaypoints(); void ResetOldWaypoints();

View File

@@ -18,7 +18,7 @@
/** Description of a sign within the savegame. */ /** Description of a sign within the savegame. */
static const SaveLoad _sign_desc[] = { static const SaveLoad _sign_desc[] = {
SLE_CONDVAR(Sign, name, SLE_NAME, SL_MIN_VERSION, SLV_84), SLE_CONDVAR(Sign, name, SLE_NAME, SL_MIN_VERSION, SLV_84),
SLE_CONDSTR(Sign, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(Sign, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5), SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5), SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Sign, x, SLE_INT32, SLV_5, SL_MAX_VERSION), SLE_CONDVAR(Sign, x, SLE_INT32, SLV_5, SL_MAX_VERSION),

View File

@@ -65,8 +65,7 @@ void MoveBuoysToWaypoints()
TileIndex xy = st->xy; TileIndex xy = st->xy;
Town *town = st->town; Town *town = st->town;
StringID string_id = st->string_id; StringID string_id = st->string_id;
char *name = st->name; std::string name = st->name;
st->name = nullptr;
Date build_date = st->build_date; Date build_date = st->build_date;
/* TTDPatch could use "buoys with rail station" for rail waypoints */ /* TTDPatch could use "buoys with rail station" for rail waypoints */
bool train = st->train_station.tile != INVALID_TILE; bool train = st->train_station.tile != INVALID_TILE;
@@ -179,7 +178,7 @@ static const SaveLoad _old_station_desc[] = {
SLE_CONDNULL(1, SL_MIN_VERSION, SLV_4), ///< alpha_order SLE_CONDNULL(1, SL_MIN_VERSION, SLV_4), ///< alpha_order
SLE_VAR(Station, string_id, SLE_STRINGID), SLE_VAR(Station, string_id, SLE_STRINGID),
SLE_CONDSTR(Station, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(Station, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_CONDVAR(Station, indtype, SLE_UINT8, SLV_103, SL_MAX_VERSION), SLE_CONDVAR(Station, indtype, SLE_UINT8, SLV_103, SL_MAX_VERSION),
SLE_CONDVAR(Station, had_vehicle_of_type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_122), SLE_CONDVAR(Station, had_vehicle_of_type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_122),
SLE_CONDVAR(Station, had_vehicle_of_type, SLE_UINT8, SLV_122, SL_MAX_VERSION), SLE_CONDVAR(Station, had_vehicle_of_type, SLE_UINT8, SLV_122, SL_MAX_VERSION),
@@ -400,7 +399,7 @@ static const SaveLoad _base_station_desc[] = {
SLE_VAR(BaseStation, xy, SLE_UINT32), SLE_VAR(BaseStation, xy, SLE_UINT32),
SLE_REF(BaseStation, town, REF_TOWN), SLE_REF(BaseStation, town, REF_TOWN),
SLE_VAR(BaseStation, string_id, SLE_STRINGID), SLE_VAR(BaseStation, string_id, SLE_STRINGID),
SLE_STR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL, 0), SLE_SSTR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL),
SLE_CONDVAR_X(Station, delete_ctr, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 0, 3)), SLE_CONDVAR_X(Station, delete_ctr, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 0, 3)),
SLE_CONDVAR_X(Station, delete_ctr, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 4)), SLE_CONDVAR_X(Station, delete_ctr, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP, 4)),
SLE_VAR(BaseStation, owner, SLE_UINT8), SLE_VAR(BaseStation, owner, SLE_UINT8),

Some files were not shown because too many files have changed in this diff Show More