From eef8225cfd400c8d35be119ef6ee65ddeda415fa Mon Sep 17 00:00:00 2001 From: Fulldroper <40297614+Fulldroper@users.noreply.github.com> Date: Sat, 3 Oct 2026 06:32:31 +0300 Subject: [PATCH] 0.6.0: in-game tutorial in Create's Ponder style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Ponder for KubeJS 2.4.0 (client) + client_scripts/createrp_ponder.js: six scenes (terminal, selling, buying, money and bank, land and ore, jobs) on «Довідник громадянина», frogport and CC computers, plus a «Держава Create RP» tag in the Ponder index - startup_scripts/createrp_items.js registers kubejs:citizen_guide (identical in the server pack) Co-Authored-By: Claude Opus 5.5 --- index.toml | 13 ++ kubejs/client_scripts/createrp_ponder.js | 264 +++++++++++++++++++++++ kubejs/startup_scripts/createrp_items.js | 12 ++ mods/ponder.pw.toml | 13 ++ pack.toml | 4 +- 5 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 kubejs/client_scripts/createrp_ponder.js create mode 100644 kubejs/startup_scripts/createrp_items.js create mode 100644 mods/ponder.pw.toml diff --git a/index.toml b/index.toml index 9ffc625..d624cba 100644 --- a/index.toml +++ b/index.toml @@ -812,6 +812,14 @@ hash = "19b844245d03fcdd488a7a791e287447191a74acd0f14995209339d768c5e6ce" file = "kubejs/assets/computercraft/textures/gui/term_font.png" hash = "db4c4a8ab49265f6e8e456f495800ea148b133b18a3242aabca30b98ab7f784f" +[[files]] +file = "kubejs/client_scripts/createrp_ponder.js" +hash = "193c9f8b283e32f85504f8b198869d80f6ba1647924884a7f0db7de5eb8c6b47" + +[[files]] +file = "kubejs/startup_scripts/createrp_items.js" +hash = "58100f02cf749b138c2a91567df37afce4b2ef494738268963e8443a3e603036" + [[files]] file = "mods/3dskinlayers.pw.toml" hash = "82becc6910845ae1a68884e6f7a3dcdc861d79a087ae81b1d7e120e82884372d" @@ -1242,6 +1250,11 @@ file = "mods/polytone.pw.toml" hash = "636f08c84e9a1e1793850aa4f2390e5ece8fc25abee1d5d83679f3813e113802" metafile = true +[[files]] +file = "mods/ponder.pw.toml" +hash = "5ead8d8bc26cdbe1a17dc055f7f0fe762a08254d0199d6ea8fcc58839ab274f2" +metafile = true + [[files]] file = "mods/puzzles-lib.pw.toml" hash = "6812c3faa178cd48c65c5b8e7aeef50bc0b63d8e3b2117065d6179a43d8d3649" diff --git a/kubejs/client_scripts/createrp_ponder.js b/kubejs/client_scripts/createrp_ponder.js new file mode 100644 index 0000000..b72c172 --- /dev/null +++ b/kubejs/client_scripts/createrp_ponder.js @@ -0,0 +1,264 @@ +// Create RP — туторіал у стилі Create (Ponder): наведи на предмет і затисни W. +// Потрібні PonderJS (мод «Ponder for KubeJS») і startup_scripts/createrp_items.js (предмет kubejs:citizen_guide). +// Сцени будуються на стандартній плиті 5x5: y=0 — плита, блоки з y=1. Текст: _слово_ — підсвітка, як у Create. + +const PACKAGE = 'create:cardboard_package_10x12' + +// посилка «летить» від однієї пакужаби до іншої: лінія маршруту + предмет-посилка +function sendPackage(scene, from, to, ticks) { + scene.overlay.showBigLine(PonderPalette.OUTPUT, from, to, ticks) + const dx = (to[0] - from[0]) / ticks, dy = 0.22, dz = (to[2] - from[2]) / ticks + const box = scene.world.createItemEntity(from, [dx, dy, dz], PACKAGE) + scene.idle(ticks) + scene.world.removeEntity(box) +} + +// --------------------------------------------------------------------------------------------- +// 1. Термінал держави + +function terminalScene(scene, util) { + scene.showBasePlate() + scene.world.setBlocks([2, 1, 2], 'computercraft:computer_advanced') + scene.world.setBlocks([1, 1, 3, 3, 2, 3], 'computercraft:monitor_advanced') + scene.idle(10) + scene.world.showSection([2, 1, 2], Direction.DOWN) + scene.idle(15) + + scene.text(80, 'Будь-який _комп\'ютер_ — це термінал держави. Відкрий його й набери _rp_.', [2.5, 1.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.showControls(60, [2.5, 2, 2.5], 'down').rightClick() + scene.idle(90) + + scene.text(90, 'Вхід — твій _нік_ і _пароль_. Першого разу термінал попросить створити пароль. Стій поруч із комп\'ютером — здалеку не пустить.', [2.5, 1.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(100) + + scene.text(90, 'У меню: _рахунок_, _бізнес_, _ціни_, _магазин_, _земля_, _робота_, _тендери_, _банк_. Стрілки й Enter, Backspace — назад.', [2.5, 1.5, 2.5]) + .placeNearTarget() + scene.idle(100) + + scene.world.showSection([1, 1, 3, 3, 2, 3], Direction.DOWN) + scene.idle(15) + scene.text(90, 'Комп\'ютер з _монітором_ — табло цін держави: програма _prices metal_ (або stone, wood, farm, food, create…).', [2, 2.5, 3]) + .colored(PonderPalette.BLUE).placeNearTarget().attachKeyFrame() + scene.idle(100) +} + +// --------------------------------------------------------------------------------------------- +// 2. Продаж державі + +function sellScene(scene, util) { + scene.showBasePlate() + // бізнес ліворуч: сховище → пакувальник → пакужаба; держава праворуч + scene.world.setBlocks([0, 1, 2], 'minecraft:barrel') + scene.world.setBlocks([1, 1, 2], 'create:packager') + scene.world.setBlocks([1, 2, 2], 'create:package_frogport') + scene.world.setBlocks([3, 1, 2], 'create:packager') + scene.world.setBlocks([3, 2, 2], 'create:package_frogport') + scene.idle(10) + + scene.world.showSection([0, 1, 2], Direction.DOWN) + scene.idle(5) + scene.world.showSection([1, 1, 2], Direction.DOWN) + scene.idle(5) + scene.world.showSection([1, 2, 2], Direction.DOWN) + scene.idle(15) + + scene.text(90, 'Держава _купує_ все, що добувають і виробляють: руду, метали, будматеріали, їжу, деталі Create.', [1.5, 2.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(100) + + scene.text(100, 'Адреса продажу твого бізнесу — _gov-…_ (термінал → Бізнес → Адреса продажу). Познач нею пакувальник табличкою або в замовленні.', [1.5, 1.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.showControls(70, [1.5, 1.8, 2], 'down').rightClick().withItem('minecraft:oak_sign') + scene.idle(110) + + scene.world.showSection([3, 1, 2, 3, 2, 2], Direction.DOWN) + scene.idle(15) + scene.text(90, '_Державна пакужаба_ приймає посилки на всі адреси gov-… Під нею — державний приймач.', [3.5, 2.5, 2.5]) + .colored(PonderPalette.BLUE).placeNearTarget().attachKeyFrame() + scene.idle(100) + + sendPackage(scene, [1.5, 3, 2.5], [3.5, 3, 2.5], 30) + scene.idle(5) + + scene.text(100, 'Гроші приходять на _рахунок бізнесу_. Товару забагато — ціна падає, дефіцит — росте. Ціни — на табло й у терміналі.', [3.5, 1.5, 2.5]) + .colored(PonderPalette.GREEN).placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.text(80, 'Усе автоматизується: ланцюги, поїзди, ферми — продаж іде, поки ти робиш інше.', [2.5, 3.5, 2.5]) + scene.idle(90) +} + +// --------------------------------------------------------------------------------------------- +// 3. Покупка в держави + +function buyScene(scene, util) { + scene.showBasePlate() + scene.world.setBlocks([3, 1, 2], 'create:packager') + scene.world.setBlocks([3, 2, 2], 'create:package_frogport') + scene.world.setBlocks([0, 1, 2], 'minecraft:chest') + scene.world.setBlocks([1, 1, 2], 'create:packager') + scene.world.setBlocks([1, 2, 2], 'create:package_frogport') + scene.idle(10) + + scene.world.showSection([3, 1, 2, 3, 2, 2], Direction.DOWN) + scene.idle(15) + scene.text(90, 'Держава продає _імпорт_ (алмази, незерит, елітри…) і _ліцензії_. Купівля — термінал → Магазин держави.', [3.5, 2.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(100) + + scene.world.showSection([0, 1, 2], Direction.DOWN) + scene.idle(5) + scene.world.showSection([1, 1, 2, 1, 2, 2], Direction.DOWN) + scene.idle(15) + scene.text(100, 'Під час покупки вкажи _адресу своєї пакужаби_ — так, як вона названа. Термінал запам\'ятає її.', [1.5, 2.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.text(60, 'Товар виїжджає з _державного складу_…', [3.5, 3, 2.5]).colored(PonderPalette.BLUE) + scene.idle(20) + sendPackage(scene, [3.5, 3, 2.5], [1.5, 3, 2.5], 30) + scene.idle(20) + + scene.text(100, '…і приходить посилкою. _Пакувальник_ під твоєю пакужабою розпакує її у скриню.', [0.5, 1.5, 2.5]) + .colored(PonderPalette.GREEN).placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.text(80, 'Не дійшла? Гроші _повертаються_ автоматично, а в чаті буде причина.', [2.5, 3.5, 2.5]) + scene.idle(90) +} + +// --------------------------------------------------------------------------------------------- +// 4. Гроші й банк + +function moneyScene(scene, util) { + scene.showBasePlate() + scene.world.setBlocks([2, 1, 2], 'computercraft:computer_advanced') + scene.world.showSection([2, 1, 2], Direction.DOWN) + scene.idle(15) + + scene.text(90, 'Твої гроші — на _рахунку_ в державному банку. Баланс і перекази — термінал → Рахунок.', [2.5, 1.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(100) + + const coins = ['numismatics:spur', 'numismatics:bevel', 'numismatics:sprocket', 'numismatics:cog'] + for (let i = 0; i < coins.length; i++) { + scene.world.createItemEntity([1 + i, 3, 1], [0, 0.1, 0], coins[i]) + scene.idle(5) + } + scene.idle(10) + scene.text(110, '_Готівка_ — монети: зняти /cash withdraw <сума>, покласти — /cash deposit з монетами в руці. Готівкою платять одне одному з рук.', [2.5, 2, 1.5]) + .colored(PonderPalette.GREEN).placeNearTarget().attachKeyFrame() + scene.idle(120) + + scene.text(100, '_Банк_ (термінал → Банк): стартовий та інвестиційний кредити для бізнесу, вклади під відсоток щодня.', [2.5, 1.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.text(90, 'Кредит платиться щоденними внесками. Пропустиш тричі — _дефолт_: рахунок бізнесу заморожено, тендери заборонені.', [2.5, 1.5, 2.5]) + .colored(PonderPalette.RED).placeNearTarget() + scene.idle(100) +} + +// --------------------------------------------------------------------------------------------- +// 5. Земля й надра + +function landScene(scene, util) { + scene.showBasePlate() + scene.world.setBlocks([1, 1, 1], 'minecraft:oak_fence') + scene.world.setBlocks([3, 1, 1], 'minecraft:oak_fence') + scene.world.setBlocks([1, 1, 3], 'minecraft:oak_fence') + scene.world.setBlocks([3, 1, 3], 'minecraft:oak_fence') + scene.world.setBlocks([2, 1, 2], 'minecraft:iron_ore') + scene.idle(10) + + scene.text(90, 'Уся незареєстрована земля _належить державі_. Будувати можна на своїх ділянках.', [2.5, 1, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(100) + + scene.overlay.showOutline(PonderPalette.GREEN, 'plot', util.select.fromTo(0, 0, 0, 4, 0, 4), 120) + scene.world.showSection([1, 1, 1, 3, 1, 3], Direction.DOWN) + scene.text(110, '_Ділянки_ орендують на ігрові дні або викуповують: термінал → Земля. Заходячи на ділянку, бачиш її назву над хотбаром.', [2.5, 1.5, 2.5]) + .colored(PonderPalette.GREEN).placeNearTarget().attachKeyFrame() + scene.idle(120) + + scene.text(100, 'Орендована ділянка — _приват_ бізнесу: чужі не ламають, а твої працівники мають доступ.', [2.5, 1.5, 2.5]) + .placeNearTarget() + scene.idle(110) + + scene.overlay.showOutline(PonderPalette.RED, 'ore', util.select.position(2, 1, 2), 100) + scene.text(100, '_Руда_ видобувається за _концесією_: купи дозвіл на руду й квоту на ділянці (термінал → Земля → Купити концесію).', [2.5, 1.5, 2.5]) + .colored(PonderPalette.RED).placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.text(80, 'За землю щодня — орендна плата або податок. Не заплатив 3 дні — ділянка повертається державі.', [2.5, 2.5, 2.5]) + scene.idle(90) +} + +// --------------------------------------------------------------------------------------------- +// 6. Робота: ринок праці і пошта + +function jobsScene(scene, util) { + scene.showBasePlate() + scene.idle(10) + const post = scene.world.createEntity('minecraft:villager', [1, 1, 2.5]) + scene.idle(10) + + scene.text(90, 'Немає роботи? Термінал → Робота → _ринок праці_: допомога по безробіттю щодня, якщо ти був активний у грі.', [2.5, 2.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(100) + + scene.text(90, 'Хочеш заробляти більше — стань _поштарем_. Клікни по NPC пошти.', [1, 2.5, 2.5]) + .colored(PonderPalette.BLUE).placeNearTarget().attachKeyFrame() + scene.showControls(60, [1, 2.3, 2.5], 'down').rightClick() + scene.idle(70) + + scene.world.createItemEntity([1.5, 2, 2.5], [0.05, 0.25, 0], PACKAGE) + scene.world.createItemEntity([1.5, 2, 2.5], [0.03, 0.3, 0.03], 'minecraft:compass') + scene.idle(20) + scene.text(100, 'Отримаєш _посилку_ з іменем адресата й _компас_, що вказує на нього. ПКМ компасом — мітка на місці (видно лише тобі).', [2, 1.5, 2.5]) + .placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.world.createEntity('minecraft:villager', [4, 1, 2.5]) + scene.overlay.showBigLine(PonderPalette.OUTPUT, [1.5, 1.2, 2.5], [4, 1.2, 2.5], 80) + scene.text(100, 'Адресат чекає в іншій частині світу. Принеси посилку й клікни по ньому — гроші на рахунок. Що далі, то дорожче.', [4, 2.5, 2.5]) + .colored(PonderPalette.GREEN).placeNearTarget().attachKeyFrame() + scene.idle(110) + + scene.text(80, 'На доставку — _2 ігрові дні_. Не встиг — адресат поїде, і посилка згорить.', [2.5, 2.5, 2.5]) + .colored(PonderPalette.RED) + scene.idle(90) + + scene.text(90, 'Або наймися до бізнесу: власник пропонує зарплату, ти приймаєш у терміналі → Бізнес → Прийняти запрошення.', [2.5, 2.5, 2.5]) + scene.idle(100) +} + +// --------------------------------------------------------------------------------------------- + +Ponder.tags(event => { + event.createTag('kubejs:createrp', 'kubejs:citizen_guide', 'Держава Create RP', + 'Як жити й заробляти в державній економіці: термінал, продаж і покупки посилками, гроші, земля, робота.', + ['kubejs:citizen_guide', 'create:package_frogport', 'computercraft:computer_advanced', 'computercraft:computer_normal', 'computercraft:monitor_advanced']) +}) + +Ponder.registry(event => { + event.create('kubejs:citizen_guide') + .scene('guide_terminal', 'Термінал держави', terminalScene) + .scene('guide_sell', 'Продаж державі', sellScene) + .scene('guide_buy', 'Покупки в держави', buyScene) + .scene('guide_money', 'Гроші й банк', moneyScene) + .scene('guide_land', 'Земля й надра', landScene) + .scene('guide_jobs', 'Робота: ринок праці й пошта', jobsScene) + + event.create('create:package_frogport') + .scene('frogport_sell', 'Create RP: продаж державі', sellScene) + .scene('frogport_buy', 'Create RP: покупки в держави', buyScene) + + event.create(['computercraft:computer_advanced', 'computercraft:computer_normal']) + .scene('computer_terminal', 'Create RP: термінал держави', terminalScene) + + event.create('computercraft:monitor_advanced') + .scene('monitor_terminal', 'Create RP: термінал і табло цін', terminalScene) +}) diff --git a/kubejs/startup_scripts/createrp_items.js b/kubejs/startup_scripts/createrp_items.js new file mode 100644 index 0000000..93a11d8 --- /dev/null +++ b/kubejs/startup_scripts/createrp_items.js @@ -0,0 +1,12 @@ +// Create RP — предмети збірки. Цей файл має бути ОДНАКОВИМ у серверній і клієнтській збірках: +// реєстр предметів сервера й клієнта мусить збігатися. + +StartupEvents.registry('item', event => { + // «Довідник громадянина»: навести в інвентарі й затиснути W — туторіал Ponder (клієнтський client_scripts/createrp_ponder.js) + event.create('citizen_guide') + .displayName('Довідник громадянина') + .texture('minecraft:item/knowledge_book') + .maxStackSize(1) + .glow(true) + .tooltip('§7Наведи в інвентарі й затисни §fW§7 — як у Create') +}) diff --git a/mods/ponder.pw.toml b/mods/ponder.pw.toml new file mode 100644 index 0000000..bcb5c4f --- /dev/null +++ b/mods/ponder.pw.toml @@ -0,0 +1,13 @@ +name = "Ponder for KubeJS" +filename = "ponderjs-neoforge-1.21.1-2.4.0.jar" +side = "client" + +[download] +url = "https://cdn.modrinth.com/data/5A34Stj8/versions/BqhDf7W8/ponderjs-neoforge-1.21.1-2.4.0.jar" +hash-format = "sha512" +hash = "6390c4bf631561c29a76b8b29a496d4b984bf847572940b28e551f2c2e3da4a8fb04b6a82cf98a7935792a7d3485cdc45c76f2bdf7f93799210262ba5f184955" + +[update] +[update.modrinth] +mod-id = "5A34Stj8" +version = "BqhDf7W8" diff --git a/pack.toml b/pack.toml index fef756b..0de1976 100644 --- a/pack.toml +++ b/pack.toml @@ -1,12 +1,12 @@ name = "Create RP" author = "Pinecraft-CreateRP" -version = "0.5.0" +version = "0.6.0" pack-format = "packwiz:1.1.0" [index] file = "index.toml" hash-format = "sha256" -hash = "5efee6e704068bfd1642a913e0812e57f779941fd2c6d043c66c738351447a78" +hash = "6502e1eebae1d8993f10f350f6d1ffe6554b04211de7f0646bbcc2212a6c2852" [versions] minecraft = "1.21.1"