22 constexpr int PanelX = 600;
29 constexpr std::uint32_t
TextColour = 0x00DCDCDCU;
34 const data::LanguageCatalog& catalog, std::uint32_t
id)
37 if (!
text)
return std::unexpected(
text.error().detail);
42 const data::LanguageCatalog& catalog, std::uint32_t
id)
45 if (!
text)
return std::unexpected(
text.error());
52 const data::LanguageCatalog& catalog,
int square,
56 return std::unexpected(
"Trade square-name index is out of range");
59 city =
static_cast<int>(
catalog.language()) - 2;
62 42ULL *
static_cast<std::uint32_t
>(std::max(city, 0)) +
63 static_cast<std::uint32_t
>(square);
64 if (
id64 > std::numeric_limits<std::uint32_t>::max())
65 return std::unexpected(
"Trade property-name index is out of range");
68 if (!
text)
return std::unexpected(
text.error().detail);
69 if (!*
text)
return std::unexpected(
"Trade property name is missing from LANG");
70 if (!(**text)->empty() && (**text)->front() == u
'*')
74 if (!
text)
return std::unexpected(
text.error().detail);
76 return std::unexpected(
77 "Trade base property name is missing from LANG");
83 const data::LanguageCatalog& catalog, std::uint32_t properties,
95 if (!
text)
return std::unexpected(
text.error());
102 const data::LanguageCatalog& catalog, std::uint32_t properties,
106 auto remaining = properties;
111 if (
bit == 0 || (remaining &
bit) == 0)
continue;
114 if (!
name)
return std::unexpected(
name.error());
119 if (remaining != 0)
output += u
"...";
125 const data::LanguageCatalog& catalog,
130 std::wstring_view(
gameState.players[player].name));
138 std::u16string_view
pattern, std::int32_t amount,
141 const data::LanguageCatalog& catalog,
144 const language::LegacyFormatArguments
arguments{
146 language::LegacyFormatResolvers
resolvers;
151 resolvers.squareName = [&](std::int64_t square)
154 catalog,
static_cast<int>(square), city, edition);
156 resolvers.propertySetNames = [&](std::uint32_t properties)
159 catalog, properties, city, edition);
179 const auto offset = (
static_cast<std::size_t
>(
y) *
image.width +
180 static_cast<std::size_t
>(
x)) * 4U;
189 data::LegacyBitmapRGBA8&
image, fonts::Runtime&
font,
190 std::string_view
text,
int x,
int y, std::uint32_t
colour)
192 if (
text.empty())
return {};
199 data::LegacyBitmapRGBA8&
image, fonts::Runtime&
font,
200 std::string_view
text,
int y, std::uint32_t
colour)
210 key += std::to_string(
value.size());
215 struct RestoreDefaultFont
final
228 state.contractDialogVisible;
231 if (!visible_)
return {};
233 *surface_, TradeContractTextPriority, false}))
234 return std::unexpected(
"Trade contract-text stop queue is full");
238 const auto mode =
state.contractDialogMode;
239 if (mode > 6 ||
state.contractDialogSide > 1 ||
242 return std::unexpected(
"Trade contract-text state is invalid");
244 return std::unexpected(
"Trade contract-text font runtime is unavailable");
245 const auto resources =
playback.resources();
246 const auto language = resources ? resources->language() :
nullptr;
247 if (!language || !language->catalog)
248 return std::unexpected(
"Trade contract text has no language catalog");
249 if (!visible_ &&
playback.commands().pendingCount() >=
251 return std::unexpected(
"Trade contract-text start queue is full");
253 const auto& catalog = *language->catalog;
254 const auto edition = resources->context().board;
257 constexpr std::array<std::uint32_t, 7>
PromptOffsets{{1, 2, 4, 5, 6, 7, 8}};
259 (mode == 1 ?
state.contractDialogSide : 0
U);
270 if (!
okay)
return std::unexpected(
okay.error());
271 std::string playerName;
274 const auto player =
state.contractDialogSide ?
state.playerA :
state.playerB;
276 return std::unexpected(
"Trade contract recipient is out of range");
278 std::wstring_view(
gameState.players[player].name));
295 amount = std::to_string(
state.contractAmount);
296 if (amount.size() < 2) amount.insert(amount.begin(),
' ');
301 const auto offset =
state.contractList.empty() ? 0 : std::clamp(
302 state.contractListOffset, 0,
static_cast<int>(
state.contractList.size()) - 1);
303 for (std::size_t
row = 0; mode != 0 &&
row < rows.size(); ++
row)
306 if (
index >=
state.contractList.size())
break;
309 if (!
name)
return std::unexpected(
name.error());
312 rows[
row] = std::to_string(
entry.hitCount);
313 if (rows[
row].size() < 2) rows[
row].insert(rows[
row].begin(),
'0');
314 rows[
row].push_back(
' ');
322 if (mode != 0 &&
offset != 0)
324 const auto&
first =
state.contractList.front();
326 if (!
name)
return std::unexpected(
name.error());
336 std::string
key = std::to_string(mode) +
':' +
337 std::to_string(
static_cast<int>(edition)) +
':';
341 for (std::size_t
row = 0;
row < rows.size(); ++
row)
344 key.push_back(selected[
row] ?
'1' :
'0');
348 !contentKey_ || *contentKey_ !=
key;
351 return std::unexpected(
"sequence command queue cannot fit text redraw");
355 const auto settings =
fontRuntime->restoreSettings(7);
356 if (!settings)
return std::unexpected(settings.error().detail);
397 for (std::size_t
row = 0;
row < rows.size(); ++
row)
399 if (
static_cast<std::size_t
>(
offset) +
row >=
state.contractList.size())
break;
404 selected[
row] ? 255 : 0);
419 if (!size)
return std::unexpected(size.error().detail);
421 20 + (20 - size->width) / 2, 101,
TextColour); !result)
430 const auto updated =
playback.runtimeBitmaps().update(*surface_, std::move(
image));
431 if (!updated)
return std::unexpected(updated.error());
432 contentKey_ = std::move(
key);
445 if (!program)
return std::unexpected(program.error().detail);
448 return std::unexpected(
"Validated Trade contract-text start rejected");
std::deque< Bytes > output
static constexpr std::size_t Capacity
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > rawBitmap(data::DataId id, data::LegacyDataType sourceType, DescriptionLimits limits={})
std::expected< void, std::string > sync(const State &state, const rules::GameState &gameState, display::Screen2D desiredView, int city, fonts::Runtime *fontRuntime, engine::SequencePlayback &playback)
std::expected< std::string, Error > transcodeUtf8(std::u16string_view text)
PropertyMask propertyBit(int square) noexcept
std::expected< std::u16string, std::string > wideToUtf16(std::wstring_view text)
std::expected< std::u16string, std::string > formatLegacyMessage(std::u16string_view pattern, const LegacyFormatArguments &arguments, const LegacyFormatResolvers &resolvers, std::size_t limit)
std::vector< ObjectSpec > catalog(bool europe)
constexpr PlayerNumber BankPlayer
std::uint8_t PlayerNumber
constexpr std::size_t SquareCount
constexpr PlayerNumber MaxPlayers
constexpr PlayerNumber NobodyPlayer
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept
constexpr std::uint16_t TradeContractTextPriority
constexpr std::array< Rect, 5 > ContractListRects
constexpr std::uint8_t OffBoardSquare
std::vector< std::uint8_t > pixels