Merge pull request #422 from MihailRis/base-loot-property
Add base:loot property
This commit is contained in:
commit
7132bb0758
@ -213,3 +213,39 @@ 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).
|
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.
|
||||||
|
|
||||||
|
### `property_name@append`
|
||||||
|
|
||||||
|
Adds elements to the end of the list instead of completely overwriting it.
|
||||||
|
|||||||
@ -224,3 +224,39 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
Пример: [пользовательские свойства пака **base**](../../res/content/base/config/user-props.toml).
|
Пример: [пользовательские свойства пака **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`.
|
||||||
|
|
||||||
|
## Методы
|
||||||
|
|
||||||
|
Методы используются для управлением перезаписью свойств при расширении блока другими паками.
|
||||||
|
|
||||||
|
### `имя_свойства@append`
|
||||||
|
|
||||||
|
Добавляет элементы в конец списка, вместо его полной перезаписи.
|
||||||
|
|||||||
@ -9,5 +9,6 @@
|
|||||||
"grounded": true,
|
"grounded": true,
|
||||||
"model": "X",
|
"model": "X",
|
||||||
"hitbox": [0.15, 0.0, 0.15, 0.7, 0.7, 0.7],
|
"hitbox": [0.15, 0.0, 0.15, 0.7, 0.7, 0.7],
|
||||||
"base:durability": 0.0
|
"base:durability": 0.0,
|
||||||
|
"base:loot": []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,5 +8,8 @@
|
|||||||
"grass_side",
|
"grass_side",
|
||||||
"grass_side"
|
"grass_side"
|
||||||
],
|
],
|
||||||
"base:durability": 1.3
|
"base:durability": 1.3,
|
||||||
|
"base:loot": [
|
||||||
|
{"item": "base:dirt.item"}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
"base:durability" = {}
|
"base:durability" = {}
|
||||||
|
"base:loot" = {}
|
||||||
|
|||||||
@ -11,4 +11,34 @@ function util.drop(ppos, itemid, count, pickup_delay)
|
|||||||
}})
|
}})
|
||||||
end
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
function util.block_loot(blockid)
|
||||||
|
local lootscheme = block.properties[blockid]["base:loot"]
|
||||||
|
if lootscheme then
|
||||||
|
return calc_loot(lootscheme)
|
||||||
|
end
|
||||||
|
return {{item=block.get_picking_item(blockid), count=1}}
|
||||||
|
end
|
||||||
|
|
||||||
return util
|
return util
|
||||||
|
|||||||
@ -11,4 +11,6 @@ function on_block_broken(id, x, y, z, playerid)
|
|||||||
spawn_spread={0.4, 0.4, 0.4}
|
spawn_spread={0.4, 0.4, 0.4}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rules.create("do-loot-non-player", true)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -93,8 +93,8 @@ std::unique_ptr<Content> ContentBuilder::build() {
|
|||||||
def->rt.surfaceReplacement = content->blocks.require(def->surfaceReplacement).rt.id;
|
def->rt.surfaceReplacement = content->blocks.require(def->surfaceReplacement).rt.id;
|
||||||
if (def->properties == nullptr) {
|
if (def->properties == nullptr) {
|
||||||
def->properties = dv::object();
|
def->properties = dv::object();
|
||||||
|
def->properties["name"] = def->name;
|
||||||
}
|
}
|
||||||
def->properties["name"] = def->name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ItemDef* def : itemDefsIndices) {
|
for (ItemDef* def : itemDefsIndices) {
|
||||||
|
|||||||
@ -187,11 +187,49 @@ static void perform_user_block_fields(
|
|||||||
layout = StructLayout::create(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(
|
void ContentLoader::loadBlock(
|
||||||
Block& def, const std::string& name, const fs::path& file
|
Block& def, const std::string& name, const fs::path& file
|
||||||
) {
|
) {
|
||||||
auto root = files::read_json(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")) {
|
if (root.has("parent")) {
|
||||||
const auto& parentName = root["parent"].asString();
|
const auto& parentName = root["parent"].asString();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user