mirror of
https://github.com/diasurgical/DevilutionX.git
synced 2026-11-07 09:26:09 -10:00
Replace libfmt with std::format
- `fmt::format` with literal format strings -> `std::format`. - `fmt::format(fmt::runtime(...))` -> `FormatRuntime` in the new `utils/format.hpp`, a std::vformat wrapper that is also safe under the P2905 lvalue requirement of `std::make_format_args`. - `fmt::dynamic_format_arg_store` (Lua logging) -> a small hand-rolled per-field formatter over `std::variant`, returning `std::expected`. - `fmt::format_int` -> `std::to_chars`. - `fmt::join` -> manual joins at the two call sites. - SDL_audiolib: new patch that rewrites aulib_log.h to use std::format and drops the fmt dependency from its CMakeLists. - The `-static-libstdc++` guard now keys off `DEVILUTIONX_STATIC_SDL_AUDIOLIB` instead of `DEVILUTIONX_STATIC_LIBFMT`. - libfmt removed from CMake, vcpkg, Brewfile, CI workflows, Dockerfiles, packaging scripts, UWP project, and docs. - macOS bumped to 13.3+, iOS to 16.3+ (required for `<format>`) - Amiga m68k: provide `__cmpdf2`, which is missing from the hard-float libgcc multilib but referenced via libstdc++'s long double paths. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
c00b5f44da
commit
ac2d7fc731
109 files changed
+692
-662
No files matched your search
@@ -7,7 +7,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install tar curl zip unzip bash-completion build-essential ripgrep htop \
|
||||
ninja-build ccache g++ mold gdb clang-format clang-tidy \
|
||||
rpm pkg-config cmake git gettext libsdl2-dev libsdl2-image-dev libsodium-dev \
|
||||
libpng-dev libbz2-dev libfmt-dev libgtest-dev libgmock-dev libbenchmark-dev zsh \
|
||||
libpng-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev zsh \
|
||||
qtbase5-dev qt6-base-dev ristretto \
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: android-project/app/.cxx
|
||||
key: ${{ github.workflow }}-v5-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v5-
|
||||
key: ${{ github.workflow }}-v6-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v6-
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
|
||||
@@ -40,20 +40,19 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v8-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v8-
|
||||
key: ${{ github.workflow }}-v9-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v9-
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
shell: bash
|
||||
env:
|
||||
CMAKE_BUILD_TYPE: ${{github.event_name == 'release' && 'Release' || 'RelWithDebInfo'}}
|
||||
# We set DEVILUTIONX_SYSTEM_LIBFMT=OFF because its soversion changes frequently.
|
||||
# We set DEVILUTIONX_SYSTEM_LIBSODIUM=OFF because its soversion changes frequently.
|
||||
# We set DEVILUTIONX_SYSTEM_BZIP2=OFF because Fedora and Debian do not agree on how to link it.
|
||||
run: |
|
||||
cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/aarch64-linux-gnu.toolchain.cmake \
|
||||
-DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON -DDEVILUTIONX_SYSTEM_LIBFMT=OFF \
|
||||
-DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON \
|
||||
-DDEVILUTIONX_SYSTEM_LIBSODIUM=OFF -DDEVILUTIONX_SYSTEM_BZIP2=OFF && \
|
||||
cmake --build build -j $(getconf _NPROCESSORS_ONLN) --target package
|
||||
|
||||
|
||||
@@ -40,21 +40,20 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v7-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v7-
|
||||
key: ${{ github.workflow }}-v8-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v8-
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
shell: bash
|
||||
env:
|
||||
CMAKE_BUILD_TYPE: ${{github.event_name == 'release' && 'Release' || 'RelWithDebInfo'}}
|
||||
# We set DEVILUTIONX_SYSTEM_LIBFMT=OFF because its soversion changes frequently.
|
||||
# We set DEVILUTIONX_SYSTEM_LIBSODIUM=OFF because its soversion changes frequently.
|
||||
# We set DEVILUTIONX_SYSTEM_BZIP2=OFF because Fedora and Debian do not agree on how to link it.
|
||||
run: |
|
||||
cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/linux_i386.toolchain.cmake \
|
||||
-DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON \
|
||||
-DBUILD_TESTING=OFF -DDEVILUTIONX_SYSTEM_LIBFMT=OFF -DDEVILUTIONX_SYSTEM_LIBSODIUM=OFF \
|
||||
-DBUILD_TESTING=OFF -DDEVILUTIONX_SYSTEM_LIBSODIUM=OFF \
|
||||
-DDEVILUTIONX_SYSTEM_BZIP2=OFF && \
|
||||
cmake --build build -j $(getconf _NPROCESSORS_ONLN) --target package
|
||||
|
||||
|
||||
@@ -40,20 +40,19 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v7-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v7-
|
||||
key: ${{ github.workflow }}-v8-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v8-
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
shell: bash
|
||||
env:
|
||||
CMAKE_BUILD_TYPE: ${{github.event_name == 'release' && 'Release' || 'RelWithDebInfo'}}
|
||||
# We set DEVILUTIONX_SYSTEM_LIBFMT=OFF because its soversion changes frequently.
|
||||
# We set DEVILUTIONX_SYSTEM_LIBSODIUM=OFF because its soversion changes frequently.
|
||||
# We set DEVILUTIONX_SYSTEM_BZIP2=OFF because Fedora and Debian do not agree on how to link it.
|
||||
run: |
|
||||
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON \
|
||||
-DDISCORD_INTEGRATION=ON -DBUILD_TESTING=OFF -DDEVILUTIONX_SYSTEM_LIBFMT=OFF \
|
||||
-DDISCORD_INTEGRATION=ON -DBUILD_TESTING=OFF \
|
||||
-DDEVILUTIONX_SYSTEM_LIBSODIUM=OFF -DDEVILUTIONX_SYSTEM_BZIP2=OFF && \
|
||||
cmake --build build -j $(getconf _NPROCESSORS_ONLN) --target package
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ jobs:
|
||||
- name: Create Build Environment
|
||||
run: >
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y cmake file g++ gettext git libfmt-dev libsdl1.2-dev libsodium-dev libpng-dev libbz2-dev rpm smpq
|
||||
sudo apt-get install -y cmake file g++ gettext git libsdl1.2-dev libsodium-dev libpng-dev libbz2-dev rpm smpq
|
||||
|
||||
- name: Cache CMake build folder
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v3-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v3-
|
||||
key: ${{ github.workflow }}-v4-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v4-
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
|
||||
@@ -30,14 +30,14 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y cmake curl g++ git libgtest-dev libgmock-dev libbenchmark-dev libfmt-dev libsodium-dev libpng-dev libbz2-dev libasound2-dev libxcursor-dev libxi-dev libxrandr-dev libxss-dev libxtst-dev libxkbcommon-dev wget
|
||||
sudo apt-get install -y cmake curl g++ git libgtest-dev libgmock-dev libbenchmark-dev libsodium-dev libpng-dev libbz2-dev libasound2-dev libxcursor-dev libxi-dev libxrandr-dev libxss-dev libxtst-dev libxkbcommon-dev wget
|
||||
|
||||
- name: Cache CMake build folder
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v4-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v4-
|
||||
key: ${{ github.workflow }}-v5-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v5-
|
||||
|
||||
# We specify `-DDEVILUTIONX_SYSTEM_BENCHMARK=OFF` to work around the following error:
|
||||
# lto1: fatal error: bytecode stream in file ‘/usr/lib/x86_64-linux-gnu/libbenchmark_main.a’ generated with LTO version 11.2 instead of the expected 11.3
|
||||
|
||||
@@ -30,14 +30,14 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y cmake curl g++ git lcov libgtest-dev libgmock-dev libbenchmark-dev libfmt-dev libsdl2-dev libsodium-dev libpng-dev libbz2-dev wget
|
||||
sudo apt-get install -y cmake curl g++ git lcov libgtest-dev libgmock-dev libbenchmark-dev libsdl2-dev libsodium-dev libpng-dev libbz2-dev wget
|
||||
|
||||
- name: Cache CMake build folder
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v3-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v3-
|
||||
key: ${{ github.workflow }}-v4-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v4-
|
||||
|
||||
# We specify `-DDEVILUTIONX_SYSTEM_BENCHMARK=OFF` to work around the following error:
|
||||
# lto1: fatal error: bytecode stream in file ‘/usr/lib/x86_64-linux-gnu/libbenchmark_main.a’ generated with LTO version 11.2 instead of the expected 11.3
|
||||
|
||||
@@ -67,7 +67,6 @@ jobs:
|
||||
path: |
|
||||
build-ninja-vcpkg-relwithdebinfo/devilutionx.exe
|
||||
build-ninja-vcpkg-relwithdebinfo/bz2.dll
|
||||
build-ninja-vcpkg-relwithdebinfo/fmt.dll
|
||||
build-ninja-vcpkg-relwithdebinfo/libpng16.dll
|
||||
build-ninja-vcpkg-relwithdebinfo/libsodium.dll
|
||||
build-ninja-vcpkg-relwithdebinfo/SDL2.dll
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y cmake curl g++ git libgtest-dev libgmock-dev libbenchmark-dev libfmt-dev libsdl2-dev libsodium-dev libpng-dev libbz2-dev wget
|
||||
sudo apt-get install -y cmake curl g++ git libgtest-dev libgmock-dev libbenchmark-dev libsdl2-dev libsodium-dev libpng-dev libbz2-dev wget
|
||||
|
||||
- name: CMake Configure
|
||||
run: cmake -S. -Bbuild
|
||||
|
||||
@@ -39,8 +39,8 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v5-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v5-
|
||||
key: ${{ github.workflow }}-v6-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v6-
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
|
||||
@@ -38,8 +38,8 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v2-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v2-
|
||||
key: ${{ github.workflow }}-v3-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v3-
|
||||
|
||||
- name: Clean previous DMG
|
||||
working-directory: ${{github.workspace}}
|
||||
|
||||
@@ -38,8 +38,8 @@ jobs:
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v4-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v4-
|
||||
key: ${{ github.workflow }}-v5-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v5-
|
||||
|
||||
- name: Clean previous DMG
|
||||
working-directory: ${{github.workspace}}
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
run: >
|
||||
docker run --platform linux/s390x --rm --interactive --mount type=bind,source=$(pwd),target=/host s390x/alpine sh -c
|
||||
"
|
||||
apk add --update-cache g++ ninja cmake ccache sdl2-dev sdl2_image-dev fmt-dev libpng-dev jpeg-dev bzip2-dev gtest-dev wget &&
|
||||
apk add --update-cache g++ ninja cmake ccache sdl2-dev sdl2_image-dev libpng-dev jpeg-dev bzip2-dev gtest-dev wget &&
|
||||
cd /host &&
|
||||
export CCACHE_DIR=/host/.ccache &&
|
||||
cmake -S. -Bbuild -G Ninja -DNONET=ON -DNOSOUND=ON &&
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Create Build Environment
|
||||
run: >
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libfmt-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev git smpq gettext python-is-python3
|
||||
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev git smpq gettext python-is-python3
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
- name: Create Build Environment
|
||||
run: >
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libfmt-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev git smpq gettext python-is-python3
|
||||
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev git smpq gettext python-is-python3
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
From e89e20a71e824a182c1ba519a9f4004686ed2433 Mon Sep 17 00:00:00 2001
|
||||
From: Gleb Mazovetskiy <[email protected]>
|
||||
Date: Sun, 28 Jun 2026 22:50:06 +0100
|
||||
Subject: [PATCH] aulib_log.h: Include missing <fmt/format.h>
|
||||
|
||||
This include was missing and this started causing an error recently in our CI
|
||||
---
|
||||
src/aulib_log.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/aulib_log.h b/src/aulib_log.h
|
||||
index b87ee7d..bfd8652 100644
|
||||
--- a/src/aulib_log.h
|
||||
+++ b/src/aulib_log.h
|
||||
@@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
#include "aulib_config.h"
|
||||
#include <fmt/core.h>
|
||||
+#include <fmt/format.h>
|
||||
|
||||
namespace aulib {
|
||||
namespace log {
|
||||
--
|
||||
2.53.0
|
||||
|
||||
Vendored
+12
-5
@@ -6,9 +6,6 @@ else()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif()
|
||||
|
||||
# Will use our `fmt::fmt` target if it exists.
|
||||
set(WITH_SYSTEM_FMTLIB ON)
|
||||
|
||||
# No need for the libsamplerate resampler:
|
||||
set(USE_RESAMP_SRC OFF)
|
||||
|
||||
@@ -36,13 +33,23 @@ set(USE_DEC_WILDMIDI OFF)
|
||||
set(USE_DEC_ADLMIDI OFF)
|
||||
set(USE_DEC_DRMP3 ON)
|
||||
|
||||
find_package(Patch REQUIRED)
|
||||
# SDL_audiolib only uses fmt in aulib_log.h, which we replace with a
|
||||
# std::format version below. Pretend that fmt is already provided so that
|
||||
# SDL_audiolib does not require or build it (linking the empty INTERFACE
|
||||
# target is a no-op).
|
||||
set(WITH_SYSTEM_FMTLIB ON)
|
||||
if(NOT TARGET fmt::fmt)
|
||||
add_library(devilutionx_fmt_stub INTERFACE)
|
||||
add_library(fmt::fmt ALIAS devilutionx_fmt_stub)
|
||||
endif()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare_ExcludeFromAll(SDL_audiolib
|
||||
URL https://github.com/realnc/SDL_audiolib/archive/cc1bb6af8d4cf5e200259072bde1edd1c8c5137e.tar.gz
|
||||
URL_HASH MD5=0e8174264ac9c6b314c6b2d9a5f72efd
|
||||
PATCH_COMMAND "${Patch_EXECUTABLE}" -p1 -N < "${CMAKE_CURRENT_LIST_DIR}/0001-aulib_log.h-Include-missing-fmt-format.h.patch" || true
|
||||
# A file replacement instead of a diff: unlike the `patch` tool, this is
|
||||
# idempotent and works the same on every host platform.
|
||||
PATCH_COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_LIST_DIR}/aulib_log.h" <SOURCE_DIR>/src/aulib_log.h
|
||||
)
|
||||
FetchContent_MakeAvailable_ExcludeFromAll(SDL_audiolib)
|
||||
|
||||
|
||||
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
// This is copyrighted software. More information is at the end of this file.
|
||||
#pragma once
|
||||
#include "aulib_config.h"
|
||||
#include <cstdio>
|
||||
#include <format>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace aulib {
|
||||
namespace log {
|
||||
|
||||
template <typename... Args>
|
||||
void debug([[maybe_unused]] std::format_string<Args...> fmt_str,
|
||||
[[maybe_unused]] Args &&...args) {
|
||||
#if AULIB_DEBUG
|
||||
const std::string message = std::format(fmt_str, std::forward<Args>(args)...);
|
||||
std::fprintf(stderr, "SDL_audiolib debug: %s", message.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void debugLn([[maybe_unused]] std::format_string<Args...> fmt_str,
|
||||
[[maybe_unused]] Args &&...args) {
|
||||
#if AULIB_DEBUG
|
||||
const std::string message = std::format(fmt_str, std::forward<Args>(args)...);
|
||||
std::fprintf(stderr, "SDL_audiolib debug: %s\n", message.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void warn(std::format_string<Args...> fmt_str, Args &&...args) {
|
||||
const std::string message = std::format(fmt_str, std::forward<Args>(args)...);
|
||||
std::fprintf(stderr, "SDL_audiolib warning: %s", message.c_str());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void warnLn(std::format_string<Args...> fmt_str, Args &&...args) {
|
||||
const std::string message = std::format(fmt_str, std::forward<Args>(args)...);
|
||||
std::fprintf(stderr, "SDL_audiolib warning: %s\n", message.c_str());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void info(std::format_string<Args...> fmt_str, Args &&...args) {
|
||||
const std::string message = std::format(fmt_str, std::forward<Args>(args)...);
|
||||
std::printf("SDL_audiolib info: %s", message.c_str());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void infoLn(std::format_string<Args...> fmt_str, Args &&...args) {
|
||||
const std::string message = std::format(fmt_str, std::forward<Args>(args)...);
|
||||
std::printf("SDL_audiolib info: %s\n", message.c_str());
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
} // namespace aulib
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 2022 Nikos Chantziaras.
|
||||
|
||||
This file is part of SDL_audiolib.
|
||||
|
||||
SDL_audiolib is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
SDL_audiolib 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 Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with SDL_audiolib. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
Vendored
-39
@@ -1,39 +0,0 @@
|
||||
include(functions/FetchContent_ExcludeFromAll_backport)
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||
# Enable POSIX extensions such as `readlink` and `ftruncate`.
|
||||
add_definitions(-D_POSIX_C_SOURCE=200809L)
|
||||
endif()
|
||||
|
||||
# Disable fmt/os.h functionality.
|
||||
# We do not use it and it is not supported on some systems.
|
||||
set(FMT_OS OFF)
|
||||
|
||||
if(DEVILUTIONX_STATIC_LIBFMT)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare_ExcludeFromAll(libfmt
|
||||
URL https://github.com/fmtlib/fmt/releases/download/12.0.0/fmt-12.0.0.zip
|
||||
URL_HASH SHA256=1c32293203449792bf8e94c7f6699c643887e826f2d66a80869b4f279fb07d25
|
||||
)
|
||||
FetchContent_MakeAvailable_ExcludeFromAll(libfmt)
|
||||
|
||||
# We do not use locale-specific features of libfmt and disabling them reduces the size.
|
||||
target_compile_definitions(fmt PUBLIC FMT_USE_LOCALE=0)
|
||||
|
||||
if(DEVILUTIONX_WINDOWS_NO_WCHAR)
|
||||
target_compile_definitions(fmt PUBLIC FMT_USE_WRITE_CONSOLE)
|
||||
endif()
|
||||
|
||||
# Reduces the overall binary size by 8 KiB.
|
||||
if(TARGET_PLATFORM STREQUAL "rg99")
|
||||
target_compile_definitions(fmt PUBLIC FMT_BUILTIN_TYPES=0)
|
||||
endif()
|
||||
|
||||
# https://github.com/fmtlib/fmt/issues/4189
|
||||
if(NINTENDO_3DS OR NINTENDO_SWITCH OR VITA)
|
||||
target_compile_definitions(fmt PUBLIC FMT_USE_FALLBACK_FILE=1)
|
||||
endif()
|
||||
@@ -1,5 +1,4 @@
|
||||
brew "cmake"
|
||||
brew "fmt"
|
||||
brew "sdl2"
|
||||
brew "libsodium"
|
||||
brew "pkg-config"
|
||||
|
||||
@@ -179,22 +179,6 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED DEVILUTIONX_SYSTEM_LIBFMT)
|
||||
find_package(fmt 8.0.0 QUIET)
|
||||
if(fmt_FOUND)
|
||||
message("-- Found fmt ${fmt_VERSION}")
|
||||
else()
|
||||
message("-- Suitable system fmt package not found, will use fmt from source")
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
endif()
|
||||
endif()
|
||||
dependency_options("libfmt" DEVILUTIONX_SYSTEM_LIBFMT ON DEVILUTIONX_STATIC_LIBFMT)
|
||||
if(DEVILUTIONX_SYSTEM_LIBFMT)
|
||||
find_package(fmt 8.0.0 REQUIRED)
|
||||
else()
|
||||
add_subdirectory(3rdParty/libfmt)
|
||||
endif()
|
||||
|
||||
if(NOT NOSOUND)
|
||||
if(USE_SDL3)
|
||||
if(NOT DEFINED DEVILUTIONX_SYSTEM_SDL_MIXER)
|
||||
|
||||
@@ -106,8 +106,5 @@ if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
# For older macOS, we assume MacPorts because Homebrew only supports newer version
|
||||
if(DARWIN_MAJOR_VERSION VERSION_LESS 11)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/platforms/macports/finders")
|
||||
|
||||
# On MacPorts, libfmt is in a subdirectory:
|
||||
list(APPEND CMAKE_MODULE_PATH "/opt/local/lib/libfmt11/cmake")
|
||||
endif()
|
||||
endif()
|
||||
@@ -163,7 +163,6 @@ if(DEVILUTIONX_SCREENSHOT_FORMAT STREQUAL DEVILUTIONX_SCREENSHOT_FORMAT_PNG AND
|
||||
DevilutionX::SDL
|
||||
GTest::gmock
|
||||
GTest::gtest
|
||||
fmt::fmt
|
||||
tl
|
||||
app_fatal_for_testing
|
||||
language_for_testing
|
||||
|
||||
@@ -18,7 +18,6 @@ set(DEVILUTIONX_SYSTEM_SDL_IMAGE OFF)
|
||||
set(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBPNG OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
|
||||
|
||||
# Package the assets with the APK.
|
||||
|
||||
@@ -7,7 +7,6 @@ set(PACKET_ENCRYPTION OFF)
|
||||
set(DEFAULT_PER_PIXEL_LIGHTING false)
|
||||
|
||||
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_SYSTEM_ZLIB OFF)
|
||||
set(DEVILUTIONX_STATIC_ZLIB ON)
|
||||
set(USE_SDL3 ON)
|
||||
|
||||
@@ -4,7 +4,6 @@ set(DISABLE_ZERO_TIER ON)
|
||||
set(DISABLE_TCP ON)
|
||||
set(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(NOEXIT ON)
|
||||
# Emscripten ports do have a bzip2 but it fails to link with this error:
|
||||
# warning: _BZ2_bzDecompress may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
|
||||
|
||||
@@ -10,7 +10,6 @@ set(DEVILUTIONX_SYSTEM_SDL_IMAGE OFF)
|
||||
set(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBPNG OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
|
||||
set(NOEXIT ON)
|
||||
|
||||
|
||||
@@ -8,11 +8,6 @@ set(USE_SDL1 ON)
|
||||
# ZeroTier is yet to be tested.
|
||||
set(DISABLE_ZERO_TIER ON)
|
||||
|
||||
# Use vendored libfmt until this issue is resolved:
|
||||
# https://trac.macports.org/ticket/71503
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_STATIC_LIBFMT ON)
|
||||
|
||||
# https://trac.macports.org/ticket/71511
|
||||
set(DEVILUTIONX_SYSTEM_GOOGLETEST OFF)
|
||||
set(DEVILUTIONX_STATIC_GOOGLETEST OFF)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
set(USE_SDL1 ON)
|
||||
set(NONET ON)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF)
|
||||
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ set(UBSAN OFF)
|
||||
set(BUILD_TESTING OFF)
|
||||
set(BUILD_ASSETS_MPQ OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_STATIC_LIBSODIUM ON)
|
||||
set(DEVILUTIONX_STATIC_LIBFMT ON)
|
||||
set(DISABLE_ZERO_TIER ON)
|
||||
set(MPQFS_FILE_BUFFER_SIZE 32768)
|
||||
set(NOEXIT ON)
|
||||
|
||||
@@ -11,7 +11,6 @@ set(DEVILUTIONX_SYSTEM_SDL_IMAGE OFF)
|
||||
set(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBPNG OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
|
||||
set(DEVILUTIONX_SYSTEM_ZLIB OFF)
|
||||
|
||||
@@ -20,7 +19,6 @@ set(DEVILUTIONX_STATIC_SDL_IMAGE ON)
|
||||
set(DEVILUTIONX_STATIC_SDL_AUDIOLIB ON)
|
||||
set(DEVILUTIONX_STATIC_LIBSODIUM ON)
|
||||
set(DEVILUTIONX_STATIC_LIBPNG ON)
|
||||
set(DEVILUTIONX_STATIC_LIBFMT ON)
|
||||
set(DEVILUTIONX_STATIC_BZIP2 ON)
|
||||
set(DEVILUTIONX_STATIC_ZLIB ON)
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ set(NONET ON)
|
||||
set(DISABLE_ZERO_TIER ON)
|
||||
set(USE_SDL1 ON)
|
||||
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
set(DEVILUTIONX_STATIC_LIBSODIUM OFF)
|
||||
|
||||
# Compatibility with Windows 9x 8-bit mode and improved performance
|
||||
|
||||
@@ -5,7 +5,6 @@ set(UBSAN OFF)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/xbox_nxdk/finders")
|
||||
|
||||
set(DEVILUTIONX_SYSTEM_BZIP2 OFF)
|
||||
set(DEVILUTIONX_SYSTEM_LIBFMT OFF)
|
||||
|
||||
# nxdk's zlib is built with Z_SOLO, which excludes utility functions like
|
||||
# uncompress() that mpqfs needs for zlib-compressed MPQ sectors.
|
||||
|
||||
+15
-3
@@ -73,6 +73,14 @@ if(NOT VERSION_SUFFIX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The iOS toolchain file reads DEPLOYMENT_TARGET when it is processed by
|
||||
# `project()`, so the default must be set before that.
|
||||
# libc++'s <format> requires the floating-point std::to_chars symbols,
|
||||
# which are only available in the iOS 16.3+ system libc++.
|
||||
if(CMAKE_TOOLCHAIN_FILE MATCHES "ios\\.toolchain\\.cmake" AND NOT DEFINED DEPLOYMENT_TARGET)
|
||||
set(DEPLOYMENT_TARGET "16.3")
|
||||
endif()
|
||||
|
||||
project(DevilutionX
|
||||
VERSION ${VERSION_NUM}
|
||||
LANGUAGES C CXX)
|
||||
@@ -355,7 +363,7 @@ include(Dependencies)
|
||||
# Mixing `-static-libstdc++` with a dynamic C++ dependency causes both copies
|
||||
# to initialize, which is UB and can cause crashes, e.g. in
|
||||
# `std::ios_base_library_init()`.
|
||||
if(NOT DEVILUTIONX_STATIC_LIBFMT)
|
||||
if(NOT NOSOUND AND NOT DEVILUTIONX_STATIC_SDL_AUDIOLIB)
|
||||
set(DEVILUTIONX_STATIC_CXX_STDLIB OFF)
|
||||
endif()
|
||||
|
||||
@@ -448,10 +456,14 @@ if(APPLE)
|
||||
if(IOS)
|
||||
set(MACOSX_BUNDLE_REQUIRED_PLATFORM IPhoneOS)
|
||||
set_target_properties(${BIN_TARGET} PROPERTIES XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "9.0")
|
||||
# libc++'s <format> requires the floating-point std::to_chars symbols,
|
||||
# which are only available in the iOS 16.3+ system libc++.
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "16.3")
|
||||
elseif(DARWIN_MAJOR_VERSION GREATER_EQUAL 17)
|
||||
set(MACOSX_BUNDLE_REQUIRED_PLATFORM Carbon)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13.0")
|
||||
# libc++'s <format> requires the floating-point std::to_chars symbols,
|
||||
# which are only available in the macOS 13.3+ system libc++.
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.3")
|
||||
endif()
|
||||
if(DARWIN_MAJOR_VERSION VERSION_LESS 9)
|
||||
# Finder on OSX Tiger can only handle icns files with up to 128x128 icons.
|
||||
|
||||
@@ -201,7 +201,6 @@ cmake_configure() {
|
||||
"-DTARGET_PLATFORM=$TARGET" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN}/usr/share/buildroot/toolchainfile.cmake" \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DDEVILUTIONX_SYSTEM_LIBFMT=OFF \
|
||||
-DDEVILUTIONX_SYSTEM_LIBSODIUM=OFF \
|
||||
-DDEVILUTIONX_SYSTEM_BZIP2=OFF \
|
||||
-DSTACK_PROTECTOR=OFF \
|
||||
|
||||
@@ -22,7 +22,7 @@ fi
|
||||
PACKAGES=(
|
||||
cmake git smpq gettext dpkg-cross libc-dev-arm64-cross
|
||||
libsdl2-dev:arm64 libsdl2-image-dev:arm64 libsodium-dev:arm64
|
||||
libpng-dev:arm64 libbz2-dev:arm64 libfmt-dev:arm64
|
||||
libpng-dev:arm64 libbz2-dev:arm64
|
||||
libspeechd-dev:arm64
|
||||
)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ fi
|
||||
PACKAGES=(
|
||||
cmake git smpq gettext
|
||||
libsdl2-dev:i386 libsdl2-image-dev:i386 libsodium-dev:i386
|
||||
libpng-dev:i386 libbz2-dev:i386 libfmt-dev:i386 libspeechd-dev:i386
|
||||
libpng-dev:i386 libbz2-dev:i386 libspeechd-dev:i386
|
||||
)
|
||||
|
||||
if (( $# < 1 )) || [[ "$1" != --no-gcc ]]; then
|
||||
|
||||
@@ -4,7 +4,7 @@ set -x
|
||||
|
||||
PACKAGES=(
|
||||
rpm pkg-config cmake git smpq gettext libsdl2-dev libsdl2-image-dev libsodium-dev
|
||||
libpng-dev libbz2-dev libfmt-dev libspeechd-dev
|
||||
libpng-dev libbz2-dev libspeechd-dev
|
||||
)
|
||||
|
||||
if (( $# < 1 )) || [[ "$1" != --no-gcc ]]; then
|
||||
|
||||
+6
-18
@@ -200,7 +200,6 @@ add_devilutionx_object_library(libdevilutionx_assets
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_assets PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
tl
|
||||
libdevilutionx_headless_mode
|
||||
libdevilutionx_game_mode
|
||||
@@ -233,7 +232,6 @@ add_devilutionx_object_library(libdevilutionx_clx_render
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_clx_render PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
libdevilutionx_light_render
|
||||
libdevilutionx_palette_blending
|
||||
libdevilutionx_strings
|
||||
@@ -262,7 +260,6 @@ target_link_dependencies(libdevilutionx_control
|
||||
tl
|
||||
libdevilutionx_text_input
|
||||
PRIVATE
|
||||
fmt::fmt
|
||||
libdevilutionx_clx_render
|
||||
libdevilutionx_control_mode
|
||||
libdevilutionx_format_int
|
||||
@@ -404,7 +401,6 @@ add_devilutionx_object_library(libdevilutionx_gendung
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_gendung PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
tl
|
||||
libdevilutionx_assets
|
||||
libdevilutionx_items
|
||||
@@ -508,7 +504,6 @@ add_devilutionx_object_library(libdevilutionx_lighting
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_lighting PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
magic_enum::magic_enum
|
||||
tl
|
||||
unordered_dense::unordered_dense
|
||||
@@ -552,7 +547,6 @@ add_devilutionx_object_library(libdevilutionx_ini
|
||||
utils/ini.cpp
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_ini PUBLIC
|
||||
fmt::fmt
|
||||
tl
|
||||
unordered_dense::unordered_dense
|
||||
libdevilutionx_strings
|
||||
@@ -566,7 +560,6 @@ target_include_directories(libdevilutionx_log INTERFACE
|
||||
${PROJECT_SOURCE_DIR}/Source)
|
||||
target_link_libraries(libdevilutionx_log INTERFACE
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
)
|
||||
target_sources(libdevilutionx_log INTERFACE $<TARGET_OBJECTS:libdevilutionx_strings>)
|
||||
|
||||
@@ -632,7 +625,6 @@ if(SUPPORTS_MPQ)
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_mpq PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
mpqfs::mpqfs
|
||||
tl
|
||||
libdevilutionx_file_util
|
||||
@@ -655,7 +647,6 @@ add_devilutionx_object_library(libdevilutionx_options
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_options PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
magic_enum::magic_enum
|
||||
tl
|
||||
unordered_dense::unordered_dense
|
||||
@@ -695,7 +686,6 @@ add_devilutionx_object_library(libdevilutionx_player
|
||||
target_link_dependencies(libdevilutionx_player
|
||||
PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
magic_enum::magic_enum
|
||||
sol2::sol2
|
||||
tl
|
||||
@@ -760,7 +750,6 @@ target_link_dependencies(libdevilutionx_text_render
|
||||
PUBLIC
|
||||
libdevilutionx_surface
|
||||
PRIVATE
|
||||
fmt::fmt
|
||||
unordered_dense::unordered_dense
|
||||
libdevilutionx_clx_render
|
||||
libdevilutionx_game_mode
|
||||
@@ -787,7 +776,6 @@ add_devilutionx_object_library(libdevilutionx_txtdata
|
||||
data/value_reader.cpp
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_txtdata PUBLIC
|
||||
fmt::fmt
|
||||
tl
|
||||
libdevilutionx_assets
|
||||
libdevilutionx_parse_int
|
||||
@@ -808,7 +796,6 @@ if(NOSOUND)
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_sound PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
magic_enum::magic_enum
|
||||
tl
|
||||
unordered_dense::unordered_dense
|
||||
@@ -835,7 +822,6 @@ else()
|
||||
endif()
|
||||
target_link_dependencies(libdevilutionx_sound PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
magic_enum::magic_enum
|
||||
tl
|
||||
unordered_dense::unordered_dense
|
||||
@@ -850,7 +836,6 @@ add_devilutionx_object_library(libdevilutionx_stores
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_stores PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
tl
|
||||
libdevilutionx_clx_render
|
||||
libdevilutionx_control
|
||||
@@ -863,8 +848,7 @@ add_devilutionx_object_library(libdevilutionx_strings
|
||||
utils/str_cat.cpp
|
||||
utils/str_case.cpp
|
||||
)
|
||||
target_link_dependencies(libdevilutionx_strings PRIVATE
|
||||
fmt::fmt)
|
||||
target_link_dependencies(libdevilutionx_strings PRIVATE)
|
||||
|
||||
add_devilutionx_object_library(libdevilutionx_utils_console
|
||||
utils/console.cpp
|
||||
@@ -903,6 +887,11 @@ if(IOS)
|
||||
list(APPEND libdevilutionx_SRCS platform/ios/ios_paths.m)
|
||||
endif()
|
||||
|
||||
if(AMIGA AND NOT WARPOS)
|
||||
# Works around a missing `__cmpdf2` in the hard-float libgcc multilib.
|
||||
list(APPEND libdevilutionx_SRCS platform/amiga/cmpdf2.c)
|
||||
endif()
|
||||
|
||||
if(NOT DISABLE_DEMOMODE)
|
||||
list(APPEND libdevilutionx_SRCS engine/demomode.cpp)
|
||||
endif()
|
||||
@@ -969,7 +958,6 @@ add_devilutionx_object_library(libdevilutionx ${libdevilutionx_SRCS})
|
||||
target_include_directories(libdevilutionx PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_link_dependencies(libdevilutionx PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
libsmackerdec
|
||||
${LUA_LIBRARIES}
|
||||
magic_enum::magic_enum
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "DiabloUI/dialogs.h"
|
||||
#include "DiabloUI/multi/selgame.h"
|
||||
@@ -36,6 +33,7 @@
|
||||
#include "pfile.h"
|
||||
#include "tables/playerdat.hpp"
|
||||
#include "utils/enum_traits.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/sdl_geometry.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -620,7 +618,7 @@ static void UiSelHeroDialog(
|
||||
} else {
|
||||
CopyUtf8(dialogTitle, _("Delete Single Player Hero"), sizeof(dialogTitle));
|
||||
}
|
||||
strcpy(dialogText, fmt::format(fmt::runtime(_("Are you sure you want to delete the character \"{:s}\"?")), selhero_heroInfo.name).c_str());
|
||||
strcpy(dialogText, FormatRuntime(_("Are you sure you want to delete the character \"{:s}\"?"), selhero_heroInfo.name).c_str());
|
||||
|
||||
if (UiSelHeroYesNoDialog(dialogTitle, dialogText))
|
||||
fnremove(&selhero_heroInfo);
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "DiabloUI/ui_item.h"
|
||||
@@ -20,6 +17,7 @@
|
||||
#include "engine/render/text_render.hpp"
|
||||
#include "multi.h"
|
||||
#include "storm/storm_net.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/ui_fwd.h"
|
||||
#include "utils/utf8.hpp"
|
||||
@@ -138,7 +136,7 @@ void SelconnFocus(size_t value)
|
||||
break;
|
||||
}
|
||||
|
||||
CopyUtf8(selconn_MaxPlayers, fmt::format(fmt::runtime(_("Players Supported: {:d}")), players), sizeof(selconn_MaxPlayers));
|
||||
CopyUtf8(selconn_MaxPlayers, FormatRuntime(_("Players Supported: {:d}"), players), sizeof(selconn_MaxPlayers));
|
||||
CopyUtf8(selconn_Description, WordWrapString(selconn_Description, DESCRIPTION_WIDTH), sizeof(selconn_Description));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "DiabloUI/hero/selhero.h"
|
||||
#include "DiabloUI/scrollbar.h"
|
||||
@@ -35,6 +32,7 @@
|
||||
#include "multi.h"
|
||||
#include "options.h"
|
||||
#include "storm/storm_net.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
#include "utils/ui_fwd.h"
|
||||
@@ -107,7 +105,7 @@ static std::string GetErrorMessageIncompatibility(const GameData &data)
|
||||
else
|
||||
return std::string(_("You need to full version of the game to join this game."));
|
||||
}
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: Error message when somebody tries to join a game running another version. */ "Your version {:s} does not match the host {:d}.{:d}.{:d}.")), PROJECT_VERSION, data.versionMajor, data.versionMinor, data.versionPatch);
|
||||
return FormatRuntime(_(/* TRANSLATORS: Error message when somebody tries to join a game running another version. */ "Your version {:s} does not match the host {:d}.{:d}.{:d}."), PROJECT_VERSION, data.versionMajor, data.versionMinor, data.versionPatch);
|
||||
}
|
||||
|
||||
void UiInitGameSelectionList(std::string_view search)
|
||||
@@ -248,7 +246,7 @@ void selgame_GameSelection_Focus(size_t value)
|
||||
difficulty = _("Hell");
|
||||
break;
|
||||
}
|
||||
infoString.append(fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} means: Game Difficulty. */ "Difficulty: {:s}")), difficulty));
|
||||
infoString.append(FormatRuntime(_(/* TRANSLATORS: {:s} means: Game Difficulty. */ "Difficulty: {:s}"), difficulty));
|
||||
infoString += '\n';
|
||||
switch (gameInfo.gameData.nTickRate) {
|
||||
case 20:
|
||||
@@ -276,9 +274,9 @@ void selgame_GameSelection_Focus(size_t value)
|
||||
}
|
||||
infoString += '\n';
|
||||
if (gameInfo.peerIsRelayed.value_or(false))
|
||||
infoString.append(fmt::format(fmt::runtime(_("Ping: {:d} ms (RELAYED)")), gameInfo.latency.value_or(0)));
|
||||
infoString.append(FormatRuntime(_("Ping: {:d} ms (RELAYED)"), gameInfo.latency.value_or(0)));
|
||||
else
|
||||
infoString.append(fmt::format(fmt::runtime(_("Ping: {:d} ms")), gameInfo.latency.value_or(0)));
|
||||
infoString.append(FormatRuntime(_("Ping: {:d} ms"), gameInfo.latency.value_or(0)));
|
||||
} else {
|
||||
infoString.append(GetErrorMessageIncompatibility(gameInfo.gameData));
|
||||
}
|
||||
@@ -354,7 +352,7 @@ void selgame_GameSelection_Select(size_t value)
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
selgame_Title = fmt::format(fmt::runtime(_("Join {:s} Games")), _(ConnectionNames[provider]));
|
||||
selgame_Title = FormatRuntime(_("Join {:s} Games"), _(ConnectionNames[provider]));
|
||||
title = selgame_Title.c_str();
|
||||
|
||||
const char *inputHint;
|
||||
|
||||
+6
-7
@@ -18,12 +18,11 @@
|
||||
#include "utils/sdl_compat.h"
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "diablo.h"
|
||||
#include "dvlnet/leaveinfo.hpp"
|
||||
#include "multi.h"
|
||||
#include "storm/storm_net.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/sdl_thread.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -83,16 +82,16 @@ void ErrDlg(const char *title, std::string_view error, std::string_view logFileP
|
||||
{
|
||||
DisplayFatalErrorAndExit(
|
||||
title,
|
||||
fmt::format(fmt::runtime(_(/* TRANSLATORS: Error message that displays relevant information for bug report */ "{:s}\n\nThe error occurred at: {:s} line {:d}")),
|
||||
FormatRuntime(_(/* TRANSLATORS: Error message that displays relevant information for bug report */ "{:s}\n\nThe error occurred at: {:s} line {:d}"),
|
||||
error, logFilePath, logLineNr));
|
||||
}
|
||||
|
||||
void InsertCDDlg(std::string_view archiveName)
|
||||
{
|
||||
DisplayFatalErrorAndExit(_("Data File Error"),
|
||||
fmt::format(fmt::runtime(_("Unable to open main data archive ({:s}).\n"
|
||||
"\n"
|
||||
"Make sure that it is in the game folder.")),
|
||||
FormatRuntime(_("Unable to open main data archive ({:s}).\n"
|
||||
"\n"
|
||||
"Make sure that it is in the game folder."),
|
||||
archiveName));
|
||||
}
|
||||
|
||||
@@ -100,7 +99,7 @@ void DirErrorDlg(std::string_view error)
|
||||
{
|
||||
DisplayFatalErrorAndExit(
|
||||
_("Read-Only Directory Error"),
|
||||
fmt::format(fmt::runtime(_(/* TRANSLATORS: Error when Program is not allowed to write data */ "Unable to write to location:\n{:s}")),
|
||||
FormatRuntime(_(/* TRANSLATORS: Error when Program is not allowed to write data */ "Unable to write to location:\n{:s}"),
|
||||
error));
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -8,8 +8,6 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "engine/load_file.hpp"
|
||||
#include "engine/palette.h"
|
||||
@@ -21,6 +19,7 @@
|
||||
#include "player.h"
|
||||
#include "utils/attributes.h"
|
||||
#include "utils/enum_traits.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/ui_fwd.h"
|
||||
@@ -1467,16 +1466,16 @@ void DrawAutomapText(const Surface &out)
|
||||
std::string description;
|
||||
switch (leveltype) {
|
||||
case DTYPE_NEST:
|
||||
description = fmt::format(fmt::runtime(_("Level: Nest {:d}")), currlevel - 16);
|
||||
description = FormatRuntime(_("Level: Nest {:d}"), currlevel - 16);
|
||||
break;
|
||||
case DTYPE_CRYPT:
|
||||
description = fmt::format(fmt::runtime(_("Level: Crypt {:d}")), currlevel - 20);
|
||||
description = FormatRuntime(_("Level: Crypt {:d}"), currlevel - 20);
|
||||
break;
|
||||
case DTYPE_TOWN:
|
||||
description = std::string(_("Town"));
|
||||
break;
|
||||
default:
|
||||
description = fmt::format(fmt::runtime(_("Level: {:d}")), currlevel);
|
||||
description = FormatRuntime(_("Level: {:d}"), currlevel);
|
||||
break;
|
||||
}
|
||||
drawStringAndAdvanceLine(description);
|
||||
@@ -1495,7 +1494,7 @@ void DrawAutomapText(const Surface &out)
|
||||
break;
|
||||
}
|
||||
|
||||
const std::string description = fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} means: Game Difficulty. */ "Difficulty: {:s}")), difficulty);
|
||||
const std::string description = FormatRuntime(_(/* TRANSLATORS: {:s} means: Game Difficulty. */ "Difficulty: {:s}"), difficulty);
|
||||
drawStringAndAdvanceLine(description);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#include "control_chat_commands.hpp"
|
||||
#include "control.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "diablo_msg.hpp"
|
||||
#include "engine/backbuffer_state.hpp"
|
||||
#include "inv.h"
|
||||
#include "levels/setmaps.h"
|
||||
#include "storm/storm_net.hpp"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/parse_int.hpp"
|
||||
#include "utils/str_case.hpp"
|
||||
@@ -232,15 +231,15 @@ std::string TextCmdPing(const std::string_view parameter)
|
||||
Player &player = *it;
|
||||
DvlNetLatencies latencies = DvlNet_GetLatencies(player.getId());
|
||||
|
||||
StrAppend(ret, fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} means: Character Name */ "Latency statistics for {:s}:")), player.name()));
|
||||
StrAppend(ret, FormatRuntime(_(/* TRANSLATORS: {:s} means: Character Name */ "Latency statistics for {:s}:"), player.name()));
|
||||
|
||||
StrAppend(ret, "\n", fmt::format(fmt::runtime(_(/* TRANSLATORS: Network connectivity statistics */ "Echo latency: {:d} ms")), latencies.echoLatency));
|
||||
StrAppend(ret, "\n", FormatRuntime(_(/* TRANSLATORS: Network connectivity statistics */ "Echo latency: {:d} ms"), latencies.echoLatency));
|
||||
|
||||
if (latencies.providerLatency) {
|
||||
if (latencies.isRelayed && *latencies.isRelayed) {
|
||||
StrAppend(ret, "\n", fmt::format(fmt::runtime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms (Relayed)")), *latencies.providerLatency));
|
||||
StrAppend(ret, "\n", FormatRuntime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms (Relayed)"), *latencies.providerLatency));
|
||||
} else {
|
||||
StrAppend(ret, "\n", fmt::format(fmt::runtime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms")), *latencies.providerLatency));
|
||||
StrAppend(ret, "\n", FormatRuntime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms"), *latencies.providerLatency));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#include "control.hpp"
|
||||
#include "control_chat.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/text_input.hpp"
|
||||
#include "engine/render/clx_render.hpp"
|
||||
#include "inv.h"
|
||||
#include "utils/display.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/sdl_compat.h"
|
||||
@@ -56,12 +55,12 @@ void DrawGoldSplit(const Surface &out)
|
||||
const TextInputCursorState &cursor = GoldDropCursor;
|
||||
const int max = GetGoldDropMax();
|
||||
|
||||
const std::string description = fmt::format(
|
||||
fmt::runtime(ngettext(
|
||||
const std::string description = FormatRuntime(
|
||||
ngettext(
|
||||
/* TRANSLATORS: {:s} is a number with separators. Dialog is shown when splitting a stash of Gold.*/
|
||||
"You have {:s} gold piece. How many do you want to remove?",
|
||||
"You have {:s} gold pieces. How many do you want to remove?",
|
||||
max)),
|
||||
max),
|
||||
FormatInteger(max));
|
||||
|
||||
// Pre-wrap the string at spaces, otherwise DrawString would hard wrap in the middle of words
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "control.hpp"
|
||||
#include "control_panel.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "engine/render/primitive_render.hpp"
|
||||
#include "inv.h"
|
||||
@@ -14,6 +11,7 @@
|
||||
#include "qol/xpbar.h"
|
||||
#include "towners.h"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/screen_reader.hpp"
|
||||
@@ -330,7 +328,7 @@ void CheckPanelInfo()
|
||||
InfoString = _("Player attack");
|
||||
}
|
||||
if (PanBtnHotKey[i] != nullptr) {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Hotkey: {:s}")), _(PanBtnHotKey[i])));
|
||||
AddInfoBoxString(FormatRuntime(_("Hotkey: {:s}"), _(PanBtnHotKey[i])));
|
||||
}
|
||||
InfoColor = UiFlags::ColorWhite;
|
||||
MainPanelFlag = true;
|
||||
@@ -349,30 +347,30 @@ void CheckPanelInfo()
|
||||
? GetOptions().Padmapper.InputNameForAction("DisplaySpells", true)
|
||||
: GetOptions().Keymapper.KeyNameForAction("DisplaySpells");
|
||||
if (!speedbookKeyName.empty()) {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Hotkey: '{:s}'")), speedbookKeyName));
|
||||
AddInfoBoxString(FormatRuntime(_("Hotkey: '{:s}'"), speedbookKeyName));
|
||||
}
|
||||
const Player &myPlayer = *MyPlayer;
|
||||
const SpellID spellId = myPlayer._pRSpell;
|
||||
if (IsValidSpell(spellId)) {
|
||||
switch (myPlayer._pRSplType) {
|
||||
case SpellType::Skill:
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("{:s} Skill")), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
AddInfoBoxString(FormatRuntime(_("{:s} Skill"), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
break;
|
||||
case SpellType::Spell: {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("{:s} Spell")), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
AddInfoBoxString(FormatRuntime(_("{:s} Spell"), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
const int spellLevel = myPlayer.GetSpellLevel(spellId);
|
||||
AddInfoBoxString(spellLevel == 0 ? _("Spell Level 0 - Unusable") : fmt::format(fmt::runtime(_("Spell Level {:d}")), spellLevel));
|
||||
AddInfoBoxString(spellLevel == 0 ? _("Spell Level 0 - Unusable") : FormatRuntime(_("Spell Level {:d}"), spellLevel));
|
||||
} break;
|
||||
case SpellType::Scroll: {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Scroll of {:s}")), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
AddInfoBoxString(FormatRuntime(_("Scroll of {:s}"), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
const int scrollCount = c_count_if(InventoryAndBeltPlayerItemsRange { myPlayer }, [spellId](const Item &item) {
|
||||
return item.isScrollOf(spellId);
|
||||
});
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(ngettext("{:d} Scroll", "{:d} Scrolls", scrollCount)), scrollCount));
|
||||
AddInfoBoxString(FormatRuntime(ngettext("{:d} Scroll", "{:d} Scrolls", scrollCount), scrollCount));
|
||||
} break;
|
||||
case SpellType::Charges:
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Staff of {:s}")), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(ngettext("{:d} Charge", "{:d} Charges", myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges)), myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges));
|
||||
AddInfoBoxString(FormatRuntime(_("Staff of {:s}"), pgettext("spell", GetSpellData(spellId).sNameText)));
|
||||
AddInfoBoxString(FormatRuntime(ngettext("{:d} Charge", "{:d} Charges", myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges), myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges));
|
||||
break;
|
||||
case SpellType::Invalid:
|
||||
break;
|
||||
@@ -404,7 +402,7 @@ void DrawInfoBox(const Surface &out)
|
||||
} else if (!myPlayer.HoldItem.isEmpty()) {
|
||||
if (myPlayer.HoldItem._itype == ItemType::Gold) {
|
||||
const int nGold = myPlayer.HoldItem._ivalue;
|
||||
InfoString = fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold));
|
||||
InfoString = FormatRuntime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold), FormatInteger(nGold));
|
||||
} else if (!myPlayer.CanUseItem(myPlayer.HoldItem)) {
|
||||
InfoString = _("Requirements not met");
|
||||
} else {
|
||||
@@ -435,8 +433,8 @@ void DrawInfoBox(const Surface &out)
|
||||
InfoColor = UiFlags::ColorWhitegold;
|
||||
const auto &target = *PlayerUnderCursor;
|
||||
InfoString = std::string_view(target._pName);
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("{:s}, Level: {:d}")), target.getClassName(), target.getCharacterLevel()));
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Hit Points {:d} of {:d}")), target._pHitPoints >> 6, target._pMaxHP >> 6));
|
||||
AddInfoBoxString(FormatRuntime(_("{:s}, Level: {:d}"), target.getClassName(), target.getCharacterLevel()));
|
||||
AddInfoBoxString(FormatRuntime(_("Hit Points {:d} of {:d}"), target._pHitPoints >> 6, target._pMaxHP >> 6));
|
||||
}
|
||||
if (PortraitIdUnderCursor != -1) {
|
||||
InfoColor = UiFlags::ColorWhitegold;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "control_chat.hpp"
|
||||
#include "control_flasks.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "automap.h"
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "controls/modifier_hints.h"
|
||||
@@ -27,6 +25,7 @@
|
||||
#include "qol/stash.h"
|
||||
#include "qol/visual_store.h"
|
||||
#include "stores.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/sdl_compat.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -820,12 +819,12 @@ void DrawDeathText(const Surface &out)
|
||||
|
||||
if (!gbIsMultiplayer) {
|
||||
if (gbValidSaveFile)
|
||||
text = fmt::format(fmt::runtime(_("Press {} to load last save.")), buttonText);
|
||||
text = FormatRuntime(_("Press {} to load last save."), buttonText);
|
||||
else
|
||||
text = fmt::format(fmt::runtime(_("Press {} to return to Main Menu.")), buttonText);
|
||||
text = FormatRuntime(_("Press {} to return to Main Menu."), buttonText);
|
||||
|
||||
} else {
|
||||
text = fmt::format(fmt::runtime(_("Press {} to restart in town.")), buttonText);
|
||||
text = FormatRuntime(_("Press {} to restart in town."), buttonText);
|
||||
}
|
||||
DrawString(out, text, linePosition, smallTextOptions);
|
||||
}
|
||||
|
||||
+2
-3
@@ -18,8 +18,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "control/control.hpp"
|
||||
#include "controls/control_mode.hpp"
|
||||
@@ -44,6 +42,7 @@
|
||||
#include "towners.h"
|
||||
#include "track.h"
|
||||
#include "utils/attributes.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/palette_blending.hpp"
|
||||
@@ -628,7 +627,7 @@ void CheckTown()
|
||||
if (EntranceBoundaryContains(missile.position.tile, cursPosition)) {
|
||||
trigflag = true;
|
||||
InfoString = _("Town Portal");
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("from {:s}")), Players[missile._misource]._pName));
|
||||
AddInfoBoxString(FormatRuntime(_("from {:s}"), Players[missile._misource]._pName));
|
||||
cursPosition = missile.position.tile;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-20
@@ -7,10 +7,9 @@
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "engine/assets.hpp"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -47,19 +46,19 @@ void DataFile::reportFatalError(Error code, std::string_view fileName)
|
||||
case Error::NotFound:
|
||||
case Error::OpenFailed:
|
||||
case Error::BadRead:
|
||||
app_fatal(fmt::format(fmt::runtime(_(
|
||||
/* TRANSLATORS: Error message when a data file is missing or corrupt. Arguments are {file name} */
|
||||
"Unable to load data from file {0}")),
|
||||
app_fatal(FormatRuntime(_(
|
||||
/* TRANSLATORS: Error message when a data file is missing or corrupt. Arguments are {file name} */
|
||||
"Unable to load data from file {0}"),
|
||||
fileName));
|
||||
case Error::NoContent:
|
||||
app_fatal(fmt::format(fmt::runtime(_(
|
||||
/* TRANSLATORS: Error message when a data file is empty or only contains the header row. Arguments are {file name} */
|
||||
"{0} is incomplete, please check the file contents.")),
|
||||
app_fatal(FormatRuntime(_(
|
||||
/* TRANSLATORS: Error message when a data file is empty or only contains the header row. Arguments are {file name} */
|
||||
"{0} is incomplete, please check the file contents."),
|
||||
fileName));
|
||||
case Error::NotEnoughColumns:
|
||||
app_fatal(fmt::format(fmt::runtime(_(
|
||||
/* TRANSLATORS: Error message when a data file doesn't contain the expected columns. Arguments are {file name} */
|
||||
"Your {0} file doesn't have the expected columns, please make sure it matches the documented format.")),
|
||||
app_fatal(FormatRuntime(_(
|
||||
/* TRANSLATORS: Error message when a data file doesn't contain the expected columns. Arguments are {file name} */
|
||||
"Your {0} file doesn't have the expected columns, please make sure it matches the documented format."),
|
||||
fileName));
|
||||
}
|
||||
}
|
||||
@@ -72,21 +71,21 @@ void DataFile::reportFatalFieldError(DataFileField::Error code, std::string_view
|
||||
}
|
||||
switch (code) {
|
||||
case DataFileField::Error::NotANumber:
|
||||
app_fatal(fmt::format(fmt::runtime(_(
|
||||
/* TRANSLATORS: Error message when parsing a data file and a text value is encountered when a number is expected. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
|
||||
"Non-numeric value {0} for {1} in {2} at row {3} and column {4}")),
|
||||
app_fatal(FormatRuntime(_(
|
||||
/* TRANSLATORS: Error message when parsing a data file and a text value is encountered when a number is expected. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
|
||||
"Non-numeric value {0} for {1} in {2} at row {3} and column {4}"),
|
||||
field.currentValue(), fieldName, fileName, field.row(), field.column())
|
||||
.append(detailsStr));
|
||||
case DataFileField::Error::OutOfRange:
|
||||
app_fatal(fmt::format(fmt::runtime(_(
|
||||
/* TRANSLATORS: Error message when parsing a data file and we find a number larger than expected. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
|
||||
"Out of range value {0} for {1} in {2} at row {3} and column {4}")),
|
||||
app_fatal(FormatRuntime(_(
|
||||
/* TRANSLATORS: Error message when parsing a data file and we find a number larger than expected. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
|
||||
"Out of range value {0} for {1} in {2} at row {3} and column {4}"),
|
||||
field.currentValue(), fieldName, fileName, field.row(), field.column())
|
||||
.append(detailsStr));
|
||||
case DataFileField::Error::InvalidValue:
|
||||
app_fatal(fmt::format(fmt::runtime(_(
|
||||
/* TRANSLATORS: Error message when we find an unrecognised value in a key column. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
|
||||
"Invalid value {0} for {1} in {2} at row {3} and column {4}")),
|
||||
app_fatal(FormatRuntime(_(
|
||||
/* TRANSLATORS: Error message when we find an unrecognised value in a key column. Arguments are {found value}, {column heading}, {file name}, {row/record number}, {column/field number} */
|
||||
"Invalid value {0} for {1} in {2} at row {3} and column {4}"),
|
||||
field.currentValue(), fieldName, fileName, field.row(), field.column())
|
||||
.append(detailsStr));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "data/value_reader.hpp"
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <format>
|
||||
|
||||
#include "appfat.h"
|
||||
|
||||
@@ -17,7 +16,7 @@ ValueReader::ValueReader(DataFile &dataFile, std::string_view filename)
|
||||
DataFileField ValueReader::getValueField(std::string_view expectedKey)
|
||||
{
|
||||
if (it_ == end_) {
|
||||
app_fatal(fmt::format("Missing field {} in {}", expectedKey, filename_));
|
||||
app_fatal(std::format("Missing field {} in {}", expectedKey, filename_));
|
||||
}
|
||||
DataFileRecord record = *it_;
|
||||
FieldIterator fieldIt = record.begin();
|
||||
@@ -25,7 +24,7 @@ DataFileField ValueReader::getValueField(std::string_view expectedKey)
|
||||
|
||||
const std::string_view key = (*fieldIt).value();
|
||||
if (key != expectedKey) {
|
||||
app_fatal(fmt::format("Unexpected field in {}: got {}, expected {}", filename_, key, expectedKey));
|
||||
app_fatal(std::format("Unexpected field in {}: got {}, expected {}", filename_, key, expectedKey));
|
||||
}
|
||||
|
||||
++fieldIt;
|
||||
|
||||
+10
-11
@@ -19,8 +19,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "DiabloUI/selstart.h"
|
||||
@@ -108,6 +106,7 @@
|
||||
#include "track.h"
|
||||
#include "utils/console.h"
|
||||
#include "utils/display.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/parse_int.hpp"
|
||||
@@ -1587,17 +1586,17 @@ void TimeoutCursor(bool bTimeout)
|
||||
|
||||
DvlNetLatencies latencies = DvlNet_GetLatencies(i);
|
||||
|
||||
std::string ping = fmt::format(
|
||||
fmt::runtime(_(/* TRANSLATORS: {:s} means: Character Name */ "Player {:s} is timing out!")),
|
||||
std::string ping = FormatRuntime(
|
||||
_(/* TRANSLATORS: {:s} means: Character Name */ "Player {:s} is timing out!"),
|
||||
Players[i].name());
|
||||
|
||||
StrAppend(ping, "\n ", fmt::format(fmt::runtime(_(/* TRANSLATORS: Network connectivity statistics */ "Echo latency: {:d} ms")), latencies.echoLatency));
|
||||
StrAppend(ping, "\n ", FormatRuntime(_(/* TRANSLATORS: Network connectivity statistics */ "Echo latency: {:d} ms"), latencies.echoLatency));
|
||||
|
||||
if (latencies.providerLatency) {
|
||||
if (latencies.isRelayed && *latencies.isRelayed) {
|
||||
StrAppend(ping, "\n ", fmt::format(fmt::runtime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms (Relayed)")), *latencies.providerLatency));
|
||||
StrAppend(ping, "\n ", FormatRuntime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms (Relayed)"), *latencies.providerLatency));
|
||||
} else {
|
||||
StrAppend(ping, "\n ", fmt::format(fmt::runtime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms")), *latencies.providerLatency));
|
||||
StrAppend(ping, "\n ", FormatRuntime(_(/* TRANSLATORS: Network connectivity statistics */ "Provider latency: {:d} ms"), *latencies.providerLatency));
|
||||
}
|
||||
}
|
||||
EventPlrMsg(ping);
|
||||
@@ -2117,8 +2116,8 @@ void InitKeymapActions()
|
||||
N_("Displays game infos."),
|
||||
'V',
|
||||
[] {
|
||||
EventPlrMsg(fmt::format(
|
||||
fmt::runtime(_(/* TRANSLATORS: {:s} means: Project Name, Game Version. */ "{:s} {:s}")),
|
||||
EventPlrMsg(FormatRuntime(
|
||||
_(/* TRANSLATORS: {:s} means: Project Name, Game Version. */ "{:s} {:s}"),
|
||||
PROJECT_NAME,
|
||||
PROJECT_VERSION),
|
||||
UiFlags::ColorWhite);
|
||||
@@ -2629,8 +2628,8 @@ void InitPadmapActions()
|
||||
N_("Displays game infos."),
|
||||
ControllerButton_NONE,
|
||||
[] {
|
||||
EventPlrMsg(fmt::format(
|
||||
fmt::runtime(_(/* TRANSLATORS: {:s} means: Project Name, Game Version. */ "{:s} {:s}")),
|
||||
EventPlrMsg(FormatRuntime(
|
||||
_(/* TRANSLATORS: {:s} means: Project Name, Game Version. */ "{:s} {:s}"),
|
||||
PROJECT_NAME,
|
||||
PROJECT_VERSION),
|
||||
UiFlags::ColorWhite);
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "levels/gendung.h"
|
||||
#include "levels/setmaps.h"
|
||||
@@ -24,6 +22,7 @@
|
||||
#include "panels/charpanel.hpp"
|
||||
#include "player.h"
|
||||
#include "tables/playerdat.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
|
||||
@@ -94,14 +93,14 @@ std::string GetLocationString()
|
||||
else if (tracked_data.dungeonArea == DTYPE_CRYPT)
|
||||
level -= 20;
|
||||
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: dungeon type and floor number i.e. "Cathedral 3"*/ "{} {}")), dungeonStr, level);
|
||||
return FormatRuntime(_(/* TRANSLATORS: dungeon type and floor number i.e. "Cathedral 3"*/ "{} {}"), dungeonStr, level);
|
||||
}
|
||||
return dungeonStr;
|
||||
}
|
||||
|
||||
std::string GetCharacterString()
|
||||
{
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: Discord character, i.e. "Lv 6 Warrior" */ "Lv {} {}")), tracked_data.playerLevel, MyPlayer->getClassName());
|
||||
return FormatRuntime(_(/* TRANSLATORS: Discord character, i.e. "Lv 6 Warrior" */ "Lv {} {}"), tracked_data.playerLevel, MyPlayer->getClassName());
|
||||
}
|
||||
|
||||
std::string GetDetailString()
|
||||
@@ -113,7 +112,7 @@ std::string GetStateString()
|
||||
{
|
||||
constexpr std::array<const char *, 3> DifficultyStrs = { N_("Normal"), N_("Nightmare"), N_("Hell") };
|
||||
const std::string_view difficultyStr = _(DifficultyStrs[sgGameInitInfo.nDifficulty]);
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: Discord state i.e. "Nightmare difficulty" */ "{} difficulty")), difficultyStr);
|
||||
return FormatRuntime(_(/* TRANSLATORS: Discord state i.e. "Nightmare difficulty" */ "{} difficulty"), difficultyStr);
|
||||
}
|
||||
|
||||
std::string GetTooltipString()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <exception>
|
||||
#include <expected>
|
||||
#include <format>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
@@ -15,7 +16,6 @@
|
||||
#endif
|
||||
|
||||
#include <asio/connect.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "utils/language.h"
|
||||
@@ -216,7 +216,7 @@ void tcp_client::HandleTcpErrorCode()
|
||||
if (code == PacketError::ErrorCode::DecryptionFailed)
|
||||
RaiseIoHandlerError(_("Server failed to decrypt your packet. Check if you typed the password correctly."));
|
||||
else
|
||||
RaiseIoHandlerError(fmt::format("Unknown error code received from server: {:#04x}", pktData[0]));
|
||||
RaiseIoHandlerError(std::format("Unknown error code received from server: {:#04x}", pktData[0]));
|
||||
}
|
||||
|
||||
std::expected<void, PacketError> tcp_client::send(packet &pkt)
|
||||
|
||||
@@ -3,15 +3,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
// This header must be included before any 3DS code
|
||||
// because 3DS SDK defines a macro with the same name
|
||||
// as an fmt template parameter in some versions of fmt.
|
||||
// See https://github.com/fmtlib/fmt/issues/3632
|
||||
//
|
||||
// 3DS uses some custom ASIO code that transitively includes
|
||||
// the 3DS SDK.
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <asio/ts/buffer.hpp>
|
||||
#include <asio/ts/internet.hpp>
|
||||
#include <asio/ts/io_context.hpp>
|
||||
|
||||
@@ -5,15 +5,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
// This header must be included before any 3DS code
|
||||
// because 3DS SDK defines a macro with the same name
|
||||
// as an fmt template parameter in some versions of fmt.
|
||||
// See https://github.com/fmtlib/fmt/issues/3632
|
||||
//
|
||||
// 3DS uses some custom ASIO code that transitively includes
|
||||
// the 3DS SDK.
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <asio/ts/buffer.hpp>
|
||||
#include <asio/ts/internet.hpp>
|
||||
#include <asio/ts/io_context.hpp>
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "game_mode.hpp"
|
||||
#include "mods/mod_identity.h"
|
||||
#include "utils/file_util.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/paths.h"
|
||||
#include "utils/sdl_compat.h"
|
||||
@@ -358,7 +357,7 @@ std::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
|
||||
|
||||
std::string FailedToOpenFileErrorMessage(std::string_view path, std::string_view error)
|
||||
{
|
||||
return fmt::format(fmt::runtime(_("Failed to open file:\n{:s}\n\n{:s}\n\nThe MPQ file(s) might be damaged. Please check the file integrity.")), path, error);
|
||||
return FormatRuntime(_("Failed to open file:\n{:s}\n\n{:s}\n\nThe MPQ file(s) might be damaged. Please check the file integrity."), path, error);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "game_mode.hpp"
|
||||
#include "headless_mode.hpp"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
|
||||
#include "engine/point.hpp"
|
||||
#include "engine/render/blit_impl.hpp"
|
||||
@@ -16,7 +17,6 @@
|
||||
#include "utils/static_vector.hpp"
|
||||
|
||||
#ifdef DEBUG_CLX
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "utils/str_cat.hpp"
|
||||
#endif
|
||||
@@ -564,15 +564,20 @@ std::string ClxDescribe(ClxSprite clx)
|
||||
if (IsClxOpaque(control)) {
|
||||
if (IsClxOpaqueFill(control)) {
|
||||
const uint8_t length = GetClxOpaqueFillWidth(control);
|
||||
out.append(fmt::format("Fill | {:>5} | {:>5} | {}\n", length, 2, src[1]));
|
||||
out.append(std::format("Fill | {:>5} | {:>5} | {}\n", length, 2, src[1]));
|
||||
++src;
|
||||
} else {
|
||||
const uint8_t length = GetClxOpaquePixelsWidth(control);
|
||||
out.append(fmt::format("Pixels | {:>5} | {:>5} | {}\n", length, length + 1, fmt::join(src + 1, src + 1 + length, " ")));
|
||||
std::string pixels;
|
||||
for (const uint8_t *it = src + 1, *pixelsEnd = src + 1 + length; it != pixelsEnd; ++it) {
|
||||
if (!pixels.empty()) pixels += ' ';
|
||||
StrAppend(pixels, *it);
|
||||
}
|
||||
out.append(std::format("Pixels | {:>5} | {:>5} | {}\n", length, length + 1, pixels));
|
||||
src += length;
|
||||
}
|
||||
} else {
|
||||
out.append(fmt::format("Transp. | {:>5} | {:>5} |\n", control, 1));
|
||||
out.append(std::format("Transp. | {:>5} | {:>5} |\n", control, 1));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <variant>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
@@ -32,6 +30,7 @@
|
||||
#include "engine/ticks.hpp"
|
||||
#include "game_mode.hpp"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -343,7 +342,7 @@ public:
|
||||
} else {
|
||||
if (!args_[*result].HasFormatted()) {
|
||||
const auto fmtStr = positional ? "{}" : std::string_view(rest.data(), fmtLen);
|
||||
args_[*result].SetFormatted(fmt::format(fmt::runtime(fmtStr), std::get<int>(args_[*result].value())));
|
||||
args_[*result].SetFormatted(FormatRuntime(fmtStr, std::get<int>(args_[*result].value())));
|
||||
}
|
||||
rest.remove_prefix(fmtLen);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/palette.h"
|
||||
@@ -182,7 +180,7 @@ int GetLineWidth(std::string_view text, GameFontTables size = GameFont12, int sp
|
||||
|
||||
/**
|
||||
* @brief Calculate pixel width of first line of text, respecting kerning
|
||||
* @param fmt An fmt::format string.
|
||||
* @param fmt A std::format string.
|
||||
* @param args Format arguments.
|
||||
* @param argsLen Number of format arguments.
|
||||
* @param argsOffset Index of the first unprocessed format argument.
|
||||
@@ -252,7 +250,7 @@ inline void DrawString(const Surface &out, std::string_view text, const Point &p
|
||||
* DrawStringWithColors(out, "Press {} to start", {{"Ⓧ", UiFlags::ColorBlue}}, {.flags = UiFlags::ColorWhite})
|
||||
*
|
||||
* @param out Output buffer to draw the text on.
|
||||
* @param fmt An fmt::format string.
|
||||
* @param fmt A std::format string.
|
||||
* @param args Format arguments.
|
||||
* @param argsLen Number of format arguments.
|
||||
* @param rect Clipping region relative to the output buffer describing where to draw the text and when to wrap long lines.
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
+3
-4
@@ -16,8 +16,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "controls/plrctrls.h"
|
||||
@@ -43,6 +41,7 @@
|
||||
#include "stores.h"
|
||||
#include "towners.h"
|
||||
#include "utils/display.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
@@ -2002,8 +2001,8 @@ int8_t CheckInvHLight()
|
||||
AddInfoBoxString(_("Fully Repaired"));
|
||||
} else if (pi->_itype == ItemType::Gold) {
|
||||
const int nGold = pi->_ivalue;
|
||||
InfoString = fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold));
|
||||
FloatingInfoString = fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold));
|
||||
InfoString = FormatRuntime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold), FormatInteger(nGold));
|
||||
FloatingInfoString = FormatRuntime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold), FormatInteger(nGold));
|
||||
} else {
|
||||
InfoColor = pi->getTextColor();
|
||||
InfoString = pi->getName();
|
||||
|
||||
+77
-79
@@ -25,9 +25,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "control/control.hpp"
|
||||
#include "controls/control_mode.hpp"
|
||||
@@ -81,6 +78,7 @@
|
||||
#include "tables/spelldat.h"
|
||||
#include "tables/textdat.h"
|
||||
#include "utils/enum_traits.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
@@ -1108,10 +1106,10 @@ std::string GenerateStaffName(const ItemData &baseItemData, SpellID spellId, boo
|
||||
std::string_view baseName = translate ? _(baseItemData.iName) : baseItemData.iName;
|
||||
std::string_view spellName = translate ? pgettext("spell", GetSpellData(spellId).sNameText) : GetSpellData(spellId).sNameText;
|
||||
const std::string_view normalFmt = translate ? pgettext("spell", /* TRANSLATORS: Constructs item names. Format: {Item} of {Spell}. Example: War Staff of Firewall */ "{0} of {1}") : "{0} of {1}";
|
||||
std::string name = fmt::format(fmt::runtime(normalFmt), baseName, spellName);
|
||||
std::string name = FormatRuntime(normalFmt, baseName, spellName);
|
||||
if (!StringInPanel(name.c_str())) {
|
||||
std::string_view shortName = translate ? _(baseItemData.iSName) : baseItemData.iSName;
|
||||
name = fmt::format(fmt::runtime(normalFmt), shortName, spellName);
|
||||
name = FormatRuntime(normalFmt, shortName, spellName);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@@ -1123,10 +1121,10 @@ std::string GenerateStaffNameMagical(const ItemData &baseItemData, SpellID spell
|
||||
std::string_view spellName = translate ? pgettext("spell", GetSpellData(spellId).sNameText) : GetSpellData(spellId).sNameText;
|
||||
std::string_view prefixName = translate ? _(power.PLName) : power.PLName;
|
||||
|
||||
std::string identifiedName = fmt::format(fmt::runtime(magicFmt), prefixName, baseName, spellName);
|
||||
std::string identifiedName = FormatRuntime(magicFmt, prefixName, baseName, spellName);
|
||||
if (forceNameLengthCheck ? *forceNameLengthCheck : !StringInPanel(identifiedName.c_str())) {
|
||||
std::string_view shortName = translate ? _(baseItemData.iSName) : baseItemData.iSName;
|
||||
identifiedName = fmt::format(fmt::runtime(magicFmt), prefixName, shortName, spellName);
|
||||
identifiedName = FormatRuntime(magicFmt, prefixName, shortName, spellName);
|
||||
}
|
||||
return identifiedName;
|
||||
}
|
||||
@@ -1158,15 +1156,15 @@ std::string GenerateMagicItemName(const std::string_view &baseNamel, const PLStr
|
||||
{
|
||||
if (pPrefix != nullptr && pSufix != nullptr) {
|
||||
const std::string_view fmt = translate ? _(/* TRANSLATORS: Constructs item names. Format: {Prefix} {Item} of {Suffix}. Example: King's Long Sword of the Whale */ "{0} {1} of {2}") : "{0} {1} of {2}";
|
||||
return fmt::format(fmt::runtime(fmt), translate ? _(pPrefix->PLName) : pPrefix->PLName, baseNamel, translate ? _(pSufix->PLName) : pSufix->PLName);
|
||||
return FormatRuntime(fmt, translate ? _(pPrefix->PLName) : pPrefix->PLName, baseNamel, translate ? _(pSufix->PLName) : pSufix->PLName);
|
||||
}
|
||||
if (pPrefix != nullptr) {
|
||||
const std::string_view fmt = translate ? _(/* TRANSLATORS: Constructs item names. Format: {Prefix} {Item}. Example: King's Long Sword */ "{0} {1}") : "{0} {1}";
|
||||
return fmt::format(fmt::runtime(fmt), translate ? _(pPrefix->PLName) : pPrefix->PLName, baseNamel);
|
||||
return FormatRuntime(fmt, translate ? _(pPrefix->PLName) : pPrefix->PLName, baseNamel);
|
||||
}
|
||||
if (pSufix != nullptr) {
|
||||
const std::string_view fmt = translate ? _(/* TRANSLATORS: Constructs item names. Format: {Item} of {Suffix}. Example: Long Sword of the Whale */ "{0} of {1}") : "{0} of {1}";
|
||||
return fmt::format(fmt::runtime(fmt), baseNamel, translate ? _(pSufix->PLName) : pSufix->PLName);
|
||||
return FormatRuntime(fmt, baseNamel, translate ? _(pSufix->PLName) : pSufix->PLName);
|
||||
}
|
||||
|
||||
return std::string(baseNamel);
|
||||
@@ -1801,25 +1799,25 @@ void printItemMiscGamepad(const Item &item, bool isOil, bool isCastOnTarget)
|
||||
const std::string_view castButton = GetOptions().Padmapper.InputNameForAction("SpellAction");
|
||||
|
||||
if (item._iMiscId == IMISC_MAPOFDOOM) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("{} to view")), activateButton));
|
||||
AddItemInfoBoxString(FormatRuntime(_("{} to view"), activateButton));
|
||||
} else if (isOil) {
|
||||
PrintItemOil(item._iMiscId);
|
||||
if (!invflag) {
|
||||
AddItemInfoBoxString(_("Open inventory to use"));
|
||||
} else {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("{} to use")), activateButton));
|
||||
AddItemInfoBoxString(FormatRuntime(_("{} to use"), activateButton));
|
||||
}
|
||||
} else if (isCastOnTarget) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("Select from spell book,\nthen {} to read")), castButton));
|
||||
AddItemInfoBoxString(FormatRuntime(_("Select from spell book,\nthen {} to read"), castButton));
|
||||
} else if (IsAnyOf(item._iMiscId, IMISC_BOOK, IMISC_NOTE, IMISC_SCROLL, IMISC_SCROLLT)) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("{} to read")), activateButton));
|
||||
AddItemInfoBoxString(FormatRuntime(_("{} to read"), activateButton));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintItemMisc(const Item &item)
|
||||
{
|
||||
if (item._iMiscId == IMISC_EAR) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(pgettext("player", "Level: {:d}")), item._ivalue));
|
||||
AddItemInfoBoxString(FormatRuntime(pgettext("player", "Level: {:d}"), item._ivalue));
|
||||
return;
|
||||
}
|
||||
if (item._iMiscId == IMISC_AURIC) {
|
||||
@@ -1858,11 +1856,11 @@ void PrintItemInfo(const Item &item)
|
||||
if (str != 0 || mag != 0 || dex != 0) {
|
||||
std::string text = std::string(_("Required:"));
|
||||
if (str != 0)
|
||||
text.append(fmt::format(fmt::runtime(_(" {:d} Str")), str));
|
||||
text.append(FormatRuntime(_(" {:d} Str"), str));
|
||||
if (mag != 0)
|
||||
text.append(fmt::format(fmt::runtime(_(" {:d} Mag")), mag));
|
||||
text.append(FormatRuntime(_(" {:d} Mag"), mag));
|
||||
if (dex != 0)
|
||||
text.append(fmt::format(fmt::runtime(_(" {:d} Dex")), dex));
|
||||
text.append(FormatRuntime(_(" {:d} Dex"), dex));
|
||||
AddItemInfoBoxString(text);
|
||||
}
|
||||
}
|
||||
@@ -2218,10 +2216,10 @@ StringOrView GetTranslatedItemName(const Item &item)
|
||||
}
|
||||
if (item._iMiscId == IMISC_BOOK) {
|
||||
const std::string_view spellName = pgettext("spell", GetSpellData(item._iSpell).sNameText);
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} will be a spell name */ "Book of {:s}")), spellName);
|
||||
return FormatRuntime(_(/* TRANSLATORS: {:s} will be a spell name */ "Book of {:s}"), spellName);
|
||||
}
|
||||
if (item._iMiscId == IMISC_EAR) {
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} will be a Character Name */ "Ear of {:s}")), item._iIName);
|
||||
return FormatRuntime(_(/* TRANSLATORS: {:s} will be a Character Name */ "Ear of {:s}"), item._iIName);
|
||||
}
|
||||
if (item._iMiscId > IMISC_OILFIRST && item._iMiscId < IMISC_OILLAST) {
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
@@ -3575,7 +3573,7 @@ void RecreateEar(Item &item, uint16_t ic, uint32_t iseed, uint8_t bCursval, std:
|
||||
{
|
||||
InitializeItem(item, IDI_EAR);
|
||||
|
||||
const std::string itemName = fmt::format(fmt::runtime("Ear of {:s}"), heroName);
|
||||
const std::string itemName = FormatRuntime("Ear of {:s}", heroName);
|
||||
|
||||
CopyUtf8(item._iName, itemName, ItemNameLength);
|
||||
CopyUtf8(item._iIName, heroName, ItemNameLength);
|
||||
@@ -3827,7 +3825,7 @@ void GetItemStr(Item &item)
|
||||
InfoColor = item.getTextColor();
|
||||
} else {
|
||||
const int nGold = item._ivalue;
|
||||
InfoString = fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold));
|
||||
InfoString = FormatRuntime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold), FormatInteger(nGold));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3893,87 +3891,87 @@ bool DoOil(Player &player, int cii)
|
||||
switch (plidx) {
|
||||
case IPL_TOHIT:
|
||||
case IPL_TOHIT_CURSE:
|
||||
return fmt::format(fmt::runtime(_("chance to hit: {:+d}%")), item._iPLToHit);
|
||||
return FormatRuntime(_("chance to hit: {:+d}%"), item._iPLToHit);
|
||||
case IPL_DAMP:
|
||||
case IPL_DAMP_CURSE:
|
||||
return fmt::format(fmt::runtime(_(/*xgettext:no-c-format*/ "{:+d}% damage")), item._iPLDam);
|
||||
return FormatRuntime(_(/*xgettext:no-c-format*/ "{:+d}% damage"), item._iPLDam);
|
||||
case IPL_TOHIT_DAMP:
|
||||
case IPL_TOHIT_DAMP_CURSE:
|
||||
return fmt::format(fmt::runtime(_("to hit: {:+d}%, {:+d}% damage")), item._iPLToHit, item._iPLDam);
|
||||
return FormatRuntime(_("to hit: {:+d}%, {:+d}% damage"), item._iPLToHit, item._iPLDam);
|
||||
case IPL_ACP:
|
||||
case IPL_ACP_CURSE:
|
||||
return fmt::format(fmt::runtime(_(/*xgettext:no-c-format*/ "{:+d}% armor")), item._iPLAC);
|
||||
return FormatRuntime(_(/*xgettext:no-c-format*/ "{:+d}% armor"), item._iPLAC);
|
||||
case IPL_SETAC:
|
||||
case IPL_AC_CURSE:
|
||||
return fmt::format(fmt::runtime(_("armor class: {:d}")), item._iAC);
|
||||
return FormatRuntime(_("armor class: {:d}"), item._iAC);
|
||||
case IPL_FIRERES:
|
||||
case IPL_FIRERES_CURSE:
|
||||
if (item._iPLFR < MaxResistance)
|
||||
return fmt::format(fmt::runtime(_("Resist Fire: {:+d}%")), item._iPLFR);
|
||||
return FormatRuntime(_("Resist Fire: {:+d}%"), item._iPLFR);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("Resist Fire: {:+d}% MAX")), MaxResistance);
|
||||
return FormatRuntime(_("Resist Fire: {:+d}% MAX"), MaxResistance);
|
||||
case IPL_LIGHTRES:
|
||||
case IPL_LIGHTRES_CURSE:
|
||||
if (item._iPLLR < MaxResistance)
|
||||
return fmt::format(fmt::runtime(_("Resist Lightning: {:+d}%")), item._iPLLR);
|
||||
return FormatRuntime(_("Resist Lightning: {:+d}%"), item._iPLLR);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("Resist Lightning: {:+d}% MAX")), MaxResistance);
|
||||
return FormatRuntime(_("Resist Lightning: {:+d}% MAX"), MaxResistance);
|
||||
case IPL_MAGICRES:
|
||||
case IPL_MAGICRES_CURSE:
|
||||
if (item._iPLMR < MaxResistance)
|
||||
return fmt::format(fmt::runtime(_("Resist Magic: {:+d}%")), item._iPLMR);
|
||||
return FormatRuntime(_("Resist Magic: {:+d}%"), item._iPLMR);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("Resist Magic: {:+d}% MAX")), MaxResistance);
|
||||
return FormatRuntime(_("Resist Magic: {:+d}% MAX"), MaxResistance);
|
||||
case IPL_ALLRES:
|
||||
if (item._iPLFR < MaxResistance)
|
||||
return fmt::format(fmt::runtime(_("Resist All: {:+d}%")), item._iPLFR);
|
||||
return FormatRuntime(_("Resist All: {:+d}%"), item._iPLFR);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("Resist All: {:+d}% MAX")), MaxResistance);
|
||||
return FormatRuntime(_("Resist All: {:+d}% MAX"), MaxResistance);
|
||||
case IPL_SPLLVLADD:
|
||||
if (item._iSplLvlAdd > 0)
|
||||
return fmt::format(fmt::runtime(ngettext("spells are increased {:d} level", "spells are increased {:d} levels", item._iSplLvlAdd)), item._iSplLvlAdd);
|
||||
return FormatRuntime(ngettext("spells are increased {:d} level", "spells are increased {:d} levels", item._iSplLvlAdd), item._iSplLvlAdd);
|
||||
else if (item._iSplLvlAdd < 0)
|
||||
return fmt::format(fmt::runtime(ngettext("spells are decreased {:d} level", "spells are decreased {:d} levels", -item._iSplLvlAdd)), -item._iSplLvlAdd);
|
||||
return FormatRuntime(ngettext("spells are decreased {:d} level", "spells are decreased {:d} levels", -item._iSplLvlAdd), -item._iSplLvlAdd);
|
||||
else
|
||||
return _("spell levels unchanged (?)");
|
||||
case IPL_CHARGES:
|
||||
return _("Extra charges");
|
||||
case IPL_SPELL:
|
||||
return fmt::format(fmt::runtime(ngettext("{:d} {:s} charge", "{:d} {:s} charges", item._iMaxCharges)), item._iMaxCharges, pgettext("spell", GetSpellData(item._iSpell).sNameText));
|
||||
return FormatRuntime(ngettext("{:d} {:s} charge", "{:d} {:s} charges", item._iMaxCharges), item._iMaxCharges, pgettext("spell", GetSpellData(item._iSpell).sNameText));
|
||||
case IPL_FIREDAM:
|
||||
if (item._iFMinDam == item._iFMaxDam)
|
||||
return fmt::format(fmt::runtime(_("Fire hit damage: {:d}")), item._iFMinDam);
|
||||
return FormatRuntime(_("Fire hit damage: {:d}"), item._iFMinDam);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("Fire hit damage: {:d}-{:d}")), item._iFMinDam, item._iFMaxDam);
|
||||
return FormatRuntime(_("Fire hit damage: {:d}-{:d}"), item._iFMinDam, item._iFMaxDam);
|
||||
case IPL_LIGHTDAM:
|
||||
if (item._iLMinDam == item._iLMaxDam)
|
||||
return fmt::format(fmt::runtime(_("Lightning hit damage: {:d}")), item._iLMinDam);
|
||||
return FormatRuntime(_("Lightning hit damage: {:d}"), item._iLMinDam);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("Lightning hit damage: {:d}-{:d}")), item._iLMinDam, item._iLMaxDam);
|
||||
return FormatRuntime(_("Lightning hit damage: {:d}-{:d}"), item._iLMinDam, item._iLMaxDam);
|
||||
case IPL_STR:
|
||||
case IPL_STR_CURSE:
|
||||
return fmt::format(fmt::runtime(_("{:+d} to strength")), item._iPLStr);
|
||||
return FormatRuntime(_("{:+d} to strength"), item._iPLStr);
|
||||
case IPL_MAG:
|
||||
case IPL_MAG_CURSE:
|
||||
return fmt::format(fmt::runtime(_("{:+d} to magic")), item._iPLMag);
|
||||
return FormatRuntime(_("{:+d} to magic"), item._iPLMag);
|
||||
case IPL_DEX:
|
||||
case IPL_DEX_CURSE:
|
||||
return fmt::format(fmt::runtime(_("{:+d} to dexterity")), item._iPLDex);
|
||||
return FormatRuntime(_("{:+d} to dexterity"), item._iPLDex);
|
||||
case IPL_VIT:
|
||||
case IPL_VIT_CURSE:
|
||||
return fmt::format(fmt::runtime(_("{:+d} to vitality")), item._iPLVit);
|
||||
return FormatRuntime(_("{:+d} to vitality"), item._iPLVit);
|
||||
case IPL_ATTRIBS:
|
||||
case IPL_ATTRIBS_CURSE:
|
||||
return fmt::format(fmt::runtime(_("{:+d} to all attributes")), item._iPLStr);
|
||||
return FormatRuntime(_("{:+d} to all attributes"), item._iPLStr);
|
||||
case IPL_GETHIT_CURSE:
|
||||
case IPL_GETHIT:
|
||||
return fmt::format(fmt::runtime(_("{:+d} damage from enemies")), item._iPLGetHit);
|
||||
return FormatRuntime(_("{:+d} damage from enemies"), item._iPLGetHit);
|
||||
case IPL_LIFE:
|
||||
case IPL_LIFE_CURSE:
|
||||
return fmt::format(fmt::runtime(_("Hit Points: {:+d}")), item._iPLHP >> 6);
|
||||
return FormatRuntime(_("Hit Points: {:+d}"), item._iPLHP >> 6);
|
||||
case IPL_MANA:
|
||||
case IPL_MANA_CURSE:
|
||||
return fmt::format(fmt::runtime(_("Mana: {:+d}")), item._iPLMana >> 6);
|
||||
return FormatRuntime(_("Mana: {:+d}"), item._iPLMana >> 6);
|
||||
case IPL_DUR:
|
||||
return _("high durability");
|
||||
case IPL_DUR_CURSE:
|
||||
@@ -3981,26 +3979,26 @@ bool DoOil(Player &player, int cii)
|
||||
case IPL_INDESTRUCTIBLE:
|
||||
return _("indestructible");
|
||||
case IPL_LIGHT:
|
||||
return fmt::format(fmt::runtime(_(/*xgettext:no-c-format*/ "+{:d}% light radius")), 10 * item._iPLLight);
|
||||
return FormatRuntime(_(/*xgettext:no-c-format*/ "+{:d}% light radius"), 10 * item._iPLLight);
|
||||
case IPL_LIGHT_CURSE:
|
||||
return fmt::format(fmt::runtime(_(/*xgettext:no-c-format*/ "-{:d}% light radius")), -10 * item._iPLLight);
|
||||
return FormatRuntime(_(/*xgettext:no-c-format*/ "-{:d}% light radius"), -10 * item._iPLLight);
|
||||
case IPL_MULT_ARROWS:
|
||||
return _("multiple arrows per shot");
|
||||
case IPL_FIRE_ARROWS:
|
||||
if (item._iFMinDam == item._iFMaxDam)
|
||||
return fmt::format(fmt::runtime(_("fire arrows damage: {:d}")), item._iFMinDam);
|
||||
return FormatRuntime(_("fire arrows damage: {:d}"), item._iFMinDam);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("fire arrows damage: {:d}-{:d}")), item._iFMinDam, item._iFMaxDam);
|
||||
return FormatRuntime(_("fire arrows damage: {:d}-{:d}"), item._iFMinDam, item._iFMaxDam);
|
||||
case IPL_LIGHT_ARROWS:
|
||||
if (item._iLMinDam == item._iLMaxDam)
|
||||
return fmt::format(fmt::runtime(_("lightning arrows damage {:d}")), item._iLMinDam);
|
||||
return FormatRuntime(_("lightning arrows damage {:d}"), item._iLMinDam);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("lightning arrows damage {:d}-{:d}")), item._iLMinDam, item._iLMaxDam);
|
||||
return FormatRuntime(_("lightning arrows damage {:d}-{:d}"), item._iLMinDam, item._iLMaxDam);
|
||||
case IPL_FIREBALL:
|
||||
if (item._iFMinDam == item._iFMaxDam)
|
||||
return fmt::format(fmt::runtime(_("fireball damage: {:d}")), item._iFMinDam);
|
||||
return FormatRuntime(_("fireball damage: {:d}"), item._iFMinDam);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("fireball damage: {:d}-{:d}")), item._iFMinDam, item._iFMaxDam);
|
||||
return FormatRuntime(_("fireball damage: {:d}-{:d}"), item._iFMinDam, item._iFMaxDam);
|
||||
case IPL_THORNS:
|
||||
return _("attacker takes 1-3 damage");
|
||||
case IPL_NOMANA:
|
||||
@@ -4048,7 +4046,7 @@ bool DoOil(Player &player, int cii)
|
||||
case IPL_FASTBLOCK:
|
||||
return _("fast block");
|
||||
case IPL_DAMMOD:
|
||||
return fmt::format(fmt::runtime(ngettext("adds {:d} point to damage", "adds {:d} points to damage", item._iPLDamMod)), item._iPLDamMod);
|
||||
return FormatRuntime(ngettext("adds {:d} point to damage", "adds {:d} points to damage", item._iPLDamMod), item._iPLDamMod);
|
||||
case IPL_RNDARROWVEL:
|
||||
return _("fires random speed arrows");
|
||||
case IPL_SETDAM:
|
||||
@@ -4065,23 +4063,23 @@ bool DoOil(Player &player, int cii)
|
||||
return _("no strength requirement");
|
||||
case IPL_ADDACLIFE:
|
||||
if (item._iFMinDam == item._iFMaxDam)
|
||||
return fmt::format(fmt::runtime(_("lightning damage: {:d}")), item._iFMinDam);
|
||||
return FormatRuntime(_("lightning damage: {:d}"), item._iFMinDam);
|
||||
else
|
||||
return fmt::format(fmt::runtime(_("lightning damage: {:d}-{:d}")), item._iFMinDam, item._iFMaxDam);
|
||||
return FormatRuntime(_("lightning damage: {:d}-{:d}"), item._iFMinDam, item._iFMaxDam);
|
||||
case IPL_ADDMANAAC:
|
||||
return _("charged bolts on hits");
|
||||
case IPL_DEVASTATION:
|
||||
return _("occasional triple damage");
|
||||
case IPL_DECAY:
|
||||
return fmt::format(fmt::runtime(_(/*xgettext:no-c-format*/ "decaying {:+d}% damage")), item._iPLDam);
|
||||
return FormatRuntime(_(/*xgettext:no-c-format*/ "decaying {:+d}% damage"), item._iPLDam);
|
||||
case IPL_PERIL:
|
||||
return _("2x dmg to monst, 1x to you");
|
||||
case IPL_JESTERS:
|
||||
return std::string(_(/*xgettext:no-c-format*/ "Random 0 - 600% damage"));
|
||||
case IPL_CRYSTALLINE:
|
||||
return fmt::format(fmt::runtime(_(/*xgettext:no-c-format*/ "low dur, {:+d}% damage")), item._iPLDam);
|
||||
return FormatRuntime(_(/*xgettext:no-c-format*/ "low dur, {:+d}% damage"), item._iPLDam);
|
||||
case IPL_DOPPELGANGER:
|
||||
return fmt::format(fmt::runtime(_("to hit: {:+d}%, {:+d}% damage")), item._iPLToHit, item._iPLDam);
|
||||
return FormatRuntime(_("to hit: {:+d}%, {:+d}% damage"), item._iPLToHit, item._iPLDam);
|
||||
case IPL_ACDEMON:
|
||||
return _("extra AC vs demons");
|
||||
case IPL_ACUNDEAD:
|
||||
@@ -4132,24 +4130,24 @@ void PrintItemDetails(const Item &item)
|
||||
if (item._iClass == ICLASS_WEAPON) {
|
||||
if (item._iMinDam == item._iMaxDam) {
|
||||
if (item._iMaxDur == DUR_INDESTRUCTIBLE)
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("damage: {:d} Indestructible")), item._iMinDam));
|
||||
AddItemInfoBoxString(FormatRuntime(_("damage: {:d} Indestructible"), item._iMinDam));
|
||||
else
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_(/* TRANSLATORS: Dur: is durability */ "damage: {:d} Dur: {:d}/{:d}")), item._iMinDam, item._iDurability, item._iMaxDur));
|
||||
AddItemInfoBoxString(FormatRuntime(_(/* TRANSLATORS: Dur: is durability */ "damage: {:d} Dur: {:d}/{:d}"), item._iMinDam, item._iDurability, item._iMaxDur));
|
||||
} else {
|
||||
if (item._iMaxDur == DUR_INDESTRUCTIBLE)
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("damage: {:d}-{:d} Indestructible")), item._iMinDam, item._iMaxDam));
|
||||
AddItemInfoBoxString(FormatRuntime(_("damage: {:d}-{:d} Indestructible"), item._iMinDam, item._iMaxDam));
|
||||
else
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_(/* TRANSLATORS: Dur: is durability */ "damage: {:d}-{:d} Dur: {:d}/{:d}")), item._iMinDam, item._iMaxDam, item._iDurability, item._iMaxDur));
|
||||
AddItemInfoBoxString(FormatRuntime(_(/* TRANSLATORS: Dur: is durability */ "damage: {:d}-{:d} Dur: {:d}/{:d}"), item._iMinDam, item._iMaxDam, item._iDurability, item._iMaxDur));
|
||||
}
|
||||
}
|
||||
if (item._iClass == ICLASS_ARMOR) {
|
||||
if (item._iMaxDur == DUR_INDESTRUCTIBLE)
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("armor: {:d} Indestructible")), item._iAC));
|
||||
AddItemInfoBoxString(FormatRuntime(_("armor: {:d} Indestructible"), item._iAC));
|
||||
else
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_(/* TRANSLATORS: Dur: is durability */ "armor: {:d} Dur: {:d}/{:d}")), item._iAC, item._iDurability, item._iMaxDur));
|
||||
AddItemInfoBoxString(FormatRuntime(_(/* TRANSLATORS: Dur: is durability */ "armor: {:d} Dur: {:d}/{:d}"), item._iAC, item._iDurability, item._iMaxDur));
|
||||
}
|
||||
if (item._iMiscId == IMISC_STAFF && item._iMaxCharges != 0) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("Charges: {:d}/{:d}")), item._iCharges, item._iMaxCharges));
|
||||
AddItemInfoBoxString(FormatRuntime(_("Charges: {:d}/{:d}"), item._iCharges, item._iMaxCharges));
|
||||
}
|
||||
if (item._iPrePower != -1) {
|
||||
AddItemInfoBoxString(PrintItemPower(item._iPrePower, item));
|
||||
@@ -4173,30 +4171,30 @@ void PrintItemDur(const Item &item)
|
||||
if (item._iClass == ICLASS_WEAPON) {
|
||||
if (item._iMinDam == item._iMaxDam) {
|
||||
if (item._iMaxDur == DUR_INDESTRUCTIBLE)
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("damage: {:d} Indestructible")), item._iMinDam));
|
||||
AddItemInfoBoxString(FormatRuntime(_("damage: {:d} Indestructible"), item._iMinDam));
|
||||
else
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("damage: {:d} Dur: {:d}/{:d}")), item._iMinDam, item._iDurability, item._iMaxDur));
|
||||
AddItemInfoBoxString(FormatRuntime(_("damage: {:d} Dur: {:d}/{:d}"), item._iMinDam, item._iDurability, item._iMaxDur));
|
||||
} else {
|
||||
if (item._iMaxDur == DUR_INDESTRUCTIBLE)
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("damage: {:d}-{:d} Indestructible")), item._iMinDam, item._iMaxDam));
|
||||
AddItemInfoBoxString(FormatRuntime(_("damage: {:d}-{:d} Indestructible"), item._iMinDam, item._iMaxDam));
|
||||
else
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("damage: {:d}-{:d} Dur: {:d}/{:d}")), item._iMinDam, item._iMaxDam, item._iDurability, item._iMaxDur));
|
||||
AddItemInfoBoxString(FormatRuntime(_("damage: {:d}-{:d} Dur: {:d}/{:d}"), item._iMinDam, item._iMaxDam, item._iDurability, item._iMaxDur));
|
||||
}
|
||||
if (item._iMiscId == IMISC_STAFF && item._iMaxCharges > 0) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("Charges: {:d}/{:d}")), item._iCharges, item._iMaxCharges));
|
||||
AddItemInfoBoxString(FormatRuntime(_("Charges: {:d}/{:d}"), item._iCharges, item._iMaxCharges));
|
||||
}
|
||||
if (item._iMagical != ITEM_QUALITY_NORMAL)
|
||||
AddItemInfoBoxString(_("Not Identified"));
|
||||
}
|
||||
if (item._iClass == ICLASS_ARMOR) {
|
||||
if (item._iMaxDur == DUR_INDESTRUCTIBLE)
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("armor: {:d} Indestructible")), item._iAC));
|
||||
AddItemInfoBoxString(FormatRuntime(_("armor: {:d} Indestructible"), item._iAC));
|
||||
else
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("armor: {:d} Dur: {:d}/{:d}")), item._iAC, item._iDurability, item._iMaxDur));
|
||||
AddItemInfoBoxString(FormatRuntime(_("armor: {:d} Dur: {:d}/{:d}"), item._iAC, item._iDurability, item._iMaxDur));
|
||||
if (item._iMagical != ITEM_QUALITY_NORMAL)
|
||||
AddItemInfoBoxString(_("Not Identified"));
|
||||
if (item._iMiscId == IMISC_STAFF && item._iMaxCharges > 0) {
|
||||
AddItemInfoBoxString(fmt::format(fmt::runtime(_("Charges: {:d}/{:d}")), item._iCharges, item._iMaxCharges));
|
||||
AddItemInfoBoxString(FormatRuntime(_("Charges: {:d}/{:d}"), item._iCharges, item._iMaxCharges));
|
||||
}
|
||||
}
|
||||
if (IsAnyOf(item._itype, ItemType::Ring, ItemType::Amulet))
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include "engine/path.h"
|
||||
#include "engine/points_in_rectangle_range.hpp"
|
||||
#include "engine/random.hpp"
|
||||
|
||||
+16
-17
@@ -8,8 +8,6 @@
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "controls/plrctrls.h"
|
||||
@@ -18,6 +16,7 @@
|
||||
#include "game_mode.hpp"
|
||||
#include "multi.h"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/utf8.hpp"
|
||||
@@ -416,7 +415,7 @@ bool ForceL1Trig()
|
||||
for (const uint16_t tileId : L1UpList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
if (currlevel > 1)
|
||||
InfoString = fmt::format(fmt::runtime(_("Up to level {:d}")), currlevel - 1);
|
||||
InfoString = FormatRuntime(_("Up to level {:d}"), currlevel - 1);
|
||||
else
|
||||
InfoString = _("Up to town");
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
@@ -429,7 +428,7 @@ bool ForceL1Trig()
|
||||
}
|
||||
for (const uint16_t tileId : L1DownList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Down to level {:d}")), currlevel + 1);
|
||||
InfoString = FormatRuntime(_("Down to level {:d}"), currlevel + 1);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -451,7 +450,7 @@ bool ForceL2Trig()
|
||||
const int dx = std::abs(trigs[j].position.x - cursPosition.x);
|
||||
const int dy = std::abs(trigs[j].position.y - cursPosition.y);
|
||||
if (dx < 4 && dy < 4) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Up to level {:d}")), currlevel - 1);
|
||||
InfoString = FormatRuntime(_("Up to level {:d}"), currlevel - 1);
|
||||
cursPosition = trigs[j].position;
|
||||
return true;
|
||||
}
|
||||
@@ -462,7 +461,7 @@ bool ForceL2Trig()
|
||||
|
||||
for (const uint16_t tileId : L2DownList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Down to level {:d}")), currlevel + 1);
|
||||
InfoString = FormatRuntime(_("Down to level {:d}"), currlevel + 1);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -497,7 +496,7 @@ bool ForceL3Trig()
|
||||
{
|
||||
for (const uint16_t tileId : L3UpList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Up to level {:d}")), currlevel - 1);
|
||||
InfoString = FormatRuntime(_("Up to level {:d}"), currlevel - 1);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABPREVLVL) {
|
||||
const int dx = std::abs(trigs[j].position.x - cursPosition.x);
|
||||
@@ -514,7 +513,7 @@ bool ForceL3Trig()
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId
|
||||
|| dPiece[cursPosition.x + 1][cursPosition.y] == tileId
|
||||
|| dPiece[cursPosition.x + 2][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Down to level {:d}")), currlevel + 1);
|
||||
InfoString = FormatRuntime(_("Down to level {:d}"), currlevel + 1);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -549,7 +548,7 @@ bool ForceL4Trig()
|
||||
{
|
||||
for (const uint16_t tileId : L4UpList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Up to level {:d}")), currlevel - 1);
|
||||
InfoString = FormatRuntime(_("Up to level {:d}"), currlevel - 1);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABPREVLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -561,7 +560,7 @@ bool ForceL4Trig()
|
||||
|
||||
for (const uint16_t tileId : L4DownList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Down to level {:d}")), currlevel + 1);
|
||||
InfoString = FormatRuntime(_("Down to level {:d}"), currlevel + 1);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -610,7 +609,7 @@ bool ForceHiveTrig()
|
||||
{
|
||||
for (const uint16_t tileId : L6UpList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Up to Nest level {:d}")), currlevel - 17);
|
||||
InfoString = FormatRuntime(_("Up to Nest level {:d}"), currlevel - 17);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABPREVLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -623,7 +622,7 @@ bool ForceHiveTrig()
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId
|
||||
|| dPiece[cursPosition.x + 1][cursPosition.y] == tileId
|
||||
|| dPiece[cursPosition.x + 2][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Down to level {:d}")), currlevel - 15);
|
||||
InfoString = FormatRuntime(_("Down to level {:d}"), currlevel - 15);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -658,7 +657,7 @@ bool ForceCryptTrig()
|
||||
{
|
||||
for (const uint16_t tileId : L5UpList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Up to Crypt level {:d}")), currlevel - 21);
|
||||
InfoString = FormatRuntime(_("Up to Crypt level {:d}"), currlevel - 21);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABPREVLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -673,7 +672,7 @@ bool ForceCryptTrig()
|
||||
}
|
||||
for (const uint16_t tileId : L5DownList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Down to Crypt level {:d}")), currlevel - 19);
|
||||
InfoString = FormatRuntime(_("Down to Crypt level {:d}"), currlevel - 19);
|
||||
for (int j = 0; j < numtrigs; j++) {
|
||||
if (trigs[j]._tmsg == WM_DIABNEXTLVL) {
|
||||
cursPosition = trigs[j].position;
|
||||
@@ -721,7 +720,7 @@ bool ForceSKingTrig()
|
||||
{
|
||||
for (const uint16_t tileId : L1UpList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Back to Level {:d}")), Quests[Q_SKELKING]._qlevel);
|
||||
InfoString = FormatRuntime(_("Back to Level {:d}"), Quests[Q_SKELKING]._qlevel);
|
||||
cursPosition = trigs[0].position;
|
||||
|
||||
return true;
|
||||
@@ -735,7 +734,7 @@ bool ForceSChambTrig()
|
||||
{
|
||||
for (const uint16_t tileId : L2DownList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Back to Level {:d}")), Quests[Q_SCHAMB]._qlevel);
|
||||
InfoString = FormatRuntime(_("Back to Level {:d}"), Quests[Q_SCHAMB]._qlevel);
|
||||
cursPosition = trigs[0].position;
|
||||
|
||||
return true;
|
||||
@@ -749,7 +748,7 @@ bool ForcePWaterTrig()
|
||||
{
|
||||
for (const uint16_t tileId : L3DownList) {
|
||||
if (dPiece[cursPosition.x][cursPosition.y] == tileId) {
|
||||
InfoString = fmt::format(fmt::runtime(_("Back to Level {:d}")), Quests[Q_PWATER]._qlevel);
|
||||
InfoString = FormatRuntime(_("Back to Level {:d}"), Quests[Q_PWATER]._qlevel);
|
||||
cursPosition = trigs[0].position;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "lua/metadoc.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -19,7 +19,7 @@ sol::table LuaI18nModule(sol::state_view &lua)
|
||||
"Translates the given string", [](const char *key) { return LanguageTranslate(key); });
|
||||
LuaSetDocFn(table, "plural_translate", "(singular: string, plural: string, count: integer)",
|
||||
"Returns a singular or plural translation for the given keys and count", [](const char *singular, std::string_view plural, int count) {
|
||||
return fmt::format(fmt::runtime(LanguagePluralTranslate(singular, plural, count)), count);
|
||||
return FormatRuntime(LanguagePluralTranslate(singular, plural, count), count);
|
||||
});
|
||||
LuaSetDocFn(table, "particular_translate", "(context: string, text: string)",
|
||||
"Returns the translation for the given context identifier and key.", LanguageParticularTranslate);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
|
||||
+112
-38
@@ -6,12 +6,23 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/args.h>
|
||||
#include <fmt/format.h>
|
||||
#include <charconv>
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <format>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include <sol/sol.hpp>
|
||||
#include <sol/utility/to_string.hpp>
|
||||
|
||||
#include "utils/attributes.h"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/str_cat.hpp"
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
@@ -21,50 +32,113 @@ namespace devilution {
|
||||
|
||||
namespace {
|
||||
|
||||
using LuaFormatArg = std::variant<bool, lua_Integer, lua_Number, std::string>;
|
||||
|
||||
/**
|
||||
* @brief Formats a message with arguments only known at runtime.
|
||||
*
|
||||
* `std::format` has no equivalent of `fmt::dynamic_format_arg_store`, so we
|
||||
* parse the replacement fields ourselves and format each one individually.
|
||||
*/
|
||||
std::expected<std::string, std::string> FormatLuaMessage(std::string_view fmt, std::span<const LuaFormatArg> args)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(fmt.size());
|
||||
size_t autoIndex = 0;
|
||||
bool manualIndexing = false;
|
||||
bool automaticIndexing = false;
|
||||
for (size_t i = 0; i < fmt.size(); ++i) {
|
||||
const char c = fmt[i];
|
||||
if (c == '}') {
|
||||
if (i + 1 < fmt.size() && fmt[i + 1] == '}') {
|
||||
result += '}';
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
return std::unexpected("unmatched '}' in format string");
|
||||
}
|
||||
if (c != '{') {
|
||||
result += c;
|
||||
continue;
|
||||
}
|
||||
if (i + 1 < fmt.size() && fmt[i + 1] == '{') {
|
||||
result += '{';
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
const size_t fieldEnd = fmt.find_first_of("{}", i + 1);
|
||||
if (fieldEnd == std::string_view::npos || fmt[fieldEnd] == '{')
|
||||
return std::unexpected("unmatched '{' in format string");
|
||||
const std::string_view field = fmt.substr(i + 1, fieldEnd - (i + 1));
|
||||
const size_t colonPos = field.find(':');
|
||||
const std::string_view argId = field.substr(0, colonPos);
|
||||
size_t argIndex;
|
||||
if (argId.empty()) {
|
||||
if (manualIndexing)
|
||||
return std::unexpected("cannot switch from manual to automatic argument indexing");
|
||||
automaticIndexing = true;
|
||||
argIndex = autoIndex++;
|
||||
} else {
|
||||
if (automaticIndexing)
|
||||
return std::unexpected("cannot switch from automatic to manual argument indexing");
|
||||
manualIndexing = true;
|
||||
const std::from_chars_result parseResult = std::from_chars(argId.data(), argId.data() + argId.size(), argIndex);
|
||||
if (parseResult.ec != std::errc() || parseResult.ptr != argId.data() + argId.size())
|
||||
return std::unexpected(StrCat("invalid argument id \"", argId, "\""));
|
||||
}
|
||||
if (argIndex >= args.size())
|
||||
return std::unexpected(StrCat("argument index ", argIndex, " out of range"));
|
||||
const std::string fieldFmt = colonPos == std::string_view::npos
|
||||
? "{}"
|
||||
: StrCat("{:", field.substr(colonPos + 1), "}");
|
||||
#if DVL_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
std::visit([&](const auto &value) {
|
||||
result += std::vformat(fieldFmt, std::make_format_args(value));
|
||||
},
|
||||
args[argIndex]);
|
||||
#if DVL_EXCEPTIONS
|
||||
} catch (const std::format_error &e) {
|
||||
return std::unexpected(e.what());
|
||||
}
|
||||
#endif
|
||||
i = fieldEnd;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LuaLogMessage(LogPriority priority, std::string_view fmt, sol::variadic_args args)
|
||||
{
|
||||
std::string formatted;
|
||||
FMT_TRY
|
||||
{
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
for (const sol::stack_proxy arg : args) {
|
||||
switch (arg.get_type()) {
|
||||
case sol::type::boolean:
|
||||
store.push_back(arg.as<bool>());
|
||||
break;
|
||||
case sol::type::number:
|
||||
if (lua_isinteger(arg.lua_state(), arg.stack_index())) {
|
||||
store.push_back(lua_tointeger(arg.lua_state(), arg.stack_index()));
|
||||
} else {
|
||||
store.push_back(lua_tonumber(arg.lua_state(), arg.stack_index()));
|
||||
}
|
||||
break;
|
||||
case sol::type::string:
|
||||
store.push_back(arg.as<std::string>());
|
||||
break;
|
||||
default:
|
||||
store.push_back(sol::utility::to_string(sol::stack_object(arg)));
|
||||
break;
|
||||
std::vector<LuaFormatArg> formatArgs;
|
||||
formatArgs.reserve(args.size());
|
||||
for (const sol::stack_proxy arg : args) {
|
||||
switch (arg.get_type()) {
|
||||
case sol::type::boolean:
|
||||
formatArgs.emplace_back(arg.as<bool>());
|
||||
break;
|
||||
case sol::type::number:
|
||||
if (lua_isinteger(arg.lua_state(), arg.stack_index())) {
|
||||
formatArgs.emplace_back(lua_tointeger(arg.lua_state(), arg.stack_index()));
|
||||
} else {
|
||||
formatArgs.emplace_back(lua_tonumber(arg.lua_state(), arg.stack_index()));
|
||||
}
|
||||
break;
|
||||
case sol::type::string:
|
||||
formatArgs.emplace_back(arg.as<std::string>());
|
||||
break;
|
||||
default:
|
||||
formatArgs.emplace_back(sol::utility::to_string(sol::stack_object(arg)));
|
||||
break;
|
||||
}
|
||||
formatted = fmt::vformat(fmt, store);
|
||||
}
|
||||
#if FMT_EXCEPTIONS
|
||||
FMT_CATCH(const fmt::format_error &e)
|
||||
{
|
||||
// e.what() is undefined if exceptions are disabled, so we wrap it
|
||||
// with an `FMT_EXCEPTIONS` check.
|
||||
std::string error = e.what();
|
||||
#else
|
||||
FMT_CATCH(const fmt::format_error &)
|
||||
{
|
||||
std::string error = "unknown (FMT_EXCEPTIONS disabled)";
|
||||
#endif
|
||||
std::string fullError = StrCat("Format error, fmt: ", fmt, " error: ", error);
|
||||
const std::expected<std::string, std::string> formatted = FormatLuaMessage(fmt, formatArgs);
|
||||
if (!formatted.has_value()) {
|
||||
const std::string fullError = StrCat("Format error, fmt: ", fmt, " error: ", formatted.error());
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "%s", fullError.c_str());
|
||||
return;
|
||||
}
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, static_cast<SDL_LogPriority>(priority), "%s", formatted.c_str());
|
||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, static_cast<SDL_LogPriority>(priority), "%s", formatted->c_str());
|
||||
}
|
||||
|
||||
void LuaLogInfo(std::string_view fmt, sol::variadic_args args)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <sol/sol.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
|
||||
+5
-7
@@ -31,9 +31,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "automap.h"
|
||||
#include "control/control.hpp"
|
||||
#include "crawl.hpp"
|
||||
@@ -96,6 +93,7 @@
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/enum_traits.h"
|
||||
#include "utils/file_name_generator.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -4472,9 +4470,9 @@ void M_FallenFear(Point position)
|
||||
void PrintMonstHistory(int mt)
|
||||
{
|
||||
if (*GetOptions().Gameplay.showMonsterType) {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Type: {:s} Kills: {:d}")), GetMonsterTypeText(MonstersData[mt]), MonsterKillCounts[mt]));
|
||||
AddInfoBoxString(FormatRuntime(_("Type: {:s} Kills: {:d}"), GetMonsterTypeText(MonstersData[mt]), MonsterKillCounts[mt]));
|
||||
} else {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Total kills: {:d}")), MonsterKillCounts[mt]));
|
||||
AddInfoBoxString(FormatRuntime(_("Total kills: {:d}"), MonsterKillCounts[mt]));
|
||||
}
|
||||
|
||||
if (MonsterKillCounts[mt] >= 30) {
|
||||
@@ -4500,7 +4498,7 @@ void PrintMonstHistory(int mt)
|
||||
minHP = 4 * minHP + hpBonusHell;
|
||||
maxHP = 4 * maxHP + hpBonusHell;
|
||||
}
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Hit Points: {:d}-{:d}")), minHP, maxHP));
|
||||
AddInfoBoxString(FormatRuntime(_("Hit Points: {:d}-{:d}"), minHP, maxHP));
|
||||
}
|
||||
if (MonsterKillCounts[mt] >= 15) {
|
||||
const int res = (sgGameInitInfo.nDifficulty != DIFF_HELL) ? MonstersData[mt].resistance : MonstersData[mt].resistanceHell;
|
||||
@@ -4535,7 +4533,7 @@ void PrintUniqueHistory()
|
||||
{
|
||||
const Monster &monster = Monsters[pcursmonst];
|
||||
if (*GetOptions().Gameplay.showMonsterType) {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Type: {:s}")), GetMonsterTypeText(monster.data())));
|
||||
AddInfoBoxString(FormatRuntime(_("Type: {:s}"), GetMonsterTypeText(monster.data())));
|
||||
}
|
||||
|
||||
const int res = monster.resistance & (RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING);
|
||||
|
||||
+4
-3
@@ -8,6 +8,7 @@
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
@@ -18,7 +19,6 @@
|
||||
#endif
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#if !defined(UNPACKED_MPQS) || !defined(UNPACKED_SAVES) || !defined(NONET)
|
||||
#define USE_PKWARE
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "tmsg.h"
|
||||
#include "towners.h"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -86,7 +87,7 @@ namespace devilution {
|
||||
|
||||
void EventFailedPacket(const char *playerName)
|
||||
{
|
||||
const std::string message = fmt::format("Player '{}' sent an invalid packet.", playerName);
|
||||
const std::string message = std::format("Player '{}' sent an invalid packet.", playerName);
|
||||
EventPlrMsg(message);
|
||||
}
|
||||
|
||||
@@ -2313,7 +2314,7 @@ size_t OnPlayerJoinLevel(const TCmdLocParam2 &message, Player &player)
|
||||
ResetPlayerGFX(player);
|
||||
player.plractive = true;
|
||||
gbActivePlayers++;
|
||||
EventPlrMsg(fmt::format(fmt::runtime(_("Player '{:s}' (level {:d}) just joined the game")), player._pName, player.getCharacterLevel()));
|
||||
EventPlrMsg(FormatRuntime(_("Player '{:s}' (level {:d}) just joined the game"), player._pName, player.getCharacterLevel()));
|
||||
}
|
||||
|
||||
if (player.plractive && &player != MyPlayer) {
|
||||
|
||||
+7
-6
@@ -8,6 +8,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
@@ -19,7 +20,6 @@
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/diabloui.h"
|
||||
#include "diablo.h"
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "tmsg.h"
|
||||
#include "utils/endian_read.hpp"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -302,7 +303,7 @@ void PlayerLeftMsg(Player &player, bool left)
|
||||
else
|
||||
LogInfo("Player left the {} game ({}, {}/{} players)", ConnectionNames[provider], reasonDescription, remainingPlayers, MAX_PLRS);
|
||||
}
|
||||
EventPlrMsg(fmt::format(fmt::runtime(pszFmt), player._pName));
|
||||
EventPlrMsg(FormatRuntime(pszFmt, player._pName));
|
||||
}
|
||||
player.plractive = false;
|
||||
player._pName[0] = '\0';
|
||||
@@ -589,13 +590,13 @@ DVL_API_FOR_TEST std::string DescribeLeaveReason(leaveinfo_t leaveReason)
|
||||
case leaveinfo_t::LEAVE_DROP:
|
||||
return "connection timeout";
|
||||
default:
|
||||
return fmt::format("code 0x{:08X}", static_cast<uint32_t>(leaveReason));
|
||||
return std::format("code 0x{:08X}", static_cast<uint32_t>(leaveReason));
|
||||
}
|
||||
}
|
||||
|
||||
std::string FormatGameSeed(const uint32_t gameSeed[4])
|
||||
{
|
||||
return fmt::format("{:08X}{:08X}{:08X}{:08X}",
|
||||
return std::format("{:08X}{:08X}{:08X}{:08X}",
|
||||
gameSeed[0], gameSeed[1], gameSeed[2], gameSeed[3]);
|
||||
}
|
||||
|
||||
@@ -894,7 +895,7 @@ bool NetInit(bool bSinglePlayer)
|
||||
Player &myPlayer = *MyPlayer;
|
||||
// separator for marking messages from a different game
|
||||
AddMessageToChatLog(_("New Game"), nullptr, UiFlags::ColorRed);
|
||||
AddMessageToChatLog(fmt::format(fmt::runtime(_("Player '{:s}' (level {:d}) just joined the game")), myPlayer._pName, myPlayer.getCharacterLevel()));
|
||||
AddMessageToChatLog(FormatRuntime(_("Player '{:s}' (level {:d}) just joined the game"), myPlayer._pName, myPlayer.getCharacterLevel()));
|
||||
|
||||
// Log join message with seed for joining players (creator already logged it in SNetCreateGame)
|
||||
if (gbIsMultiplayer && !IsLoopback && MyPlayerId != 0) {
|
||||
@@ -960,7 +961,7 @@ void recv_plrinfo(Player &player, const TCmdPlrInfoHdr &header, bool recv)
|
||||
} else {
|
||||
szEvent = _("Player '{:s}' (level {:d}) is already in the game");
|
||||
}
|
||||
EventPlrMsg(fmt::format(fmt::runtime(szEvent), player._pName, player.getCharacterLevel()));
|
||||
EventPlrMsg(FormatRuntime(szEvent, player._pName, player.getCharacterLevel()));
|
||||
|
||||
SyncInitPlr(player);
|
||||
|
||||
|
||||
+4
-6
@@ -12,9 +12,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "automap.h"
|
||||
#include "cursor.h"
|
||||
@@ -47,6 +44,7 @@
|
||||
#include "track.h"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -4853,7 +4851,7 @@ StringOrView Object::name() const
|
||||
return _("Urn");
|
||||
case OBJ_SHRINEL:
|
||||
case OBJ_SHRINER:
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} will be a name from the Shrine block above */ "{:s} Shrine")), _(ShrineNames[_oVar1]));
|
||||
return FormatRuntime(_(/* TRANSLATORS: {:s} will be a name from the Shrine block above */ "{:s} Shrine"), _(ShrineNames[_oVar1]));
|
||||
case OBJ_SKELBOOK:
|
||||
return _("Skeleton Tome");
|
||||
case OBJ_BOOKSTAND:
|
||||
@@ -4908,12 +4906,12 @@ void GetObjectStr(const Object &object)
|
||||
const ClassAttributes &classAttributes = GetClassAttributes(MyPlayer->_pClass);
|
||||
if (HasAnyOf(classAttributes.classFlags, PlayerClassFlag::TrapSense)) {
|
||||
if (object._oTrapFlag) {
|
||||
InfoString = fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} will either be a chest or a door */ "Trapped {:s}")), InfoString.str());
|
||||
InfoString = FormatRuntime(_(/* TRANSLATORS: {:s} will either be a chest or a door */ "Trapped {:s}"), InfoString.str());
|
||||
InfoColor = UiFlags::ColorRed;
|
||||
}
|
||||
}
|
||||
if (object.IsDisabled()) {
|
||||
InfoString = fmt::format(fmt::runtime(_(/* TRANSLATORS: If user enabled diablo.ini setting "Disable Crippling Shrines" is set to 1; also used for Na-Kruls lever */ "{:s} (disabled)")), InfoString.str());
|
||||
InfoString = FormatRuntime(_(/* TRANSLATORS: If user enabled diablo.ini setting "Disable Crippling Shrines" is set to 1; also used for Na-Kruls lever */ "{:s} (disabled)"), InfoString.str());
|
||||
InfoColor = UiFlags::ColorRed;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-9
@@ -27,7 +27,6 @@
|
||||
#include <SDL_version.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "appfat.h"
|
||||
@@ -39,6 +38,7 @@
|
||||
#include "quick_messages.hpp"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/file_util.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/ini.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -994,7 +994,14 @@ void OptionEntryLanguageCode::LoadFromIni(std::string_view category)
|
||||
}
|
||||
}
|
||||
|
||||
LogVerbose("Found user preferred locales: {}", fmt::join(locales, ", "));
|
||||
if (IsLogLevel(defaultCategory, SDL_LOG_PRIORITY_VERBOSE)) {
|
||||
std::string joinedLocales;
|
||||
for (const std::string &locale : locales) {
|
||||
if (!joinedLocales.empty()) joinedLocales.append(", ");
|
||||
joinedLocales.append(locale);
|
||||
}
|
||||
LogVerbose("Found user preferred locales: {}", joinedLocales);
|
||||
}
|
||||
|
||||
for (const auto &locale : locales) {
|
||||
LogVerbose("Trying to load translation: {}", locale);
|
||||
@@ -1180,7 +1187,7 @@ KeymapperOptions::Action::Action(std::string_view key, const char *name, const c
|
||||
, dynamicIndex(index)
|
||||
{
|
||||
if (index != 0) {
|
||||
dynamicKey = fmt::format(fmt::runtime(std::string_view(key.data(), key.size())), index);
|
||||
dynamicKey = FormatRuntime(std::string_view(key.data(), key.size()), index);
|
||||
this->key = dynamicKey;
|
||||
}
|
||||
}
|
||||
@@ -1189,7 +1196,7 @@ std::string_view KeymapperOptions::Action::GetName() const
|
||||
{
|
||||
if (dynamicIndex == 0)
|
||||
return _(name);
|
||||
dynamicName = fmt::format(fmt::runtime(_(name)), dynamicIndex);
|
||||
dynamicName = FormatRuntime(_(name), dynamicIndex);
|
||||
return dynamicName;
|
||||
}
|
||||
|
||||
@@ -1358,7 +1365,7 @@ PadmapperOptions::Action::Action(std::string_view key, const char *name, const c
|
||||
, dynamicIndex(index)
|
||||
{
|
||||
if (index != 0) {
|
||||
dynamicKey = fmt::format(fmt::runtime(std::string_view(key.data(), key.size())), index);
|
||||
dynamicKey = FormatRuntime(std::string_view(key.data(), key.size()), index);
|
||||
this->key = dynamicKey;
|
||||
}
|
||||
}
|
||||
@@ -1367,7 +1374,7 @@ std::string_view PadmapperOptions::Action::GetName() const
|
||||
{
|
||||
if (dynamicIndex == 0)
|
||||
return _(name);
|
||||
dynamicName = fmt::format(fmt::runtime(_(name)), dynamicIndex);
|
||||
dynamicName = FormatRuntime(_(name), dynamicIndex);
|
||||
return dynamicName;
|
||||
}
|
||||
|
||||
@@ -1643,11 +1650,11 @@ std::string BuildModDescription(const ModManifest &manifest)
|
||||
const bool hasVersion = !manifest.version.empty();
|
||||
const bool hasAuthor = !manifest.author.empty();
|
||||
if (hasVersion && hasAuthor)
|
||||
return fmt::format(fmt::runtime(_("Version {:s} by {:s}")), manifest.version, manifest.author);
|
||||
return FormatRuntime(_("Version {:s} by {:s}"), manifest.version, manifest.author);
|
||||
if (hasVersion)
|
||||
return fmt::format(fmt::runtime(_("Version {:s}")), manifest.version);
|
||||
return FormatRuntime(_("Version {:s}"), manifest.version);
|
||||
if (hasAuthor)
|
||||
return fmt::format(fmt::runtime(_("By {:s}")), manifest.author);
|
||||
return FormatRuntime(_("By {:s}"), manifest.author);
|
||||
return {};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
+2
-3
@@ -6,8 +6,7 @@
|
||||
#include "pack.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <format>
|
||||
|
||||
#include "engine/random.hpp"
|
||||
#include "game_mode.hpp"
|
||||
@@ -46,7 +45,7 @@ namespace {
|
||||
|
||||
void EventFailedJoinAttempt(const char *playerName)
|
||||
{
|
||||
const std::string message = fmt::format("Player '{}' sent invalid player data during attempt to join the game.", playerName);
|
||||
const std::string message = std::format("Player '{}' sent invalid player data during attempt to join the game.", playerName);
|
||||
EventPlrMsg(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
#include "control/control.hpp"
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "engine/backbuffer_state.hpp"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
@@ -21,6 +19,7 @@
|
||||
#include "panels/ui_panels.hpp"
|
||||
#include "player.h"
|
||||
#include "tables/spelldat.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/status_macros.hpp"
|
||||
|
||||
@@ -112,9 +111,9 @@ StringOrView GetSpellPowerText(SpellID spell, int spellLevel)
|
||||
return StringOrView {};
|
||||
}
|
||||
if (spell == SpellID::Healing || spell == SpellID::HealOther) {
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: UI constraints, keep short please.*/ "Heals: {:d} - {:d}")), min, max);
|
||||
return FormatRuntime(_(/* TRANSLATORS: UI constraints, keep short please.*/ "Heals: {:d} - {:d}"), min, max);
|
||||
}
|
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: UI constraints, keep short please.*/ "Damage: {:d} - {:d}")), min, max);
|
||||
return FormatRuntime(_(/* TRANSLATORS: UI constraints, keep short please.*/ "Damage: {:d} - {:d}"), min, max);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -173,16 +172,16 @@ void DrawSpellBook(const Surface &out)
|
||||
break;
|
||||
case SpellType::Charges: {
|
||||
const int charges = player.InvBody[INVLOC_HAND_LEFT]._iCharges;
|
||||
PrintSBookStr(out, line1, fmt::format(fmt::runtime(ngettext("Staff ({:d} charge)", "Staff ({:d} charges)", charges)), charges));
|
||||
PrintSBookStr(out, line1, FormatRuntime(ngettext("Staff ({:d} charge)", "Staff ({:d} charges)", charges), charges));
|
||||
} break;
|
||||
default: {
|
||||
const int mana = GetManaAmount(player, sn) >> 6;
|
||||
const int lvl = player.GetSpellLevel(sn);
|
||||
PrintSBookStr(out, line0, fmt::format(fmt::runtime(pgettext(/* TRANSLATORS: UI constraints, keep short please.*/ "spellbook", "Level {:d}")), lvl), UiFlags::AlignRight);
|
||||
PrintSBookStr(out, line0, FormatRuntime(pgettext(/* TRANSLATORS: UI constraints, keep short please.*/ "spellbook", "Level {:d}"), lvl), UiFlags::AlignRight);
|
||||
if (const StringOrView text = GetSpellPowerText(sn, lvl); !text.empty()) {
|
||||
PrintSBookStr(out, line1, text, UiFlags::AlignRight);
|
||||
}
|
||||
PrintSBookStr(out, line1, fmt::format(fmt::runtime(pgettext(/* TRANSLATORS: UI constraints, keep short please.*/ "spellbook", "Mana: {:d}")), mana));
|
||||
PrintSBookStr(out, line1, FormatRuntime(pgettext(/* TRANSLATORS: UI constraints, keep short please.*/ "spellbook", "Mana: {:d}"), mana));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "controls/plrctrls.h"
|
||||
@@ -17,6 +15,7 @@
|
||||
#include "player.h"
|
||||
#include "spells.h"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
#include "utils/utf8.hpp"
|
||||
@@ -150,48 +149,48 @@ void DrawSpellList(const Surface &out)
|
||||
case SpellType::Skill:
|
||||
spellColor = PAL16_YELLOW - 46;
|
||||
PrintSBookSpellType(out, spellListItem.location, _("Skill"), spellColor);
|
||||
InfoString = fmt::format(fmt::runtime(_("{:s} Skill")), pgettext("spell", spellDataItem.sNameText));
|
||||
InfoString = FormatRuntime(_("{:s} Skill"), pgettext("spell", spellDataItem.sNameText));
|
||||
break;
|
||||
case SpellType::Spell:
|
||||
if (!myPlayer.isOnLevel(0)) {
|
||||
spellColor = PAL16_BLUE + 5;
|
||||
}
|
||||
PrintSBookSpellType(out, spellListItem.location, _("Spell"), spellColor);
|
||||
InfoString = fmt::format(fmt::runtime(_("{:s} Spell")), pgettext("spell", spellDataItem.sNameText));
|
||||
InfoString = FormatRuntime(_("{:s} Spell"), pgettext("spell", spellDataItem.sNameText));
|
||||
if (spellId == SpellID::HolyBolt) {
|
||||
AddInfoBoxString(_("Damages undead only"));
|
||||
}
|
||||
if (spellLevel == 0)
|
||||
AddInfoBoxString(_("Spell Level 0 - Unusable"));
|
||||
else
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Spell Level {:d}")), spellLevel));
|
||||
AddInfoBoxString(FormatRuntime(_("Spell Level {:d}"), spellLevel));
|
||||
break;
|
||||
case SpellType::Scroll: {
|
||||
if (!myPlayer.isOnLevel(0)) {
|
||||
spellColor = PAL16_RED - 59;
|
||||
}
|
||||
PrintSBookSpellType(out, spellListItem.location, _("Scroll"), spellColor);
|
||||
InfoString = fmt::format(fmt::runtime(_("Scroll of {:s}")), pgettext("spell", spellDataItem.sNameText));
|
||||
InfoString = FormatRuntime(_("Scroll of {:s}"), pgettext("spell", spellDataItem.sNameText));
|
||||
const int scrollCount = c_count_if(InventoryAndBeltPlayerItemsRange { myPlayer }, [spellId](const Item &item) {
|
||||
return item.isScrollOf(spellId);
|
||||
});
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(ngettext("{:d} Scroll", "{:d} Scrolls", scrollCount)), scrollCount));
|
||||
AddInfoBoxString(FormatRuntime(ngettext("{:d} Scroll", "{:d} Scrolls", scrollCount), scrollCount));
|
||||
} break;
|
||||
case SpellType::Charges: {
|
||||
if (!myPlayer.isOnLevel(0)) {
|
||||
spellColor = PAL16_ORANGE + 5;
|
||||
}
|
||||
PrintSBookSpellType(out, spellListItem.location, _("Staff"), spellColor);
|
||||
InfoString = fmt::format(fmt::runtime(_("Staff of {:s}")), pgettext("spell", spellDataItem.sNameText));
|
||||
InfoString = FormatRuntime(_("Staff of {:s}"), pgettext("spell", spellDataItem.sNameText));
|
||||
int charges = myPlayer.InvBody[INVLOC_HAND_LEFT]._iCharges;
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(ngettext("{:d} Charge", "{:d} Charges", charges)), charges));
|
||||
AddInfoBoxString(FormatRuntime(ngettext("{:d} Charge", "{:d} Charges", charges), charges));
|
||||
} break;
|
||||
case SpellType::Invalid:
|
||||
break;
|
||||
}
|
||||
std::optional<std::string_view> fullHotkeyName = GetHotkeyName(spellId, spellListItem.type);
|
||||
if (fullHotkeyName) {
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Spell Hotkey {:s}")), *fullHotkeyName));
|
||||
AddInfoBoxString(FormatRuntime(_("Spell Hotkey {:s}"), *fullHotkeyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* The m68k-amigaos hard-float libgcc multilib omits the software
|
||||
* double-precision comparison routine `__cmpdf2` (doubles are compared in
|
||||
* hardware), but its software extended-precision comparison routines
|
||||
* (xfpgnulib `__cmpxf2`, `__eqxf2`, ...) still call it.
|
||||
*
|
||||
* libstdc++'s <format> machinery references the extended-precision routines
|
||||
* through its `long double` code paths, so linking fails with an undefined
|
||||
* `__cmpdf2` even though it is never actually called.
|
||||
*/
|
||||
int __cmpdf2(double a, double b);
|
||||
|
||||
int __cmpdf2(double a, double b)
|
||||
{
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -26,7 +26,6 @@ endif()
|
||||
target_link_dependencies(libdevilutionx_ctr
|
||||
PUBLIC
|
||||
DevilutionX::SDL
|
||||
fmt::fmt
|
||||
3ds::citro3d
|
||||
3ds::ctrulib
|
||||
PRIVATE
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
#include <cstdint>
|
||||
#include <malloc.h>
|
||||
|
||||
// This header must be included before any 3DS code
|
||||
// because 3DS SDK defines a macro with the same name
|
||||
// as an fmt template parameter in some versions of fmt.
|
||||
// See https://github.com/fmtlib/fmt/issues/3632
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include "utils/log.hpp"
|
||||
|
||||
+2
-4
@@ -14,9 +14,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "controls/plrctrls.h"
|
||||
@@ -55,6 +52,7 @@
|
||||
#include "spells.h"
|
||||
#include "stores.h"
|
||||
#include "towners.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -2749,7 +2747,7 @@ StartPlayerKill(Player &player, DeathReason deathReason)
|
||||
if (dropEar) {
|
||||
Item ear;
|
||||
InitializeItem(ear, IDI_EAR);
|
||||
CopyUtf8(ear._iName, fmt::format(fmt::runtime("Ear of {:s}"), player._pName), sizeof(ear._iName));
|
||||
CopyUtf8(ear._iName, FormatRuntime("Ear of {:s}", player._pName), sizeof(ear._iName));
|
||||
CopyUtf8(ear._iIName, player._pName, ItemNameLength);
|
||||
switch (player._pClass) {
|
||||
case HeroClass::Sorcerer:
|
||||
|
||||
+2
-3
@@ -15,8 +15,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "engine/render/primitive_render.hpp"
|
||||
#include "engine/render/text_render.hpp"
|
||||
@@ -24,6 +22,7 @@
|
||||
#include "qol/chatlog.h"
|
||||
#include "qol/stash.h"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/utf8.hpp"
|
||||
|
||||
@@ -82,7 +81,7 @@ void SendPlrMsg(Player &player, std::string_view text)
|
||||
{
|
||||
PlayerMessage &message = GetNextMessage();
|
||||
|
||||
const std::string from = fmt::format(fmt::runtime(_("{:s} (lvl {:d}): ")), player._pName, player.getCharacterLevel());
|
||||
const std::string from = FormatRuntime(_("{:s} (lvl {:d}): "), player._pName, player.getCharacterLevel());
|
||||
|
||||
message.style = UiFlags::ColorWhite;
|
||||
message.time = SDL_GetTicks();
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "automap.h"
|
||||
#include "chatlog.h"
|
||||
@@ -23,6 +21,7 @@
|
||||
#include "inv.h"
|
||||
#include "minitext.h"
|
||||
#include "stores.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
|
||||
@@ -127,7 +126,7 @@ void AddMessageToChatLog(std::string_view message, Player *player, UiFlags flags
|
||||
if (player == nullptr) {
|
||||
ChatLogLines.emplace_back(MultiColoredText { "{0} {1}", { { timestamp, UiFlags::ColorRed }, { std::string(message), flags } } });
|
||||
} else {
|
||||
std::string playerInfo = fmt::format(fmt::runtime(_("{:s} (lvl {:d}): ")), player->_pName, player->getCharacterLevel());
|
||||
std::string playerInfo = FormatRuntime(_("{:s} (lvl {:d}): "), player->_pName, player->getCharacterLevel());
|
||||
UiFlags nameColor = player == MyPlayer ? UiFlags::ColorWhitegold : UiFlags::ColorBlue;
|
||||
const std::string prefix = timestamp + " - " + playerInfo;
|
||||
const std::string text = WordWrapString(prefix + std::string(message), ContentTextWidth);
|
||||
@@ -167,7 +166,7 @@ void DrawChatLog(const Surface &out)
|
||||
const int sx = uiPosition.x + PaddingLeft;
|
||||
const int sy = uiPosition.y;
|
||||
|
||||
DrawString(out, fmt::format(fmt::runtime(_("Chat History (Messages: {:d})")), MessageCounter),
|
||||
DrawString(out, FormatRuntime(_("Chat History (Messages: {:d})"), MessageCounter),
|
||||
{ { sx, sy + PaddingTop + blankLineHeight }, { ContentTextWidth, lineHeight } },
|
||||
{ .flags = (UnreadFlag ? UiFlags::ColorRed : UiFlags::ColorWhitegold) | UiFlags::AlignCenter });
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <deque>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "cursor.h"
|
||||
#include "engine/point.hpp"
|
||||
@@ -20,6 +18,7 @@
|
||||
#include "qol/stash.h"
|
||||
#include "stores.h"
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/language.h"
|
||||
|
||||
@@ -110,7 +109,7 @@ void AddItemToLabelQueue(int id, Point position)
|
||||
|
||||
StringOrView textOnGround;
|
||||
if (item._itype == ItemType::Gold) {
|
||||
textOnGround = fmt::format(fmt::runtime(_("{:s} gold")), FormatInteger(item._ivalue));
|
||||
textOnGround = FormatRuntime(_("{:s} gold"), FormatInteger(item._ivalue));
|
||||
} else {
|
||||
textOnGround = item.getName();
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "cursor.h"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/text_input.hpp"
|
||||
#include "control/control.hpp"
|
||||
#include "controls/plrctrls.h"
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "control/control.hpp"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
#include "engine/load_clx.hpp"
|
||||
@@ -20,6 +17,7 @@
|
||||
#include "game_mode.hpp"
|
||||
#include "options.h"
|
||||
#include "tables/playerdat.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/language.h"
|
||||
|
||||
@@ -137,13 +135,13 @@ bool CheckXPBarInfo()
|
||||
|
||||
const uint8_t charLevel = player.getCharacterLevel();
|
||||
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Level {:d}")), charLevel));
|
||||
AddInfoBoxString(FormatRuntime(_("Level {:d}"), charLevel));
|
||||
|
||||
if (player.isMaxCharacterLevel()) {
|
||||
// Show a maximum level indicator for max level players.
|
||||
InfoColor = UiFlags::ColorWhitegold;
|
||||
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Experience: {:s}")), FormatInteger(player._pExperience)));
|
||||
AddInfoBoxString(FormatRuntime(_("Experience: {:s}"), FormatInteger(player._pExperience)));
|
||||
AddInfoBoxString(_("Maximum Level"));
|
||||
|
||||
return true;
|
||||
@@ -151,10 +149,10 @@ bool CheckXPBarInfo()
|
||||
|
||||
InfoColor = UiFlags::ColorWhite;
|
||||
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Experience: {:s}")), FormatInteger(player._pExperience)));
|
||||
AddInfoBoxString(FormatRuntime(_("Experience: {:s}"), FormatInteger(player._pExperience)));
|
||||
const uint32_t nextExperienceThreshold = player.getNextExperienceThreshold();
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("Next Level: {:s}")), FormatInteger(nextExperienceThreshold)));
|
||||
AddInfoBoxString(fmt::format(fmt::runtime(_("{:s} to Level {:d}")), FormatInteger(nextExperienceThreshold - player._pExperience), charLevel + 1));
|
||||
AddInfoBoxString(FormatRuntime(_("Next Level: {:s}"), FormatInteger(nextExperienceThreshold)));
|
||||
AddInfoBoxString(FormatRuntime(_("{:s} to Level {:d}"), FormatInteger(nextExperienceThreshold - player._pExperience), charLevel + 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-3
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DiabloUI/ui_flags.hpp"
|
||||
#include "control/control.hpp"
|
||||
#include "cursor.h"
|
||||
@@ -32,6 +30,7 @@
|
||||
#include "tables/townerdat.hpp"
|
||||
#include "towners.h"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/is_of.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/utf8.hpp"
|
||||
@@ -354,7 +353,7 @@ bool ForceQuests()
|
||||
const int ql = quest._qslvl - 1;
|
||||
|
||||
if (EntranceBoundaryContains(quest.position, cursPosition)) {
|
||||
InfoString = fmt::format(fmt::runtime(_(/* TRANSLATORS: Used for Quest Portals. {:s} is a Map Name */ "To {:s}")), _(QuestTriggerNames[ql]));
|
||||
InfoString = FormatRuntime(_(/* TRANSLATORS: Used for Quest Portals. {:s} is a Map Name */ "To {:s}"), _(QuestTriggerNames[ql]));
|
||||
cursPosition = quest.position;
|
||||
return true;
|
||||
}
|
||||
|
||||
+11
-12
@@ -13,8 +13,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "controls/control_mode.hpp"
|
||||
#include "controls/plrctrls.h"
|
||||
#include "cursor.h"
|
||||
@@ -34,6 +32,7 @@
|
||||
#include "qol/visual_store.h"
|
||||
#include "tables/townerdat.hpp"
|
||||
#include "towners.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/format_int.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -370,7 +369,7 @@ void PrintStoreItem(const Item &item, int l, UiFlags flags, bool cursIndent = fa
|
||||
if (item._iMiscId == IMISC_STAFF && item._iMaxCharges != 0) {
|
||||
if (!productLine.empty())
|
||||
productLine.append(_(", "));
|
||||
productLine.append(fmt::format(fmt::runtime(_("Charges: {:d}/{:d}")), item._iCharges, item._iMaxCharges));
|
||||
productLine.append(FormatRuntime(_("Charges: {:d}/{:d}"), item._iCharges, item._iMaxCharges));
|
||||
}
|
||||
if (!productLine.empty()) {
|
||||
AddSText(40, l, productLine, flags, false, -1, cursIndent);
|
||||
@@ -380,11 +379,11 @@ void PrintStoreItem(const Item &item, int l, UiFlags flags, bool cursIndent = fa
|
||||
|
||||
if (item._itype != ItemType::Misc) {
|
||||
if (item._iClass == ICLASS_WEAPON)
|
||||
productLine = fmt::format(fmt::runtime(_("Damage: {:d}-{:d} ")), item._iMinDam, item._iMaxDam);
|
||||
productLine = FormatRuntime(_("Damage: {:d}-{:d} "), item._iMinDam, item._iMaxDam);
|
||||
else if (item._iClass == ICLASS_ARMOR)
|
||||
productLine = fmt::format(fmt::runtime(_("Armor: {:d} ")), item._iAC);
|
||||
productLine = FormatRuntime(_("Armor: {:d} "), item._iAC);
|
||||
if (item._iMaxDur != DUR_INDESTRUCTIBLE && item._iMaxDur != 0)
|
||||
productLine += fmt::format(fmt::runtime(_("Dur: {:d}/{:d}")), item._iDurability, item._iMaxDur);
|
||||
productLine += FormatRuntime(_("Dur: {:d}/{:d}"), item._iDurability, item._iMaxDur);
|
||||
else
|
||||
productLine.append(_("Indestructible"));
|
||||
}
|
||||
@@ -398,11 +397,11 @@ void PrintStoreItem(const Item &item, int l, UiFlags flags, bool cursIndent = fa
|
||||
productLine.append(_(", "));
|
||||
productLine.append(_("Required:"));
|
||||
if (str != 0)
|
||||
productLine.append(fmt::format(fmt::runtime(_(" {:d} Str")), str));
|
||||
productLine.append(FormatRuntime(_(" {:d} Str"), str));
|
||||
if (mag != 0)
|
||||
productLine.append(fmt::format(fmt::runtime(_(" {:d} Mag")), mag));
|
||||
productLine.append(FormatRuntime(_(" {:d} Mag"), mag));
|
||||
if (dex != 0)
|
||||
productLine.append(fmt::format(fmt::runtime(_(" {:d} Dex")), dex));
|
||||
productLine.append(FormatRuntime(_(" {:d} Dex"), dex));
|
||||
}
|
||||
AddSText(40, l++, productLine, flags, false, -1, cursIndent);
|
||||
}
|
||||
@@ -1207,10 +1206,10 @@ void StartTalk()
|
||||
|
||||
IsTextFullSize = false;
|
||||
HasScrollbar = false;
|
||||
AddSText(0, 2, fmt::format(fmt::runtime(_("Talk to {:s}")), _(TownerNames[TownerId])), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false);
|
||||
AddSText(0, 2, FormatRuntime(_("Talk to {:s}"), _(TownerNames[TownerId])), UiFlags::ColorWhitegold | UiFlags::AlignCenter, false);
|
||||
AddSLine(5);
|
||||
if (gbIsSpawn) {
|
||||
AddSText(0, 10, fmt::format(fmt::runtime(_("Talking to {:s}")), _(TownerNames[TownerId])), UiFlags::ColorWhite | UiFlags::AlignCenter, false);
|
||||
AddSText(0, 10, FormatRuntime(_("Talking to {:s}"), _(TownerNames[TownerId])), UiFlags::ColorWhite | UiFlags::AlignCenter, false);
|
||||
AddSText(0, 12, _("is not available"), UiFlags::ColorWhite | UiFlags::AlignCenter, false);
|
||||
AddSText(0, 14, _("in the shareware"), UiFlags::ColorWhite | UiFlags::AlignCenter, false);
|
||||
AddSText(0, 16, _("version"), UiFlags::ColorWhite | UiFlags::AlignCenter, false);
|
||||
@@ -2471,7 +2470,7 @@ void DrawSText(const Surface &out)
|
||||
}
|
||||
|
||||
if (RenderGold) {
|
||||
PrintSString(out, 28, 1, fmt::format(fmt::runtime(_("Your gold: {:s}")), FormatInteger(TotalPlayerGold())).c_str(), UiFlags::ColorWhitegold | UiFlags::AlignRight);
|
||||
PrintSString(out, 28, 1, FormatRuntime(_("Your gold: {:s}"), FormatInteger(TotalPlayerGold())).c_str(), UiFlags::ColorWhitegold | UiFlags::AlignRight);
|
||||
}
|
||||
|
||||
if (HasScrollbar)
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
|
||||
#include "tables/itemdat.h"
|
||||
|
||||
#include <format>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "data/file.hpp"
|
||||
#include "data/iterators.hpp"
|
||||
#include "data/record_reader.hpp"
|
||||
@@ -367,7 +366,7 @@ std::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::strin
|
||||
const size_t newUniqueBaseItemIndex = static_cast<size_t>(NUM_DEFAULT_UITYPES) + AdditionalUniqueBaseItemStringsToIndices.size();
|
||||
|
||||
if (newUniqueBaseItemIndex >= static_cast<size_t>(NUM_MAX_UITYPES)) {
|
||||
return std::unexpected(fmt::format("Could not define new unique base item \"{}\", since the maximum number of {} has already been reached.", value, static_cast<size_t>(NUM_MAX_UITYPES)));
|
||||
return std::unexpected(std::format("Could not define new unique base item \"{}\", since the maximum number of {} has already been reached.", value, static_cast<size_t>(NUM_MAX_UITYPES)));
|
||||
}
|
||||
|
||||
const auto newUniqueBaseItem = static_cast<unique_base_item>(newUniqueBaseItemIndex);
|
||||
@@ -599,7 +598,7 @@ void LoadItemDatFromFile(DataFile &dataFile, std::string_view filename, int32_t
|
||||
item.iMappingId = currentMappingId;
|
||||
const auto [it, inserted] = ItemMappingIdsToIndices.emplace(item.iMappingId, static_cast<int16_t>(AllItemsList.size()) - 1);
|
||||
if (!inserted) {
|
||||
DisplayFatalErrorAndExit("Adding Item Failed", fmt::format("An item already exists for mapping ID {}.", item.iMappingId));
|
||||
DisplayFatalErrorAndExit("Adding Item Failed", std::format("An item already exists for mapping ID {}.", item.iMappingId));
|
||||
}
|
||||
|
||||
++currentMappingId;
|
||||
@@ -657,7 +656,7 @@ void LoadUniqueItemDatFromFile(DataFile &dataFile, std::string_view filename, in
|
||||
item.mappingId = currentMappingId;
|
||||
const auto [it, inserted] = UniqueItemMappingIdsToIndices.emplace(item.mappingId, static_cast<int32_t>(UniqueItems.size()) - 1);
|
||||
if (!inserted) {
|
||||
DisplayFatalErrorAndExit("Adding Unique Item Failed", fmt::format("A unique item already exists for mapping ID {}.", item.mappingId));
|
||||
DisplayFatalErrorAndExit("Adding Unique Item Failed", std::format("A unique item already exists for mapping ID {}.", item.mappingId));
|
||||
}
|
||||
|
||||
++currentMappingId;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "appfat.h"
|
||||
@@ -28,6 +26,7 @@
|
||||
#include "lua/lua_event.hpp"
|
||||
#include "monster.h"
|
||||
#include "tables/textdat.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -329,7 +328,7 @@ void LoadMonstDatFromFile(DataFile &dataFile, const std::string_view filename, b
|
||||
|
||||
for (DataFileRecord record : dataFile) {
|
||||
if (MonstersData.size() >= static_cast<size_t>(NUM_MAX_MTYPES)) {
|
||||
DisplayFatalErrorAndExit(_("Loading Monster Data Failed"), fmt::format(fmt::runtime(_("Could not add a monster, since the maximum monster type number of {} has already been reached.")), static_cast<size_t>(NUM_MAX_MTYPES)));
|
||||
DisplayFatalErrorAndExit(_("Loading Monster Data Failed"), FormatRuntime(_("Could not add a monster, since the maximum monster type number of {} has already been reached."), static_cast<size_t>(NUM_MAX_MTYPES)));
|
||||
}
|
||||
|
||||
RecordReader reader { record, filename };
|
||||
@@ -342,7 +341,7 @@ void LoadMonstDatFromFile(DataFile &dataFile, const std::string_view filename, b
|
||||
const size_t monsterIndex = MonstersData.size();
|
||||
const auto [it, inserted] = AdditionalMonsterIdStringsToIndices.emplace(monsterId, static_cast<int16_t>(monsterIndex));
|
||||
if (!inserted) {
|
||||
DisplayFatalErrorAndExit(_("Loading Monster Data Failed"), fmt::format(fmt::runtime(_("A monster type already exists for ID \"{}\".")), monsterId));
|
||||
DisplayFatalErrorAndExit(_("Loading Monster Data Failed"), FormatRuntime(_("A monster type already exists for ID \"{}\"."), monsterId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <expected>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <magic_enum/magic_enum_utility.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
@@ -23,6 +22,7 @@
|
||||
#include "items.h"
|
||||
#include "player.h"
|
||||
#include "tables/textdat.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
#include "utils/static_vector.hpp"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -317,7 +317,7 @@ void LoadClassDatFromFile(DataFile &dataFile, const std::string_view filename)
|
||||
|
||||
for (DataFileRecord record : dataFile) {
|
||||
if (PlayersData.size() >= static_cast<size_t>(HeroClass::NUM_MAX_CLASSES)) {
|
||||
DisplayFatalErrorAndExit(_("Loading Class Data Failed"), fmt::format(fmt::runtime(_("Could not add a class, since the maximum class number of {} has already been reached.")), static_cast<size_t>(HeroClass::NUM_MAX_CLASSES)));
|
||||
DisplayFatalErrorAndExit(_("Loading Class Data Failed"), FormatRuntime(_("Could not add a class, since the maximum class number of {} has already been reached."), static_cast<size_t>(HeroClass::NUM_MAX_CLASSES)));
|
||||
}
|
||||
|
||||
RecordReader reader { record, filename };
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
#include "tables/textdat.h"
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "data/file.hpp"
|
||||
#include "data/record_reader.hpp"
|
||||
#include "effects.h"
|
||||
#include "utils/format.hpp"
|
||||
#include "utils/language.h"
|
||||
|
||||
namespace devilution {
|
||||
@@ -70,7 +69,7 @@ void LoadTextDatFromFile(DataFile &dataFile, std::string_view filename, bool gro
|
||||
const size_t textEntryIndex = Speeches.size();
|
||||
const auto [it, inserted] = AdditionalTextIdStringsToIndices.emplace(txtstrid, static_cast<int16_t>(textEntryIndex));
|
||||
if (!inserted) {
|
||||
DisplayFatalErrorAndExit(_("Loading Text Data Failed"), fmt::format(fmt::runtime(_("A text data entry already exists for ID \"{}\".")), txtstrid));
|
||||
DisplayFatalErrorAndExit(_("Loading Text Data Failed"), FormatRuntime(_("A text data entry already exists for ID \"{}\"."), txtstrid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <format>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace devilution {
|
||||
|
||||
/**
|
||||
* @brief Formats using a format string that is only known at runtime, such as a translation.
|
||||
*
|
||||
* Unlike `std::format`, the format string is not checked at compile time.
|
||||
* An invalid format string results in `std::format_error` being thrown
|
||||
* (or program termination if exceptions are disabled).
|
||||
*/
|
||||
template <typename... Args>
|
||||
[[nodiscard]] std::string FormatRuntime(std::string_view fmt, Args &&...args)
|
||||
{
|
||||
return std::vformat(fmt, std::make_format_args(args...));
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
+8
-13
@@ -7,6 +7,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <expected>
|
||||
#include <format>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -16,8 +17,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "utils/algorithm/container.hpp"
|
||||
#include "utils/str_cat.hpp"
|
||||
@@ -160,10 +159,10 @@ std::expected<Ini, std::string> Ini::parse(std::string_view buffer)
|
||||
++keyEnd;
|
||||
}
|
||||
if (keyEnd == lineEnd) {
|
||||
return std::unexpected(fmt::format("line {}: unclosed section name {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin)));
|
||||
return std::unexpected(std::format("line {}: unclosed section name {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin)));
|
||||
}
|
||||
if (const char *after = SkipTrailingWhitespace(keyEnd + 1, lineEnd); after != lineEnd) {
|
||||
return std::unexpected(fmt::format("line {}: content after section [{}]: {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin), std::string_view(after, lineEnd - after)));
|
||||
return std::unexpected(std::format("line {}: content after section [{}]: {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin), std::string_view(after, lineEnd - after)));
|
||||
}
|
||||
const std::string_view sectionName = std::string_view(keyBegin, keyEnd - keyBegin);
|
||||
auto it = fileData.sections.find(sectionName);
|
||||
@@ -180,10 +179,10 @@ std::expected<Ini, std::string> Ini::parse(std::string_view buffer)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sectionEntries == nullptr) return std::unexpected(fmt::format("line {}: key not in any section", lineNum));
|
||||
if (sectionEntries == nullptr) return std::unexpected(std::format("line {}: key not in any section", lineNum));
|
||||
const char *eqPos = static_cast<const char *>(memchr(keyBegin, '=', lineEnd - keyBegin));
|
||||
if (eqPos == nullptr) {
|
||||
return std::unexpected(fmt::format("line {}: key {} has no value", lineNum, std::string_view(keyBegin, lineEnd - keyBegin)));
|
||||
return std::unexpected(std::format("line {}: key {} has no value", lineNum, std::string_view(keyBegin, lineEnd - keyBegin)));
|
||||
}
|
||||
const char *keyEnd = SkipTrailingWhitespace(keyBegin, eqPos);
|
||||
const std::string_view key = std::string_view(keyBegin, keyEnd - keyBegin);
|
||||
@@ -230,7 +229,7 @@ int Ini::getInt(std::string_view section, std::string_view key, int defaultValue
|
||||
int value;
|
||||
const std::from_chars_result result = std::from_chars(str.data(), str.data() + str.size(), value);
|
||||
if (result.ec != std::errc()) {
|
||||
app_fatal(fmt::format("ini: Failed to parse {}.{}={} as int", section, key, str));
|
||||
app_fatal(std::format("ini: Failed to parse {}.{}={} as int", section, key, str));
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
@@ -243,7 +242,7 @@ bool Ini::getBool(std::string_view section, std::string_view key, bool defaultVa
|
||||
const std::string_view str = xs.back().value;
|
||||
if (str == "0") return false;
|
||||
if (str == "1") return true;
|
||||
app_fatal(fmt::format("ini: Failed to parse {}.{}={} as bool", section, key, str));
|
||||
app_fatal(std::format("ini: Failed to parse {}.{}={} as bool", section, key, str));
|
||||
}
|
||||
|
||||
float Ini::getFloat(std::string_view section, std::string_view key, float defaultValue) const
|
||||
@@ -256,7 +255,7 @@ float Ini::getFloat(std::string_view section, std::string_view key, float defaul
|
||||
float value;
|
||||
const std::from_chars_result result = std::from_chars(str.data(), str.data() + str.size(), value);
|
||||
if (result.ec != std::errc()) {
|
||||
app_fatal(fmt::format("ini: Failed to parse {}.{}={} as float", section, key, str));
|
||||
app_fatal(std::format("ini: Failed to parse {}.{}={} as float", section, key, str));
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
@@ -375,7 +374,6 @@ void Ini::set(std::string_view section, std::string_view key, bool value)
|
||||
|
||||
void Ini::set(std::string_view section, std::string_view key, float value)
|
||||
{
|
||||
#if __cpp_lib_to_chars >= 201611L
|
||||
constexpr size_t BufSize = 64;
|
||||
char buf[BufSize] {};
|
||||
const std::to_chars_result result = std::to_chars(buf, buf + BufSize, value);
|
||||
@@ -383,9 +381,6 @@ void Ini::set(std::string_view section, std::string_view key, float value)
|
||||
app_fatal("float->string failed"); // should never happen
|
||||
}
|
||||
set(section, key, std::string_view(buf, result.ptr - buf));
|
||||
#else
|
||||
set(section, key, fmt::format("{}", value));
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
// libstdc++'s <locale> (which <format> includes in GCC 13) includes
|
||||
// <libintl.h>, which declares `ngettext`. Include it before defining the
|
||||
// `ngettext` macro below, so that the declaration is not rewritten into a
|
||||
// conflicting `LanguagePluralTranslate` overload that is never defined.
|
||||
#if __has_include(<libintl.h>)
|
||||
#include <libintl.h>
|
||||
// GNU libintl.h may define `ngettext` as a macro itself.
|
||||
#undef ngettext
|
||||
#endif
|
||||
|
||||
#define _(x) LanguageTranslate(x)
|
||||
#define ngettext(x, y, z) LanguagePluralTranslate(x, y, z)
|
||||
#define pgettext(context, x) LanguageParticularTranslate(context, x)
|
||||
|
||||
+12
-19
@@ -8,10 +8,10 @@
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ranges.h>
|
||||
#include <format>
|
||||
#include <string>
|
||||
|
||||
#include "utils/attributes.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
|
||||
#ifdef USE_SDL1
|
||||
@@ -51,25 +51,18 @@ namespace detail {
|
||||
template <typename... Args>
|
||||
std::string format(std::string_view fmt, Args &&...args)
|
||||
{
|
||||
FMT_TRY
|
||||
{
|
||||
return fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...);
|
||||
#if DVL_EXCEPTIONS
|
||||
try {
|
||||
return std::vformat(fmt, std::make_format_args(args...));
|
||||
} catch (const std::format_error &e) {
|
||||
const std::string fullError = StrCat("Format error, fmt: ", fmt, " error: ", e.what());
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "%s", fullError.c_str());
|
||||
app_fatal(fullError);
|
||||
}
|
||||
#if FMT_EXCEPTIONS
|
||||
FMT_CATCH(const fmt::format_error &e)
|
||||
{
|
||||
// e.what() is undefined if exceptions are disabled, so we wrap it
|
||||
// with an `FMT_EXCEPTIONS` check.
|
||||
std::string error = e.what();
|
||||
#else
|
||||
FMT_CATCH(const fmt::format_error &)
|
||||
{
|
||||
std::string error = "unknown (FMT_EXCEPTIONS disabled)";
|
||||
// `std::vformat` terminates the program on error when exceptions are disabled.
|
||||
return std::vformat(fmt, std::make_format_args(args...));
|
||||
#endif
|
||||
std::string fullError = StrCat("Format error, fmt: ", fmt, " error: ", error);
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "%s", error.c_str());
|
||||
app_fatal(error);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
Loaded 100 of 109 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user