From 773d14406c4cd752aef65d9326812c7199084706 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 26 Dec 2024 17:53:04 +0300 Subject: [PATCH 1/6] feat: add base:loot property (WIP) --- res/content/base/blocks/grass.json | 3 ++- res/content/base/blocks/grass_block.json | 5 ++++- res/content/base/config/user-props.toml | 1 + res/content/base/modules/util.lua | 23 +++++++++++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/res/content/base/blocks/grass.json b/res/content/base/blocks/grass.json index 7308d1a1..52bfb11d 100644 --- a/res/content/base/blocks/grass.json +++ b/res/content/base/blocks/grass.json @@ -9,5 +9,6 @@ "grounded": true, "model": "X", "hitbox": [0.15, 0.0, 0.15, 0.7, 0.7, 0.7], - "base:durability": 0.0 + "base:durability": 0.0, + "base:drop": [] } diff --git a/res/content/base/blocks/grass_block.json b/res/content/base/blocks/grass_block.json index a6087afc..e89a774c 100644 --- a/res/content/base/blocks/grass_block.json +++ b/res/content/base/blocks/grass_block.json @@ -8,5 +8,8 @@ "grass_side", "grass_side" ], - "base:durability": 1.3 + "base:durability": 1.3, + "base:loot": [ + {"item": "base:dirt.item"} + ] } diff --git a/res/content/base/config/user-props.toml b/res/content/base/config/user-props.toml index b7306ba1..eab7a628 100644 --- a/res/content/base/config/user-props.toml +++ b/res/content/base/config/user-props.toml @@ -1 +1,2 @@ "base:durability" = {} +"base:loot" = {} diff --git a/res/content/base/modules/util.lua b/res/content/base/modules/util.lua index 2112c210..2a8326ec 100644 --- a/res/content/base/modules/util.lua +++ b/res/content/base/modules/util.lua @@ -11,4 +11,27 @@ function util.drop(ppos, itemid, count, pickup_delay) }}) end +local function calc_loot(loot_table) + local results = {} + for _, loot in ipairs(loot_table) do + local chance = loot.chance or 1 + local count = loot.count or 1 + + local roll = math.random() + + if roll < chance then + table.insert(results, {item=loot.item, count=count}) + end + end + return results +end + +function util.block_loot(blockid) + local lootscheme = block.properties[blockid]["base:loot"] + if lootscheme then + return calc_loot(lootscheme) + end + return {{block.get_picking_item(blockid), 1}} +end + return util From ef777542b139c0ac31eef98f214951df9a18cfcc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 26 Dec 2024 18:23:19 +0300 Subject: [PATCH 2/6] fix --- res/content/base/blocks/grass.json | 2 +- res/content/base/modules/util.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/content/base/blocks/grass.json b/res/content/base/blocks/grass.json index 52bfb11d..e55bc2ac 100644 --- a/res/content/base/blocks/grass.json +++ b/res/content/base/blocks/grass.json @@ -10,5 +10,5 @@ "model": "X", "hitbox": [0.15, 0.0, 0.15, 0.7, 0.7, 0.7], "base:durability": 0.0, - "base:drop": [] + "base:loot": [] } diff --git a/res/content/base/modules/util.lua b/res/content/base/modules/util.lua index 2a8326ec..6dfa90a6 100644 --- a/res/content/base/modules/util.lua +++ b/res/content/base/modules/util.lua @@ -20,7 +20,7 @@ local function calc_loot(loot_table) local roll = math.random() if roll < chance then - table.insert(results, {item=loot.item, count=count}) + table.insert(results, {item=item.index(loot.item), count=count}) end end return results @@ -31,7 +31,7 @@ function util.block_loot(blockid) if lootscheme then return calc_loot(lootscheme) end - return {{block.get_picking_item(blockid), 1}} + return {{item=block.get_picking_item(blockid), count=1}} end return util From 8aa55cff2788f9a1033197bd2119bb3513ff9789 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 26 Dec 2024 18:32:11 +0300 Subject: [PATCH 3/6] add 'do-loot-non-player' rule to base pack --- res/content/base/scripts/world.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/content/base/scripts/world.lua b/res/content/base/scripts/world.lua index 3f69dc44..4b78a3f1 100644 --- a/res/content/base/scripts/world.lua +++ b/res/content/base/scripts/world.lua @@ -11,4 +11,6 @@ function on_block_broken(id, x, y, z, playerid) spawn_spread={0.4, 0.4, 0.4} }) end + + rules.create("do-loot-non-player", true) end From ebea9af38037d30a0657a5cc14fe634590242755 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 29 Dec 2024 08:56:47 +0300 Subject: [PATCH 4/6] add '...@append' method to block properties --- doc/en/block-properties.md | 8 +++++++ doc/ru/block-properties.md | 8 +++++++ src/content/ContentBuilder.cpp | 2 +- src/content/ContentLoader.cpp | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/doc/en/block-properties.md b/doc/en/block-properties.md index 87df173b..8011e9cc 100644 --- a/doc/en/block-properties.md +++ b/doc/en/block-properties.md @@ -213,3 +213,11 @@ User properties must be declared in `pack:config/user-props.toml` file: ``` Example: [user properties of pack **base**](../../res/content/base/config/user-props.toml). + +## Methods + +Methods are used to manage the overwriting of properties when extending a block with other packs. + +### `property_name@append` + +Adds elements to the end of the list instead of completely overwriting it. diff --git a/doc/ru/block-properties.md b/doc/ru/block-properties.md index 2f958e88..71d7cea3 100644 --- a/doc/ru/block-properties.md +++ b/doc/ru/block-properties.md @@ -224,3 +224,11 @@ ``` Пример: [пользовательские свойства пака **base**](../../res/content/base/config/user-props.toml). + +## Методы + +Методы используются для управлением перезаписью свойств при расширении блока другими паками. + +### `имя_свойства@append` + +Добавляет элементы в конец списка, вместо его полной перезаписи. diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index 63308578..49433dfd 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -93,8 +93,8 @@ std::unique_ptr ContentBuilder::build() { def->rt.surfaceReplacement = content->blocks.require(def->surfaceReplacement).rt.id; if (def->properties == nullptr) { def->properties = dv::object(); + def->properties["name"] = def->name; } - def->properties["name"] = def->name; } for (ItemDef* def : itemDefsIndices) { diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 1dc676ea..1b650f1d 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -187,11 +187,49 @@ static void perform_user_block_fields( layout = StructLayout::create(fields); } +static void process_method( + dv::value& properties, + const std::string& method, + const std::string& name, + const dv::value& value +) { + if (method == "append") { + if (!properties.has(name)) { + properties[name] = dv::list(); + } + auto& list = properties[name]; + if (value.isList()) { + for (const auto& item : value) { + list.add(item); + } + } else { + list.add(value); + } + } else { + throw std::runtime_error( + "unknown method " + method + " for " + name + ); + } +} + void ContentLoader::loadBlock( Block& def, const std::string& name, const fs::path& file ) { auto root = files::read_json(file); - def.properties = root; + if (def.properties == nullptr) { + def.properties = dv::object(); + def.properties["name"] = name; + } + for (auto& [key, value] : root.asObject()) { + auto pos = key.rfind('@'); + if (pos == std::string::npos) { + def.properties[key] = value; + continue; + } + auto field = key.substr(0, pos); + auto suffix = key.substr(pos + 1); + process_method(def.properties, suffix, field, value); + } if (root.has("parent")) { const auto& parentName = root["parent"].asString(); From f744c87c8e56eecb652c0322539d125384b02843 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 29 Dec 2024 09:04:10 +0300 Subject: [PATCH 5/6] add loot count 'min' and 'max' --- res/content/base/modules/util.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/res/content/base/modules/util.lua b/res/content/base/modules/util.lua index 6dfa90a6..d12337fb 100644 --- a/res/content/base/modules/util.lua +++ b/res/content/base/modules/util.lua @@ -20,8 +20,15 @@ local function calc_loot(loot_table) local roll = math.random() if roll < chance then + if loot.min and loot.max then + count = math.random(loot.min, loot.max) + end + if count == 0 then + goto continue + end table.insert(results, {item=item.index(loot.item), count=count}) end + ::continue:: end return results end From 7044c12da59607db7e6fcc63502c64dff3ebad84 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 29 Dec 2024 09:22:35 +0300 Subject: [PATCH 6/6] update doc/*/block-properties.md --- doc/en/block-properties.md | 28 ++++++++++++++++++++++++++++ doc/ru/block-properties.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/doc/en/block-properties.md b/doc/en/block-properties.md index 8011e9cc..f5478e0b 100644 --- a/doc/en/block-properties.md +++ b/doc/en/block-properties.md @@ -214,6 +214,34 @@ User properties must be declared in `pack:config/user-props.toml` file: Example: [user properties of pack **base**](../../res/content/base/config/user-props.toml). +## Properties introduced by the `base` pack + +### *base:durability* + +The time it takes to break a block without tools or effects, measured in seconds. + +### Loot - *base:loot* + +A list of tables with properties: + +```json +{ + "item": "pack:item", + "min": 1, + "max": 3, + "chance": 0.5 +} +``` + +- `count` defaults to 1. It does not need to be specified if `min` and `max` are provided. +- `min`, `max` - the minimum and maximum quantity of the item. +- `chance` - the probability of the item dropping. Defaults to 1.0. + +It should be noted that the `item` refers specifically to the item. That is, to specify the item of a block, you need to add `.item` after the block name. +Example: `base:dirt.item`. + +To generate loot, the function `block_loot(block_id: int)` in the `base:util` module should be used. + ## Methods Methods are used to manage the overwriting of properties when extending a block with other packs. diff --git a/doc/ru/block-properties.md b/doc/ru/block-properties.md index 71d7cea3..3b75759e 100644 --- a/doc/ru/block-properties.md +++ b/doc/ru/block-properties.md @@ -225,6 +225,34 @@ Пример: [пользовательские свойства пака **base**](../../res/content/base/config/user-props.toml). +## Свойства, вводимые паком `base` + +### Прочность - *base:durability* + +Время разрушения блока без инструментов и эффектов в секундах. + +### Лут - *base:loot* + +Список таблиц со свойствами: + +```json +{ + "item": "пак:предмет", + "min": 1, + "max": 3, + "chance": 0.5 +} +``` + +- count равен 1 по-умолчанию. Не нужно указывать если указаны `min` и `max`. +- min, max - минимальное и максимальное количество предмета. +- chance - вероятность выпадения предмета. По-умолчанию: 1.0. + +Следует учитывать, что в item указывается именно предмет. Т.е. чтобы указать предмет блока, нужно добавить `.item` после имени блока. +Пример: `base:dirt.item`. + +Для генерации лута следует использовать функцию `block_loot(block_id: int)` в модуле `base:util`. + ## Методы Методы используются для управлением перезаписью свойств при расширении блока другими паками.