From b5878df34a9dda1e8e146c8c1bd6093ba74f749d Mon Sep 17 00:00:00 2001 From: iisaev Date: Sat, 24 Oct 2026 10:01:16 +0200 Subject: [PATCH] Trading: shop kind and trade.open schema; trade test passes the RPG Plus prologue Co-Authored-By: Claude Opus 5.5 --- locale/schema_en.properties | 11 ++++ locale/schema_es.properties | 11 ++++ locale/schema_ja.properties | 11 ++++ locale/schema_ko.properties | 11 ++++ locale/schema_ru.properties | 11 ++++ locale/schema_vi.properties | 11 ++++ locale/schema_zh.properties | 11 ++++ schemas/trading.json | 83 ++++++++++++++++++++++++ test_suites/trade/manifest.json | 2 +- test_suites/trade/src/TradeTestDriver.cs | 27 +++++++- 10 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 locale/schema_en.properties create mode 100644 locale/schema_es.properties create mode 100644 locale/schema_ja.properties create mode 100644 locale/schema_ko.properties create mode 100644 locale/schema_ru.properties create mode 100644 locale/schema_vi.properties create mode 100644 locale/schema_zh.properties create mode 100644 schemas/trading.json diff --git a/locale/schema_en.properties b/locale/schema_en.properties new file mode 100644 index 0000000..5c839fc --- /dev/null +++ b/locale/schema_en.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = Open a shop +trading/schema/builtin/trade_open_desc = The trade window with the merchant +trading/schema/field/shop = Shop +trading/schema/kind/shop = Shops +trading/schema/kind/shop_desc = What merchants sell and buy +trading/schema/field/name = Name +trading/schema/field/currency = Currency +trading/schema/field/sells = Sells +trading/schema/field/item = Item +trading/schema/field/price = Price +trading/schema/field/buys = Buys diff --git a/locale/schema_es.properties b/locale/schema_es.properties new file mode 100644 index 0000000..bc466da --- /dev/null +++ b/locale/schema_es.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = Abrir una tienda +trading/schema/builtin/trade_open_desc = La ventana de comercio con el mercader +trading/schema/field/shop = Tienda +trading/schema/kind/shop = Tiendas +trading/schema/kind/shop_desc = Lo que venden y compran los mercaderes +trading/schema/field/name = Nombre +trading/schema/field/currency = Moneda +trading/schema/field/sells = Vende +trading/schema/field/item = Objeto +trading/schema/field/price = Precio +trading/schema/field/buys = Compra diff --git a/locale/schema_ja.properties b/locale/schema_ja.properties new file mode 100644 index 0000000..2ae3b4e --- /dev/null +++ b/locale/schema_ja.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = 店を開く +trading/schema/builtin/trade_open_desc = その商人との交易ウィンドウ +trading/schema/field/shop = 店 +trading/schema/kind/shop = 店 +trading/schema/kind/shop_desc = 商人が売るもの・買うもの +trading/schema/field/name = 名前 +trading/schema/field/currency = 通貨 +trading/schema/field/sells = 売る品 +trading/schema/field/item = アイテム +trading/schema/field/price = 価格 +trading/schema/field/buys = 買う品 diff --git a/locale/schema_ko.properties b/locale/schema_ko.properties new file mode 100644 index 0000000..dbcad1d --- /dev/null +++ b/locale/schema_ko.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = 상점 열기 +trading/schema/builtin/trade_open_desc = 그 상인과의 거래 창 +trading/schema/field/shop = 상점 +trading/schema/kind/shop = 상점 +trading/schema/kind/shop_desc = 상인이 팔고 사는 것 +trading/schema/field/name = 이름 +trading/schema/field/currency = 화폐 +trading/schema/field/sells = 판매 +trading/schema/field/item = 아이템 +trading/schema/field/price = 가격 +trading/schema/field/buys = 구매 diff --git a/locale/schema_ru.properties b/locale/schema_ru.properties new file mode 100644 index 0000000..a83cd30 --- /dev/null +++ b/locale/schema_ru.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = Открыть лавку +trading/schema/builtin/trade_open_desc = Окно торговли с выбранным торговцем +trading/schema/field/shop = Лавка +trading/schema/kind/shop = Лавки +trading/schema/kind/shop_desc = Что продают и скупают торговцы +trading/schema/field/name = Название +trading/schema/field/currency = Валюта +trading/schema/field/sells = Продаёт +trading/schema/field/item = Предмет +trading/schema/field/price = Цена +trading/schema/field/buys = Покупает diff --git a/locale/schema_vi.properties b/locale/schema_vi.properties new file mode 100644 index 0000000..f14fbf7 --- /dev/null +++ b/locale/schema_vi.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = Mở cửa hàng +trading/schema/builtin/trade_open_desc = Cửa sổ giao dịch với thương nhân +trading/schema/field/shop = Cửa hàng +trading/schema/kind/shop = Cửa hàng +trading/schema/kind/shop_desc = Thương nhân bán gì, mua gì +trading/schema/field/name = Tên +trading/schema/field/currency = Tiền tệ +trading/schema/field/sells = Bán +trading/schema/field/item = Vật phẩm +trading/schema/field/price = Giá +trading/schema/field/buys = Mua diff --git a/locale/schema_zh.properties b/locale/schema_zh.properties new file mode 100644 index 0000000..1171863 --- /dev/null +++ b/locale/schema_zh.properties @@ -0,0 +1,11 @@ +trading/schema/builtin/trade_open = 打开商店 +trading/schema/builtin/trade_open_desc = 与该商人的交易窗口 +trading/schema/field/shop = 商店 +trading/schema/kind/shop = 商店 +trading/schema/kind/shop_desc = 商人卖什么、收什么 +trading/schema/field/name = 名称 +trading/schema/field/currency = 货币 +trading/schema/field/sells = 出售 +trading/schema/field/item = 物品 +trading/schema/field/price = 价格 +trading/schema/field/buys = 收购 diff --git a/schemas/trading.json b/schemas/trading.json new file mode 100644 index 0000000..f7ba8f6 --- /dev/null +++ b/schemas/trading.json @@ -0,0 +1,83 @@ +{ + "Actions": [ + { + "Id": "trade.open", + "Name": "trading/schema/builtin/trade_open", + "Description": "trading/schema/builtin/trade_open_desc", + "Category": "items", + "Params": [ + { + "Key": "shop", + "Type": "ref", + "Kind": "shop", + "Required": true, + "Name": "trading/schema/field/shop" + } + ] + } + ], + "Kinds": [ + { + "Kind": "shop", + "Name": "trading/schema/kind/shop", + "Description": "trading/schema/kind/shop_desc", + "Folder": "shops", + "NewId": "{mod}/new_shop", + "Order": 13, + "Fields": [ + { + "Key": "Name", + "Type": "locale", + "KeyPattern": "{mod}/shop/{id}", + "Name": "trading/schema/field/name" + }, + { + "Key": "Currency", + "Type": "ref", + "Kind": "item", + "Name": "trading/schema/field/currency" + }, + { + "Key": "Sells", + "Type": "list", + "Name": "trading/schema/field/sells", + "Of": [ + { + "Key": "Item", + "Type": "ref", + "Kind": "item", + "Required": true, + "Name": "trading/schema/field/item" + }, + { + "Key": "Price", + "Type": "int", + "Required": true, + "Name": "trading/schema/field/price" + } + ] + }, + { + "Key": "Buys", + "Type": "list", + "Name": "trading/schema/field/buys", + "Of": [ + { + "Key": "Item", + "Type": "ref", + "Kind": "item", + "Required": true, + "Name": "trading/schema/field/item" + }, + { + "Key": "Price", + "Type": "int", + "Required": true, + "Name": "trading/schema/field/price" + } + ] + } + ] + } + ] +} diff --git a/test_suites/trade/manifest.json b/test_suites/trade/manifest.json index 4c853dc..af55b36 100644 --- a/test_suites/trade/manifest.json +++ b/test_suites/trade/manifest.json @@ -1,6 +1,6 @@ { "name": "Trade Test", - "description": "Integration test of trading on the rpg_demo game: gathers brushwood, stones and a mushroom in the forest by walking onto them, heals the hero with the mushroom, talks to the village merchant whose dialog opens the trade window, sells the junk and buys an elixir by clicking the two inventories, checks that walking is blocked while the window is open and that Esc closes it. Activated by --itest=trade with --game=rpg_demo --new; --shots= saves screenshots (windowed runs only).", + "description": "Integration test of trading on the rpg_plus game (its rpg_demo_game world): gathers brushwood, stones and a mushroom in the forest by walking onto them, heals the hero with the mushroom, talks to the village merchant whose dialog opens the trade window, sells the junk and buys an elixir by clicking the two inventories, checks that walking is blocked while the window is open and that Esc closes it. Activated by --itest=trade with --game=rpg_plus --new (the prologue is clicked through first); --shots= saves screenshots (windowed runs only).", "sources": [ "src/*.cs" ], diff --git a/test_suites/trade/src/TradeTestDriver.cs b/test_suites/trade/src/TradeTestDriver.cs index 4a2d730..f7622e3 100644 --- a/test_suites/trade/src/TradeTestDriver.cs +++ b/test_suites/trade/src/TradeTestDriver.cs @@ -88,13 +88,18 @@ namespace Cthangover.Mods.Trading.Tests switch (step) { case 0: + if (Boot.IsReady && SkipPrologue()) + return; if (Boot.IsReady && View?.Map?.ID == Village) Next(); return; case 1: if (AdvanceDialog()) return; - Check(Inventory.CheckCount(Coin) == 0, "a new game starts without money"); + // The prologue gives a purse; the deals below count from an empty one. + if (Inventory.CheckCount(Coin) > 0) + Inventory.Remove(Coin, Inventory.CheckCount(Coin)); + Check(Inventory.CheckCount(Coin) == 0, "the purse is emptied for the test"); RpgWorldHost.Teleport(new RpgTeleport { Map = Forest, X = 6, Y = 4, Dir = RpgDirection.Down }); Next(); return; @@ -292,6 +297,26 @@ namespace Cthangover.Mods.Trading.Tests } /// Advances a running dialog with the action key; true while it is still running. + /// + /// The game opens with a novel-style prologue (no map yet): its lines are clicked + /// through and every choice takes the first answer. True while it runs. + /// + private static bool SkipPrologue() + { + // Asking for the dialog box before the first scene is up caches the wrong node. + var scene = ((SceneTree)Engine.GetMainLoop()).Root.GetNodeOrNull("SceneManager")?.CurrentSceneName; + if (string.IsNullOrEmpty(scene) || RpgWorldHost.Current?.View?.Map != null) + return false; + var box = RpgInput.FindDialogBox(); + if (box == null || !box.IsRunning) + return false; + if (box.IsWaitingAnswer) + box.TrySelectVariant(0); + else + box.NextAction(); + return true; + } + private static bool AdvanceDialog() { var box = RpgInput.FindDialogBox();