mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
37 Commits
c1a0662c1b
...
b0fab1558a
Author | SHA1 | Date |
---|---|---|
|
b0fab1558a | |
|
eaae762189 | |
|
29b41df46a | |
|
7bb4940ebd | |
|
b8e56cd05d | |
|
df5237e721 | |
|
03f5f7145f | |
|
0dc40877fd | |
|
03672ed8eb | |
|
1b01a0636c | |
|
bccbd64037 | |
|
434163aa31 | |
|
55605ae8f2 | |
|
7f792e9c5f | |
|
6b6caa6fa8 | |
|
67e56391c7 | |
|
e015e3ecc3 | |
|
8330957a4d | |
|
9ce2aca949 | |
|
55098a2f2e | |
|
7ff0c67f77 | |
|
b2de1ff66f | |
|
fc924161ab | |
|
61a299bc99 | |
|
7546c1acab | |
|
a6143eea21 | |
|
1d38cbafcb | |
|
992d58d799 | |
|
8f34b7a821 | |
|
bf6d0c4934 | |
|
3c4fb21a5e | |
|
baced00e9f | |
|
aaf5d39b15 | |
|
7db135099a | |
|
290144c5c9 | |
|
9b55ad5b8d | |
|
f6e78a480d |
|
@ -0,0 +1,50 @@
|
||||||
|
name: 'Setup vcpkg'
|
||||||
|
description: 'Installs vcpkg and initialises binary caching via NuGet'
|
||||||
|
inputs:
|
||||||
|
vcpkg-location:
|
||||||
|
description: 'Where to install vcpkg'
|
||||||
|
required: true
|
||||||
|
mono-install-command:
|
||||||
|
description: 'Command to run to install mono'
|
||||||
|
required: false
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Install vcpkg
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/microsoft/vcpkg "${{ inputs.vcpkg-location }}"
|
||||||
|
cd "${{ inputs.vcpkg-location }}"
|
||||||
|
./bootstrap-vcpkg.$(if [ "${{ runner.os }}" = "Windows" ]; then echo "bat"; else echo "sh"; fi) -disableMetrics
|
||||||
|
|
||||||
|
- name: Install mono
|
||||||
|
if: inputs.mono-install-command
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
${{ inputs.mono-install-command }}
|
||||||
|
echo "MONO=mono" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Setup NuGet Credentials
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
FEED_URL: 'https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json'
|
||||||
|
run: |
|
||||||
|
cd "${{ inputs.vcpkg-location }}"
|
||||||
|
${{ env.MONO }} $(./vcpkg fetch nuget | tail -n 1) \
|
||||||
|
sources add \
|
||||||
|
-source "${{ env.FEED_URL }}" \
|
||||||
|
-storepasswordincleartext \
|
||||||
|
-name "GitHub" \
|
||||||
|
-username "${{ github.repository_owner }}" \
|
||||||
|
-password "${{ github.token }}"
|
||||||
|
${{ env.MONO }} $(./vcpkg fetch nuget | tail -n 1) \
|
||||||
|
setapikey "${{ github.token }}" \
|
||||||
|
-source "${{ env.FEED_URL }}"
|
||||||
|
|
||||||
|
- name: Setup vcpkg caching
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;nuget,GitHub,readwrite')
|
||||||
|
|
|
@ -32,18 +32,11 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
- name: Setup vcpkg
|
||||||
uses: actions/github-script@v7
|
uses: ./.github/actions/setup-vcpkg
|
||||||
with:
|
with:
|
||||||
script: |
|
vcpkg-location: ${{ runner.temp }}/vcpkg
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
mono-install-command: 'sudo apt-get install -y --no-install-recommends mono-complete'
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install vcpkg
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
|
||||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -34,18 +34,11 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
- name: Setup vcpkg
|
||||||
uses: actions/github-script@v7
|
uses: ./.github/actions/setup-vcpkg
|
||||||
with:
|
with:
|
||||||
script: |
|
vcpkg-location: ${{ runner.temp }}/vcpkg
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
mono-install-command: 'brew install mono'
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install vcpkg
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
|
||||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
|
||||||
|
|
||||||
- name: Install OpenGFX
|
- name: Install OpenGFX
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -15,23 +15,17 @@ jobs:
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
- name: Setup vcpkg
|
||||||
uses: actions/github-script@v7
|
uses: ./.github/actions/setup-vcpkg
|
||||||
with:
|
with:
|
||||||
script: |
|
vcpkg-location: ${{ runner.temp }}/vcpkg
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install vcpkg
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}\vcpkg
|
|
||||||
${{ runner.temp }}\vcpkg\bootstrap-vcpkg.bat -disableMetrics
|
|
||||||
|
|
||||||
- name: Install OpenGFX
|
- name: Install OpenGFX
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
@ -21,23 +21,17 @@ jobs:
|
||||||
actions: read
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
security-events: write
|
security-events: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
- name: Setup vcpkg
|
||||||
uses: actions/github-script@v7
|
uses: ./.github/actions/setup-vcpkg
|
||||||
with:
|
with:
|
||||||
script: |
|
vcpkg-location: ${{ runner.temp }}/vcpkg
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
mono-install-command: 'sudo apt-get install -y --no-install-recommends mono-complete'
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install vcpkg
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
|
||||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -35,14 +35,6 @@ jobs:
|
||||||
- name: Enable Rust cache
|
- name: Enable Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
echo "::group::Install system dependencies"
|
echo "::group::Install system dependencies"
|
||||||
|
@ -113,20 +105,16 @@ jobs:
|
||||||
# EOF
|
# EOF
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
# We use vcpkg for our dependencies, to get more up-to-date version.
|
|
||||||
echo "::group::Install vcpkg and dependencies"
|
|
||||||
|
|
||||||
git clone https://github.com/microsoft/vcpkg /vcpkg
|
|
||||||
|
|
||||||
(
|
|
||||||
cd /vcpkg
|
|
||||||
./bootstrap-vcpkg.sh -disableMetrics
|
|
||||||
)
|
|
||||||
|
|
||||||
echo "::group::Install breakpad dependencies"
|
echo "::group::Install breakpad dependencies"
|
||||||
cargo install --locked dump_syms
|
cargo install --locked dump_syms
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
- name: Setup vcpkg
|
||||||
|
uses: ./.github/actions/setup-vcpkg
|
||||||
|
with:
|
||||||
|
vcpkg-location: /vcpkg
|
||||||
|
mono-install-command: 'yum install -y mono-complete'
|
||||||
|
|
||||||
- name: Install GCC problem matcher
|
- name: Install GCC problem matcher
|
||||||
uses: ammaraskar/gcc-problem-matcher@master
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
|
|
@ -37,18 +37,11 @@ jobs:
|
||||||
- name: Enable Rust cache
|
- name: Enable Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
- name: Setup vcpkg
|
||||||
uses: actions/github-script@v7
|
uses: ./.github/actions/setup-vcpkg
|
||||||
with:
|
with:
|
||||||
script: |
|
vcpkg-location: ${{ runner.temp }}/vcpkg
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
mono-install-command: 'brew install mono'
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install vcpkg
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}/vcpkg
|
|
||||||
${{ runner.temp }}/vcpkg/bootstrap-vcpkg.sh -disableMetrics
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -45,18 +45,10 @@ jobs:
|
||||||
- name: Enable Rust cache
|
- name: Enable Rust cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
- name: Setup vcpkg caching
|
- name: Setup vcpkg
|
||||||
uses: actions/github-script@v7
|
uses: ./.github/actions/setup-vcpkg
|
||||||
with:
|
with:
|
||||||
script: |
|
vcpkg-location: ${{ runner.temp }}/vcpkg
|
||||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
||||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
||||||
core.exportVariable('VCPKG_BINARY_SOURCES', 'clear;x-gha,readwrite')
|
|
||||||
|
|
||||||
- name: Install vcpkg
|
|
||||||
run: |
|
|
||||||
git clone https://github.com/microsoft/vcpkg ${{ runner.temp }}\vcpkg
|
|
||||||
${{ runner.temp }}\vcpkg\bootstrap-vcpkg.bat -disableMetrics
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
@ -36,3 +36,11 @@ AITown.FoundTown <- function(tile, size, city, layout, name) { return AITown.Fou
|
||||||
|
|
||||||
AIVehicle.SetNameCompat14 <- AIVehicle.SetName;
|
AIVehicle.SetNameCompat14 <- AIVehicle.SetName;
|
||||||
AIVehicle.SetName <- function(id, name) { return AIVehicle.SetNameCompat14(id, AICompat14.Text(name)); }
|
AIVehicle.SetName <- function(id, name) { return AIVehicle.SetNameCompat14(id, AICompat14.Text(name)); }
|
||||||
|
|
||||||
|
AIObject.constructorCompat14 <- AIObject.constructor;
|
||||||
|
foreach(name, object in CompatScriptRootTable) {
|
||||||
|
if (type(object) != "class") continue;
|
||||||
|
if (!object.rawin("constructor")) continue;
|
||||||
|
if (object.constructor != AIObject.constructorCompat14) continue;
|
||||||
|
object.constructor <- function() : (name) { AILog.Error("'" + name + "' is not instantiable"); }
|
||||||
|
}
|
||||||
|
|
|
@ -81,3 +81,11 @@ GSTown.FoundTown <- function(tile, size, city, layout, name) { return GSTown.Fou
|
||||||
|
|
||||||
GSVehicle.SetNameCompat14 <- GSVehicle.SetName;
|
GSVehicle.SetNameCompat14 <- GSVehicle.SetName;
|
||||||
GSVehicle.SetName <- function(id, name) { return GSVehicle.SetNameCompat14(id, GSCompat14.Text(name)); }
|
GSVehicle.SetName <- function(id, name) { return GSVehicle.SetNameCompat14(id, GSCompat14.Text(name)); }
|
||||||
|
|
||||||
|
GSObject.constructorCompat14 <- GSObject.constructor;
|
||||||
|
foreach(name, object in CompatScriptRootTable) {
|
||||||
|
if (type(object) != "class") continue;
|
||||||
|
if (!object.rawin("constructor")) continue;
|
||||||
|
if (object.constructor != GSObject.constructorCompat14) continue;
|
||||||
|
object.constructor <- function() : (name) { GSLog.Error("'" + name + "' is not instantiable"); }
|
||||||
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ template <> SQInteger PushClassName<AIInfo, ScriptType::AI>(HSQUIRRELVM vm) { sq
|
||||||
/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
|
/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
|
||||||
sq_setinstanceup(vm, 2, nullptr);
|
sq_setinstanceup(vm, 2, nullptr);
|
||||||
/* Register the AI to the base system */
|
/* Register the AI to the base system */
|
||||||
info->GetScanner()->RegisterScript(info);
|
info->GetScanner()->RegisterScript(std::unique_ptr<AIInfo>{info});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,22 +136,21 @@ bool AIInfo::CanLoadFromVersion(int version) const
|
||||||
/* static */ SQInteger AILibrary::Constructor(HSQUIRRELVM vm)
|
/* static */ SQInteger AILibrary::Constructor(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
/* Create a new library */
|
/* Create a new library */
|
||||||
AILibrary *library = new AILibrary();
|
auto library = std::make_unique<AILibrary>();
|
||||||
|
|
||||||
SQInteger res = ScriptInfo::Constructor(vm, *library);
|
SQInteger res = ScriptInfo::Constructor(vm, *library);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
delete library;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cache the category */
|
/* Cache the category */
|
||||||
if (!library->CheckMethod("GetCategory") || !library->engine->CallStringMethod(library->SQ_instance, "GetCategory", &library->category, MAX_GET_OPS)) {
|
if (!library->CheckMethod("GetCategory") || !library->engine->CallStringMethod(library->SQ_instance, "GetCategory", &library->category, MAX_GET_OPS)) {
|
||||||
delete library;
|
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the Library to the base system */
|
/* Register the Library to the base system */
|
||||||
library->GetScanner()->RegisterScript(library);
|
ScriptScanner *scanner = library->GetScanner();
|
||||||
|
scanner->RegisterScript(std::move(library));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ void AIInstance::Died()
|
||||||
|
|
||||||
void AIInstance::LoadDummyScript()
|
void AIInstance::LoadDummyScript()
|
||||||
{
|
{
|
||||||
ScriptAllocatorScope alloc_scope(this->engine);
|
ScriptAllocatorScope alloc_scope(this->engine.get());
|
||||||
Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI");
|
Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ void AIScannerInfo::Initialize()
|
||||||
{
|
{
|
||||||
ScriptScanner::Initialize("AIScanner");
|
ScriptScanner::Initialize("AIScanner");
|
||||||
|
|
||||||
ScriptAllocatorScope alloc_scope(this->engine);
|
ScriptAllocatorScope alloc_scope(this->engine.get());
|
||||||
|
|
||||||
/* Create the dummy AI */
|
/* Create the dummy AI */
|
||||||
this->main_script = "%_dummy";
|
this->main_script = "%_dummy";
|
||||||
|
|
|
@ -1125,6 +1125,15 @@ static bool AircraftController(Aircraft *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amd.flags.Test(AirportMovingDataFlag::Land)) {
|
if (amd.flags.Test(AirportMovingDataFlag::Land)) {
|
||||||
|
if (st->airport.blocks.Test(AirportBlock::Zeppeliner)) {
|
||||||
|
/* Zeppeliner blocked the runway, abort landing */
|
||||||
|
v->state = FLYING;
|
||||||
|
UpdateAircraftCache(v);
|
||||||
|
SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlightLevel(v));
|
||||||
|
v->pos = v->previous_pos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (st->airport.tile == INVALID_TILE) {
|
if (st->airport.tile == INVALID_TILE) {
|
||||||
/* Airport has been removed, abort the landing procedure */
|
/* Airport has been removed, abort the landing procedure */
|
||||||
v->state = FLYING;
|
v->state = FLYING;
|
||||||
|
@ -1782,6 +1791,11 @@ static void AirportClearBlock(const Aircraft *v, const AirportFTAClass *apc)
|
||||||
if (apc->layout[v->previous_pos].blocks != apc->layout[v->pos].blocks) {
|
if (apc->layout[v->previous_pos].blocks != apc->layout[v->pos].blocks) {
|
||||||
Station *st = Station::Get(v->targetairport);
|
Station *st = Station::Get(v->targetairport);
|
||||||
|
|
||||||
|
if (st->airport.blocks.Test(AirportBlock::Zeppeliner) &&
|
||||||
|
apc->layout[v->previous_pos].blocks == AirportBlock::RunwayIn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
st->airport.blocks.Reset(apc->layout[v->previous_pos].blocks);
|
st->airport.blocks.Reset(apc->layout[v->previous_pos].blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ enum AirportTypes : uint8_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Flags for airport movement data. */
|
/** Flags for airport movement data. */
|
||||||
enum AirportMovingDataFlag : uint8_t {
|
enum class AirportMovingDataFlag : uint8_t {
|
||||||
NoSpeedClamp, ///< No speed restrictions.
|
NoSpeedClamp, ///< No speed restrictions.
|
||||||
Takeoff, ///< Takeoff movement.
|
Takeoff, ///< Takeoff movement.
|
||||||
SlowTurn, ///< Turn slowly (mostly used in the air).
|
SlowTurn, ///< Turn slowly (mostly used in the air).
|
||||||
|
@ -127,6 +127,7 @@ enum class AirportBlock : uint8_t {
|
||||||
/* end of new blocks */
|
/* end of new blocks */
|
||||||
|
|
||||||
Nothing = 30,
|
Nothing = 30,
|
||||||
|
Zeppeliner = 62, ///< Block for the zeppeliner disaster vehicle.
|
||||||
AirportClosed = 63, ///< Dummy block for indicating a closed airport.
|
AirportClosed = 63, ///< Dummy block for indicating a closed airport.
|
||||||
};
|
};
|
||||||
using AirportBlocks = EnumBitSet<AirportBlock, uint64_t>;
|
using AirportBlocks = EnumBitSet<AirportBlock, uint64_t>;
|
||||||
|
|
|
@ -141,6 +141,8 @@ void SetLocalCompany(CompanyID new_company)
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
InvalidateWindowClassesData(WC_SIGN_LIST, -1);
|
InvalidateWindowClassesData(WC_SIGN_LIST, -1);
|
||||||
InvalidateWindowClassesData(WC_GOALS_LIST);
|
InvalidateWindowClassesData(WC_GOALS_LIST);
|
||||||
|
InvalidateWindowClassesData(WC_COMPANY_COLOUR, -1);
|
||||||
|
ResetVehicleColourMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2369,7 +2369,7 @@ static bool ConFont(std::span<std::string_view> argv)
|
||||||
FontCacheSubSetting *setting = GetFontCacheSubSetting(fs);
|
FontCacheSubSetting *setting = GetFontCacheSubSetting(fs);
|
||||||
/* Make sure all non sprite fonts are loaded. */
|
/* Make sure all non sprite fonts are loaded. */
|
||||||
if (!setting->font.empty() && !fc->HasParent()) {
|
if (!setting->font.empty() && !fc->HasParent()) {
|
||||||
InitFontCache(fs == FS_MONO);
|
InitFontCache(fs);
|
||||||
fc = FontCache::Get(fs);
|
fc = FontCache::Get(fs);
|
||||||
}
|
}
|
||||||
IConsolePrint(CC_DEFAULT, "{} font:", FontSizeToName(fs));
|
IConsolePrint(CC_DEFAULT, "{} font:", FontSizeToName(fs));
|
||||||
|
|
|
@ -215,7 +215,7 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeppeliner handling, v->state states:
|
* Zeppeliner handling, v->state states:
|
||||||
* 0: Zeppeliner initialization has found a small airport, go there and crash
|
* 0: Zeppeliner initialization has found an airport, go there and crash
|
||||||
* 1: Create crash and animate falling down for extra dramatic effect
|
* 1: Create crash and animate falling down for extra dramatic effect
|
||||||
* 2: Create more smoke and leave debris on ground
|
* 2: Create more smoke and leave debris on ground
|
||||||
* 2: Clear the runway after some time and remove crashed zeppeliner
|
* 2: Clear the runway after some time and remove crashed zeppeliner
|
||||||
|
@ -263,7 +263,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||||
|
|
||||||
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
|
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
|
||||||
Station *st = Station::GetByTile(v->tile);
|
Station *st = Station::GetByTile(v->tile);
|
||||||
st->airport.blocks.Reset(AirportBlock::RunwayIn);
|
st->airport.blocks.Reset({AirportBlock::Zeppeliner, AirportBlock::RunwayIn});
|
||||||
AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCleared(st->index));
|
AI::NewEvent(GetTileOwner(v->tile), new ScriptEventDisasterZeppelinerCleared(st->index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
|
if (IsValidTile(v->tile) && IsAirportTile(v->tile)) {
|
||||||
Station::GetByTile(v->tile)->airport.blocks.Set(AirportBlock::RunwayIn);
|
Station::GetByTile(v->tile)->airport.blocks.Reset({AirportBlock::Zeppeliner, AirportBlock::RunwayIn});
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -722,14 +722,14 @@ typedef void DisasterInitProc();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeppeliner which crashes on a small airport if one found,
|
* Zeppeliner which crashes on an airport if one found,
|
||||||
* otherwise crashes on a random tile
|
* otherwise crashes on a random tile
|
||||||
*/
|
*/
|
||||||
static void Disaster_Zeppeliner_Init()
|
static void Disaster_Zeppeliner_Init()
|
||||||
{
|
{
|
||||||
if (!Vehicle::CanAllocateItem(2)) return;
|
if (!Vehicle::CanAllocateItem(2)) return;
|
||||||
|
|
||||||
/* Pick a random place, unless we find a small airport */
|
/* Pick a random place, unless we find an airport */
|
||||||
int x = TileX(RandomTile()) * TILE_SIZE + TILE_SIZE / 2;
|
int x = TileX(RandomTile()) * TILE_SIZE + TILE_SIZE / 2;
|
||||||
|
|
||||||
for (const Station *st : Station::Iterate()) {
|
for (const Station *st : Station::Iterate()) {
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct EnginePreviewWindow : Window {
|
||||||
|
|
||||||
/* Get size of engine sprite, on loan from depot_gui.cpp */
|
/* Get size of engine sprite, on loan from depot_gui.cpp */
|
||||||
EngineID engine = static_cast<EngineID>(this->window_number);
|
EngineID engine = static_cast<EngineID>(this->window_number);
|
||||||
EngineImageType image_type = EIT_PURCHASE;
|
EngineImageType image_type = EIT_PREVIEW;
|
||||||
uint x, y;
|
uint x, y;
|
||||||
int x_offs, y_offs;
|
int x_offs, y_offs;
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,10 @@
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
/** Default heights for the different sizes of fonts. */
|
/** Default unscaled heights for the different sizes of fonts. */
|
||||||
static const int _default_font_height[FS_END] = {10, 6, 18, 10};
|
/* static */ const int FontCache::DEFAULT_FONT_HEIGHT[FS_END] = {10, 6, 18, 10};
|
||||||
static const int _default_font_ascender[FS_END] = { 8, 5, 15, 8};
|
/** Default unscaled ascenders for the different sizes of fonts. */
|
||||||
|
/* static */ const int FontCache::DEFAULT_FONT_ASCENDER[FS_END] = {8, 5, 15, 8};
|
||||||
|
|
||||||
FontCacheSettings _fcsettings;
|
FontCacheSettings _fcsettings;
|
||||||
|
|
||||||
|
@ -32,8 +33,7 @@ FontCacheSettings _fcsettings;
|
||||||
* Create a new font cache.
|
* Create a new font cache.
|
||||||
* @param fs The size of the font.
|
* @param fs The size of the font.
|
||||||
*/
|
*/
|
||||||
FontCache::FontCache(FontSize fs) : parent(FontCache::Get(fs)), fs(fs), height(_default_font_height[fs]),
|
FontCache::FontCache(FontSize fs) : parent(FontCache::Get(fs)), fs(fs)
|
||||||
ascender(_default_font_ascender[fs]), descender(_default_font_ascender[fs] - _default_font_height[fs])
|
|
||||||
{
|
{
|
||||||
assert(this->parent == nullptr || this->fs == this->parent->fs);
|
assert(this->parent == nullptr || this->fs == this->parent->fs);
|
||||||
FontCache::caches[this->fs] = this;
|
FontCache::caches[this->fs] = this;
|
||||||
|
@ -50,7 +50,7 @@ FontCache::~FontCache()
|
||||||
|
|
||||||
int FontCache::GetDefaultFontHeight(FontSize fs)
|
int FontCache::GetDefaultFontHeight(FontSize fs)
|
||||||
{
|
{
|
||||||
return _default_font_height[fs];
|
return FontCache::DEFAULT_FONT_HEIGHT[fs];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,10 +126,10 @@ void SetFont(FontSize fontsize, const std::string &font, uint size)
|
||||||
CheckForMissingGlyphs();
|
CheckForMissingGlyphs();
|
||||||
_fcsettings = std::move(backup);
|
_fcsettings = std::move(backup);
|
||||||
} else {
|
} else {
|
||||||
InitFontCache(true);
|
InitFontCache(fontsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadStringWidthTable(fontsize == FS_MONO);
|
LoadStringWidthTable(fontsize);
|
||||||
UpdateAllVirtCoords();
|
UpdateAllVirtCoords();
|
||||||
ReInitAllWindows(true);
|
ReInitAllWindows(true);
|
||||||
|
|
||||||
|
@ -213,15 +213,13 @@ std::string GetFontCacheFontName(FontSize fs)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Re)initialize the font cache related things, i.e. load the non-sprite fonts.
|
* (Re)initialize the font cache related things, i.e. load the non-sprite fonts.
|
||||||
* @param monospace Whether to initialise the monospace or regular fonts.
|
* @param fontsizes Font sizes to be initialised.
|
||||||
*/
|
*/
|
||||||
void InitFontCache(bool monospace)
|
void InitFontCache(FontSizes fontsizes)
|
||||||
{
|
{
|
||||||
FontCache::InitializeFontCaches();
|
FontCache::InitializeFontCaches();
|
||||||
|
|
||||||
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
|
for (FontSize fs : fontsizes) {
|
||||||
if (monospace != (fs == FS_MONO)) continue;
|
|
||||||
|
|
||||||
FontCache *fc = FontCache::Get(fs);
|
FontCache *fc = FontCache::Get(fs);
|
||||||
if (fc->HasParent()) delete fc;
|
if (fc->HasParent()) delete fc;
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,9 @@ protected:
|
||||||
static FontCache *caches[FS_END]; ///< All the font caches.
|
static FontCache *caches[FS_END]; ///< All the font caches.
|
||||||
FontCache *parent; ///< The parent of this font cache.
|
FontCache *parent; ///< The parent of this font cache.
|
||||||
const FontSize fs; ///< The size of the font.
|
const FontSize fs; ///< The size of the font.
|
||||||
int height; ///< The height of the font.
|
int height = 0; ///< The height of the font.
|
||||||
int ascender; ///< The ascender value of the font.
|
int ascender = 0; ///< The ascender value of the font.
|
||||||
int descender; ///< The descender value of the font.
|
int descender = 0; ///< The descender value of the font.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FontCache(FontSize fs);
|
FontCache(FontSize fs);
|
||||||
|
@ -33,6 +33,11 @@ public:
|
||||||
|
|
||||||
static void InitializeFontCaches();
|
static void InitializeFontCaches();
|
||||||
|
|
||||||
|
/** Default unscaled font heights. */
|
||||||
|
static const int DEFAULT_FONT_HEIGHT[FS_END];
|
||||||
|
/** Default unscaled font ascenders. */
|
||||||
|
static const int DEFAULT_FONT_ASCENDER[FS_END];
|
||||||
|
|
||||||
static int GetDefaultFontHeight(FontSize fs);
|
static int GetDefaultFontHeight(FontSize fs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,9 +167,9 @@ inline void InitializeUnicodeGlyphMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ClearFontCache()
|
inline void ClearFontCache(FontSizes fontsizes)
|
||||||
{
|
{
|
||||||
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
|
for (FontSize fs : fontsizes) {
|
||||||
FontCache::Get(fs)->ClearFontCache();
|
FontCache::Get(fs)->ClearFontCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +231,7 @@ inline FontCacheSubSetting *GetFontCacheSubSetting(FontSize fs)
|
||||||
|
|
||||||
uint GetFontCacheFontSize(FontSize fs);
|
uint GetFontCacheFontSize(FontSize fs);
|
||||||
std::string GetFontCacheFontName(FontSize fs);
|
std::string GetFontCacheFontName(FontSize fs);
|
||||||
void InitFontCache(bool monospace);
|
void InitFontCache(FontSizes fontsizes);
|
||||||
void UninitFontCache();
|
void UninitFontCache();
|
||||||
|
|
||||||
bool GetFontAAState();
|
bool GetFontAAState();
|
||||||
|
|
|
@ -43,26 +43,26 @@ SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get SpriteID associated with a GlyphID.
|
* Get SpriteID associated with a character.
|
||||||
* @param key Glyph to find.
|
* @param key Character to find.
|
||||||
* @return SpriteID of glyph, or 0 if not present.
|
* @return SpriteID for character, or 0 if not present.
|
||||||
*/
|
*/
|
||||||
SpriteID SpriteFontCache::GetUnicodeGlyph(GlyphID key)
|
SpriteID SpriteFontCache::GetUnicodeGlyph(char32_t key)
|
||||||
{
|
{
|
||||||
const auto found = this->glyph_to_spriteid_map.find(key & ~SPRITE_GLYPH);
|
const auto found = this->char_map.find(key);
|
||||||
if (found == std::end(this->glyph_to_spriteid_map)) return 0;
|
if (found == std::end(this->char_map)) return 0;
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFontCache::SetUnicodeGlyph(char32_t key, SpriteID sprite)
|
void SpriteFontCache::SetUnicodeGlyph(char32_t key, SpriteID sprite)
|
||||||
{
|
{
|
||||||
this->glyph_to_spriteid_map[key] = sprite;
|
this->char_map[key] = sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFontCache::InitializeUnicodeGlyphMap()
|
void SpriteFontCache::InitializeUnicodeGlyphMap()
|
||||||
{
|
{
|
||||||
/* Clear out existing glyph map if it exists */
|
/* Clear out existing glyph map if it exists */
|
||||||
this->glyph_to_spriteid_map.clear();
|
this->char_map.clear();
|
||||||
|
|
||||||
SpriteID base;
|
SpriteID base;
|
||||||
switch (this->fs) {
|
switch (this->fs) {
|
||||||
|
@ -103,14 +103,14 @@ void SpriteFontCache::ClearFontCache()
|
||||||
|
|
||||||
const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
|
const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
|
||||||
{
|
{
|
||||||
SpriteID sprite = this->GetUnicodeGlyph(static_cast<char32_t>(key & ~SPRITE_GLYPH));
|
SpriteID sprite = static_cast<SpriteID>(key & ~SPRITE_GLYPH);
|
||||||
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
|
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
|
||||||
return GetSprite(sprite, SpriteType::Font);
|
return GetSprite(sprite, SpriteType::Font);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint SpriteFontCache::GetGlyphWidth(GlyphID key)
|
uint SpriteFontCache::GetGlyphWidth(GlyphID key)
|
||||||
{
|
{
|
||||||
SpriteID sprite = this->GetUnicodeGlyph(static_cast<char32_t>(key & ~SPRITE_GLYPH));
|
SpriteID sprite = static_cast<SpriteID>(key & ~SPRITE_GLYPH);
|
||||||
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
|
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
|
||||||
return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
|
return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ GlyphID SpriteFontCache::MapCharToGlyph(char32_t key, [[maybe_unused]] bool allo
|
||||||
assert(IsPrintable(key));
|
assert(IsPrintable(key));
|
||||||
SpriteID sprite = this->GetUnicodeGlyph(key);
|
SpriteID sprite = this->GetUnicodeGlyph(key);
|
||||||
if (sprite == 0) return 0;
|
if (sprite == 0) return 0;
|
||||||
return SPRITE_GLYPH | key;
|
return SPRITE_GLYPH | sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpriteFontCache::GetDrawGlyphShadow()
|
bool SpriteFontCache::GetDrawGlyphShadow()
|
||||||
|
|
|
@ -28,8 +28,8 @@ public:
|
||||||
bool IsBuiltInFont() override { return true; }
|
bool IsBuiltInFont() override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<GlyphID, SpriteID> glyph_to_spriteid_map{}; ///< Mapping of glyphs to sprite IDs.
|
std::unordered_map<char32_t, SpriteID> char_map{}; ///< Mapping of characters to sprite IDs.
|
||||||
SpriteID GetUnicodeGlyph(GlyphID key);
|
SpriteID GetUnicodeGlyph(char32_t key);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SPRITEFONTCACHE_H */
|
#endif /* SPRITEFONTCACHE_H */
|
||||||
|
|
|
@ -78,7 +78,7 @@ template <> SQInteger PushClassName<GameInfo, ScriptType::GS>(HSQUIRRELVM vm) {
|
||||||
/* Remove the link to the real instance, else it might get deleted by RegisterGame() */
|
/* Remove the link to the real instance, else it might get deleted by RegisterGame() */
|
||||||
sq_setinstanceup(vm, 2, nullptr);
|
sq_setinstanceup(vm, 2, nullptr);
|
||||||
/* Register the Game to the base system */
|
/* Register the Game to the base system */
|
||||||
info->GetScanner()->RegisterScript(info);
|
info->GetScanner()->RegisterScript(std::unique_ptr<GameInfo>{info});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,22 +106,21 @@ bool GameInfo::CanLoadFromVersion(int version) const
|
||||||
/* static */ SQInteger GameLibrary::Constructor(HSQUIRRELVM vm)
|
/* static */ SQInteger GameLibrary::Constructor(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
/* Create a new library */
|
/* Create a new library */
|
||||||
GameLibrary *library = new GameLibrary();
|
auto library = std::make_unique<GameLibrary>();
|
||||||
|
|
||||||
SQInteger res = ScriptInfo::Constructor(vm, *library);
|
SQInteger res = ScriptInfo::Constructor(vm, *library);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
delete library;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cache the category */
|
/* Cache the category */
|
||||||
if (!library->CheckMethod("GetCategory") || !library->engine->CallStringMethod(library->SQ_instance, "GetCategory", &library->category, MAX_GET_OPS)) {
|
if (!library->CheckMethod("GetCategory") || !library->engine->CallStringMethod(library->SQ_instance, "GetCategory", &library->category, MAX_GET_OPS)) {
|
||||||
delete library;
|
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the Library to the base system */
|
/* Register the Library to the base system */
|
||||||
library->GetScanner()->RegisterScript(library);
|
ScriptScanner *scanner = library->GetScanner();
|
||||||
|
scanner->RegisterScript(std::move(library));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,8 @@ GameLibrary *GameScannerLibrary::FindLibrary(const std::string &library, int ver
|
||||||
std::string library_name = fmt::format("{}.{}", library, version);
|
std::string library_name = fmt::format("{}.{}", library, version);
|
||||||
|
|
||||||
/* Check if the library + version exists */
|
/* Check if the library + version exists */
|
||||||
ScriptInfoList::iterator it = this->info_list.find(library_name);
|
auto it = this->info_list.find(library_name);
|
||||||
if (it == this->info_list.end()) return nullptr;
|
if (it == this->info_list.end()) return nullptr;
|
||||||
|
|
||||||
return static_cast<GameLibrary *>((*it).second);
|
return static_cast<GameLibrary *>(it->second);
|
||||||
}
|
}
|
||||||
|
|
72
src/gfx.cpp
72
src/gfx.cpp
|
@ -8,6 +8,7 @@
|
||||||
/** @file gfx.cpp Handling of drawing text and other gfx related stuff. */
|
/** @file gfx.cpp Handling of drawing text and other gfx related stuff. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "gfx_func.h"
|
||||||
#include "gfx_layout.h"
|
#include "gfx_layout.h"
|
||||||
#include "progress.h"
|
#include "progress.h"
|
||||||
#include "zoom_func.h"
|
#include "zoom_func.h"
|
||||||
|
@ -523,10 +524,9 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
||||||
int max_x = right; // The maximum x position to draw normal glyphs on.
|
int max_x = right; // The maximum x position to draw normal glyphs on.
|
||||||
|
|
||||||
truncation &= max_w < w; // Whether we need to do truncation.
|
truncation &= max_w < w; // Whether we need to do truncation.
|
||||||
int dot_width = 0; // Cache for the width of the dot.
|
int truncation_width = 0; // Width of the ellipsis string.
|
||||||
const Sprite *dot_sprite = nullptr; // Cache for the sprite of the dot.
|
|
||||||
bool dot_has_shadow = false; // Whether the dot's font requires shadows.
|
|
||||||
|
|
||||||
|
std::optional<Layouter> truncation_layout; ///< Layout for truncation ellipsis.
|
||||||
if (truncation) {
|
if (truncation) {
|
||||||
/*
|
/*
|
||||||
* Assumption may be made that all fonts of a run are of the same size.
|
* Assumption may be made that all fonts of a run are of the same size.
|
||||||
|
@ -534,20 +534,17 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
||||||
* another size would be chosen it won't have truncated too little for
|
* another size would be chosen it won't have truncated too little for
|
||||||
* the truncation dots.
|
* the truncation dots.
|
||||||
*/
|
*/
|
||||||
FontCache *fc = line.GetVisualRun(0).GetFont()->fc;
|
truncation_layout.emplace(GetEllipsis(), INT32_MAX, line.GetVisualRun(0).GetFont()->fc->GetSize());
|
||||||
dot_has_shadow = fc->GetDrawGlyphShadow();
|
truncation_width = truncation_layout->GetBounds().width;
|
||||||
GlyphID dot_glyph = fc->MapCharToGlyph('.');
|
|
||||||
dot_width = fc->GetGlyphWidth(dot_glyph);
|
|
||||||
dot_sprite = fc->GetGlyph(dot_glyph);
|
|
||||||
|
|
||||||
/* Is there enough space even for an ellipsis? */
|
/* Is there enough space even for an ellipsis? */
|
||||||
if (max_w < dot_width * 3) return (_current_text_dir == TD_RTL) ? left : right;
|
if (max_w < truncation_width) return (_current_text_dir == TD_RTL) ? left : right;
|
||||||
|
|
||||||
if (_current_text_dir == TD_RTL) {
|
if (_current_text_dir == TD_RTL) {
|
||||||
min_x += 3 * dot_width;
|
min_x += truncation_width;
|
||||||
offset_x = w - max_w;
|
offset_x = w - max_w;
|
||||||
} else {
|
} else {
|
||||||
max_x -= 3 * dot_width;
|
max_x -= truncation_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
w = max_w;
|
w = max_w;
|
||||||
|
@ -583,9 +580,11 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
||||||
|
|
||||||
const uint shadow_offset = ScaleGUITrad(1);
|
const uint shadow_offset = ScaleGUITrad(1);
|
||||||
|
|
||||||
/* Draw shadow, then foreground */
|
auto draw_line = [&](const ParagraphLayouter::Line &line, bool do_shadow, int left, int min_x, int max_x, bool truncation, TextColour &last_colour) {
|
||||||
for (bool do_shadow : { true, false }) {
|
const DrawPixelInfo *dpi = _cur_dpi;
|
||||||
bool colour_has_shadow = false;
|
int dpi_left = dpi->left;
|
||||||
|
int dpi_right = dpi->left + dpi->width - 1;
|
||||||
|
|
||||||
for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
|
for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
|
||||||
const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index);
|
const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index);
|
||||||
const auto &glyphs = run.GetGlyphs();
|
const auto &glyphs = run.GetGlyphs();
|
||||||
|
@ -594,14 +593,15 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
||||||
|
|
||||||
FontCache *fc = f->fc;
|
FontCache *fc = f->fc;
|
||||||
TextColour colour = f->colour;
|
TextColour colour = f->colour;
|
||||||
if (colour == TC_INVALID || HasFlag(default_colour, TC_FORCED)) colour = default_colour;
|
if (colour == TC_INVALID || HasFlag(last_colour, TC_FORCED)) {
|
||||||
colour_has_shadow = (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK;
|
colour = last_colour;
|
||||||
SetColourRemap(do_shadow ? TC_BLACK : colour); // the last run also sets the colour for the truncation dots
|
} else {
|
||||||
|
/* Update the last colour for the truncation ellipsis. */
|
||||||
|
last_colour = colour;
|
||||||
|
}
|
||||||
|
bool colour_has_shadow = (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK;
|
||||||
if (do_shadow && (!fc->GetDrawGlyphShadow() || !colour_has_shadow)) continue;
|
if (do_shadow && (!fc->GetDrawGlyphShadow() || !colour_has_shadow)) continue;
|
||||||
|
SetColourRemap(do_shadow ? TC_BLACK : colour);
|
||||||
DrawPixelInfo *dpi = _cur_dpi;
|
|
||||||
int dpi_left = dpi->left;
|
|
||||||
int dpi_right = dpi->left + dpi->width - 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
||||||
GlyphID glyph = glyphs[i];
|
GlyphID glyph = glyphs[i];
|
||||||
|
@ -609,8 +609,8 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
||||||
/* Not a valid glyph (empty) */
|
/* Not a valid glyph (empty) */
|
||||||
if (glyph == 0xFFFF) continue;
|
if (glyph == 0xFFFF) continue;
|
||||||
|
|
||||||
int begin_x = positions[i].left + left - offset_x;
|
int begin_x = positions[i].left + left;
|
||||||
int end_x = positions[i].right + left - offset_x;
|
int end_x = positions[i].right + left;
|
||||||
int top = positions[i].top + y;
|
int top = positions[i].top + y;
|
||||||
|
|
||||||
/* Truncated away. */
|
/* Truncated away. */
|
||||||
|
@ -625,12 +625,16 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
||||||
GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0), BlitterMode::ColourRemap);
|
GfxMainBlitter(sprite, begin_x + (do_shadow ? shadow_offset : 0), top + (do_shadow ? shadow_offset : 0), BlitterMode::ColourRemap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (truncation && (!do_shadow || (dot_has_shadow && colour_has_shadow))) {
|
/* Draw shadow, then foreground */
|
||||||
int x = (_current_text_dir == TD_RTL) ? left : (right - 3 * dot_width);
|
for (bool do_shadow : {true, false}) {
|
||||||
for (int i = 0; i < 3; i++, x += dot_width) {
|
TextColour last_colour = default_colour;
|
||||||
GfxMainBlitter(dot_sprite, x + (do_shadow ? shadow_offset : 0), y + (do_shadow ? shadow_offset : 0), BlitterMode::ColourRemap);
|
draw_line(line, do_shadow, left - offset_x, min_x, max_x, truncation, last_colour);
|
||||||
}
|
|
||||||
|
if (truncation) {
|
||||||
|
int x = (_current_text_dir == TD_RTL) ? left : (right - truncation_width);
|
||||||
|
draw_line(*truncation_layout->front(), do_shadow, x, INT32_MIN, INT32_MAX, false, last_colour);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,14 +1247,14 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize _stringwidth_table cache
|
* Initialize _stringwidth_table cache for the specified font sizes.
|
||||||
* @param monospace Whether to load the monospace cache or the normal fonts.
|
* @param fontsizes Font sizes to initialise.
|
||||||
*/
|
*/
|
||||||
void LoadStringWidthTable(bool monospace)
|
void LoadStringWidthTable(FontSizes fontsizes)
|
||||||
{
|
{
|
||||||
ClearFontCache();
|
ClearFontCache(fontsizes);
|
||||||
|
|
||||||
for (FontSize fs = monospace ? FS_MONO : FS_BEGIN; fs < (monospace ? FS_END : FS_MONO); fs++) {
|
for (FontSize fs : fontsizes) {
|
||||||
for (uint i = 0; i != 224; i++) {
|
for (uint i = 0; i != 224; i++) {
|
||||||
_stringwidth_table[fs][i] = GetGlyphWidth(fs, i + 32);
|
_stringwidth_table[fs][i] = GetGlyphWidth(fs, i + 32);
|
||||||
}
|
}
|
||||||
|
@ -1815,7 +1819,7 @@ bool AdjustGUIZoom(bool automatic)
|
||||||
if (old_font_zoom != _font_zoom) {
|
if (old_font_zoom != _font_zoom) {
|
||||||
GfxClearFontSpriteCache();
|
GfxClearFontSpriteCache();
|
||||||
}
|
}
|
||||||
ClearFontCache();
|
ClearFontCache(FONTSIZES_ALL);
|
||||||
LoadStringWidthTable();
|
LoadStringWidthTable();
|
||||||
|
|
||||||
SetupWidgetDimensions();
|
SetupWidgetDimensions();
|
||||||
|
|
|
@ -149,7 +149,7 @@ int GetStringHeight(StringID str, int maxw);
|
||||||
int GetStringLineCount(std::string_view str, int maxw);
|
int GetStringLineCount(std::string_view str, int maxw);
|
||||||
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
|
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
|
||||||
Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion, FontSize fontsize = FS_NORMAL);
|
Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion, FontSize fontsize = FS_NORMAL);
|
||||||
void LoadStringWidthTable(bool monospace = false);
|
void LoadStringWidthTable(FontSizes fontsizes = FONTSIZES_REQUIRED);
|
||||||
|
|
||||||
void DrawDirtyBlocks();
|
void DrawDirtyBlocks();
|
||||||
void AddDirtyBlock(int left, int top, int right, int bottom);
|
void AddDirtyBlock(int left, int top, int right, int bottom);
|
||||||
|
|
|
@ -258,6 +258,13 @@ enum FontSize : uint8_t {
|
||||||
};
|
};
|
||||||
DECLARE_INCREMENT_DECREMENT_OPERATORS(FontSize)
|
DECLARE_INCREMENT_DECREMENT_OPERATORS(FontSize)
|
||||||
|
|
||||||
|
using FontSizes = EnumBitSet<FontSize, uint8_t>;
|
||||||
|
|
||||||
|
/** Mask of all possible font sizes. */
|
||||||
|
constexpr FontSizes FONTSIZES_ALL{FS_NORMAL, FS_SMALL, FS_LARGE, FS_MONO};
|
||||||
|
/** Mask of font sizes required to be present. */
|
||||||
|
constexpr FontSizes FONTSIZES_REQUIRED{FS_NORMAL, FS_SMALL, FS_LARGE};
|
||||||
|
|
||||||
inline std::string_view FontSizeToName(FontSize fs)
|
inline std::string_view FontSizeToName(FontSize fs)
|
||||||
{
|
{
|
||||||
static const std::string_view SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
|
static const std::string_view SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void RealChangeBlitter(std::string_view repl_blitter)
|
||||||
|
|
||||||
/* Clear caches that might have sprites for another blitter. */
|
/* Clear caches that might have sprites for another blitter. */
|
||||||
VideoDriver::GetInstance()->ClearSystemSprites();
|
VideoDriver::GetInstance()->ClearSystemSprites();
|
||||||
ClearFontCache();
|
ClearFontCache(FONTSIZES_ALL);
|
||||||
GfxClearSpriteCache();
|
GfxClearSpriteCache();
|
||||||
ReInitAllWindows(false);
|
ReInitAllWindows(false);
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@ void CheckBlitter()
|
||||||
{
|
{
|
||||||
if (!SwitchNewGRFBlitter()) return;
|
if (!SwitchNewGRFBlitter()) return;
|
||||||
|
|
||||||
ClearFontCache();
|
ClearFontCache(FONTSIZES_ALL);
|
||||||
GfxClearSpriteCache();
|
GfxClearSpriteCache();
|
||||||
ReInitAllWindows(false);
|
ReInitAllWindows(false);
|
||||||
}
|
}
|
||||||
|
@ -338,7 +338,7 @@ void GfxLoadSprites()
|
||||||
|
|
||||||
SwitchNewGRFBlitter();
|
SwitchNewGRFBlitter();
|
||||||
VideoDriver::GetInstance()->ClearSystemSprites();
|
VideoDriver::GetInstance()->ClearSystemSprites();
|
||||||
ClearFontCache();
|
ClearFontCache(FONTSIZES_ALL);
|
||||||
GfxInitSpriteMem();
|
GfxInitSpriteMem();
|
||||||
LoadSpriteTables();
|
LoadSpriteTables();
|
||||||
GfxInitPalettes();
|
GfxInitPalettes();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
/** @file graph_gui.cpp GUI that shows performance graphs. */
|
/** @file graph_gui.cpp GUI that shows performance graphs. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "misc/history_func.hpp"
|
||||||
#include "graph_gui.h"
|
#include "graph_gui.h"
|
||||||
#include "window_gui.h"
|
#include "window_gui.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
|
@ -215,6 +216,15 @@ protected:
|
||||||
uint8_t highlight_range = UINT8_MAX; ///< Data range that should be highlighted, or UINT8_MAX for none.
|
uint8_t highlight_range = UINT8_MAX; ///< Data range that should be highlighted, or UINT8_MAX for none.
|
||||||
bool highlight_state = false; ///< Current state of highlight, toggled every TIMER_BLINK_INTERVAL period.
|
bool highlight_state = false; ///< Current state of highlight, toggled every TIMER_BLINK_INTERVAL period.
|
||||||
|
|
||||||
|
template <typename Tprojection>
|
||||||
|
struct Filler {
|
||||||
|
DataSet &dataset; ///< Dataset to fill.
|
||||||
|
const Tprojection &proj; ///< Projection to apply.
|
||||||
|
|
||||||
|
inline void Fill(uint i, const auto &data) const { this->dataset.values[i] = std::invoke(this->proj, data); }
|
||||||
|
inline void MakeInvalid(uint i) const { this->dataset.values[i] = INVALID_DATAPOINT; }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get appropriate part of dataset values for the current number of horizontal points.
|
* Get appropriate part of dataset values for the current number of horizontal points.
|
||||||
* @param dataset Dataset to get values of
|
* @param dataset Dataset to get values of
|
||||||
|
@ -378,7 +388,9 @@ protected:
|
||||||
/* Draw the background of the graph itself. */
|
/* Draw the background of the graph itself. */
|
||||||
GfxFillRect(r.left, r.top, r.right, r.bottom, GRAPH_BASE_COLOUR);
|
GfxFillRect(r.left, r.top, r.right, r.bottom, GRAPH_BASE_COLOUR);
|
||||||
|
|
||||||
/* Draw the vertical grid lines. */
|
/* Draw the grid lines. */
|
||||||
|
int gridline_width = WidgetDimensions::scaled.bevel.top;
|
||||||
|
int grid_colour = GRAPH_GRID_COLOUR;
|
||||||
|
|
||||||
/* Don't draw the first line, as that's where the axis will be. */
|
/* Don't draw the first line, as that's where the axis will be. */
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
|
@ -388,13 +400,12 @@ protected:
|
||||||
x = r.left + x_sep;
|
x = r.left + x_sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
int grid_colour = GRAPH_GRID_COLOUR;
|
|
||||||
for (int i = 1; i < this->num_vert_lines + 1; i++) {
|
for (int i = 1; i < this->num_vert_lines + 1; i++) {
|
||||||
/* If using wallclock units, we separate periods with a lighter line. */
|
/* If using wallclock units, we separate periods with a lighter line. */
|
||||||
if (TimerGameEconomy::UsingWallclockUnits()) {
|
if (TimerGameEconomy::UsingWallclockUnits()) {
|
||||||
grid_colour = (i % 4 == 0) ? GRAPH_YEAR_LINE_COLOUR : GRAPH_GRID_COLOUR;
|
grid_colour = (i % 4 == 0) ? GRAPH_YEAR_LINE_COLOUR : GRAPH_GRID_COLOUR;
|
||||||
}
|
}
|
||||||
GfxFillRect(x, r.top, x, r.bottom, grid_colour);
|
GfxFillRect(x, r.top, x + gridline_width - 1, r.bottom, grid_colour);
|
||||||
x += x_sep;
|
x += x_sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,20 +414,20 @@ protected:
|
||||||
|
|
||||||
for (int i = 0; i < (num_hori_lines + 1); i++) {
|
for (int i = 0; i < (num_hori_lines + 1); i++) {
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
GfxFillRect(r.right + 1, y, r.right + ScaleGUITrad(3), y, GRAPH_AXIS_LINE_COLOUR);
|
GfxFillRect(r.right + 1, y, r.right + ScaleGUITrad(3), y + gridline_width - 1, GRAPH_AXIS_LINE_COLOUR);
|
||||||
} else {
|
} else {
|
||||||
GfxFillRect(r.left - ScaleGUITrad(3), y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR);
|
GfxFillRect(r.left - ScaleGUITrad(3), y, r.left - 1, y + gridline_width - 1, GRAPH_AXIS_LINE_COLOUR);
|
||||||
}
|
}
|
||||||
GfxFillRect(r.left, y, r.right, y, GRAPH_GRID_COLOUR);
|
GfxFillRect(r.left, y, r.right + gridline_width - 1, y + gridline_width - 1, GRAPH_GRID_COLOUR);
|
||||||
y -= y_sep;
|
y -= y_sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the y axis. */
|
/* Draw the y axis. */
|
||||||
GfxFillRect(r.left, r.top, r.left, r.bottom, GRAPH_AXIS_LINE_COLOUR);
|
GfxFillRect(r.left, r.top, r.left + gridline_width - 1, r.bottom + gridline_width - 1, GRAPH_AXIS_LINE_COLOUR);
|
||||||
|
|
||||||
/* Draw the x axis. */
|
/* Draw the x axis. */
|
||||||
y = x_axis_offset + r.top;
|
y = x_axis_offset + r.top;
|
||||||
GfxFillRect(r.left, y, r.right, y, GRAPH_ZERO_LINE_COLOUR);
|
GfxFillRect(r.left, y, r.right + gridline_width - 1, y + gridline_width - 1, GRAPH_ZERO_LINE_COLOUR);
|
||||||
|
|
||||||
/* Find the largest value that will be drawn. */
|
/* Find the largest value that will be drawn. */
|
||||||
if (this->num_on_x_axis == 0) return;
|
if (this->num_on_x_axis == 0) return;
|
||||||
|
@ -471,7 +482,7 @@ protected:
|
||||||
year++;
|
year++;
|
||||||
|
|
||||||
/* Draw a lighter grid line between years. Top and bottom adjustments ensure we don't draw over top and bottom horizontal grid lines. */
|
/* Draw a lighter grid line between years. Top and bottom adjustments ensure we don't draw over top and bottom horizontal grid lines. */
|
||||||
GfxFillRect(x + x_sep, r.top + 1, x + x_sep, r.bottom - 1, GRAPH_YEAR_LINE_COLOUR);
|
GfxFillRect(x + x_sep, r.top + gridline_width, x + x_sep + gridline_width - 1, r.bottom - 1, GRAPH_YEAR_LINE_COLOUR);
|
||||||
}
|
}
|
||||||
x += x_sep;
|
x += x_sep;
|
||||||
}
|
}
|
||||||
|
@ -499,10 +510,11 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw lines and dots */
|
/* Draw lines and dots. */
|
||||||
uint linewidth = _settings_client.gui.graph_line_thickness;
|
uint linewidth = ScaleGUITrad(_settings_client.gui.graph_line_thickness);
|
||||||
uint pointoffs1 = (linewidth + 1) / 2;
|
uint pointwidth = ScaleGUITrad(_settings_client.gui.graph_line_thickness + 1);
|
||||||
uint pointoffs2 = linewidth + 1 - pointoffs1;
|
uint pointoffs1 = pointwidth / 2;
|
||||||
|
uint pointoffs2 = pointwidth - pointoffs1;
|
||||||
|
|
||||||
auto draw_dataset = [&](const DataSet &dataset, uint8_t colour) {
|
auto draw_dataset = [&](const DataSet &dataset, uint8_t colour) {
|
||||||
if (HasBit(this->excluded_data, dataset.exclude_bit)) return;
|
if (HasBit(this->excluded_data, dataset.exclude_bit)) return;
|
||||||
|
@ -1661,24 +1673,22 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow {
|
||||||
if (!IsValidCargoType(p.cargo)) continue;
|
if (!IsValidCargoType(p.cargo)) continue;
|
||||||
const CargoSpec *cs = CargoSpec::Get(p.cargo);
|
const CargoSpec *cs = CargoSpec::Get(p.cargo);
|
||||||
|
|
||||||
|
this->data.reserve(this->data.size() + 2);
|
||||||
|
|
||||||
DataSet &produced = this->data.emplace_back();
|
DataSet &produced = this->data.emplace_back();
|
||||||
produced.colour = cs->legend_colour;
|
produced.colour = cs->legend_colour;
|
||||||
produced.exclude_bit = cs->Index();
|
produced.exclude_bit = cs->Index();
|
||||||
produced.range_bit = 0;
|
produced.range_bit = 0;
|
||||||
|
auto produced_filler = Filler{produced, &Industry::ProducedHistory::production};
|
||||||
for (uint j = 0; j < GRAPH_NUM_MONTHS; j++) {
|
|
||||||
produced.values[j] = p.history[GRAPH_NUM_MONTHS - j].production;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSet &transported = this->data.emplace_back();
|
DataSet &transported = this->data.emplace_back();
|
||||||
transported.colour = cs->legend_colour;
|
transported.colour = cs->legend_colour;
|
||||||
transported.exclude_bit = cs->Index();
|
transported.exclude_bit = cs->Index();
|
||||||
transported.range_bit = 1;
|
transported.range_bit = 1;
|
||||||
transported.dash = 2;
|
transported.dash = 2;
|
||||||
|
auto transported_filler = Filler{transported, &Industry::ProducedHistory::transported};
|
||||||
|
|
||||||
for (uint j = 0; j < GRAPH_NUM_MONTHS; j++) {
|
FillFromHistory<GRAPH_NUM_MONTHS>(p.history, i->valid_history, produced_filler, transported_filler);
|
||||||
transported.values[j] = p.history[GRAPH_NUM_MONTHS - j].transported;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define INDUSTRY_H
|
#define INDUSTRY_H
|
||||||
|
|
||||||
#include "core/flatset_type.hpp"
|
#include "core/flatset_type.hpp"
|
||||||
|
#include "misc/history_type.hpp"
|
||||||
#include "newgrf_storage.h"
|
#include "newgrf_storage.h"
|
||||||
#include "subsidy_type.h"
|
#include "subsidy_type.h"
|
||||||
#include "industry_map.h"
|
#include "industry_map.h"
|
||||||
|
@ -55,9 +56,6 @@ enum class IndustryControlFlag : uint8_t {
|
||||||
};
|
};
|
||||||
using IndustryControlFlags = EnumBitSet<IndustryControlFlag, uint8_t, IndustryControlFlag::End>;
|
using IndustryControlFlags = EnumBitSet<IndustryControlFlag, uint8_t, IndustryControlFlag::End>;
|
||||||
|
|
||||||
static const int THIS_MONTH = 0;
|
|
||||||
static const int LAST_MONTH = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the internal data of a functional industry.
|
* Defines the internal data of a functional industry.
|
||||||
*/
|
*/
|
||||||
|
@ -72,12 +70,11 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
||||||
return ClampTo<uint8_t>(this->transported * 256 / this->production);
|
return ClampTo<uint8_t>(this->transported * 256 / this->production);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProducedCargo {
|
struct ProducedCargo {
|
||||||
CargoType cargo = 0; ///< Cargo type
|
CargoType cargo = 0; ///< Cargo type
|
||||||
uint16_t waiting = 0; ///< Amount of cargo produced
|
uint16_t waiting = 0; ///< Amount of cargo produced
|
||||||
uint8_t rate = 0; ///< Production rate
|
uint8_t rate = 0; ///< Production rate
|
||||||
std::array<ProducedHistory, 25> history{}; ///< History of cargo produced and transported for this month and 24 previous months
|
HistoryData<ProducedHistory> history{}; ///< History of cargo produced and transported for this month and 24 previous months
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AcceptedCargo {
|
struct AcceptedCargo {
|
||||||
|
@ -92,6 +89,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
||||||
TileArea location{INVALID_TILE, 0, 0}; ///< Location of the industry
|
TileArea location{INVALID_TILE, 0, 0}; ///< Location of the industry
|
||||||
Town *town = nullptr; ///< Nearest town
|
Town *town = nullptr; ///< Nearest town
|
||||||
Station *neutral_station = nullptr; ///< Associated neutral station
|
Station *neutral_station = nullptr; ///< Associated neutral station
|
||||||
|
ValidHistoryMask valid_history = 0; ///< Mask of valid history records.
|
||||||
ProducedCargoes produced{}; ///< produced cargo slots
|
ProducedCargoes produced{}; ///< produced cargo slots
|
||||||
AcceptedCargoes accepted{}; ///< accepted cargo slots
|
AcceptedCargoes accepted{}; ///< accepted cargo slots
|
||||||
uint8_t prod_level = 0; ///< general production level
|
uint8_t prod_level = 0; ///< general production level
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
/** @file industry_cmd.cpp Handling of industry tiles. */
|
/** @file industry_cmd.cpp Handling of industry tiles. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "misc/history_type.hpp"
|
||||||
|
#include "misc/history_func.hpp"
|
||||||
#include "clear_map.h"
|
#include "clear_map.h"
|
||||||
#include "industry.h"
|
#include "industry.h"
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
|
@ -1835,6 +1837,8 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
|
||||||
for (auto &p : i->produced) {
|
for (auto &p : i->produced) {
|
||||||
p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false);
|
p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateValidHistory(i->valid_history);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indspec->callback_mask.Test(IndustryCallbackMask::DecideColour)) {
|
if (indspec->callback_mask.Test(IndustryCallbackMask::DecideColour)) {
|
||||||
|
@ -2492,14 +2496,13 @@ void GenerateIndustries()
|
||||||
*/
|
*/
|
||||||
static void UpdateIndustryStatistics(Industry *i)
|
static void UpdateIndustryStatistics(Industry *i)
|
||||||
{
|
{
|
||||||
|
UpdateValidHistory(i->valid_history);
|
||||||
|
|
||||||
for (auto &p : i->produced) {
|
for (auto &p : i->produced) {
|
||||||
if (IsValidCargoType(p.cargo)) {
|
if (IsValidCargoType(p.cargo)) {
|
||||||
if (p.history[THIS_MONTH].production != 0) i->last_prod_year = TimerGameEconomy::year;
|
if (p.history[THIS_MONTH].production != 0) i->last_prod_year = TimerGameEconomy::year;
|
||||||
|
|
||||||
/* Move history from this month to last month. */
|
RotateHistory(p.history);
|
||||||
std::rotate(std::rbegin(p.history), std::rbegin(p.history) + 1, std::rend(p.history));
|
|
||||||
p.history[THIS_MONTH].production = 0;
|
|
||||||
p.history[THIS_MONTH].transported = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}ano{
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtro:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtro:
|
||||||
|
@ -5001,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}O terren
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção errada
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção errada
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}A construção precisa ser demolida primeiro
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}A construção precisa ser demolida primeiro
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... construção é protegida
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... local não adequado
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... local não adequado
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... já construído
|
STR_ERROR_ALREADY_BUILT :{WHITE}... já construído
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}any{
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}període{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}període{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtre:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtre:
|
||||||
|
@ -286,7 +287,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Tanca la
|
||||||
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Títol de la finestra: arrossegueu el títol per desplaçar la finestra.
|
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Títol de la finestra: arrossegueu el títol per desplaçar la finestra.
|
||||||
STR_TOOLTIP_SHADE :{BLACK}Ombra de la finestra: mostra només la barra de títol.
|
STR_TOOLTIP_SHADE :{BLACK}Ombra de la finestra: mostra només la barra de títol.
|
||||||
STR_TOOLTIP_DEBUG :{BLACK}Mostra la informació de depuració NewGRF
|
STR_TOOLTIP_DEBUG :{BLACK}Mostra la informació de depuració NewGRF
|
||||||
STR_TOOLTIP_DEFSIZE :{BLACK}Redimensiona la finestra a la mida predeterminada. Ctrl+Clic desa la mida actual com a predeterminada.
|
STR_TOOLTIP_DEFSIZE :{BLACK}Redimensiona la finestra a la mida predeterminada. Amb Ctrl+Clic, es desa la mida actual com a predeterminada. Amb Ctrl+doble clic, es restableix als valors per defecte.
|
||||||
STR_TOOLTIP_STICKY :{BLACK}Marca aquesta finestra com a no eliminable per la tecla «Tanca totes les finestres». Ctrl+Clic per desar també l'estat predeterminat.
|
STR_TOOLTIP_STICKY :{BLACK}Marca aquesta finestra com a no eliminable per la tecla «Tanca totes les finestres». Ctrl+Clic per desar també l'estat predeterminat.
|
||||||
STR_TOOLTIP_RESIZE :{BLACK}Clica i arrossega per redimensionar aquesta finestra
|
STR_TOOLTIP_RESIZE :{BLACK}Clica i arrossega per redimensionar aquesta finestra
|
||||||
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Commuta entre la mida gran i petita de la finestra
|
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Commuta entre la mida gran i petita de la finestra
|
||||||
|
@ -1108,7 +1109,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :Informació add
|
||||||
STR_GAME_OPTIONS_ONLINE_CONTENT :Descarrega contingut
|
STR_GAME_OPTIONS_ONLINE_CONTENT :Descarrega contingut
|
||||||
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Comprova si hi ha continguts nous o actualitzats per a descarregar.
|
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Comprova si hi ha continguts nous o actualitzats per a descarregar.
|
||||||
|
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :{LTBLUE}(no s'han instal·lat complements per a interactuar amb plataformes socials)
|
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :(no s'han instal·lat complements per a interactuar amb plataformes socials)
|
||||||
|
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
||||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Plataforma:
|
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Plataforma:
|
||||||
|
@ -1226,7 +1227,7 @@ STR_CITY_APPROVAL_PERMISSIVE :Permissiva (les
|
||||||
STR_WARNING_NO_SUITABLE_AI :{WHITE}No hi ha cap IA disponible...{}Podeu descarregar-ne a través del «Contingut en línia».
|
STR_WARNING_NO_SUITABLE_AI :{WHITE}No hi ha cap IA disponible...{}Podeu descarregar-ne a través del «Contingut en línia».
|
||||||
|
|
||||||
# Settings tree in the Game Options window
|
# Settings tree in the Game Options window
|
||||||
STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}{BLACK}Filtre:
|
STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}Filtre:
|
||||||
STR_CONFIG_SETTING_EXPAND_ALL :Desplega-ho tot
|
STR_CONFIG_SETTING_EXPAND_ALL :Desplega-ho tot
|
||||||
STR_CONFIG_SETTING_COLLAPSE_ALL :Plega-ho tot
|
STR_CONFIG_SETTING_COLLAPSE_ALL :Plega-ho tot
|
||||||
STR_CONFIG_SETTING_RESET_ALL :Restableix tots els valors
|
STR_CONFIG_SETTING_RESET_ALL :Restableix tots els valors
|
||||||
|
@ -1302,6 +1303,9 @@ STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Tipus d'interè
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS :Costos d'utilització: {STRING}
|
STR_CONFIG_SETTING_RUNNING_COSTS :Costos d'utilització: {STRING}
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixa el nivell de manteniment i els costos d'utilització dels vehicles i infraestructures
|
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixa el nivell de manteniment i els costos d'utilització dels vehicles i infraestructures
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_LOW :Baix
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_MEDIUM :Mitjà
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_HIGH :Alt
|
||||||
|
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Ritme de construcció: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Ritme de construcció: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita la quantitat d'accions de construcció per part de les IA
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita la quantitat d'accions de construcció per part de les IA
|
||||||
|
@ -1324,6 +1328,9 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Sense subsidis
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcció: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcció: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa el nivell de construcció i els preus de compra
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa el nivell de construcció i els preus de compra
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Baix
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Mitjà
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HIGH :Alt
|
||||||
|
|
||||||
STR_CONFIG_SETTING_RECESSIONS :Recessions: {STRING}
|
STR_CONFIG_SETTING_RECESSIONS :Recessions: {STRING}
|
||||||
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Si està activat, poden haver recessions periòdicament. Durant una recessió, tota la producció és significativament més baixa, tornant al nivell previ quan s'acabi el període de recessió.
|
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Si està activat, poden haver recessions periòdicament. Durant una recessió, tota la producció és significativament més baixa, tornant al nivell previ quan s'acabi el període de recessió.
|
||||||
|
@ -2079,9 +2086,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de c
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Mode de distribució per altres classes de càrrega: {STRING}
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Mode de distribució per altres classes de càrrega: {STRING}
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues.
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues.
|
||||||
###length 3
|
###length 3
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual
|
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manual
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimètric
|
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asimètric
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simètric
|
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Simètric
|
||||||
|
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisió de la distribució: {STRING}
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisió de la distribució: {STRING}
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Com més alt el valor indicat, més temps de processador requerirà el càlcul del graf de distribució. Si requereix massa temps podeu notar ralentització. Si indiqueu un valor baix, però, la distribució serà poc acurada, i us podeu trobar que la càrrega no és enviada als llocs que espereu.
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Com més alt el valor indicat, més temps de processador requerirà el càlcul del graf de distribució. Si requereix massa temps podeu notar ralentització. Si indiqueu un valor baix, però, la distribució serà poc acurada, i us podeu trobar que la càrrega no és enviada als llocs que espereu.
|
||||||
|
@ -2331,16 +2338,19 @@ STR_FACE_SIMPLE_TOOLTIP :{BLACK}Selecci
|
||||||
STR_FACE_LOAD :{BLACK}Carrega
|
STR_FACE_LOAD :{BLACK}Carrega
|
||||||
STR_FACE_LOAD_TOOLTIP :{BLACK}Carrega la cara preferida
|
STR_FACE_LOAD_TOOLTIP :{BLACK}Carrega la cara preferida
|
||||||
STR_FACE_LOAD_DONE :{WHITE}S'ha carregat la cara personalitzada des de l'arxiu de configuració de l'OpenTTD.
|
STR_FACE_LOAD_DONE :{WHITE}S'ha carregat la cara personalitzada des de l'arxiu de configuració de l'OpenTTD.
|
||||||
STR_FACE_FACECODE :{BLACK}Número de la cara
|
STR_FACE_FACECODE :{BLACK}Codi de la cara
|
||||||
STR_FACE_FACECODE_TOOLTIP :{BLACK}Veure i/o assigna el número de la cara del president
|
STR_FACE_FACECODE_TOOLTIP :{BLACK}Veure i/o assigna el codi de la cara del president
|
||||||
STR_FACE_FACECODE_CAPTION :{WHITE}Veure i/o assigna el número de la cara del president
|
STR_FACE_FACECODE_CAPTION :{WHITE}Veure i/o assigna el codi de la cara del president
|
||||||
STR_FACE_FACECODE_SET :{WHITE}El número de la nova cara ha estat assignat
|
STR_FACE_FACECODE_SET :{WHITE}S'ha assignat el codi de la nova cara del president.
|
||||||
STR_FACE_FACECODE_ERR :{WHITE}No s'ha pogut assignar el número de cara del president - ha de ser un nombre entre 0 i 4,294,967,295!
|
STR_FACE_FACECODE_ERR :{WHITE}No s'ha pogut assignar el codi de cara del president - ha de ser una etiqueta i nombre vàlids.
|
||||||
STR_FACE_SAVE :{BLACK}Desa
|
STR_FACE_SAVE :{BLACK}Desa
|
||||||
STR_FACE_SAVE_TOOLTIP :{BLACK}Desa la cara preferida
|
STR_FACE_SAVE_TOOLTIP :{BLACK}Desa la cara preferida
|
||||||
STR_FACE_SAVE_DONE :{WHITE}Es desarà aquesta cara personalitzada a l'arxiu de configuració de l'OpenTTD.
|
STR_FACE_SAVE_DONE :{WHITE}Es desarà aquesta cara personalitzada a l'arxiu de configuració de l'OpenTTD.
|
||||||
|
STR_FACE_SETTING_TOGGLE :{STRING} {ORANGE}{STRING}
|
||||||
|
STR_FACE_SETTING_NUMERIC :{STRING} {ORANGE}{NUM} / {NUM}
|
||||||
STR_FACE_YES :Sí
|
STR_FACE_YES :Sí
|
||||||
STR_FACE_NO :No
|
STR_FACE_NO :No
|
||||||
|
STR_FACE_STYLE :Estil:
|
||||||
STR_FACE_HAIR :Cabell:
|
STR_FACE_HAIR :Cabell:
|
||||||
STR_FACE_EYEBROWS :Celles:
|
STR_FACE_EYEBROWS :Celles:
|
||||||
STR_FACE_EYECOLOUR :Color dels ulls:
|
STR_FACE_EYECOLOUR :Color dels ulls:
|
||||||
|
@ -2813,6 +2823,10 @@ STR_PICKER_MODE_USED_TOOLTIP :Commuta entre m
|
||||||
STR_PICKER_MODE_SAVED :Desats
|
STR_PICKER_MODE_SAVED :Desats
|
||||||
STR_PICKER_MODE_SAVED_TOOLTIP :Commuta entre mostrar tots o bé només els elements desats.
|
STR_PICKER_MODE_SAVED_TOOLTIP :Commuta entre mostrar tots o bé només els elements desats.
|
||||||
|
|
||||||
|
STR_PICKER_PREVIEW_SHRINK :‒
|
||||||
|
STR_PICKER_PREVIEW_SHRINK_TOOLTIP :Redueix l'alçària de les vistes prèvies. Amb Ctrl+clic, es redueix fins al mínim.
|
||||||
|
STR_PICKER_PREVIEW_EXPAND :+
|
||||||
|
STR_PICKER_PREVIEW_EXPAND_TOOLTIP :Augmenta l'alçària de les vistes prèvies. Amb Ctrl+clic, s'augmenta fins al màxim.
|
||||||
|
|
||||||
STR_PICKER_STATION_CLASS_TOOLTIP :Trieu quina classe d'estació voleu veure.
|
STR_PICKER_STATION_CLASS_TOOLTIP :Trieu quina classe d'estació voleu veure.
|
||||||
STR_PICKER_STATION_TYPE_TOOLTIP :Trieu quin tipus d'estació voleu construir. Amb Ctrl+clic, s'afegeix o es trau l'element de la llista de desats.
|
STR_PICKER_STATION_TYPE_TOOLTIP :Trieu quin tipus d'estació voleu construir. Amb Ctrl+clic, s'afegeix o es trau l'element de la llista de desats.
|
||||||
|
@ -3053,6 +3067,11 @@ STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Seleccio
|
||||||
STR_FOUND_TOWN_CITY :{BLACK}Ciutat
|
STR_FOUND_TOWN_CITY :{BLACK}Ciutat
|
||||||
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Les ciutats creixen més ràpid que els pobles{}Depenent de la configuració, són més grans quan es funden
|
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Les ciutats creixen més ràpid que els pobles{}Depenent de la configuració, són més grans quan es funden
|
||||||
|
|
||||||
|
STR_FOUND_TOWN_EXPAND_MODE :{YELLOW}Expansió de la població:
|
||||||
|
STR_FOUND_TOWN_EXPAND_BUILDINGS :Edificis
|
||||||
|
STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP :Augmenta el nombre d'edificis de les poblacions.
|
||||||
|
STR_FOUND_TOWN_EXPAND_ROADS :Carreteres
|
||||||
|
STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP :Augmenta el nombre de carreteres de la població.
|
||||||
|
|
||||||
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Disposició de les carreteres de la població:
|
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Disposició de les carreteres de la població:
|
||||||
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Selecciona la disposició de les carreteres utilitzades per a aquesta població
|
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Selecciona la disposició de les carreteres utilitzades per a aquesta població
|
||||||
|
@ -3677,6 +3696,10 @@ STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Canvia e
|
||||||
|
|
||||||
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Eixampla
|
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Eixampla
|
||||||
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Incrementa la mida de la població
|
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Incrementa la mida de la població
|
||||||
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Expandeix els edificis
|
||||||
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Augmenta el nombre d'edificis de la població.
|
||||||
|
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Expandeix les carreteres
|
||||||
|
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Augmenta el nombre de carreteres de la població.
|
||||||
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Esborra
|
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Esborra
|
||||||
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Esborra totalment aquesta població
|
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Esborra totalment aquesta població
|
||||||
|
|
||||||
|
@ -4415,10 +4438,10 @@ STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Mostra l
|
||||||
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Mostra les ordres de l'avió. Ctrl+Clic per mostrar l'horari de l'avió
|
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Mostra les ordres de l'avió. Ctrl+Clic per mostrar l'horari de l'avió
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del tren
|
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del tren. Amb Ctrl+clic, es mostra el grup del tren.
|
||||||
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vehicle
|
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vehicle. Amb Ctrl+clic, es mostra el grup del vehicle.
|
||||||
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vaixell
|
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vaixell. Amb Ctrl+clic, es mostra el grup del vaixell.
|
||||||
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls de l'avió
|
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls de l'aeronau. Amb Ctrl+clic, es mostra el grup de l'aeronau.
|
||||||
|
|
||||||
###length VEHICLE_TYPES
|
###length VEHICLE_TYPES
|
||||||
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Acció actual del tren - Feu clic per parar-lo o engegar-lo.
|
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Acció actual del tren - Feu clic per parar-lo o engegar-lo.
|
||||||
|
@ -4742,14 +4765,15 @@ STR_TIMETABLE_TOOLTIP :{BLACK}Horari -
|
||||||
STR_TIMETABLE_NO_TRAVEL :Sense viatge
|
STR_TIMETABLE_NO_TRAVEL :Sense viatge
|
||||||
STR_TIMETABLE_NOT_TIMETABLEABLE :Viatge (automàtic; programat per la següent ordre manual)
|
STR_TIMETABLE_NOT_TIMETABLEABLE :Viatge (automàtic; programat per la següent ordre manual)
|
||||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Viatge (fora d'horari)
|
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Viatge (fora d'horari)
|
||||||
|
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Viatja (sense horari) com a molt a {VELOCITY}
|
||||||
STR_TIMETABLE_TRAVEL_FOR :Viatge a {STRING}
|
STR_TIMETABLE_TRAVEL_FOR :Viatge a {STRING}
|
||||||
STR_TIMETABLE_TRAVEL_FOR_SPEED :Viatja durant {STRING} com a molt a {VELOCITY}
|
STR_TIMETABLE_TRAVEL_FOR_SPEED :Viatja durant {STRING} com a molt a {VELOCITY}
|
||||||
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viatja (durant {STRING}, sense horari)
|
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viatja (durant {STRING}, sense horari)
|
||||||
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viatja (durant {STRING}, sense horari) com a molt a {VELOCITY}
|
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viatja (durant {STRING}, sense horari) com a molt a {VELOCITY}
|
||||||
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(quedar-s'hi durant {STRING}, sense horari)
|
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(quedar-s'hi durant {STRING}, sense horari)
|
||||||
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(viatja durant {STRING}, sense horari)
|
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(viatja durant {STRING}, sense horari)
|
||||||
STR_TIMETABLE_STAY_FOR :i estigues {STRING}
|
STR_TIMETABLE_STAY_FOR :{SPACE}i estigues {STRING}
|
||||||
STR_TIMETABLE_AND_TRAVEL_FOR :i viatge per {STRING}
|
STR_TIMETABLE_AND_TRAVEL_FOR :{SPACE}i viatja durant {STRING}
|
||||||
|
|
||||||
STR_TIMETABLE_APPROX_TIME :{BLACK}L'horari trigara aproximadament {STRING} a completar-se.
|
STR_TIMETABLE_APPROX_TIME :{BLACK}L'horari trigara aproximadament {STRING} a completar-se.
|
||||||
STR_TIMETABLE_TOTAL_TIME :{BLACK}L'horari tardarà {STRING} a complir-se
|
STR_TIMETABLE_TOTAL_TIME :{BLACK}L'horari tardarà {STRING} a complir-se
|
||||||
|
@ -4978,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Es neces
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreny inclinat en direcció incorrecta
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreny inclinat en direcció incorrecta
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Això no es pot fer...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Això no es pot fer...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}L'edifici s'ha d'enderrocar primer
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}L'edifici s'ha d'enderrocar primer
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... l'edifici està protegit
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}No es pot netejar aquesta àrea...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}No es pot netejar aquesta àrea...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... lloc inadequat
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... lloc inadequat
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... ja construït
|
STR_ERROR_ALREADY_BUILT :{WHITE}... ja construït
|
||||||
|
@ -5897,3 +5922,11 @@ STR_SHIP :{BLACK}{SHIP}
|
||||||
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
||||||
|
|
||||||
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
||||||
|
STR_BADGE_CONFIG_MENU_TOOLTIP :Obre la configuració d'insígnies
|
||||||
|
STR_BADGE_CONFIG_RESET :Restableix
|
||||||
|
STR_BADGE_CONFIG_ICONS :{WHITE}Icones d'insígnies
|
||||||
|
STR_BADGE_CONFIG_FILTERS :{WHITE}Filtres d'insígnies
|
||||||
|
STR_BADGE_CONFIG_PREVIEW :Imatge de previsualització
|
||||||
|
STR_BADGE_CONFIG_NAME :Nom
|
||||||
|
STR_BADGE_FILTER_ANY_LABEL :Qualsevol {STRING}
|
||||||
|
STR_BADGE_FILTER_IS_LABEL :{STRING} és {STRING}
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}jaar
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" en}
|
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" en}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}year
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
||||||
|
@ -5000,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Flat lan
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Can't do this...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Can't do this...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... building is protected
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... site unsuitable
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... site unsuitable
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... already built
|
STR_ERROR_ALREADY_BUILT :{WHITE}... already built
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}year
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
||||||
|
@ -5000,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Flat lan
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Can't do this...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Can't do this...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... building is protected
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... site unsuitable
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... site unsuitable
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... already built
|
STR_ERROR_ALREADY_BUILT :{WHITE}... already built
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}year
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}period{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
STR_LIST_FILTER_TITLE :{BLACK}Filter:
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}vuo{
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}jakso{P "" a}
|
STR_UNITS_PERIODS :{NUM}{NBSP}jakso{P "" a}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :…
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Suodatin:
|
STR_LIST_FILTER_TITLE :{BLACK}Suodatin:
|
||||||
|
@ -5000,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Tarvitaa
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa viettää väärään suuntaan.
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa viettää väärään suuntaan.
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Ei onnistu...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Ei onnistu...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Rakennus täytyy purkaa ensin.
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Rakennus täytyy purkaa ensin.
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}… rakennus on suojattu
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Aluetta ei voi tyhjentää...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Aluetta ei voi tyhjentää...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... maasto on sopimaton
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... maasto on sopimaton
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... se on jo rakennettu
|
STR_ERROR_ALREADY_BUILT :{WHITE}... se on jo rakennettu
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}ano{
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtrar:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtrar:
|
||||||
|
@ -1302,6 +1303,9 @@ STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :A taxa de inter
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS :Custos de explotación: {STRING}
|
STR_CONFIG_SETTING_RUNNING_COSTS :Custos de explotación: {STRING}
|
||||||
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Establece o nivel de mantemento e custo de operación de vehículos e infraestrutura
|
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Establece o nivel de mantemento e custo de operación de vehículos e infraestrutura
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_LOW :Baixo
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_MEDIUM :Medio
|
||||||
|
STR_CONFIG_SETTING_RUNNING_COSTS_HIGH :Alto
|
||||||
|
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidade de construción: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidade de construción: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita a cantidade de accións construtivas das IAs
|
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita a cantidade de accións construtivas das IAs
|
||||||
|
@ -1324,6 +1328,9 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Sen subvención
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Custos de construción: {STRING}
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Custos de construción: {STRING}
|
||||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa o nivel de custos de construción e compra
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa o nivel de custos de construción e compra
|
||||||
###length 3
|
###length 3
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Baixo
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Medio
|
||||||
|
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HIGH :Alto
|
||||||
|
|
||||||
STR_CONFIG_SETTING_RECESSIONS :Recesións económicas: {STRING}
|
STR_CONFIG_SETTING_RECESSIONS :Recesións económicas: {STRING}
|
||||||
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Se está activado, a economía pode entrar en recesión periódicamente. Durante unha recesión tódalas producións son significativamente máis baixas (volvendo ao nivel anterior cando a recesión remata)
|
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Se está activado, a economía pode entrar en recesión periódicamente. Durante unha recesión tódalas producións son significativamente máis baixas (volvendo ao nivel anterior cando a recesión remata)
|
||||||
|
@ -2079,9 +2086,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A clase de merc
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Xeito de distribución para outros tipos de mercadoría: {STRING}
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Xeito de distribución para outros tipos de mercadoría: {STRING}
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que calquera cantidade de mercadorías pode ser enviada en calquera dirección. "Manual" significa que non haberá distribución automática para estas mercadorías
|
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que calquera cantidade de mercadorías pode ser enviada en calquera dirección. "Manual" significa que non haberá distribución automática para estas mercadorías
|
||||||
###length 3
|
###length 3
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual
|
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manual
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimétrica
|
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asimétrica
|
||||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simétrica
|
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Simétrica
|
||||||
|
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión da distribución: {STRING}
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión da distribución: {STRING}
|
||||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Canto máis alto sexa o valor, máis tempo de CPU levará o cálculo de distribución. Se leva demasiado tempo podes experimentar retraso. Se sen embargo o fixas nun valor baixo, a distribución será imprecisa, e pode que a carga non sexa enviada aos destinos que ti queres
|
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Canto máis alto sexa o valor, máis tempo de CPU levará o cálculo de distribución. Se leva demasiado tempo podes experimentar retraso. Se sen embargo o fixas nun valor baixo, a distribución será imprecisa, e pode que a carga non sexa enviada aos destinos que ti queres
|
||||||
|
|
|
@ -329,6 +329,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}έτ
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}περίοδ{P 0 ος οι}
|
STR_UNITS_PERIODS :{NUM}{NBSP}περίοδ{P 0 ος οι}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Φιλτράρισμα λίστας:
|
STR_LIST_FILTER_TITLE :{BLACK}Φιλτράρισμα λίστας:
|
||||||
|
@ -5101,6 +5102,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Απαι
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Το έδαφος έχει λάθος κλίση
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Το έδαφος έχει λάθος κλίση
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Αυτό δεν γίνεται...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Αυτό δεν γίνεται...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίριο πρέπει πρώτα να κατεδαφιστεί
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίριο πρέπει πρώτα να κατεδαφιστεί
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... το κτίριο προστατεύεται
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Είναι αδύνατο να καθαριστεί αυτή η περιοχή...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Είναι αδύνατο να καθαριστεί αυτή η περιοχή...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... ακατάλληλη περιοχή
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... ακατάλληλη περιοχή
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κατασκευασμένο
|
STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κατασκευασμένο
|
||||||
|
|
|
@ -330,6 +330,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}év
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}időszak
|
STR_UNITS_PERIODS :{NUM}{NBSP}időszak
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Szűrő kifejezés:
|
STR_LIST_FILTER_TITLE :{BLACK}Szűrő kifejezés:
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}년
|
||||||
STR_UNITS_PERIODS :{NUM}기간
|
STR_UNITS_PERIODS :{NUM}기간
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :…
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}검색:
|
STR_LIST_FILTER_TITLE :{BLACK}검색:
|
||||||
|
|
|
@ -646,6 +646,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}{P r
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}okres{P "" y ów}
|
STR_UNITS_PERIODS :{NUM}{NBSP}okres{P "" y ów}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtr:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtr:
|
||||||
|
@ -5386,6 +5387,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Wymagany
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren pochylony w złym kierunku
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren pochylony w złym kierunku
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Nie można tego zrobić...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Nie można tego zrobić...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Należy najpierw zburzyć budynek
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Należy najpierw zburzyć budynek
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... budynek jest chroniony
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... nieodpowiednie miejsce
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... nieodpowiednie miejsce
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... już zbudowano
|
STR_ERROR_ALREADY_BUILT :{WHITE}... już zbudowano
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}ano{
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtro:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtro:
|
||||||
|
@ -646,7 +647,7 @@ STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Alternar
|
||||||
|
|
||||||
# Company league window
|
# Company league window
|
||||||
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Classificação de Empresas
|
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Classificação de Empresas
|
||||||
STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} '{STRING}'
|
STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} “{STRING}”
|
||||||
STR_COMPANY_LEAGUE_COMPANY_RANK :{YELLOW}#{NUM}
|
STR_COMPANY_LEAGUE_COMPANY_RANK :{YELLOW}#{NUM}
|
||||||
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER :Engenheiro
|
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER :Engenheiro
|
||||||
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER :Gestor de Tráfego
|
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER :Gestor de Tráfego
|
||||||
|
@ -738,7 +739,7 @@ STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Clique n
|
||||||
STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Clique numa faixa para a remover da lista (apenas Personalização 1 ou Personalização 2)
|
STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Clique numa faixa para a remover da lista (apenas Personalização 1 ou Personalização 2)
|
||||||
|
|
||||||
# Highscore window
|
# Highscore window
|
||||||
STR_HIGHSCORE_TOP_COMPANIES :{BIG_FONT}{BLACK}Melhores empresas
|
STR_HIGHSCORE_TOP_COMPANIES :{BIG_FONT}{BLACK}As melhores empresas
|
||||||
STR_HIGHSCORE_POSITION :{BIG_FONT}{BLACK}{COMMA}.
|
STR_HIGHSCORE_POSITION :{BIG_FONT}{BLACK}{COMMA}.
|
||||||
STR_HIGHSCORE_PERFORMANCE_TITLE_BUSINESSMAN :Negociante
|
STR_HIGHSCORE_PERFORMANCE_TITLE_BUSINESSMAN :Negociante
|
||||||
STR_HIGHSCORE_PERFORMANCE_TITLE_ENTREPRENEUR :Empresário
|
STR_HIGHSCORE_PERFORMANCE_TITLE_ENTREPRENEUR :Empresário
|
||||||
|
@ -748,7 +749,7 @@ STR_HIGHSCORE_PERFORMANCE_TITLE_MAGNATE :Magnata
|
||||||
STR_HIGHSCORE_PERFORMANCE_TITLE_MOGUL :Grande magnata
|
STR_HIGHSCORE_PERFORMANCE_TITLE_MOGUL :Grande magnata
|
||||||
STR_HIGHSCORE_PERFORMANCE_TITLE_TYCOON_OF_THE_CENTURY :Magnata do século
|
STR_HIGHSCORE_PERFORMANCE_TITLE_TYCOON_OF_THE_CENTURY :Magnata do século
|
||||||
STR_HIGHSCORE_NAME :{PRESIDENT_NAME}, {COMPANY}
|
STR_HIGHSCORE_NAME :{PRESIDENT_NAME}, {COMPANY}
|
||||||
STR_HIGHSCORE_STATS :{BIG_FONT}'{STRING}' ({COMMA})
|
STR_HIGHSCORE_STATS :{BIG_FONT}"{STRING}" ({COMMA})
|
||||||
STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{BLACK}{COMPANY} conquista o estatuto de '{STRING}'!
|
STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{BLACK}{COMPANY} conquista o estatuto de '{STRING}'!
|
||||||
STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{WHITE}{PRESIDENT_NAME} de {COMPANY} conquista o estatuto de '{STRING}'!
|
STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{WHITE}{PRESIDENT_NAME} de {COMPANY} conquista o estatuto de '{STRING}'!
|
||||||
|
|
||||||
|
@ -3116,8 +3117,8 @@ STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Selecion
|
||||||
# Land area window
|
# Land area window
|
||||||
STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Informações do Terreno
|
STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Informações do Terreno
|
||||||
STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização do mosaico. Ctrl+Clique para abrir uma nova janela de visualização nesse mosaico.
|
STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização do mosaico. Ctrl+Clique para abrir uma nova janela de visualização nesse mosaico.
|
||||||
STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Custo para limpar: {LTBLUE}N/D
|
STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Custo de desobstrução: {LTBLUE}N/D
|
||||||
STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Custo para limpar: {RED}{CURRENCY_LONG}
|
STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Custo de desobstrução: {RED}{CURRENCY_LONG}
|
||||||
STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Receitas apuradas: {LTBLUE}{CURRENCY_LONG}
|
STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Receitas apuradas: {LTBLUE}{CURRENCY_LONG}
|
||||||
STR_LAND_AREA_INFORMATION_OWNER_N_A :N/D
|
STR_LAND_AREA_INFORMATION_OWNER_N_A :N/D
|
||||||
STR_LAND_AREA_INFORMATION_OWNER :{BLACK}Proprietário: {LTBLUE}{STRING}
|
STR_LAND_AREA_INFORMATION_OWNER :{BLACK}Proprietário: {LTBLUE}{STRING}
|
||||||
|
@ -3125,7 +3126,7 @@ STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}Dono da
|
||||||
STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Dono da linha de eléctrico: {LTBLUE}{STRING}
|
STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Dono da linha de eléctrico: {LTBLUE}{STRING}
|
||||||
STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da linha férrea: {LTBLUE}{STRING}
|
STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da linha férrea: {LTBLUE}{STRING}
|
||||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
|
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
|
||||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhum
|
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhuma
|
||||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM}
|
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM}
|
||||||
STR_LAND_AREA_INFORMATION_LANDINFO_INDEX :{BLACK}Índice do mosaico: {LTBLUE}{NUM} ({HEX})
|
STR_LAND_AREA_INFORMATION_LANDINFO_INDEX :{BLACK}Índice do mosaico: {LTBLUE}{NUM} ({HEX})
|
||||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído/renovado: {LTBLUE}{DATE_LONG}
|
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído/renovado: {LTBLUE}{DATE_LONG}
|
||||||
|
@ -3440,20 +3441,20 @@ STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Mudar al
|
||||||
STR_GENERATION_WORLD :{WHITE}A Gerar Mundo...
|
STR_GENERATION_WORLD :{WHITE}A Gerar Mundo...
|
||||||
STR_GENERATION_ABORT :{BLACK}Cancelar
|
STR_GENERATION_ABORT :{BLACK}Cancelar
|
||||||
STR_GENERATION_ABORT_CAPTION :{WHITE}Cancelar criação do mundo
|
STR_GENERATION_ABORT_CAPTION :{WHITE}Cancelar criação do mundo
|
||||||
STR_GENERATION_ABORT_MESSAGE :{YELLOW}Quer mesmo cancelar a criação?
|
STR_GENERATION_ABORT_MESSAGE :{YELLOW}Quer mesmo cancelar o processo de geração?
|
||||||
STR_GENERATION_PROGRESS :{WHITE}{NUM}% completo
|
STR_GENERATION_PROGRESS :{WHITE}{NUM}% completo
|
||||||
STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM}
|
STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM}
|
||||||
STR_GENERATION_WORLD_GENERATION :{BLACK}A gerar mundo
|
STR_GENERATION_WORLD_GENERATION :{BLACK}A gerar mundo
|
||||||
STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Geração de paisagem
|
STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}A gerar paisagem
|
||||||
STR_GENERATION_RIVER_GENERATION :{BLACK}A gerar rios
|
STR_GENERATION_RIVER_GENERATION :{BLACK}A gerar rios
|
||||||
STR_GENERATION_CLEARING_TILES :{BLACK}A gerar zonas rochosas e montanhosas
|
STR_GENERATION_CLEARING_TILES :{BLACK}A gerar zonas rochosas e montanhosas
|
||||||
STR_GENERATION_TOWN_GENERATION :{BLACK}Geração de localidades
|
STR_GENERATION_TOWN_GENERATION :{BLACK}A gerar localidades
|
||||||
STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Geração de indústrias
|
STR_GENERATION_INDUSTRY_GENERATION :{BLACK}A gerar indústrias
|
||||||
STR_GENERATION_OBJECT_GENERATION :{BLACK}Geração inamovível
|
STR_GENERATION_OBJECT_GENERATION :{BLACK}A gerar objetos
|
||||||
STR_GENERATION_TREE_GENERATION :{BLACK}A gerar árvores
|
STR_GENERATION_TREE_GENERATION :{BLACK}A gerar árvores
|
||||||
STR_GENERATION_SETTINGUP_GAME :{BLACK}Definindo jogo
|
STR_GENERATION_SETTINGUP_GAME :{BLACK}A configurar jogo
|
||||||
STR_GENERATION_PREPARING_TILELOOP :{BLACK}A preparar o terreno
|
STR_GENERATION_PREPARING_TILELOOP :{BLACK}A preparar o terreno
|
||||||
STR_GENERATION_PREPARING_SCRIPT :{BLACK}Script a correr
|
STR_GENERATION_PREPARING_SCRIPT :{BLACK}A correr script
|
||||||
STR_GENERATION_PREPARING_GAME :{BLACK}A preparar jogo
|
STR_GENERATION_PREPARING_GAME :{BLACK}A preparar jogo
|
||||||
|
|
||||||
STR_TOWN_DATA_ERROR_LOAD_FAILED :{WHITE}Falha ao carregar dados da localidade
|
STR_TOWN_DATA_ERROR_LOAD_FAILED :{WHITE}Falha ao carregar dados da localidade
|
||||||
|
@ -3684,9 +3685,9 @@ STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{BLACK}No inver
|
||||||
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} fo{G 0 i i i ram ram} entregue{G 0 "" "" "" s s}
|
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} fo{G 0 i i i ram ram} entregue{G 0 "" "" "" s s}
|
||||||
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{RED} (ainda necessário)
|
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{RED} (ainda necessário)
|
||||||
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{GREEN} (entregue)
|
STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{GREEN} (entregue)
|
||||||
STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}Localidade cresce a cada {ORANGE}{UNITS_DAYS_OR_SECONDS}
|
STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}A localidade cresce a cada {ORANGE}{UNITS_DAYS_OR_SECONDS}
|
||||||
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Localidade cresce a cada {ORANGE}{UNITS_DAYS_OR_SECONDS} (financiada)
|
STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}A localidade cresce a cada {ORANGE}{UNITS_DAYS_OR_SECONDS} (financiada)
|
||||||
STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Localidade {RED}não{BLACK} está a crescer
|
STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}A localidade {RED}não{BLACK} está a crescer
|
||||||
STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Limite de ruído na localidade: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
|
STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Limite de ruído na localidade: {ORANGE}{COMMA}{BLACK} máx: {ORANGE}{COMMA}
|
||||||
STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centrar visualização na localização da localidade. Ctrl+Clique para abrir um novo visualizador na localização da localidade
|
STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centrar visualização na localização da localidade. Ctrl+Clique para abrir um novo visualizador na localização da localidade
|
||||||
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Autoridade Local
|
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Autoridade Local
|
||||||
|
@ -3699,7 +3700,7 @@ STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Expandir
|
||||||
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Aumentar os edifícios da localidade
|
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Aumentar os edifícios da localidade
|
||||||
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Expandir estradas
|
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Expandir estradas
|
||||||
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Aumentar as estradas da localidade
|
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Aumentar as estradas da localidade
|
||||||
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Apagar
|
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Remover
|
||||||
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Remover completamente esta localidade
|
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Remover completamente esta localidade
|
||||||
|
|
||||||
STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Renomear Localidade
|
STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Renomear Localidade
|
||||||
|
@ -3942,7 +3943,7 @@ STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infraest
|
||||||
STR_COMPANY_VIEW_CAPTION :{WHITE}{COMPANY} {BLACK}{COMPANY_NUM}
|
STR_COMPANY_VIEW_CAPTION :{WHITE}{COMPANY} {BLACK}{COMPANY_NUM}
|
||||||
STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE :{WHITE}{PRESIDENT_NAME}{}{GOLD}(Presidente)
|
STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE :{WHITE}{PRESIDENT_NAME}{}{GOLD}(Presidente)
|
||||||
|
|
||||||
STR_COMPANY_VIEW_INAUGURATED_TITLE :{GOLD}Inaugurado: {WHITE}{NUM}
|
STR_COMPANY_VIEW_INAUGURATED_TITLE :{GOLD}Inaugurada em: {WHITE}{NUM}
|
||||||
STR_COMPANY_VIEW_INAUGURATED_TITLE_WALLCLOCK :{GOLD}Inaugurada: {WHITE}{NUM} (período {NUM})
|
STR_COMPANY_VIEW_INAUGURATED_TITLE_WALLCLOCK :{GOLD}Inaugurada: {WHITE}{NUM} (período {NUM})
|
||||||
STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE :{GOLD}Cores:
|
STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE :{GOLD}Cores:
|
||||||
STR_COMPANY_VIEW_VEHICLES_TITLE :{GOLD}Veículos:
|
STR_COMPANY_VIEW_VEHICLES_TITLE :{GOLD}Veículos:
|
||||||
|
@ -5001,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}É neces
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direcção incorrecta
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direcção incorrecta
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... o edifício está protegido
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... sítio inadequado
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... sítio inadequado
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... já está construído
|
STR_ERROR_ALREADY_BUILT :{WHITE}... já está construído
|
||||||
|
|
|
@ -393,6 +393,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}{P
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}цикл{P "" а ов}
|
STR_UNITS_PERIODS :{NUM}{NBSP}цикл{P "" а ов}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Фильтр:
|
STR_LIST_FILTER_TITLE :{BLACK}Фильтр:
|
||||||
|
@ -5187,6 +5188,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Необ
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Неверный уклон земли
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Неверный уклон земли
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Это невозможно...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}Это невозможно...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сначала снесите здания
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сначала снесите здания
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... это здание защищено от изменений
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить данный участок...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить данный участок...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... неподходящее место
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... неподходящее место
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}... уже построено
|
STR_ERROR_ALREADY_BUILT :{WHITE}... уже построено
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}年
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}个周期
|
STR_UNITS_PERIODS :{NUM}{NBSP}个周期
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :、
|
STR_LIST_SEPARATOR :、
|
||||||
|
STR_TRUNCATION_ELLIPSIS :…
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}搜索:
|
STR_LIST_FILTER_TITLE :{BLACK}搜索:
|
||||||
|
@ -5000,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}需要
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}土地倾斜的方向不对
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}土地倾斜的方向不对
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能这样做……
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能这样做……
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必须先摧毁建筑
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必须先摧毁建筑
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}……建筑物被保护
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}无法清除这个区域……
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}无法清除这个区域……
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}……地点不合适
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}……地点不合适
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}……已经建成
|
STR_ERROR_ALREADY_BUILT :{WHITE}……已经建成
|
||||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}año
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
STR_UNITS_PERIODS :{NUM}{NBSP}período{P "" s}
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :,{SPACE}
|
STR_LIST_SEPARATOR :,{SPACE}
|
||||||
|
STR_TRUNCATION_ELLIPSIS :...
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}Filtrar:
|
STR_LIST_FILTER_TITLE :{BLACK}Filtrar:
|
||||||
|
|
|
@ -267,6 +267,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}年
|
||||||
STR_UNITS_PERIODS :{NUM}{NBSP}個週期
|
STR_UNITS_PERIODS :{NUM}{NBSP}個週期
|
||||||
|
|
||||||
STR_LIST_SEPARATOR :、
|
STR_LIST_SEPARATOR :、
|
||||||
|
STR_TRUNCATION_ELLIPSIS :……
|
||||||
|
|
||||||
# Common window strings
|
# Common window strings
|
||||||
STR_LIST_FILTER_TITLE :{BLACK}篩選:
|
STR_LIST_FILTER_TITLE :{BLACK}篩選:
|
||||||
|
@ -1355,8 +1356,8 @@ STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :可以在建築
|
||||||
STR_CONFIG_SETTING_CATCHMENT :容許更真實的服務範圍設定:{STRING}
|
STR_CONFIG_SETTING_CATCHMENT :容許更真實的服務範圍設定:{STRING}
|
||||||
STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :使車站和機場的服務範圍根據其種類和大小而改變。
|
STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :使車站和機場的服務範圍根據其種類和大小而改變。
|
||||||
|
|
||||||
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :公司車站可以為自帶車站的工業設施提供服務:{STRING}
|
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :公司車站可以服務附設車站的工業設施:{STRING}
|
||||||
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :啟用後,公司車站可以為附近自帶車站的工業設施(如油井)提供服務。禁用後,這些工業設施只能由其自帶的車站提供服務,並且這些車站不會提供除了該工業設施以外的產品
|
STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :啟用後,公司車站可以為附近附設車站的工業(如鑽油平台)提供服務。停用後,這些工業只能由其附設的車站提供服務,並且附設車站不會提供除了該工業設施以外的任何服務
|
||||||
|
|
||||||
STR_CONFIG_SETTING_EXTRADYNAMITE :允許移除更多市鎮擁有的道路、橋樑及隧道:{STRING}
|
STR_CONFIG_SETTING_EXTRADYNAMITE :允許移除更多市鎮擁有的道路、橋樑及隧道:{STRING}
|
||||||
STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :使玩家更容易地移除市鎮擁有的基礎建設和建築物。
|
STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :使玩家更容易地移除市鎮擁有的基礎建設和建築物。
|
||||||
|
@ -5000,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}需要
|
||||||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}地面斜坡方向不對
|
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}地面斜坡方向不對
|
||||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能執行以下動作...
|
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能執行以下動作...
|
||||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必須先摧毀建築物
|
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必須先摧毀建築物
|
||||||
|
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}……建築物被保護
|
||||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}不能清除這個地段...
|
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}不能清除這個地段...
|
||||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... 地點不適合
|
STR_ERROR_SITE_UNSUITABLE :{WHITE}... 地點不適合
|
||||||
STR_ERROR_ALREADY_BUILT :{WHITE}……經已建成
|
STR_ERROR_ALREADY_BUILT :{WHITE}……經已建成
|
||||||
|
|
|
@ -8,5 +8,7 @@ add_files(
|
||||||
getoptdata.cpp
|
getoptdata.cpp
|
||||||
getoptdata.h
|
getoptdata.h
|
||||||
hashtable.hpp
|
hashtable.hpp
|
||||||
|
history_func.hpp
|
||||||
|
history_type.hpp
|
||||||
lrucache.hpp
|
lrucache.hpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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 history_func.hpp Functions for storing historical data. */
|
||||||
|
|
||||||
|
#ifndef HISTORY_FUNC_HPP
|
||||||
|
#define HISTORY_FUNC_HPP
|
||||||
|
|
||||||
|
#include "../core/bitmath_func.hpp"
|
||||||
|
#include "history_type.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update mask of valid history records.
|
||||||
|
* @param[in,out] valid_history Valid history records.
|
||||||
|
*/
|
||||||
|
inline void UpdateValidHistory(ValidHistoryMask &valid_history)
|
||||||
|
{
|
||||||
|
SB(valid_history, LAST_MONTH, HISTORY_RECORDS - LAST_MONTH, GB(valid_history, LAST_MONTH, HISTORY_RECORDS - LAST_MONTH) << 1ULL | 1ULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate history.
|
||||||
|
* @tparam T type of history data element.
|
||||||
|
* @param history Historical data to rotate.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void RotateHistory(HistoryData<T> &history)
|
||||||
|
{
|
||||||
|
std::rotate(std::rbegin(history), std::rbegin(history) + 1, std::rend(history));
|
||||||
|
history[THIS_MONTH] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill some data with historical data.
|
||||||
|
* @param history Historical data to fill from.
|
||||||
|
* @param valid_history Mask of valid history records.
|
||||||
|
* @param fillers Fillers to fill with history data.
|
||||||
|
*/
|
||||||
|
template <uint N, typename T, typename... Tfillers>
|
||||||
|
void FillFromHistory(const HistoryData<T> &history, ValidHistoryMask valid_history, Tfillers... fillers)
|
||||||
|
{
|
||||||
|
for (uint i = 0; i != N; ++i) {
|
||||||
|
if (HasBit(valid_history, N - i)) {
|
||||||
|
auto &data = history[N - i];
|
||||||
|
(fillers.Fill(i, data), ...);
|
||||||
|
} else {
|
||||||
|
(fillers.MakeInvalid(i), ...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HISTORY_FUNC_HPP */
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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 history_type.hpp Types for storing historical data. */
|
||||||
|
|
||||||
|
#ifndef HISTORY_TYPE_HPP
|
||||||
|
#define HISTORY_TYPE_HPP
|
||||||
|
|
||||||
|
static constexpr uint8_t HISTORY_RECORDS = 25;
|
||||||
|
|
||||||
|
static constexpr uint8_t THIS_MONTH = 0;
|
||||||
|
static constexpr uint8_t LAST_MONTH = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container type for storing history data.
|
||||||
|
* @tparam T type of history data.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
using HistoryData = std::array<T, HISTORY_RECORDS>;
|
||||||
|
|
||||||
|
/** Mask of valid history records. */
|
||||||
|
using ValidHistoryMask = uint64_t;
|
||||||
|
|
||||||
|
#endif /* HISTORY_TYPE_HPP */
|
|
@ -105,8 +105,8 @@ static ChangeInfoResult RoadStopChangeInfo(uint first, uint last, int prop, Byte
|
||||||
AddStringForMapping(GRFStringID{buf.ReadWord()}, [rs = rs.get()](StringID str) { RoadStopClass::Get(rs->class_index)->name = str; });
|
AddStringForMapping(GRFStringID{buf.ReadWord()}, [rs = rs.get()](StringID str) { RoadStopClass::Get(rs->class_index)->name = str; });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0C: // The draw mode
|
case 0x0C: // The draw modes
|
||||||
rs->draw_mode = static_cast<RoadStopDrawMode>(buf.ReadByte());
|
rs->draw_mode = static_cast<RoadStopDrawModes>(buf.ReadByte());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0D: // Cargo types for random triggers
|
case 0x0D: // Cargo types for random triggers
|
||||||
|
|
|
@ -476,7 +476,7 @@ CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span
|
||||||
/* If this error isn't for the local player then it won't be seen, so don't bother encoding anything. */
|
/* If this error isn't for the local player then it won't be seen, so don't bother encoding anything. */
|
||||||
if (IsLocalCompany()) {
|
if (IsLocalCompany()) {
|
||||||
StringID stringid = GetGRFStringID(grffile->grfid, text_id);
|
StringID stringid = GetGRFStringID(grffile->grfid, text_id);
|
||||||
auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack);
|
auto params = GetGRFStringTextStackParameters(grffile, stringid, textstack);
|
||||||
res.SetEncodedMessage(GetEncodedStringWithArgs(stringid, params));
|
res.SetEncodedMessage(GetEncodedStringWithArgs(stringid, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec,
|
||||||
|
|
||||||
RoadStopDrawModes draw_mode;
|
RoadStopDrawModes draw_mode;
|
||||||
if (spec->flags.Test(RoadStopSpecFlag::DrawModeRegister)) {
|
if (spec->flags.Test(RoadStopSpecFlag::DrawModeRegister)) {
|
||||||
draw_mode = static_cast<RoadStopDrawMode>(object.GetRegister(0x100));
|
draw_mode = static_cast<RoadStopDrawModes>(object.GetRegister(0x100));
|
||||||
} else {
|
} else {
|
||||||
draw_mode = spec->draw_mode;
|
draw_mode = spec->draw_mode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -973,7 +973,7 @@ static void HandleNewGRFStringControlCodes(std::string_view str, TextRefStack &s
|
||||||
* @param textstack Text parameter stack.
|
* @param textstack Text parameter stack.
|
||||||
* @returns Parameters for GRF string.
|
* @returns Parameters for GRF string.
|
||||||
*/
|
*/
|
||||||
std::vector<StringParameter> GetGRFSringTextStackParameters(const GRFFile *grffile, StringID stringid, std::span<const int32_t> textstack)
|
std::vector<StringParameter> GetGRFStringTextStackParameters(const GRFFile *grffile, StringID stringid, std::span<const int32_t> textstack)
|
||||||
{
|
{
|
||||||
if (stringid == INVALID_STRING_ID) return {};
|
if (stringid == INVALID_STRING_ID) return {};
|
||||||
|
|
||||||
|
@ -998,6 +998,6 @@ std::vector<StringParameter> GetGRFSringTextStackParameters(const GRFFile *grffi
|
||||||
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span<const int32_t> textstack)
|
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span<const int32_t> textstack)
|
||||||
{
|
{
|
||||||
StringID stringid = GetGRFStringID(grffile->grfid, grfstringid);
|
StringID stringid = GetGRFStringID(grffile->grfid, grfstringid);
|
||||||
auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack);
|
auto params = GetGRFStringTextStackParameters(grffile, stringid, textstack);
|
||||||
return GetStringWithArgs(stringid, params);
|
return GetStringWithArgs(stringid, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ void AddGRFTextToList(GRFTextWrapper &list, std::string_view text_to_add);
|
||||||
|
|
||||||
bool CheckGrfLangID(uint8_t lang_id, uint8_t grf_version);
|
bool CheckGrfLangID(uint8_t lang_id, uint8_t grf_version);
|
||||||
|
|
||||||
std::vector<StringParameter> GetGRFSringTextStackParameters(const struct GRFFile *grffile, StringID stringid, std::span<const int32_t> textstack);
|
std::vector<StringParameter> GetGRFStringTextStackParameters(const struct GRFFile *grffile, StringID stringid, std::span<const int32_t> textstack);
|
||||||
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span<const int32_t> textstack);
|
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span<const int32_t> textstack);
|
||||||
|
|
||||||
#endif /* NEWGRF_TEXT_H */
|
#endif /* NEWGRF_TEXT_H */
|
||||||
|
|
|
@ -700,7 +700,7 @@ int openttd_main(std::span<std::string_view> arguments)
|
||||||
InitializeLanguagePacks();
|
InitializeLanguagePacks();
|
||||||
|
|
||||||
/* Initialize the font cache */
|
/* Initialize the font cache */
|
||||||
InitFontCache(false);
|
InitFontCache(FONTSIZES_REQUIRED);
|
||||||
|
|
||||||
/* This must be done early, since functions use the SetWindowDirty* calls */
|
/* This must be done early, since functions use the SetWindowDirty* calls */
|
||||||
InitWindowSystem();
|
InitWindowSystem();
|
||||||
|
|
|
@ -182,6 +182,6 @@ bool SetFallbackFont(FontCacheSettings *settings, const std::string &language_is
|
||||||
if (best_font == nullptr) return false;
|
if (best_font == nullptr) return false;
|
||||||
|
|
||||||
callback->SetFontNames(settings, best_font, &best_index);
|
callback->SetFontNames(settings, best_font, &best_index);
|
||||||
InitFontCache(callback->Monospace());
|
InitFontCache(callback->Monospace() ? FontSizes{FS_MONO} : FONTSIZES_REQUIRED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,8 @@ static const SaveLoad _industry_desc[] = {
|
||||||
SLE_CONDVAR(Industry, random, SLE_UINT16, SLV_82, SL_MAX_VERSION),
|
SLE_CONDVAR(Industry, random, SLE_UINT16, SLV_82, SL_MAX_VERSION),
|
||||||
SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION),
|
SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION),
|
||||||
|
|
||||||
|
SLE_CONDVAR(Industry, valid_history, SLE_UINT64, SLV_INDUSTRY_NUM_VALID_HISTORY, SL_MAX_VERSION),
|
||||||
|
|
||||||
SLEG_CONDSTRUCTLIST("accepted", SlIndustryAccepted, SLV_INDUSTRY_CARGO_REORGANISE, SL_MAX_VERSION),
|
SLEG_CONDSTRUCTLIST("accepted", SlIndustryAccepted, SLV_INDUSTRY_CARGO_REORGANISE, SL_MAX_VERSION),
|
||||||
SLEG_CONDSTRUCTLIST("produced", SlIndustryProduced, SLV_INDUSTRY_CARGO_REORGANISE, SL_MAX_VERSION),
|
SLEG_CONDSTRUCTLIST("produced", SlIndustryProduced, SLV_INDUSTRY_CARGO_REORGANISE, SL_MAX_VERSION),
|
||||||
};
|
};
|
||||||
|
@ -228,6 +230,24 @@ struct INDYChunkHandler : ChunkHandler {
|
||||||
} else if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) {
|
} else if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) {
|
||||||
LoadMoveAcceptsProduced(i, INDUSTRY_NUM_INPUTS, INDUSTRY_NUM_OUTPUTS);
|
LoadMoveAcceptsProduced(i, INDUSTRY_NUM_INPUTS, INDUSTRY_NUM_OUTPUTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsSavegameVersionBefore(SLV_INDUSTRY_NUM_VALID_HISTORY)) {
|
||||||
|
/* The last month has always been recorded. */
|
||||||
|
size_t oldest_valid = LAST_MONTH;
|
||||||
|
if (!IsSavegameVersionBefore(SLV_PRODUCTION_HISTORY)) {
|
||||||
|
/* History was extended but we did not keep track of valid history, so assume it from the oldest non-zero value. */
|
||||||
|
for (const auto &p : i->produced) {
|
||||||
|
if (!IsValidCargoType(p.cargo)) continue;
|
||||||
|
for (size_t n = LAST_MONTH; n < std::size(p.history); ++n) {
|
||||||
|
if (p.history[n].production == 0 && p.history[n].transported == 0) continue;
|
||||||
|
oldest_valid = std::max(oldest_valid, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Set mask bits up to and including the oldest valid record. */
|
||||||
|
i->valid_history = (std::numeric_limits<uint64_t>::max() >> (std::numeric_limits<uint64_t>::digits - (oldest_valid + 1 - LAST_MONTH))) << LAST_MONTH;
|
||||||
|
}
|
||||||
|
|
||||||
Industry::industries[i->type].insert(i->index);
|
Industry::industries[i->type].insert(i->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,6 +404,7 @@ enum SaveLoadVersion : uint16_t {
|
||||||
SLV_ORDERS_OWNED_BY_ORDERLIST, ///< 354 PR#13948 Orders stored in OrderList, pool removed.
|
SLV_ORDERS_OWNED_BY_ORDERLIST, ///< 354 PR#13948 Orders stored in OrderList, pool removed.
|
||||||
|
|
||||||
SLV_FACE_STYLES, ///< 355 PR#14319 Addition of face styles, replacing gender and ethnicity.
|
SLV_FACE_STYLES, ///< 355 PR#14319 Addition of face styles, replacing gender and ethnicity.
|
||||||
|
SLV_INDUSTRY_NUM_VALID_HISTORY, ///< 356 PR#14416 Store number of valid history records for industries.
|
||||||
|
|
||||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,7 +76,7 @@ ScriptController::ScriptController(::CompanyID company) :
|
||||||
|
|
||||||
/* static */ uint ScriptController::GetTick()
|
/* static */ uint ScriptController::GetTick()
|
||||||
{
|
{
|
||||||
return ScriptObject::GetActiveInstance().GetController()->ticks;
|
return ScriptObject::GetActiveInstance().GetController().ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ int ScriptController::GetOpsTillSuspend()
|
/* static */ int ScriptController::GetOpsTillSuspend()
|
||||||
|
@ -96,9 +96,9 @@ ScriptController::ScriptController(::CompanyID company) :
|
||||||
|
|
||||||
/* static */ HSQOBJECT ScriptController::Import(const std::string &library, const std::string &class_name, int version)
|
/* static */ HSQOBJECT ScriptController::Import(const std::string &library, const std::string &class_name, int version)
|
||||||
{
|
{
|
||||||
ScriptController *controller = ScriptObject::GetActiveInstance().GetController();
|
ScriptController &controller = ScriptObject::GetActiveInstance().GetController();
|
||||||
Squirrel *engine = ScriptObject::GetActiveInstance().engine;
|
Squirrel &engine = *ScriptObject::GetActiveInstance().engine;
|
||||||
HSQUIRRELVM vm = engine->GetVM();
|
HSQUIRRELVM vm = engine.GetVM();
|
||||||
|
|
||||||
ScriptInfo *lib = ScriptObject::GetActiveInstance().FindLibrary(library, version);
|
ScriptInfo *lib = ScriptObject::GetActiveInstance().FindLibrary(library, version);
|
||||||
if (lib == nullptr) {
|
if (lib == nullptr) {
|
||||||
|
@ -114,11 +114,11 @@ ScriptController::ScriptController(::CompanyID company) :
|
||||||
|
|
||||||
std::string fake_class;
|
std::string fake_class;
|
||||||
|
|
||||||
LoadedLibraryList::iterator it = controller->loaded_library.find(library_name);
|
LoadedLibraryList::iterator it = controller.loaded_library.find(library_name);
|
||||||
if (it != controller->loaded_library.end()) {
|
if (it != controller.loaded_library.end()) {
|
||||||
fake_class = (*it).second;
|
fake_class = (*it).second;
|
||||||
} else {
|
} else {
|
||||||
int next_number = ++controller->loaded_library_count;
|
int next_number = ++controller.loaded_library_count;
|
||||||
|
|
||||||
/* Create a new fake internal name */
|
/* Create a new fake internal name */
|
||||||
fake_class = fmt::format("_internalNA{}", next_number);
|
fake_class = fmt::format("_internalNA{}", next_number);
|
||||||
|
@ -128,14 +128,14 @@ ScriptController::ScriptController(::CompanyID company) :
|
||||||
sq_pushstring(vm, fake_class);
|
sq_pushstring(vm, fake_class);
|
||||||
sq_newclass(vm, SQFalse);
|
sq_newclass(vm, SQFalse);
|
||||||
/* Load the library */
|
/* Load the library */
|
||||||
if (!engine->LoadScript(vm, lib->GetMainScript(), false)) {
|
if (!engine.LoadScript(vm, lib->GetMainScript(), false)) {
|
||||||
throw sq_throwerror(vm, fmt::format("there was a compile error when importing '{}' version {}", library, version));
|
throw sq_throwerror(vm, fmt::format("there was a compile error when importing '{}' version {}", library, version));
|
||||||
}
|
}
|
||||||
/* Create the fake class */
|
/* Create the fake class */
|
||||||
sq_newslot(vm, -3, SQFalse);
|
sq_newslot(vm, -3, SQFalse);
|
||||||
sq_pop(vm, 1);
|
sq_pop(vm, 1);
|
||||||
|
|
||||||
controller->loaded_library[library_name] = fake_class;
|
controller.loaded_library[library_name] = fake_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the real class inside the fake class (like 'sets.Vector') */
|
/* Find the real class inside the fake class (like 'sets.Vector') */
|
||||||
|
|
|
@ -45,7 +45,7 @@ void SimpleCountedObject::Release()
|
||||||
* Get the storage associated with the current ScriptInstance.
|
* Get the storage associated with the current ScriptInstance.
|
||||||
* @return The storage.
|
* @return The storage.
|
||||||
*/
|
*/
|
||||||
static ScriptStorage *GetStorage()
|
static ScriptStorage &GetStorage()
|
||||||
{
|
{
|
||||||
return ScriptObject::GetActiveInstance().GetStorage();
|
return ScriptObject::GetActiveInstance().GetStorage();
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ static ScriptStorage *GetStorage()
|
||||||
|
|
||||||
/* static */ ScriptInstance *ScriptObject::ActiveInstance::active = nullptr;
|
/* static */ ScriptInstance *ScriptObject::ActiveInstance::active = nullptr;
|
||||||
|
|
||||||
ScriptObject::ActiveInstance::ActiveInstance(ScriptInstance &instance) : alc_scope(instance.engine)
|
ScriptObject::ActiveInstance::ActiveInstance(ScriptInstance &instance) : alc_scope(instance.engine.get())
|
||||||
{
|
{
|
||||||
this->last_active = ScriptObject::ActiveInstance::active;
|
this->last_active = ScriptObject::ActiveInstance::active;
|
||||||
ScriptObject::ActiveInstance::active = &instance;
|
ScriptObject::ActiveInstance::active = &instance;
|
||||||
|
@ -65,7 +65,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptObject::DisableDoCommandScope::DisableDoCommandScope()
|
ScriptObject::DisableDoCommandScope::DisableDoCommandScope()
|
||||||
: AutoRestoreBackup(GetStorage()->allow_do_command, false)
|
: AutoRestoreBackup(GetStorage().allow_do_command, false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/* static */ ScriptInstance &ScriptObject::GetActiveInstance()
|
/* static */ ScriptInstance &ScriptObject::GetActiveInstance()
|
||||||
|
@ -78,181 +78,181 @@ ScriptObject::DisableDoCommandScope::DisableDoCommandScope()
|
||||||
/* static */ void ScriptObject::SetDoCommandDelay(uint ticks)
|
/* static */ void ScriptObject::SetDoCommandDelay(uint ticks)
|
||||||
{
|
{
|
||||||
assert(ticks > 0);
|
assert(ticks > 0);
|
||||||
GetStorage()->delay = ticks;
|
GetStorage().delay = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ uint ScriptObject::GetDoCommandDelay()
|
/* static */ uint ScriptObject::GetDoCommandDelay()
|
||||||
{
|
{
|
||||||
return GetStorage()->delay;
|
return GetStorage().delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetDoCommandMode(ScriptModeProc *proc, ScriptObject *instance)
|
/* static */ void ScriptObject::SetDoCommandMode(ScriptModeProc *proc, ScriptObject *instance)
|
||||||
{
|
{
|
||||||
GetStorage()->mode = proc;
|
GetStorage().mode = proc;
|
||||||
GetStorage()->mode_instance = instance;
|
GetStorage().mode_instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptModeProc *ScriptObject::GetDoCommandMode()
|
/* static */ ScriptModeProc *ScriptObject::GetDoCommandMode()
|
||||||
{
|
{
|
||||||
return GetStorage()->mode;
|
return GetStorage().mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptObject *ScriptObject::GetDoCommandModeInstance()
|
/* static */ ScriptObject *ScriptObject::GetDoCommandModeInstance()
|
||||||
{
|
{
|
||||||
return GetStorage()->mode_instance;
|
return GetStorage().mode_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetDoCommandAsyncMode(ScriptAsyncModeProc *proc, ScriptObject *instance)
|
/* static */ void ScriptObject::SetDoCommandAsyncMode(ScriptAsyncModeProc *proc, ScriptObject *instance)
|
||||||
{
|
{
|
||||||
GetStorage()->async_mode = proc;
|
GetStorage().async_mode = proc;
|
||||||
GetStorage()->async_mode_instance = instance;
|
GetStorage().async_mode_instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptAsyncModeProc *ScriptObject::GetDoCommandAsyncMode()
|
/* static */ ScriptAsyncModeProc *ScriptObject::GetDoCommandAsyncMode()
|
||||||
{
|
{
|
||||||
return GetStorage()->async_mode;
|
return GetStorage().async_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptObject *ScriptObject::GetDoCommandAsyncModeInstance()
|
/* static */ ScriptObject *ScriptObject::GetDoCommandAsyncModeInstance()
|
||||||
{
|
{
|
||||||
return GetStorage()->async_mode_instance;
|
return GetStorage().async_mode_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetLastCommand(const CommandDataBuffer &data, Commands cmd)
|
/* static */ void ScriptObject::SetLastCommand(const CommandDataBuffer &data, Commands cmd)
|
||||||
{
|
{
|
||||||
ScriptStorage *s = GetStorage();
|
ScriptStorage &s = GetStorage();
|
||||||
Debug(script, 6, "SetLastCommand company={:02d} cmd={} data={}", s->root_company, cmd, FormatArrayAsHex(data));
|
Debug(script, 6, "SetLastCommand company={:02d} cmd={} data={}", s.root_company, cmd, FormatArrayAsHex(data));
|
||||||
s->last_data = data;
|
s.last_data = data;
|
||||||
s->last_cmd = cmd;
|
s.last_cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool ScriptObject::CheckLastCommand(const CommandDataBuffer &data, Commands cmd)
|
/* static */ bool ScriptObject::CheckLastCommand(const CommandDataBuffer &data, Commands cmd)
|
||||||
{
|
{
|
||||||
ScriptStorage *s = GetStorage();
|
ScriptStorage &s = GetStorage();
|
||||||
Debug(script, 6, "CheckLastCommand company={:02d} cmd={} data={}", s->root_company, cmd, FormatArrayAsHex(data));
|
Debug(script, 6, "CheckLastCommand company={:02d} cmd={} data={}", s.root_company, cmd, FormatArrayAsHex(data));
|
||||||
if (s->last_cmd != cmd) return false;
|
if (s.last_cmd != cmd) return false;
|
||||||
if (s->last_data != data) return false;
|
if (s.last_data != data) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetDoCommandCosts(Money value)
|
/* static */ void ScriptObject::SetDoCommandCosts(Money value)
|
||||||
{
|
{
|
||||||
GetStorage()->costs = CommandCost(INVALID_EXPENSES, value); // Expense type is never read.
|
GetStorage().costs = CommandCost(INVALID_EXPENSES, value); // Expense type is never read.
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::IncreaseDoCommandCosts(Money value)
|
/* static */ void ScriptObject::IncreaseDoCommandCosts(Money value)
|
||||||
{
|
{
|
||||||
GetStorage()->costs.AddCost(value);
|
GetStorage().costs.AddCost(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ Money ScriptObject::GetDoCommandCosts()
|
/* static */ Money ScriptObject::GetDoCommandCosts()
|
||||||
{
|
{
|
||||||
return GetStorage()->costs.GetCost();
|
return GetStorage().costs.GetCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetLastError(ScriptErrorType last_error)
|
/* static */ void ScriptObject::SetLastError(ScriptErrorType last_error)
|
||||||
{
|
{
|
||||||
GetStorage()->last_error = last_error;
|
GetStorage().last_error = last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptErrorType ScriptObject::GetLastError()
|
/* static */ ScriptErrorType ScriptObject::GetLastError()
|
||||||
{
|
{
|
||||||
return GetStorage()->last_error;
|
return GetStorage().last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetLastCost(Money last_cost)
|
/* static */ void ScriptObject::SetLastCost(Money last_cost)
|
||||||
{
|
{
|
||||||
GetStorage()->last_cost = last_cost;
|
GetStorage().last_cost = last_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ Money ScriptObject::GetLastCost()
|
/* static */ Money ScriptObject::GetLastCost()
|
||||||
{
|
{
|
||||||
return GetStorage()->last_cost;
|
return GetStorage().last_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetRoadType(RoadType road_type)
|
/* static */ void ScriptObject::SetRoadType(RoadType road_type)
|
||||||
{
|
{
|
||||||
GetStorage()->road_type = road_type;
|
GetStorage().road_type = road_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ RoadType ScriptObject::GetRoadType()
|
/* static */ RoadType ScriptObject::GetRoadType()
|
||||||
{
|
{
|
||||||
return GetStorage()->road_type;
|
return GetStorage().road_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetRailType(RailType rail_type)
|
/* static */ void ScriptObject::SetRailType(RailType rail_type)
|
||||||
{
|
{
|
||||||
GetStorage()->rail_type = rail_type;
|
GetStorage().rail_type = rail_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ RailType ScriptObject::GetRailType()
|
/* static */ RailType ScriptObject::GetRailType()
|
||||||
{
|
{
|
||||||
return GetStorage()->rail_type;
|
return GetStorage().rail_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetLastCommandRes(bool res)
|
/* static */ void ScriptObject::SetLastCommandRes(bool res)
|
||||||
{
|
{
|
||||||
GetStorage()->last_command_res = res;
|
GetStorage().last_command_res = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool ScriptObject::GetLastCommandRes()
|
/* static */ bool ScriptObject::GetLastCommandRes()
|
||||||
{
|
{
|
||||||
return GetStorage()->last_command_res;
|
return GetStorage().last_command_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetLastCommandResData(CommandDataBuffer data)
|
/* static */ void ScriptObject::SetLastCommandResData(CommandDataBuffer data)
|
||||||
{
|
{
|
||||||
GetStorage()->last_cmd_ret = std::move(data);
|
GetStorage().last_cmd_ret = std::move(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ const CommandDataBuffer &ScriptObject::GetLastCommandResData()
|
/* static */ const CommandDataBuffer &ScriptObject::GetLastCommandResData()
|
||||||
{
|
{
|
||||||
return GetStorage()->last_cmd_ret;
|
return GetStorage().last_cmd_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetCompany(::CompanyID company)
|
/* static */ void ScriptObject::SetCompany(::CompanyID company)
|
||||||
{
|
{
|
||||||
if (GetStorage()->root_company == INVALID_OWNER) GetStorage()->root_company = company;
|
if (GetStorage().root_company == INVALID_OWNER) GetStorage().root_company = company;
|
||||||
GetStorage()->company = company;
|
GetStorage().company = company;
|
||||||
|
|
||||||
_current_company = company;
|
_current_company = company;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ::CompanyID ScriptObject::GetCompany()
|
/* static */ ::CompanyID ScriptObject::GetCompany()
|
||||||
{
|
{
|
||||||
return GetStorage()->company;
|
return GetStorage().company;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ::CompanyID ScriptObject::GetRootCompany()
|
/* static */ ::CompanyID ScriptObject::GetRootCompany()
|
||||||
{
|
{
|
||||||
return GetStorage()->root_company;
|
return GetStorage().root_company;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool ScriptObject::CanSuspend()
|
/* static */ bool ScriptObject::CanSuspend()
|
||||||
{
|
{
|
||||||
Squirrel *squirrel = ScriptObject::GetActiveInstance().engine;
|
Squirrel &squirrel = *ScriptObject::GetActiveInstance().engine;
|
||||||
return GetStorage()->allow_do_command && squirrel->CanSuspend();
|
return GetStorage().allow_do_command && squirrel.CanSuspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptEventQueue &ScriptObject::GetEventQueue()
|
/* static */ ScriptEventQueue &ScriptObject::GetEventQueue()
|
||||||
{
|
{
|
||||||
return GetStorage()->event_queue;
|
return GetStorage().event_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ScriptLogTypes::LogData &ScriptObject::GetLogData()
|
/* static */ ScriptLogTypes::LogData &ScriptObject::GetLogData()
|
||||||
{
|
{
|
||||||
return GetStorage()->log_data;
|
return GetStorage().log_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ScriptObject::SetCallbackVariable(int index, int value)
|
/* static */ void ScriptObject::SetCallbackVariable(int index, int value)
|
||||||
{
|
{
|
||||||
if (static_cast<size_t>(index) >= GetStorage()->callback_value.size()) GetStorage()->callback_value.resize(index + 1);
|
if (static_cast<size_t>(index) >= GetStorage().callback_value.size()) GetStorage().callback_value.resize(index + 1);
|
||||||
GetStorage()->callback_value[index] = value;
|
GetStorage().callback_value[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ int ScriptObject::GetCallbackVariable(int index)
|
/* static */ int ScriptObject::GetCallbackVariable(int index)
|
||||||
{
|
{
|
||||||
return GetStorage()->callback_value[index];
|
return GetStorage().callback_value[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ CommandCallbackData *ScriptObject::GetDoCommandCallback()
|
/* static */ CommandCallbackData *ScriptObject::GetDoCommandCallback()
|
||||||
|
@ -310,8 +310,8 @@ ScriptObject::DisableDoCommandScope::DisableDoCommandScope()
|
||||||
IncreaseDoCommandCosts(res.GetCost());
|
IncreaseDoCommandCosts(res.GetCost());
|
||||||
if (!_generating_world) {
|
if (!_generating_world) {
|
||||||
/* Charge a nominal fee for asynchronously executed commands */
|
/* Charge a nominal fee for asynchronously executed commands */
|
||||||
Squirrel *engine = ScriptObject::GetActiveInstance().engine;
|
Squirrel &engine = *ScriptObject::GetActiveInstance().engine;
|
||||||
Squirrel::DecreaseOps(engine->GetVM(), 100);
|
Squirrel::DecreaseOps(engine.GetVM(), 100);
|
||||||
}
|
}
|
||||||
if (callback != nullptr) {
|
if (callback != nullptr) {
|
||||||
/* Insert return value into to stack and throw a control code that
|
/* Insert return value into to stack and throw a control code that
|
||||||
|
|
|
@ -24,10 +24,12 @@
|
||||||
#include "api/script_event.hpp"
|
#include "api/script_event.hpp"
|
||||||
#include "api/script_log.hpp"
|
#include "api/script_log.hpp"
|
||||||
|
|
||||||
#include "../company_base.h"
|
#include "../company_type.h"
|
||||||
#include "../company_func.h"
|
|
||||||
#include "../fileio_func.h"
|
#include "../fileio_func.h"
|
||||||
|
#include "../goal_type.h"
|
||||||
#include "../league_type.h"
|
#include "../league_type.h"
|
||||||
|
#include "../signs_type.h"
|
||||||
|
#include "../story_type.h"
|
||||||
#include "../misc/endian_buffer.hpp"
|
#include "../misc/endian_buffer.hpp"
|
||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
@ -48,8 +50,8 @@ static void PrintFunc(bool error_msg, std::string_view message)
|
||||||
|
|
||||||
ScriptInstance::ScriptInstance(std::string_view api_name)
|
ScriptInstance::ScriptInstance(std::string_view api_name)
|
||||||
{
|
{
|
||||||
this->storage = new ScriptStorage();
|
this->storage = std::make_unique<ScriptStorage>();
|
||||||
this->engine = new Squirrel(api_name);
|
this->engine = std::make_unique<Squirrel>(api_name);
|
||||||
this->engine->SetPrintFunction(&PrintFunc);
|
this->engine->SetPrintFunction(&PrintFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,10 +59,10 @@ void ScriptInstance::Initialize(const std::string &main_script, const std::strin
|
||||||
{
|
{
|
||||||
ScriptObject::ActiveInstance active(*this);
|
ScriptObject::ActiveInstance active(*this);
|
||||||
|
|
||||||
this->controller = new ScriptController(company);
|
this->controller = std::make_unique<ScriptController>(company);
|
||||||
|
|
||||||
/* Register the API functions and classes */
|
/* Register the API functions and classes */
|
||||||
this->engine->SetGlobalPointer(this->engine);
|
this->engine->SetGlobalPointer(this->engine.get());
|
||||||
this->RegisterAPI();
|
this->RegisterAPI();
|
||||||
if (this->IsDead()) {
|
if (this->IsDead()) {
|
||||||
/* Failed to register API; a message has already been logged. */
|
/* Failed to register API; a message has already been logged. */
|
||||||
|
@ -79,12 +81,11 @@ void ScriptInstance::Initialize(const std::string &main_script, const std::strin
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the main-class */
|
/* Create the main-class */
|
||||||
this->instance = new SQObject();
|
this->instance = std::make_unique<SQObject>();
|
||||||
if (!this->engine->CreateClassInstance(instance_name, this->controller, this->instance)) {
|
if (!this->engine->CreateClassInstance(instance_name, this->controller.get(), this->instance.get())) {
|
||||||
/* If CreateClassInstance has returned false instance has not been
|
/* If CreateClassInstance has returned false instance has not been
|
||||||
* registered with squirrel, so avoid trying to Release it by clearing it now */
|
* registered with squirrel, so avoid trying to Release it by clearing it now */
|
||||||
delete this->instance;
|
this->instance.reset();
|
||||||
this->instance = nullptr;
|
|
||||||
this->Died();
|
this->Died();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,7 @@ void ScriptInstance::Initialize(const std::string &main_script, const std::strin
|
||||||
|
|
||||||
void ScriptInstance::RegisterAPI()
|
void ScriptInstance::RegisterAPI()
|
||||||
{
|
{
|
||||||
squirrel_register_std(this->engine);
|
squirrel_register_std(*this->engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptInstance::LoadCompatibilityScript(std::string_view api_version, Subdirectory dir)
|
bool ScriptInstance::LoadCompatibilityScript(std::string_view api_version, Subdirectory dir)
|
||||||
|
@ -128,6 +129,13 @@ bool ScriptInstance::LoadCompatibilityScripts(Subdirectory dir, std::span<const
|
||||||
|
|
||||||
ScriptLog::Info(fmt::format("Downgrading API to be compatible with version {}", this->api_version));
|
ScriptLog::Info(fmt::format("Downgrading API to be compatible with version {}", this->api_version));
|
||||||
|
|
||||||
|
HSQUIRRELVM vm = this->engine->GetVM();
|
||||||
|
sq_pushroottable(vm);
|
||||||
|
sq_pushstring(vm, "CompatScriptRootTable");
|
||||||
|
sq_pushroottable(vm);
|
||||||
|
sq_newslot(vm, -3, SQFalse);
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
|
||||||
/* Downgrade the API till we are the same version as the script. The last
|
/* Downgrade the API till we are the same version as the script. The last
|
||||||
* entry in the list is always the current version, so skip that one. */
|
* entry in the list is always the current version, so skip that one. */
|
||||||
for (auto it = std::rbegin(api_versions) + 1; it != std::rend(api_versions); ++it) {
|
for (auto it = std::rbegin(api_versions) + 1; it != std::rend(api_versions); ++it) {
|
||||||
|
@ -136,6 +144,11 @@ bool ScriptInstance::LoadCompatibilityScripts(Subdirectory dir, std::span<const
|
||||||
if (*it == this->api_version) break;
|
if (*it == this->api_version) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sq_pushroottable(vm);
|
||||||
|
sq_pushstring(vm, "CompatScriptRootTable");
|
||||||
|
sq_deleteslot(vm, -2, SQFalse);
|
||||||
|
sq_pop(vm, 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,11 +157,10 @@ ScriptInstance::~ScriptInstance()
|
||||||
ScriptObject::ActiveInstance active(*this);
|
ScriptObject::ActiveInstance active(*this);
|
||||||
this->in_shutdown = true;
|
this->in_shutdown = true;
|
||||||
|
|
||||||
if (instance != nullptr) this->engine->ReleaseObject(this->instance);
|
if (instance != nullptr) this->engine->ReleaseObject(this->instance.get());
|
||||||
if (engine != nullptr) delete this->engine;
|
|
||||||
delete this->storage;
|
/* Engine must be reset explicitly in scope of the active instance. */
|
||||||
delete this->controller;
|
this->engine.reset();
|
||||||
delete this->instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptInstance::Continue()
|
void ScriptInstance::Continue()
|
||||||
|
@ -165,11 +177,9 @@ void ScriptInstance::Died()
|
||||||
|
|
||||||
this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache
|
this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache
|
||||||
|
|
||||||
if (this->instance != nullptr) this->engine->ReleaseObject(this->instance);
|
if (this->instance != nullptr) this->engine->ReleaseObject(this->instance.get());
|
||||||
delete this->instance;
|
this->engine.reset();
|
||||||
delete this->engine;
|
this->instance.reset();
|
||||||
this->instance = nullptr;
|
|
||||||
this->engine = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptInstance::GameLoop()
|
void ScriptInstance::GameLoop()
|
||||||
|
@ -316,9 +326,10 @@ void ScriptInstance::CollectGarbage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ScriptStorage *ScriptInstance::GetStorage()
|
ScriptStorage &ScriptInstance::GetStorage()
|
||||||
{
|
{
|
||||||
return this->storage;
|
assert(this->storage != nullptr);
|
||||||
|
return *this->storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptLogTypes::LogData &ScriptInstance::GetLogData()
|
ScriptLogTypes::LogData &ScriptInstance::GetLogData()
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get the storage of this script.
|
* Get the storage of this script.
|
||||||
*/
|
*/
|
||||||
class ScriptStorage *GetStorage();
|
class ScriptStorage &GetStorage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the log pointer of this script.
|
* Get the log pointer of this script.
|
||||||
|
@ -146,7 +146,11 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get the controller attached to the instance.
|
* Get the controller attached to the instance.
|
||||||
*/
|
*/
|
||||||
class ScriptController *GetController() { return controller; }
|
class ScriptController &GetController()
|
||||||
|
{
|
||||||
|
assert(this->controller != nullptr);
|
||||||
|
return *this->controller;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the "this script died" value
|
* Return the "this script died" value
|
||||||
|
@ -252,7 +256,7 @@ public:
|
||||||
void ReleaseSQObject(HSQOBJECT *obj);
|
void ReleaseSQObject(HSQOBJECT *obj);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Squirrel *engine = nullptr; ///< A wrapper around the squirrel vm.
|
std::unique_ptr<class Squirrel> engine; ///< A wrapper around the squirrel vm.
|
||||||
std::string api_version{}; ///< Current API used by this script.
|
std::string api_version{}; ///< Current API used by this script.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -284,9 +288,9 @@ protected:
|
||||||
virtual void LoadDummyScript() = 0;
|
virtual void LoadDummyScript() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ScriptController *controller = nullptr; ///< The script main class.
|
std::unique_ptr<class ScriptStorage> storage; ///< Some global information for each running script.
|
||||||
class ScriptStorage *storage = nullptr; ///< Some global information for each running script.
|
std::unique_ptr<class ScriptController> controller; ///< The script main class.
|
||||||
SQObject *instance = nullptr; ///< Squirrel-pointer to the script main class.
|
std::unique_ptr<SQObject> instance; ///< Squirrel-pointer to the script main class.
|
||||||
|
|
||||||
bool is_started = false; ///< Is the scripts constructor executed?
|
bool is_started = false; ///< Is the scripts constructor executed?
|
||||||
bool is_dead = false; ///< True if the script has been stopped.
|
bool is_dead = false; ///< True if the script has been stopped.
|
||||||
|
|
|
@ -44,10 +44,7 @@ bool ScriptScanner::AddFile(const std::string &filename, size_t, const std::stri
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptScanner::ScriptScanner() :
|
ScriptScanner::ScriptScanner() = default;
|
||||||
engine(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptScanner::ResetEngine()
|
void ScriptScanner::ResetEngine()
|
||||||
{
|
{
|
||||||
|
@ -58,7 +55,7 @@ void ScriptScanner::ResetEngine()
|
||||||
|
|
||||||
void ScriptScanner::Initialize(std::string_view name)
|
void ScriptScanner::Initialize(std::string_view name)
|
||||||
{
|
{
|
||||||
this->engine = new Squirrel(name);
|
this->engine = std::make_unique<Squirrel>(name);
|
||||||
|
|
||||||
this->RescanDir();
|
this->RescanDir();
|
||||||
|
|
||||||
|
@ -68,8 +65,6 @@ void ScriptScanner::Initialize(std::string_view name)
|
||||||
ScriptScanner::~ScriptScanner()
|
ScriptScanner::~ScriptScanner()
|
||||||
{
|
{
|
||||||
this->Reset();
|
this->Reset();
|
||||||
|
|
||||||
delete this->engine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptScanner::RescanDir()
|
void ScriptScanner::RescanDir()
|
||||||
|
@ -83,15 +78,12 @@ void ScriptScanner::RescanDir()
|
||||||
|
|
||||||
void ScriptScanner::Reset()
|
void ScriptScanner::Reset()
|
||||||
{
|
{
|
||||||
for (const auto &item : this->info_list) {
|
|
||||||
delete item.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->info_list.clear();
|
this->info_list.clear();
|
||||||
this->info_single_list.clear();
|
this->info_single_list.clear();
|
||||||
|
this->info_vector.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptScanner::RegisterScript(ScriptInfo *info)
|
void ScriptScanner::RegisterScript(std::unique_ptr<ScriptInfo> &&info)
|
||||||
{
|
{
|
||||||
std::string script_original_name = this->GetScriptName(*info);
|
std::string script_original_name = this->GetScriptName(*info);
|
||||||
std::string script_name = fmt::format("{}.{}", script_original_name, info->GetVersion());
|
std::string script_name = fmt::format("{}.{}", script_original_name, info->GetVersion());
|
||||||
|
@ -99,7 +91,6 @@ void ScriptScanner::RegisterScript(ScriptInfo *info)
|
||||||
/* Check if GetShortName follows the rules */
|
/* Check if GetShortName follows the rules */
|
||||||
if (info->GetShortName().size() != 4) {
|
if (info->GetShortName().size() != 4) {
|
||||||
Debug(script, 0, "The script '{}' returned a string from GetShortName() which is not four characters. Unable to load the script.", info->GetName());
|
Debug(script, 0, "The script '{}' returned a string from GetShortName() which is not four characters. Unable to load the script.", info->GetName());
|
||||||
delete info;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +102,6 @@ void ScriptScanner::RegisterScript(ScriptInfo *info)
|
||||||
#else
|
#else
|
||||||
if (it->second->GetMainScript() == info->GetMainScript()) {
|
if (it->second->GetMainScript() == info->GetMainScript()) {
|
||||||
#endif
|
#endif
|
||||||
delete info;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,20 +110,20 @@ void ScriptScanner::RegisterScript(ScriptInfo *info)
|
||||||
Debug(script, 1, " 2: {}", info->GetMainScript());
|
Debug(script, 1, " 2: {}", info->GetMainScript());
|
||||||
Debug(script, 1, "The first is taking precedence.");
|
Debug(script, 1, "The first is taking precedence.");
|
||||||
|
|
||||||
delete info;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->info_list[script_name] = info;
|
ScriptInfo *script_info = this->info_vector.emplace_back(std::move(info)).get();
|
||||||
|
this->info_list[script_name] = script_info;
|
||||||
|
|
||||||
if (!info->IsDeveloperOnly() || _settings_client.gui.ai_developer_tools) {
|
if (!script_info->IsDeveloperOnly() || _settings_client.gui.ai_developer_tools) {
|
||||||
/* Add the script to the 'unique' script list, where only the highest version
|
/* Add the script to the 'unique' script list, where only the highest version
|
||||||
* of the script is registered. */
|
* of the script is registered. */
|
||||||
auto it = this->info_single_list.find(script_original_name);
|
auto it = this->info_single_list.find(script_original_name);
|
||||||
if (it == this->info_single_list.end()) {
|
if (it == this->info_single_list.end()) {
|
||||||
this->info_single_list[script_original_name] = info;
|
this->info_single_list[script_original_name] = script_info;
|
||||||
} else if (it->second->GetVersion() < info->GetVersion()) {
|
} else if (it->second->GetVersion() < script_info->GetVersion()) {
|
||||||
it->second = info;
|
it->second = script_info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,17 +185,17 @@ struct ScriptFileChecksumCreator : FileScanner {
|
||||||
* @param info The script to get the shortname and md5 sum from.
|
* @param info The script to get the shortname and md5 sum from.
|
||||||
* @return True iff they're the same.
|
* @return True iff they're the same.
|
||||||
*/
|
*/
|
||||||
static bool IsSameScript(const ContentInfo &ci, bool md5sum, ScriptInfo *info, Subdirectory dir)
|
static bool IsSameScript(const ContentInfo &ci, bool md5sum, const ScriptInfo &info, Subdirectory dir)
|
||||||
{
|
{
|
||||||
uint32_t id = 0;
|
uint32_t id = 0;
|
||||||
auto str = std::string_view{info->GetShortName()}.substr(0, 4);
|
auto str = std::string_view{info.GetShortName()}.substr(0, 4);
|
||||||
for (size_t j = 0; j < str.size(); j++) id |= static_cast<uint8_t>(str[j]) << (8 * j);
|
for (size_t j = 0; j < str.size(); j++) id |= static_cast<uint8_t>(str[j]) << (8 * j);
|
||||||
|
|
||||||
if (id != ci.unique_id) return false;
|
if (id != ci.unique_id) return false;
|
||||||
if (!md5sum) return true;
|
if (!md5sum) return true;
|
||||||
|
|
||||||
ScriptFileChecksumCreator checksum(dir);
|
ScriptFileChecksumCreator checksum(dir);
|
||||||
const auto &tar_filename = info->GetTarFile();
|
const auto &tar_filename = info.GetTarFile();
|
||||||
TarList::iterator iter;
|
TarList::iterator iter;
|
||||||
if (!tar_filename.empty() && (iter = _tar_list[dir].find(tar_filename)) != _tar_list[dir].end()) {
|
if (!tar_filename.empty() && (iter = _tar_list[dir].find(tar_filename)) != _tar_list[dir].end()) {
|
||||||
/* The main script is in a tar file, so find all files that
|
/* The main script is in a tar file, so find all files that
|
||||||
|
@ -224,7 +214,7 @@ static bool IsSameScript(const ContentInfo &ci, bool md5sum, ScriptInfo *info, S
|
||||||
/* There'll always be at least 1 path separator character in a script
|
/* There'll always be at least 1 path separator character in a script
|
||||||
* main script name as the search algorithm requires the main script to
|
* main script name as the search algorithm requires the main script to
|
||||||
* be in a subdirectory of the script directory; so <dir>/<path>/main.nut. */
|
* be in a subdirectory of the script directory; so <dir>/<path>/main.nut. */
|
||||||
const std::string &main_script = info->GetMainScript();
|
const std::string &main_script = info.GetMainScript();
|
||||||
std::string path = main_script.substr(0, main_script.find_last_of(PATHSEPCHAR));
|
std::string path = main_script.substr(0, main_script.find_last_of(PATHSEPCHAR));
|
||||||
checksum.Scan(".nut", path);
|
checksum.Scan(".nut", path);
|
||||||
}
|
}
|
||||||
|
@ -235,7 +225,7 @@ static bool IsSameScript(const ContentInfo &ci, bool md5sum, ScriptInfo *info, S
|
||||||
bool ScriptScanner::HasScript(const ContentInfo &ci, bool md5sum)
|
bool ScriptScanner::HasScript(const ContentInfo &ci, bool md5sum)
|
||||||
{
|
{
|
||||||
for (const auto &item : this->info_list) {
|
for (const auto &item : this->info_list) {
|
||||||
if (IsSameScript(ci, md5sum, item.second, this->GetDirectory())) return true;
|
if (IsSameScript(ci, md5sum, *item.second, this->GetDirectory())) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -243,7 +233,7 @@ bool ScriptScanner::HasScript(const ContentInfo &ci, bool md5sum)
|
||||||
std::optional<std::string_view> ScriptScanner::FindMainScript(const ContentInfo &ci, bool md5sum)
|
std::optional<std::string_view> ScriptScanner::FindMainScript(const ContentInfo &ci, bool md5sum)
|
||||||
{
|
{
|
||||||
for (const auto &item : this->info_list) {
|
for (const auto &item : this->info_list) {
|
||||||
if (IsSameScript(ci, md5sum, item.second, this->GetDirectory())) return item.second->GetMainScript();
|
if (IsSameScript(ci, md5sum, *item.second, this->GetDirectory())) return item.second->GetMainScript();
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "../fileio_func.h"
|
#include "../fileio_func.h"
|
||||||
#include "../string_func.h"
|
#include "../string_func.h"
|
||||||
|
|
||||||
typedef std::map<std::string, class ScriptInfo *, CaseInsensitiveComparator> ScriptInfoList; ///< Type for the list of scripts.
|
using ScriptInfoList = std::map<std::string, class ScriptInfo *, CaseInsensitiveComparator>; ///< Type for the list of scripts.
|
||||||
|
|
||||||
/** Scanner to help finding scripts. */
|
/** Scanner to help finding scripts. */
|
||||||
class ScriptScanner : public FileScanner {
|
class ScriptScanner : public FileScanner {
|
||||||
|
@ -26,7 +26,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get the engine of the main squirrel handler (it indexes all available scripts).
|
* Get the engine of the main squirrel handler (it indexes all available scripts).
|
||||||
*/
|
*/
|
||||||
class Squirrel *GetEngine() { return this->engine; }
|
class Squirrel *GetEngine() { return this->engine.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current main script the ScanDir is currently tracking.
|
* Get the current main script the ScanDir is currently tracking.
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Register a ScriptInfo to the scanner.
|
* Register a ScriptInfo to the scanner.
|
||||||
*/
|
*/
|
||||||
void RegisterScript(class ScriptInfo *info);
|
void RegisterScript(std::unique_ptr<class ScriptInfo> &&info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of registered scripts to print on the console.
|
* Get the list of registered scripts to print on the console.
|
||||||
|
@ -84,11 +84,13 @@ public:
|
||||||
void RescanDir();
|
void RescanDir();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Squirrel *engine; ///< The engine we're scanning with.
|
std::unique_ptr<class Squirrel> engine; ///< The engine we're scanning with.
|
||||||
std::string main_script; ///< The full path of the script.
|
std::string main_script; ///< The full path of the script.
|
||||||
std::string tar_file; ///< If, which tar file the script was in.
|
std::string tar_file; ///< If, which tar file the script was in.
|
||||||
|
|
||||||
ScriptInfoList info_list; ///< The list of all script.
|
std::vector<std::unique_ptr<ScriptInfo>> info_vector;
|
||||||
|
|
||||||
|
ScriptInfoList info_list; ///< The list of all script.
|
||||||
ScriptInfoList info_single_list; ///< The list of all unique script. The best script (highest version) is shown.
|
ScriptInfoList info_single_list; ///< The list of all unique script. The best script (highest version) is shown.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,12 +12,10 @@
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "../signs_func.h"
|
#include "../command_type.h"
|
||||||
#include "../vehicle_func.h"
|
#include "../company_type.h"
|
||||||
|
#include "../rail_type.h"
|
||||||
#include "../road_type.h"
|
#include "../road_type.h"
|
||||||
#include "../group.h"
|
|
||||||
#include "../goal_type.h"
|
|
||||||
#include "../story_type.h"
|
|
||||||
|
|
||||||
#include "script_types.hpp"
|
#include "script_types.hpp"
|
||||||
#include "script_log_types.hpp"
|
#include "script_log_types.hpp"
|
||||||
|
|
|
@ -536,7 +536,7 @@ void Squirrel::Initialize()
|
||||||
sq_setforeignptr(this->vm, this);
|
sq_setforeignptr(this->vm, this);
|
||||||
|
|
||||||
sq_pushroottable(this->vm);
|
sq_pushroottable(this->vm);
|
||||||
squirrel_register_global_std(this);
|
squirrel_register_global_std(*this);
|
||||||
|
|
||||||
/* Set consts table as delegate of root table, so consts/enums defined via require() are accessible */
|
/* Set consts table as delegate of root table, so consts/enums defined via require() are accessible */
|
||||||
sq_pushconsttable(this->vm);
|
sq_pushconsttable(this->vm);
|
||||||
|
|
|
@ -82,20 +82,20 @@ SQInteger SquirrelStd::notifyallexceptions(HSQUIRRELVM vm)
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void squirrel_register_global_std(Squirrel *engine)
|
void squirrel_register_global_std(Squirrel &engine)
|
||||||
{
|
{
|
||||||
/* We don't use squirrel_helper here, as we want to register to the global
|
/* We don't use squirrel_helper here, as we want to register to the global
|
||||||
* scope and not to a class. */
|
* scope and not to a class. */
|
||||||
engine->AddMethod("require", &SquirrelStd::require, ".s");
|
engine.AddMethod("require", &SquirrelStd::require, ".s");
|
||||||
engine->AddMethod("notifyallexceptions", &SquirrelStd::notifyallexceptions, ".b");
|
engine.AddMethod("notifyallexceptions", &SquirrelStd::notifyallexceptions, ".b");
|
||||||
}
|
}
|
||||||
|
|
||||||
void squirrel_register_std(Squirrel *engine)
|
void squirrel_register_std(Squirrel &engine)
|
||||||
{
|
{
|
||||||
/* We don't use squirrel_helper here, as we want to register to the global
|
/* We don't use squirrel_helper here, as we want to register to the global
|
||||||
* scope and not to a class. */
|
* scope and not to a class. */
|
||||||
engine->AddMethod("min", &SquirrelStd::min, ".ii");
|
engine.AddMethod("min", &SquirrelStd::min, ".ii");
|
||||||
engine->AddMethod("max", &SquirrelStd::max, ".ii");
|
engine.AddMethod("max", &SquirrelStd::max, ".ii");
|
||||||
|
|
||||||
sqstd_register_mathlib(engine->GetVM());
|
sqstd_register_mathlib(engine.GetVM());
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,12 +52,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Register all standard functions we want to give to a script.
|
* Register all standard functions we want to give to a script.
|
||||||
*/
|
*/
|
||||||
void squirrel_register_std(Squirrel *engine);
|
void squirrel_register_std(Squirrel &engine);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register all standard functions that are available on first startup.
|
* Register all standard functions that are available on first startup.
|
||||||
* @note this set is very limited, and is only meant to load other scripts and things like that.
|
* @note this set is very limited, and is only meant to load other scripts and things like that.
|
||||||
*/
|
*/
|
||||||
void squirrel_register_global_std(Squirrel *engine);
|
void squirrel_register_global_std(Squirrel &engine);
|
||||||
|
|
||||||
#endif /* SQUIRREL_STD_HPP */
|
#endif /* SQUIRREL_STD_HPP */
|
||||||
|
|
|
@ -1036,9 +1036,8 @@ struct GameOptionsWindow : Window {
|
||||||
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
|
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
|
|
||||||
InitFontCache(false);
|
InitFontCache(FONTSIZES_ALL);
|
||||||
InitFontCache(true);
|
ClearFontCache(FONTSIZES_ALL);
|
||||||
ClearFontCache();
|
|
||||||
CheckForMissingGlyphs();
|
CheckForMissingGlyphs();
|
||||||
SetupWidgetDimensions();
|
SetupWidgetDimensions();
|
||||||
UpdateAllVirtCoords();
|
UpdateAllVirtCoords();
|
||||||
|
@ -1051,7 +1050,7 @@ struct GameOptionsWindow : Window {
|
||||||
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
|
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
||||||
ClearFontCache();
|
ClearFontCache(FONTSIZES_ALL);
|
||||||
break;
|
break;
|
||||||
#endif /* HAS_TRUETYPE_FONT */
|
#endif /* HAS_TRUETYPE_FONT */
|
||||||
|
|
||||||
|
|
|
@ -3331,7 +3331,7 @@ draw_default_foundation:
|
||||||
auto result = GetRoadStopLayout(ti, stopspec, st, type, view, regs100);
|
auto result = GetRoadStopLayout(ti, stopspec, st, type, view, regs100);
|
||||||
if (result.has_value()) {
|
if (result.has_value()) {
|
||||||
if (stopspec->flags.Test(RoadStopSpecFlag::DrawModeRegister)) {
|
if (stopspec->flags.Test(RoadStopSpecFlag::DrawModeRegister)) {
|
||||||
stop_draw_mode = static_cast<RoadStopDrawMode>(regs100[0]);
|
stop_draw_mode = static_cast<RoadStopDrawModes>(regs100[0]);
|
||||||
}
|
}
|
||||||
if (type == StationType::RoadWaypoint && stop_draw_mode.Test(RoadStopDrawMode::WaypGround)) {
|
if (type == StationType::RoadWaypoint && stop_draw_mode.Test(RoadStopDrawMode::WaypGround)) {
|
||||||
draw_ground = true;
|
draw_ground = true;
|
||||||
|
|
|
@ -607,28 +607,25 @@ bool ConvertHexToBytes(std::string_view hex, std::span<uint8_t> bytes)
|
||||||
/** String iterator using ICU as a backend. */
|
/** String iterator using ICU as a backend. */
|
||||||
class IcuStringIterator : public StringIterator
|
class IcuStringIterator : public StringIterator
|
||||||
{
|
{
|
||||||
icu::BreakIterator *char_itr; ///< ICU iterator for characters.
|
std::unique_ptr<icu::BreakIterator> char_itr; ///< ICU iterator for characters.
|
||||||
icu::BreakIterator *word_itr; ///< ICU iterator for words.
|
std::unique_ptr<icu::BreakIterator> word_itr; ///< ICU iterator for words.
|
||||||
|
|
||||||
std::vector<UChar> utf16_str; ///< UTF-16 copy of the string.
|
std::vector<UChar> utf16_str; ///< UTF-16 copy of the string.
|
||||||
std::vector<size_t> utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string.
|
std::vector<size_t> utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IcuStringIterator() : char_itr(nullptr), word_itr(nullptr)
|
IcuStringIterator()
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
this->char_itr = icu::BreakIterator::createCharacterInstance(icu::Locale(_current_language != nullptr ? _current_language->isocode : "en"), status);
|
auto locale = icu::Locale(_current_language != nullptr ? _current_language->isocode : "en");
|
||||||
this->word_itr = icu::BreakIterator::createWordInstance(icu::Locale(_current_language != nullptr ? _current_language->isocode : "en"), status);
|
this->char_itr.reset(icu::BreakIterator::createCharacterInstance(locale, status));
|
||||||
|
this->word_itr.reset(icu::BreakIterator::createWordInstance(locale, status));
|
||||||
|
|
||||||
this->utf16_str.push_back('\0');
|
this->utf16_str.push_back('\0');
|
||||||
this->utf16_to_utf8.push_back(0);
|
this->utf16_to_utf8.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
~IcuStringIterator() override
|
~IcuStringIterator() override = default;
|
||||||
{
|
|
||||||
delete this->char_itr;
|
|
||||||
delete this->word_itr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetString(std::string_view s) override
|
void SetString(std::string_view s) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -286,6 +286,7 @@ struct LoadedLanguagePack {
|
||||||
std::array<uint, TEXT_TAB_END> langtab_start; ///< Offset into langpack offs
|
std::array<uint, TEXT_TAB_END> langtab_start; ///< Offset into langpack offs
|
||||||
|
|
||||||
std::string list_separator; ///< Current list separator string.
|
std::string list_separator; ///< Current list separator string.
|
||||||
|
std::string ellipsis; ///< Current ellipsis string.
|
||||||
};
|
};
|
||||||
|
|
||||||
static LoadedLanguagePack _langpack;
|
static LoadedLanguagePack _langpack;
|
||||||
|
@ -301,6 +302,15 @@ std::string_view GetListSeparator()
|
||||||
return _langpack.list_separator;
|
return _langpack.list_separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ellipsis string for the current language.
|
||||||
|
* @returns string containing ellipsis to use.
|
||||||
|
*/
|
||||||
|
std::string_view GetEllipsis()
|
||||||
|
{
|
||||||
|
return _langpack.ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
std::string_view GetStringPtr(StringID string)
|
std::string_view GetStringPtr(StringID string)
|
||||||
{
|
{
|
||||||
switch (GetStringTab(string)) {
|
switch (GetStringTab(string)) {
|
||||||
|
@ -2063,6 +2073,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
|
||||||
_config_language_file = FS2OTTD(_current_language->file.filename().native());
|
_config_language_file = FS2OTTD(_current_language->file.filename().native());
|
||||||
SetCurrentGrfLangID(_current_language->newgrflangid);
|
SetCurrentGrfLangID(_current_language->newgrflangid);
|
||||||
_langpack.list_separator = GetString(STR_LIST_SEPARATOR);
|
_langpack.list_separator = GetString(STR_LIST_SEPARATOR);
|
||||||
|
_langpack.ellipsis = GetString(STR_TRUNCATION_ELLIPSIS);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern void Win32SetCurrentLocaleName(std::string iso_code);
|
extern void Win32SetCurrentLocaleName(std::string iso_code);
|
||||||
|
@ -2267,7 +2278,7 @@ std::string_view GetCurrentLanguageIsoCode()
|
||||||
*/
|
*/
|
||||||
bool MissingGlyphSearcher::FindMissingGlyphs()
|
bool MissingGlyphSearcher::FindMissingGlyphs()
|
||||||
{
|
{
|
||||||
InitFontCache(this->Monospace());
|
InitFontCache(this->Monospace() ? FontSizes{FS_MONO} : FONTSIZES_REQUIRED);
|
||||||
|
|
||||||
this->Reset();
|
this->Reset();
|
||||||
for (auto text = this->NextString(); text.has_value(); text = this->NextString()) {
|
for (auto text = this->NextString(); text.has_value(); text = this->NextString()) {
|
||||||
|
@ -2384,7 +2395,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
|
||||||
/* Our fallback font does miss characters too, so keep the
|
/* Our fallback font does miss characters too, so keep the
|
||||||
* user chosen font as that is more likely to be any good than
|
* user chosen font as that is more likely to be any good than
|
||||||
* the wild guess we made */
|
* the wild guess we made */
|
||||||
InitFontCache(searcher->Monospace());
|
InitFontCache(searcher->Monospace() ? FontSizes{FS_MONO} : FONTSIZES_REQUIRED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2401,12 +2412,12 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
|
||||||
ShowErrorMessage(GetEncodedString(STR_JUST_RAW_STRING, std::move(err_str)), {}, WL_WARNING);
|
ShowErrorMessage(GetEncodedString(STR_JUST_RAW_STRING, std::move(err_str)), {}, WL_WARNING);
|
||||||
|
|
||||||
/* Reset the font width */
|
/* Reset the font width */
|
||||||
LoadStringWidthTable(searcher->Monospace());
|
LoadStringWidthTable(searcher->Monospace() ? FontSizes{FS_MONO} : FONTSIZES_REQUIRED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the font with cache */
|
/* Update the font with cache */
|
||||||
LoadStringWidthTable(searcher->Monospace());
|
LoadStringWidthTable(searcher->Monospace() ? FontSizes{FS_MONO} : FONTSIZES_REQUIRED);
|
||||||
|
|
||||||
#if !(defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA)
|
#if !(defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA)
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -98,6 +98,7 @@ extern TextDirection _current_text_dir; ///< Text direction of the currently sel
|
||||||
void InitializeLanguagePacks();
|
void InitializeLanguagePacks();
|
||||||
std::string_view GetCurrentLanguageIsoCode();
|
std::string_view GetCurrentLanguageIsoCode();
|
||||||
std::string_view GetListSeparator();
|
std::string_view GetListSeparator();
|
||||||
|
std::string_view GetEllipsis();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to create the StringParameters with its own buffer with the given
|
* Helper to create the StringParameters with its own buffer with the given
|
||||||
|
|
|
@ -427,6 +427,7 @@ struct TimetableWindow : Window {
|
||||||
void DrawTimetablePanel(const Rect &r) const
|
void DrawTimetablePanel(const Rect &r) const
|
||||||
{
|
{
|
||||||
const Vehicle *v = this->vehicle;
|
const Vehicle *v = this->vehicle;
|
||||||
|
if (v->GetNumOrders() == 0) return;
|
||||||
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
|
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
|
||||||
int i = this->vscroll->GetPosition();
|
int i = this->vscroll->GetPosition();
|
||||||
VehicleOrderID order_id = (i + 1) / 2;
|
VehicleOrderID order_id = (i + 1) / 2;
|
||||||
|
|
|
@ -710,7 +710,7 @@ static void TileLoop_Town(TileIndex tile)
|
||||||
static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
|
static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
|
||||||
{
|
{
|
||||||
if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
|
if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
|
||||||
if (!CanDeleteHouse(tile)) return CMD_ERROR;
|
if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
|
||||||
|
|
||||||
const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
|
const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
|
||||||
|
|
||||||
|
@ -724,7 +724,7 @@ static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
|
||||||
if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
|
if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
|
||||||
/* NewGRFs can add indestructible houses. */
|
/* NewGRFs can add indestructible houses. */
|
||||||
if (rating > RATING_MAXIMUM) {
|
if (rating > RATING_MAXIMUM) {
|
||||||
return CommandCost(CMD_ERROR);
|
return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
|
||||||
}
|
}
|
||||||
/* If town authority controls removal, check the company's rating. */
|
/* If town authority controls removal, check the company's rating. */
|
||||||
if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
|
if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
|
||||||
|
|
|
@ -118,7 +118,7 @@ std::optional<std::string_view> VideoDriver_SDL_OpenGL::AllocateContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
this->gl_context = SDL_GL_CreateContext(this->sdl_window);
|
this->gl_context = SDL_GL_CreateContext(this->sdl_window);
|
||||||
if (this->gl_context == nullptr) return "SDL2: Can't active GL context";
|
if (this->gl_context == nullptr) return "SDL2: Can't activate GL context";
|
||||||
|
|
||||||
ToggleVsync(_video_vsync);
|
ToggleVsync(_video_vsync);
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,40 @@ static void CancelIMEComposition(HWND hwnd)
|
||||||
HandleTextInput({}, true);
|
HandleTextInput({}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(NTDDI_WIN10_RS4)
|
||||||
|
/* We only use WinRT functions on Windows 10 or later. Unfortunately, newer Windows SDKs are now
|
||||||
|
* linking the two functions below directly instead of using dynamic linking as previously.
|
||||||
|
* To avoid any runtime linking errors on Windows 7 or older, we stub in our own dynamic
|
||||||
|
* linking trampoline. */
|
||||||
|
|
||||||
|
static LibraryLoader _combase("combase.dll");
|
||||||
|
|
||||||
|
extern "C" int32_t __stdcall WINRT_IMPL_RoOriginateLanguageException(int32_t error, void *message, void *languageException) noexcept
|
||||||
|
{
|
||||||
|
typedef BOOL(WINAPI *PFNRoOriginateLanguageException)(int32_t, void *, void *);
|
||||||
|
static PFNRoOriginateLanguageException RoOriginateLanguageException = _combase.GetFunction("RoOriginateLanguageException");
|
||||||
|
|
||||||
|
if (RoOriginateLanguageException != nullptr) {
|
||||||
|
return RoOriginateLanguageException(error, message, languageException);
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int32_t __stdcall WINRT_IMPL_RoGetActivationFactory(void *classId, winrt::guid const &iid, void **factory) noexcept
|
||||||
|
{
|
||||||
|
typedef BOOL(WINAPI *PFNRoGetActivationFactory)(void *, winrt::guid const &, void **);
|
||||||
|
static PFNRoGetActivationFactory RoGetActivationFactory = _combase.GetFunction("RoGetActivationFactory");
|
||||||
|
|
||||||
|
if (RoGetActivationFactory != nullptr) {
|
||||||
|
return RoGetActivationFactory(classId, iid, factory);
|
||||||
|
} else {
|
||||||
|
*factory = nullptr;
|
||||||
|
return winrt::impl::error_class_not_available;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool IsDarkModeEnabled()
|
static bool IsDarkModeEnabled()
|
||||||
{
|
{
|
||||||
/* Only build if SDK is Windows 10 1803 or later. */
|
/* Only build if SDK is Windows 10 1803 or later. */
|
||||||
|
@ -1507,7 +1541,7 @@ std::optional<std::string_view> VideoDriver_Win32OpenGL::AllocateContext()
|
||||||
rc = wglCreateContext(this->dc);
|
rc = wglCreateContext(this->dc);
|
||||||
if (rc == nullptr) return "Can't create OpenGL context";
|
if (rc == nullptr) return "Can't create OpenGL context";
|
||||||
}
|
}
|
||||||
if (!wglMakeCurrent(this->dc, rc)) return "Can't active GL context";
|
if (!wglMakeCurrent(this->dc, rc)) return "Can't activate GL context";
|
||||||
|
|
||||||
this->ToggleVsync(_video_vsync);
|
this->ToggleVsync(_video_vsync);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue