mirror of
https://github.com/sys4-fr/server-nalc.git
synced 2024-12-25 02:00:37 +01:00
Added treasurer and forceload as directories
This commit is contained in:
parent
9538856d06
commit
99d0640d25
9
mods/forceload/README.md
Normal file
9
mods/forceload/README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Forceload Mod
|
||||||
|
=============
|
||||||
|
|
||||||
|
This mod allows areas in the map to be keep loaded.
|
||||||
|
Use the forceload:anchor block.
|
||||||
|
|
||||||
|
Created by rubenwardy
|
||||||
|
|
||||||
|
License: LGPL 2.1 or later
|
156
mods/forceload/init.lua
Normal file
156
mods/forceload/init.lua
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
local _pts = minetest.pos_to_string
|
||||||
|
function minetest.pos_to_string(pos)
|
||||||
|
if not pos then
|
||||||
|
return "(-,-,-)"
|
||||||
|
end
|
||||||
|
return _pts(pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Makes sure that force load areas are handled correctly
|
||||||
|
function ForceloadManager(filetoopen, hide_file_errors)
|
||||||
|
local blocks = {}
|
||||||
|
if filetoopen ~= nil then
|
||||||
|
local file = io.open(filetoopen, "r")
|
||||||
|
if file then
|
||||||
|
local table = minetest.deserialize(file:read("*all"))
|
||||||
|
file:close()
|
||||||
|
if type(table) == "table" then
|
||||||
|
blocks = table
|
||||||
|
end
|
||||||
|
elseif not hide_file_errors then
|
||||||
|
minetest.log("error", "File "..filetoopen.." does not exist!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i = 1, #blocks do
|
||||||
|
if not minetest.forceload_block(blocks[i]) then
|
||||||
|
minetest.log("error", "Failed to load block " .. minetest.pos_to_string(blocks[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
_blocks = blocks,
|
||||||
|
load = function(self, pos)
|
||||||
|
if minetest.forceload_block(pos) then
|
||||||
|
table.insert(self._blocks, vector.new(pos))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
minetest.log("error", "Failed to load block " .. minetest.pos_to_string(pos))
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
unload = function(self, pos)
|
||||||
|
for i = 1, #self._blocks do
|
||||||
|
if vector.equals(pos, self._blocks[i]) then
|
||||||
|
minetest.forceload_free_block(pos)
|
||||||
|
table.remove(self._blocks, i)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
save = function(self, filename)
|
||||||
|
local file = io.open(filename, "w")
|
||||||
|
if file then
|
||||||
|
file:write(minetest.serialize(self._blocks))
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
verify = function(self)
|
||||||
|
return self:verify_each(function(pos, block)
|
||||||
|
local name = "ignore"
|
||||||
|
if block ~= nil then
|
||||||
|
name = block.name
|
||||||
|
end
|
||||||
|
|
||||||
|
if name == "ignore" then
|
||||||
|
if not pos.last or elapsed_time > pos.last + 15 then
|
||||||
|
pos.last = elapsed_time
|
||||||
|
if not minetest.forceload_block(pos) then
|
||||||
|
minetest.log("error", "Failed to force load " .. minetest.pos_to_string(pos))
|
||||||
|
pos.remove = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
elseif name == "forceload:anchor" then
|
||||||
|
pos.last = elapsed_time
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
minetest.log("error", minetest.pos_to_string(pos) .. " shouldn't be loaded")
|
||||||
|
pos.remove = true
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
verify_each = function(self, func)
|
||||||
|
local not_loaded = {}
|
||||||
|
for i = 1, #self._blocks do
|
||||||
|
local res = minetest.get_node(self._blocks[i])
|
||||||
|
if not func(self._blocks[i], res) then
|
||||||
|
--[[table.insert(not_loaded, {
|
||||||
|
pos = self._blocks[i],
|
||||||
|
i = i,
|
||||||
|
b = res })]]--
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return not_loaded
|
||||||
|
end,
|
||||||
|
clean = function(self)
|
||||||
|
local i = 1
|
||||||
|
while i <= #self._blocks do
|
||||||
|
if self._blocks[i].remove then
|
||||||
|
minetest.forceload_free_block(self._blocks[i])
|
||||||
|
table.remove(self._blocks, i)
|
||||||
|
else
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local flm = ForceloadManager(minetest.get_worldpath().."/flm.json", true)
|
||||||
|
|
||||||
|
minetest.register_privilege("forceload", "Allows players to use forceload block anchors")
|
||||||
|
|
||||||
|
minetest.register_node("forceload:anchor",{
|
||||||
|
description = "Block Anchor",
|
||||||
|
walkable = false,
|
||||||
|
tiles = {"forceload_anchor.png"},
|
||||||
|
groups = {cracky = 3, oddly_breakable_by_hand = 2},
|
||||||
|
after_destruct = function(pos)
|
||||||
|
flm:unload(pos)
|
||||||
|
flm:save(minetest.get_worldpath().."/flm.json")
|
||||||
|
end,
|
||||||
|
after_place_node = function(pos, placer)
|
||||||
|
if not minetest.check_player_privs(placer:get_player_name(),
|
||||||
|
{forceload = true}) then
|
||||||
|
minetest.chat_send_player(placer:get_player_name(), "The forceload privilege is required to do that.")
|
||||||
|
elseif flm:load(pos) then
|
||||||
|
flm:save(minetest.get_worldpath().."/flm.json")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.set_node(pos, {name="air"})
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "forceload:anchor",
|
||||||
|
recipe = {
|
||||||
|
{"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"},
|
||||||
|
{"default:mese_crystal", "wool:blue", "default:mese_crystal"},
|
||||||
|
{"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
local elapsed_time = 0
|
||||||
|
local count = 0
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
count = count + dtime
|
||||||
|
elapsed_time = elapsed_time + dtime
|
||||||
|
if count > 5 then
|
||||||
|
count = 0
|
||||||
|
--print("Verifying...")
|
||||||
|
flm:verify()
|
||||||
|
flm:clean()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
BIN
mods/forceload/textures/forceload_anchor.png
Normal file
BIN
mods/forceload/textures/forceload_anchor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 463 B |
83
mods/treasurer/GROUPS_AND_PRECIOUSNESS
Normal file
83
mods/treasurer/GROUPS_AND_PRECIOUSNESS
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
If you wish to register treasures to Treasurer, it is recommended to assign the treasurer to a Treasurer group.
|
||||||
|
|
||||||
|
It is not possible to assign a treasure to multiple groups. If you think a treasure fits into two groups, create
|
||||||
|
two seperate treasure definitions instead. But try to keep it as an exception.
|
||||||
|
|
||||||
|
Think of treasurer groups as categories for treasurers to put into.
|
||||||
|
|
||||||
|
This file contains some guidelines for Treasurer groups and there are even guidelines for preciousness levels.
|
||||||
|
Keep in mind these are only guidelines.
|
||||||
|
|
||||||
|
Treasurer suggests to use the following standard Treasurer groups:
|
||||||
|
|
||||||
|
crafting_component:
|
||||||
|
Generic group for components in crafting recipes. If it is primarily a component for food, use raw_food instead.
|
||||||
|
Preciousness is based roughly on the preciousness of items it can create.
|
||||||
|
|
||||||
|
fuel:
|
||||||
|
Fuel for furnaces.
|
||||||
|
Preciousness is based on burning time.
|
||||||
|
|
||||||
|
food:
|
||||||
|
Can be eaten and restores health.
|
||||||
|
Preciousness should equal the number of hearts restored (restored HP divided by 2), but not higher than 7.
|
||||||
|
|
||||||
|
raw_food:
|
||||||
|
Food which is not fully processed and is not (quite) ready to be eaten.
|
||||||
|
|
||||||
|
melee_weapon:
|
||||||
|
Primarily used to damage close foes, i.e. a sword.
|
||||||
|
Preciousness is based on attack speed and damage.
|
||||||
|
|
||||||
|
ranged_weapon:
|
||||||
|
Primarily used to damage far away foes,
|
||||||
|
Preciousness is based on attack speed, damage and range.
|
||||||
|
|
||||||
|
tool:
|
||||||
|
A tool for other uses.
|
||||||
|
Preciousness is hard to determine; at least is should base on the number of uses.
|
||||||
|
|
||||||
|
|
||||||
|
minetool:
|
||||||
|
A tool to destroy blocks. Includes pickaxes, axes, shovels, …
|
||||||
|
Preciousness is based on power, number of uses and speed.
|
||||||
|
|
||||||
|
deco:
|
||||||
|
Primarily just a decorational thing to place.
|
||||||
|
Preciousness is based on beauty, highly subjective.
|
||||||
|
|
||||||
|
light:
|
||||||
|
Is a light source.
|
||||||
|
Preciousness is based on the brightness. For the maximum brightness (before sun brightness), preciousness should be 3.
|
||||||
|
|
||||||
|
building_block:
|
||||||
|
A block for buildings. Includes stairs, slabs, fences and similar things.
|
||||||
|
Excludes all natural blocks.
|
||||||
|
Preciousness should be roughly based on the “cost” to craft the block.
|
||||||
|
|
||||||
|
seed:
|
||||||
|
Seeds and saplings.
|
||||||
|
Preciousness is based on the percieved “usefulness” of what can grow from the seed.
|
||||||
|
|
||||||
|
transport_vehicle
|
||||||
|
A vehicle to transport players and stuff, i.e. a cart or a boat.
|
||||||
|
Preciousness is hard to determine, maybe speed?
|
||||||
|
|
||||||
|
transport_structure
|
||||||
|
A fixed structure which is neccessary for a transport vehicle to operate, i.e. rails.
|
||||||
|
Preciousness is hard to dertermine …
|
||||||
|
|
||||||
|
ladder
|
||||||
|
A ladder.
|
||||||
|
|
||||||
|
default:
|
||||||
|
This is the group your treasure get assigned to if you don’t specify a group.
|
||||||
|
|
||||||
|
|
||||||
|
Do you miss a group? Feel free to invent your own!
|
||||||
|
|
||||||
|
|
||||||
|
Note that Treasurer groups differ from the groups as defined by the Minetest API. These groups are handled differently.
|
||||||
|
|
||||||
|
|
246
mods/treasurer/README.md
Normal file
246
mods/treasurer/README.md
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
= Treasurer’s README file for Treasurer version 0.2.0 =
|
||||||
|
== Overview ==
|
||||||
|
* Name: Treasurer
|
||||||
|
* Technical name: `treasurer`
|
||||||
|
* Purpose: To provide an interface for mods which want to spawn ItemStacks randomly and an interface for mods which create new items.
|
||||||
|
* Version: 0.2.0
|
||||||
|
* Dependencies: none
|
||||||
|
* License: WTFPL
|
||||||
|
|
||||||
|
== Introduction ==
|
||||||
|
Problem:
|
||||||
|
There are a bunch of mods which have cool items but they won’t appear in the world by
|
||||||
|
themselves.
|
||||||
|
There are some mods which randomly distribute treasures into the world. Sadly, these only
|
||||||
|
distribute the items they know—which are just the items of the mod “default” most of the
|
||||||
|
time. The items of the other mods are completely missed.
|
||||||
|
|
||||||
|
The reason for this is that the distributing mods can’t know what sort of items are available
|
||||||
|
unless they explicitly depend on the mods that defines these. Viewed the other way round,
|
||||||
|
the item-defining mods that also distribute these items into the world are limited in the
|
||||||
|
sense that they only know one means of distributing items.
|
||||||
|
|
||||||
|
There is a gap between defining items and distributing them. Every time a mod does both,
|
||||||
|
flexibility is limited and expansion becomes difficult.
|
||||||
|
|
||||||
|
To bridge this gap, Treasurer has been written. Treasurer makes it possible a) for mods to define
|
||||||
|
treasures without bothering _how_ these are distributed into the world and b) for mods to distribute
|
||||||
|
treasures around the world without knowledge about _what_ treasures exactly are distributed.
|
||||||
|
|
||||||
|
== Technical side of Treasurer ==
|
||||||
|
=== technical overview ===
|
||||||
|
To get a working Treasurer architecture and actually get some treasures into the world,
|
||||||
|
you need:
|
||||||
|
* Treasurer
|
||||||
|
* at least one treasure registration mod
|
||||||
|
* at least one treasure spawning mod
|
||||||
|
|
||||||
|
=== treasurer registration mod ===
|
||||||
|
Firstly, there are the treasure registration mods (TRMs). The task of TRMs is to tell
|
||||||
|
Treasurer which items does it have to offer, which relative appearance probabilities these
|
||||||
|
treasures should have, how “precious” the treasure is considered (on a scale from 0 to 10)
|
||||||
|
, optionally how big the stack of items should be and optionally how much worn out it is.
|
||||||
|
TRMs must depend on at least two mods: On treasurer and on the mod or mods
|
||||||
|
where the items are defined. Technically, a TRM consists of nothing more than a long
|
||||||
|
list of “registration” function calls. While this seems trivial, the task of balancing
|
||||||
|
out probabilties and balancing out preciousness levels of treasures is not trivial
|
||||||
|
and it may take a long time to get right.
|
||||||
|
|
||||||
|
It is strongly recommended that a TRM really does nothing
|
||||||
|
more than registering treasures (and not defining items, for example). If you want
|
||||||
|
to make your mod compatible to Treasurer, don’t change your mod, write a TRM for
|
||||||
|
it instead.
|
||||||
|
|
||||||
|
There is an example TRM, called “`trm_default_example`”. It registers some items
|
||||||
|
of the default as treasures. Unsurprisingly, it depends on `treasurer` and `default`.
|
||||||
|
|
||||||
|
=== treasurer spawning mods ===
|
||||||
|
Secondly, there are the treasure spawning mods (TSMs). The task of a TSM is to somehow
|
||||||
|
distribute the available treasures into the world. This is also called “treasure
|
||||||
|
spawning”. How exactly the TSM spawns the treasures is completely up the TSM. But a
|
||||||
|
TSM has to request Treasurer to get some random treasures to distribute. A TSM may
|
||||||
|
optionally request to filter out treasures outside certain preciousness levels
|
||||||
|
and groups, so the result is a bit controllable and not completely random.
|
||||||
|
Treasurer can not guarantee to return the requestet amount of treasures, it may
|
||||||
|
return an empty table, for two reasons:
|
||||||
|
|
||||||
|
* There is no TRM activated. There must be at least one to work.
|
||||||
|
* The filters filtered out everything, leaving Treasurer with an empty treasure pool
|
||||||
|
to choose from. This problem can be fixed by installing more TRMs or by balancing the
|
||||||
|
existing TRMs to cover as many preciousness levels as possible. It also may be that
|
||||||
|
the range specified by the TSM was too small. It is recommended to keep the
|
||||||
|
requested range at least of a size of 1. Treasurer does, however, guarantee that
|
||||||
|
the returned treasures are always in the requested bounds.
|
||||||
|
|
||||||
|
A TSM has to at least depend on Treasurer.
|
||||||
|
Unlike for TRMs, it may not be a problem to also do some other stuff than just
|
||||||
|
spawning treasures if it seems feasible. You may choose to make your TSM fully
|
||||||
|
dependant on Treasure, then it won’t work without Treasurer. You may also choose
|
||||||
|
to only add an optional dependency on Treasurer. For this to work, your mod must
|
||||||
|
now select its own treasures, which of course will only come from a rather limited
|
||||||
|
pool.
|
||||||
|
|
||||||
|
To check if the Treasurer mod is installed, you can use something like this in
|
||||||
|
your code:
|
||||||
|
|
||||||
|
```
|
||||||
|
if(minetest.get_modpath("treasurer")~=nil) then
|
||||||
|
-- Treasurer is installed.
|
||||||
|
-- You can call Treasurer’s functions here.
|
||||||
|
else
|
||||||
|
-- Treasurer is not installed.
|
||||||
|
-- You may write your replacement code here.
|
||||||
|
-- You can not call Treasurer’s funcitons here.
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
There are two example TSMs. The first one is a very basic one and called “`tsm_gift_example`”.
|
||||||
|
It gives a “welcome gift” (1 random treasure) to players who just joined the server
|
||||||
|
or who respawn. The preciousness and group filters are not used. It does only depend on
|
||||||
|
Treasurer. The second one is called “`tsm_chests_example`” and pretty advanced for an example.
|
||||||
|
It places chests of the mod “default” between 20 and 200 node lenghts below the water
|
||||||
|
surface and puts 1-6 random treasures into these. The lower the chest, the higher
|
||||||
|
the preciousness. It depends on treasurer and default (for the chests, of course).
|
||||||
|
|
||||||
|
=== Recap ===
|
||||||
|
TRMs define treasures, TSMs spawn them. Treasurer manages the pool of available treasures.
|
||||||
|
TRMs and TSMs do not have to know anything from each other.
|
||||||
|
TRMs and TSMs do not neccessarily have to change any line of code of other mods to function.
|
||||||
|
Treasurer depends on nothing.
|
||||||
|
|
||||||
|
Important: It should always only be neccessary for TRMs and TSMs to depend on Treasurer.
|
||||||
|
All other mods do NOT HAVE TO and SHOULD NOT depend on Treasurer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== Treasure attributes ===
|
||||||
|
This section explains the various attributes a treasure can have.
|
||||||
|
|
||||||
|
==== Rarity ====
|
||||||
|
Rarity in Treasurer works in a pretty primitive way: The relative rarities of all
|
||||||
|
treasures from the treasure pool are simply all added up. The probabilitiy of one
|
||||||
|
certain treasure is then simply the rarity value divided by the sum.
|
||||||
|
|
||||||
|
==== Preciousness ====
|
||||||
|
How “precious” an item is, is highly subjective and also not always easy to categorize.
|
||||||
|
Preciousness in Treasurer’s terms should be therefore viewed as “utility” or as
|
||||||
|
“reward level” or “strength” or even “beauty” or whatever positive attributes you can
|
||||||
|
think of for items. See the text file `GROUPS_AND_PRECIOUSNESS` for a rough
|
||||||
|
guideline.
|
||||||
|
So, if you create a TRM and your treasure is something you want the player work
|
||||||
|
hard for, assign it a high preciousness. Everyday items that are already easy to
|
||||||
|
obtain in normal gameplay certainly deserve a lower precious than items that are
|
||||||
|
expensive to craft.
|
||||||
|
If your treasure consists of a powerful
|
||||||
|
item, assign it a high preciousness. When in doubt, try to value gameplay over
|
||||||
|
personal taste. Remember that TSMs can (and will!) filter out treasures based
|
||||||
|
on their preciousness.
|
||||||
|
For TSM authors, consider preciousness this way: If the trouble the player has
|
||||||
|
to get through to in order to obtain the treasure is high, better filter
|
||||||
|
out unprecious treasures. If your TSM distributes many treasures all over the world and these
|
||||||
|
are easy to obtain, filter out precious treasures.
|
||||||
|
|
||||||
|
TSMs also can just completely ignore preciousness, then the given treasures base
|
||||||
|
on sheer luck.
|
||||||
|
|
||||||
|
==== Treasurer groups ====
|
||||||
|
Every treasure can be assigned to a group. These groups are specific to Treasurer only.
|
||||||
|
The idea is that treasures which share a common property are member of the same group.
|
||||||
|
All groups have a name by which they are identified.
|
||||||
|
For example, if there are apples, plums, pears and oranges and those items can be
|
||||||
|
eaten for health, all those treasures would be members of the group “food”.
|
||||||
|
|
||||||
|
The group system can be used to further narrow down the treasure pool from which you
|
||||||
|
want Treasurer to return treasures. This makes it more interesting than just using
|
||||||
|
an one-dimensional preciousness scale.
|
||||||
|
|
||||||
|
Using the groups system is entirely optional. If your TRM does not specify any group,
|
||||||
|
your treasure will be assigned to the group “default”. It is not possible for a treasure
|
||||||
|
to not belong to any group. If your TSM does not specify a group parameter, Treasurer
|
||||||
|
will use all groups.
|
||||||
|
While not using groups as a TSM may be perfectly okay, not using groups as a TRM is
|
||||||
|
not recommended, because TSM which filter by groups may “overlook” your treasure,
|
||||||
|
even if it would actually fit, simply because you didn’t assign it to a specific group.
|
||||||
|
|
||||||
|
Note that Treasurer groups are completely distinct from Minetest’s group system.
|
||||||
|
|
||||||
|
You can basically invent your own groups on the fly, but it is strongly recommended that you
|
||||||
|
use the groups suggested in the text file `GROUPS_AND_PRECIOUSNESS` whenever possible, for
|
||||||
|
maximum portability of your TSM. The text file also has a rough guideline for finding
|
||||||
|
appropriate values for the preciousness.
|
||||||
|
|
||||||
|
|
||||||
|
==== Recap ====
|
||||||
|
Rarity determines the chance of a treasure, whereas preciousness determines
|
||||||
|
the difficulty to obtain it. Group
|
||||||
|
|
||||||
|
== Overview of examples ==
|
||||||
|
- `trm_default_example` - registers items of default mod
|
||||||
|
- `tsm_chests_example` - spawns chests (from the default mod)
|
||||||
|
- `tsm_gift_example` - gives one treasure as a “welcome gift” to joined or respawned players
|
||||||
|
|
||||||
|
== Treasurer API documentation ==
|
||||||
|
=== API documentation for treasure registration mods ===
|
||||||
|
The API consists of one function, which is called “`treasurer.register_treasure`”.
|
||||||
|
|
||||||
|
==== `treasurer.register_treasure` ====
|
||||||
|
Registers a new treasure (this means the treasure will be ready to be spawned by treasure spawning mods).
|
||||||
|
|
||||||
|
This function does some basic parameter checking to catch the most obvious
|
||||||
|
mistakes. If invalid parameters have been passed, the input is rejected and
|
||||||
|
the function returns false. However, it does not cover every possible
|
||||||
|
mistake, so some invalid treasures may slip through.
|
||||||
|
|
||||||
|
Rarity does not imply preciousness. A rare treasure may not neccessarily a
|
||||||
|
very precious one. A treasure chest with scorched stuff inside may be very
|
||||||
|
rare, but it’s certainly also very unprecious.
|
||||||
|
|
||||||
|
===== Parameters =====
|
||||||
|
* `name`: name of resulting `ItemStack`, e.g. “`mymod:item`”
|
||||||
|
* `rarity`: rarity of treasure on a scale from 0 to 1 (inclusive). lower = rarer
|
||||||
|
* `preciousness` : subjective preciousness on a scale from 0 to 10 (inclusive). higher = more precious.
|
||||||
|
* `count`: optional value which specifies the multiplicity of the item. Default is 1. See `count` syntax help in this file.
|
||||||
|
* `wear`: optional value which specifies the wear of the item. Default is 0, which disables the wear. See `wear` syntax help in this file.
|
||||||
|
* `treasurer_groups`: an optional table of group names to assign this treasure to. If omitted, the treasure is added to the default group.
|
||||||
|
|
||||||
|
===== Return value =====
|
||||||
|
`true` on success, `false` on failure.
|
||||||
|
|
||||||
|
=== data formats ===
|
||||||
|
format of count type:
|
||||||
|
==== `count` ====
|
||||||
|
A `count` can be a number or a table
|
||||||
|
|
||||||
|
* `number`: it’s always so many times
|
||||||
|
* `{min, max}`: it’s pseudorandomly between `min` and `max` times, `math.random` will be used to chose the value
|
||||||
|
* `{min, max, prob_func}`: it’s between `min` and `max` times, and the value is given by `prob_func` (see below)
|
||||||
|
|
||||||
|
==== `wear` ====
|
||||||
|
Completely analogous to `count`.
|
||||||
|
|
||||||
|
==== Format of `prob_func` function ====
|
||||||
|
There are no parameters.
|
||||||
|
|
||||||
|
It returns a random or pseudorandom number between 0 (inclusive) and 1 (exclusive).
|
||||||
|
|
||||||
|
`prob_func` is entirely optional, if it’s not used, treasurer will
|
||||||
|
default to using `math.random`. You can use `prob_func` to define your own
|
||||||
|
“randomness” function, in case you don’t wish your values to be evenly
|
||||||
|
distributed.
|
||||||
|
|
||||||
|
=== API documentation for treasure spawning mods ===
|
||||||
|
The API consists of one function, called “`treasurer.select_random_treasures`”.
|
||||||
|
|
||||||
|
==== `treasurer.select_random_treasures` ====
|
||||||
|
Request some treasures from treasurer.
|
||||||
|
|
||||||
|
===== Parameters =====
|
||||||
|
* `count`: (optional) amount of treasures. If this value is `nil`, Treasurer assumes a default of 1.
|
||||||
|
* `minimal_preciousness`: (optional) don’t consider treasures with a lower preciousness. If `nil`, there’s no lower bound.
|
||||||
|
* `maximum_preciousness`: (optional) don’t consider treasures with a higher preciousness. If `nil`, there’s no upper bound.
|
||||||
|
* `treasurer_group`: (optional): Only consider treasures which are members of at least one of the members of the provided Treasurer group table. `nil` = consider all groups
|
||||||
|
|
||||||
|
|
||||||
|
===== Return value =====
|
||||||
|
A table of `ItemStacks` (the requested treasures). It may be empty.
|
||||||
|
|
48
mods/treasurer/Treasurer_ANNOUNCEMENT
Normal file
48
mods/treasurer/Treasurer_ANNOUNCEMENT
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
== Treasurer [treasurer] ==
|
||||||
|
|
||||||
|
With Treasurer I want to introduce a new way to define and distribute random treasures into the world. Treasurer itself does neither define any items nor does it attempt to distribute them.
|
||||||
|
|
||||||
|
Instead Treasurer provides two interfaces.
|
||||||
|
|
||||||
|
To actually get a game with treasures using Treasurer running, you need at least the following:
|
||||||
|
[list]
|
||||||
|
[*]Treasurer
|
||||||
|
[*]at least one treasure registration mod
|
||||||
|
[*]at least one treasure spawning mod
|
||||||
|
[/list]
|
||||||
|
|
||||||
|
A treasure is basically just a fancy ItemStack. It consists of:
|
||||||
|
- name of item
|
||||||
|
- relative rarity
|
||||||
|
- a preciousness
|
||||||
|
- the amount of item (can be randomized)
|
||||||
|
- a wear (can be randomized)
|
||||||
|
|
||||||
|
|
||||||
|
A TRM does nothing more than telling Treasurer a bunch of treasures it has to offer. Note, however, that a TRM should really do nothing more than just that. The actual mods where the items originate from does most likely NOT have to be changed in order to register its items as treasures. TRMs are simple,
|
||||||
|
|
||||||
|
A TSM distributes (“spawns”) treasures, where it has to ask Treasurer for some treasures. Treasurer then chooses some treasures out of the pool of available treasures and returns a list of ItemStacks. The TSM also may ask Treasurer to filter out treasures which have an either too high or too low preciousness (“preciousness” is defined by the TRMs). Be warned: Treasurer may return no treasures at all, either because no TRM is activated or no treasure that matches the filter exists.
|
||||||
|
“Spawning” here means to put the treasures into the world somehow. How a TSM does the task of spawning is up to the TSM. Treasurer
|
||||||
|
|
||||||
|
Recap: The TSMs will spawn treasures into the world out of a pool of treasures which is offered by TRMs. Treasurer manages the pool.
|
||||||
|
|
||||||
|
Examples for TRMs are:
|
||||||
|
- registering bronze, gold, iron ingots and possibly other items of default (see trm_default_example)
|
||||||
|
- registering bread, wheat, seeds, etc. of farming
|
||||||
|
- registering super cool item X from awesome mod Y, where X could normally only obtained by “/give” or with creative mode.
|
||||||
|
- registering the … bla bla bla, you get the idea
|
||||||
|
|
||||||
|
Examples for TSMs are:
|
||||||
|
- let a mob drop a not mob-specific, random treasure on death
|
||||||
|
- give a random treasure as a “welcome gift” to joining and respawning players (see tsm_gift_example)
|
||||||
|
- placing chests around the world and spawning treasures into them (see tsm_chests_example)
|
||||||
|
|
||||||
|
Some of the above example have been implemented into already working mods, which are distributed with Treasurer
|
||||||
|
as seperate mods.
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies of Treasurer: None!
|
||||||
|
Minimal dependencies of all TRMs: treasurer and all mods that define the registered items
|
||||||
|
Minimal dependency of all TSMs: treasurer
|
||||||
|
|
||||||
|
License: WTFPL
|
0
mods/treasurer/depends.txt
Normal file
0
mods/treasurer/depends.txt
Normal file
1
mods/treasurer/descripton.txt
Normal file
1
mods/treasurer/descripton.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
A framework which manages treasures which helps other mods to register and distribute treasures around the world.
|
363
mods/treasurer/init.lua
Normal file
363
mods/treasurer/init.lua
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
--[==[
|
||||||
|
Treasurer
|
||||||
|
- A mod for Minetest
|
||||||
|
version 0.2.0
|
||||||
|
]==]
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
TABLE OF CONTENTS
|
||||||
|
part 1: Initialization
|
||||||
|
part 2: Treasure API
|
||||||
|
part 3: Treasure spawning mod handling
|
||||||
|
part 4: Internal functions
|
||||||
|
]=]
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
part 1: Initialization
|
||||||
|
]=]
|
||||||
|
|
||||||
|
-- This creates the main table; all functions of this mod are stored in this table
|
||||||
|
treasurer = {}
|
||||||
|
|
||||||
|
-- Table which stores all the treasures
|
||||||
|
treasurer.treasures = {}
|
||||||
|
|
||||||
|
-- This table stores the treasures again, but this time sorted by groups
|
||||||
|
treasurer.groups = {}
|
||||||
|
|
||||||
|
-- Groups defined by the Treasurer API
|
||||||
|
treasurer.groups.treasurer = {}
|
||||||
|
treasurer.groups.treasurer.default = {}
|
||||||
|
|
||||||
|
-- Groups defined by the Minetest API
|
||||||
|
treasurer.groups.minetest = {}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
format of treasure table:
|
||||||
|
treasure = {
|
||||||
|
name, -- treasure name, e.g. mymod:item
|
||||||
|
rarity, -- relative rarity on a scale from 0 to 1 (inclusive).
|
||||||
|
-- a rare treasure must not neccessarily be a precious treasure
|
||||||
|
count, -- count (see below)
|
||||||
|
preciousness, -- preciousness or “worth” of the treasure.
|
||||||
|
-- ranges from 0 (“scorched stuff”) to 10 (“diamond block”)
|
||||||
|
wear, -- wear (see below)
|
||||||
|
metadata, -- unused at the moment
|
||||||
|
|
||||||
|
}
|
||||||
|
treasures can be nodes or items
|
||||||
|
|
||||||
|
format of count type:
|
||||||
|
count = number -- it’s always number times
|
||||||
|
count = {min, max} -- it’s pseudorandomly between min and max times, math.random() will be used to chose the value
|
||||||
|
count = {min, max, prob_func} -- it’s between min and max times, and the value is given by prob_func (which is not neccessarily random [in the strictly mathematical sense])
|
||||||
|
|
||||||
|
format of wear type:
|
||||||
|
completely analogous to count type
|
||||||
|
|
||||||
|
format of prob_func function:
|
||||||
|
prob_func = function()
|
||||||
|
--> returns a random or pseudorandom number between 0 (inclusive) and 1 (exclusive)
|
||||||
|
prob_func is entirely optional, if it’s not used, treasurer will default to math.random.
|
||||||
|
You can use prob_func to define your own random function, in case you don’t like an even
|
||||||
|
distribution
|
||||||
|
|
||||||
|
format of treasurer_groups:
|
||||||
|
This is just a table of strings, each string stands for a group name.
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
part 2: Treasurer API
|
||||||
|
]=]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
treasurer.register_treasure - registers a new treasure
|
||||||
|
(this means the treasure will be ready to be spawned by treasure spawning mods.
|
||||||
|
|
||||||
|
name: name of resulting ItemStack, e.g. “mymod:item”
|
||||||
|
rarity: rarity of treasure on a scale from 0 to 1 (inclusive). lower = rarer
|
||||||
|
preciousness: preciousness of treasure on a scale from 0 (“scorched stuff”) to 10 (“diamond block”).
|
||||||
|
count: optional value which specifies the multiplicity of the item. Default is 1. See count syntax help in this file.
|
||||||
|
wear: optional value which specifies the wear of the item. Default is 0, which disables the wear. See wear syntax help in this file.
|
||||||
|
treasurer_groups: (optional) a table of group names to assign this treasure to. If omitted, the treasure is added to the default group.
|
||||||
|
This function does some basic parameter checking to catch the most obvious mistakes. If invalid parameters have been passed, the input is rejected and the function returns false. However, it does not cover every possible mistake, so some invalid treasures may slip through.
|
||||||
|
|
||||||
|
returns: true on success, false on failure
|
||||||
|
]]
|
||||||
|
function treasurer.register_treasure(name, rarity, preciousness, count, wear, treasurer_groups )
|
||||||
|
--[[ We don’t trust our input, so we first check if the parameters
|
||||||
|
have the correct types and refuse to add the treasure if a
|
||||||
|
parameter is malformed.
|
||||||
|
What follows is a bunch of parameter checks.
|
||||||
|
]]
|
||||||
|
|
||||||
|
-- check wheather name is a string
|
||||||
|
if type(name) ~= "string" then
|
||||||
|
minetest.log("error","[treasure] I rejected a treasure because the name was of type \""..type(name).."\" instead of \"string\".")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- first check if rarity is even a number
|
||||||
|
if type(rarity) == "number" then
|
||||||
|
-- then check wheather the rarity lies in the allowed range
|
||||||
|
if rarity < 0 or rarity > 1 then
|
||||||
|
minetest.log("error", "[treasurer] I rejected the treasure \""..tostring(name).."\" because it’s rarity value is out of bounds. (it was "..tostring(rarity)..".)")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log("error","[treasurer] I rejected the treasure \""..tostring(name).."\" because it had an illegal type of rarity. Given type was \""..type(rarity).."\".")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check if preciousness is even a number
|
||||||
|
if type(preciousness) == "number" then
|
||||||
|
-- then check wheather the preciousness lies in the allowed range
|
||||||
|
if preciousness < 0 or preciousness > 10 then
|
||||||
|
minetest.log("error", "[treasurer] I rejected the treasure \""..tostring(name).."\" because it’s preciousness value is out of bounds. (it was "..tostring(preciousness)..".)")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log("error","[treasurer] I rejected the treasure \""..tostring(name).."\" because it had an illegal type of preciousness. Given type was \""..type(preciousness).."\".")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- first check if count is of a correct type
|
||||||
|
if type(count) ~= "number" and type(count) ~= "nil" and type(count) ~= "table" then
|
||||||
|
minetest.log("error", "[treasurer] I rejected the treasure \""..tostring(name).."\" because it had an illegal type of “count”. Given type was \""..type(count).."\".")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- if count’s a table, check if it’s format is correct
|
||||||
|
if type(count) == "table" then
|
||||||
|
if(not (type(count[1]) == "number" and type(count[2]) == "number" and (type(count[3]) == "function" or type(count[3]) == "nil"))) then
|
||||||
|
minetest.log("error","[treasurer] I rejected the treasure \""..tostring(name).."\" because it had a malformed table for the count parameter.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- now do the same for wear:
|
||||||
|
-- first check if wear is of a correct type
|
||||||
|
if type(wear) ~= "number" and type(wear) ~= "nil" and type(wear) ~= "table" then
|
||||||
|
minetest.log("error","[treasurer] I rejected the treasure \""..tostring(name).."\" because it had an illegal type of “wear”. Given type was \""..type(wear).."\".")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- if wear’s a table, check if it’s format is correct
|
||||||
|
if type(wear) == "table" then
|
||||||
|
if(not (type(wear[1]) == "number" and type(wear[2]) == "number" and (type(wear[3]) == "function" or type(wear[3]) == "nil"))) then
|
||||||
|
minetest.log("error","[treasurer] I rejected the treasure \""..tostring(name).."\" because it had a malformed table for the wear parameter.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check type of treasurer_group
|
||||||
|
if type(treasurer_groups) ~= "table" and type(treasurer_groups) ~= "nil" and type(treasurer_groups) ~= "string" then
|
||||||
|
minetest.log("error","[treasurer] I rejected the treasure \""..tostring(name).."\" because the treasure_group parameter is of type "..tosting(type(treasurer_groups)).." (expected: nil, string or table).")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--[[ End of checks. If we reached this point of the code, all checks have been passed
|
||||||
|
and we finally register the treasure.]]
|
||||||
|
|
||||||
|
-- default count is 1
|
||||||
|
if count == nil then count = 1 end
|
||||||
|
-- default wear is 0
|
||||||
|
if wear == nil then wear = 0 end
|
||||||
|
local treasure = {
|
||||||
|
name = name,
|
||||||
|
rarity = rarity,
|
||||||
|
count = count,
|
||||||
|
wear = wear,
|
||||||
|
preciousness = preciousness,
|
||||||
|
metadata = "",
|
||||||
|
}
|
||||||
|
table.insert(treasurer.treasures, treasure)
|
||||||
|
|
||||||
|
--[[ Assign treasure to Treasurer group(s) or default if not provided ]]
|
||||||
|
-- default Treasurer group is default
|
||||||
|
if treasurer_groups == nil then treasurer_groups = "default" end
|
||||||
|
|
||||||
|
if(type(treasurer_groups) == "string") then
|
||||||
|
if(treasurer.groups.treasurer[treasurer_groups] == nil) then
|
||||||
|
treasurer.groups.treasurer[treasurer_groups] = {}
|
||||||
|
end
|
||||||
|
table.insert(treasurer.groups.treasurer[treasurer_groups], treasure)
|
||||||
|
elseif(type(treasurer_groups) == "table") then
|
||||||
|
for i=1,#treasurer_groups do
|
||||||
|
-- assign to Treasurer group (create table if it does not exist yet)
|
||||||
|
if(treasurer.groups.treasurer[treasurer_groups[i]] == nil) then
|
||||||
|
treasurer.groups.treasurer[treasurer_groups[i]] = {}
|
||||||
|
end
|
||||||
|
table.insert(treasurer.groups.treasurer[treasurer_groups[i]], treasure)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("info","[treasurer] Treasure successfully registered: "..name)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
part 3: Treasure spawning mod (TSM) handling
|
||||||
|
]=]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
treasurer.select_random_treasures - request some treasures from treasurer
|
||||||
|
parameters:
|
||||||
|
count: (optional) amount of items in the treasure. If this value is nil, treasurer assumes a default of 1.
|
||||||
|
min_preciousness: (optional) don’t consider treasures with a lower preciousness. nil = no lower limit
|
||||||
|
max_preciousness: (optional) don’t consider treasures with a higher preciousness. nil = no lower limit
|
||||||
|
treasurer_groups: (optional): Only consider treasures which are members of at least one of the members of the provided Treasurer group table. nil = consider all groups
|
||||||
|
returns:
|
||||||
|
a table of ItemStacks (the requested treasures) - may be empty
|
||||||
|
on error, it returns false
|
||||||
|
]]
|
||||||
|
function treasurer.select_random_treasures(count, min_preciousness, max_preciousness, treasurer_groups)
|
||||||
|
if #treasurer.treasures == 0 and count >= 1 then
|
||||||
|
minetest.log("info","[treasurer] I was asked to return "..count.." treasure(s) but I can’t return any because no treasure was registered to me.")
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
if count == nil then count = 1 end
|
||||||
|
local sum = 0
|
||||||
|
local cumulate = {}
|
||||||
|
local randoms = {}
|
||||||
|
|
||||||
|
-- copy treasures into helper table
|
||||||
|
local p_treasures = {}
|
||||||
|
if(treasurer_groups == nil) then
|
||||||
|
-- if the group filter is not used (defaul behaviour), copy all treasures
|
||||||
|
for i=1,#treasurer.treasures do
|
||||||
|
table.insert(p_treasures, treasurer.treasures[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if the group filter IS used, copy only the treasures from the said groups
|
||||||
|
elseif(type(treasurer_groups) == "string") then
|
||||||
|
if(treasurer.groups.treasurer[treasurer_groups] ~= nil) then
|
||||||
|
for i=1,#treasurer.groups.treasurer[treasurer_groups] do
|
||||||
|
table.insert(p_treasures, treasurer.groups.treasurer[treasurer_groups][i])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log("info","[treasurer] I was asked to return "..count.." treasure(s) but I can’t return any because no treasure which fits to the given Treasurer group “"..treasurer_groups.."”.")
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
elseif(type(treasurer_groups) == "table") then
|
||||||
|
for t=1,#treasurer_groups do
|
||||||
|
if(treasurer.groups.treasurer[treasurer_groups[t]] ~= nil) then
|
||||||
|
for i=1,#treasurer.groups.treasurer[treasurer_groups[t]] do
|
||||||
|
table.insert(p_treasures, treasurer.groups.treasurer[treasurer_groups[t]][i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.log("error","[treasurer] treasurer.select_random_treasures was called with a malformed treasurer_groups parameter!")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if(min_preciousness ~= nil) then
|
||||||
|
-- filter out too unprecious treasures
|
||||||
|
for t=#p_treasures,1,-1 do
|
||||||
|
if((p_treasures[t].preciousness) < min_preciousness) then
|
||||||
|
table.remove(p_treasures,t)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if(max_preciousness ~= nil) then
|
||||||
|
-- filter out too precious treasures
|
||||||
|
for t=#p_treasures,1,-1 do
|
||||||
|
if(p_treasures[t].preciousness > max_preciousness) then
|
||||||
|
table.remove(p_treasures,t)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for t=1,#p_treasures do
|
||||||
|
sum = sum + p_treasures[t].rarity
|
||||||
|
cumulate[t] = sum
|
||||||
|
end
|
||||||
|
for c=1,count do
|
||||||
|
randoms[c] = math.random() * sum
|
||||||
|
end
|
||||||
|
|
||||||
|
local treasures = {}
|
||||||
|
for c=1,count do
|
||||||
|
for t=1,#p_treasures do
|
||||||
|
if randoms[c] < cumulate[t] then
|
||||||
|
table.insert(treasures, p_treasures[t])
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local itemstacks = {}
|
||||||
|
for i=1,#treasures do
|
||||||
|
itemstacks[i] = treasurer.treasure_to_itemstack(treasures[i])
|
||||||
|
end
|
||||||
|
if #itemstacks < count then
|
||||||
|
minetest.log("info","[treasurer] I was asked to return "..count.." treasure(s) but I could only return "..(#itemstacks)..".")
|
||||||
|
end
|
||||||
|
return itemstacks
|
||||||
|
end
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
Part 4: internal functions
|
||||||
|
]=]
|
||||||
|
|
||||||
|
--[[ treasurer.treasure_to_itemstack - converts a treasure table to an
|
||||||
|
ItemStack
|
||||||
|
parameter:
|
||||||
|
treasure: a treasure (see format in the head of this file)
|
||||||
|
returns:
|
||||||
|
an ItemStack
|
||||||
|
]]
|
||||||
|
function treasurer.treasure_to_itemstack(treasure)
|
||||||
|
local itemstack = {}
|
||||||
|
itemstack.name = treasure.name
|
||||||
|
itemstack.count = treasurer.determine_count(treasure)
|
||||||
|
itemstack.wear = treasurer.determine_wear(treasure)
|
||||||
|
itemstack.metadata = treasure.metadata
|
||||||
|
|
||||||
|
return ItemStack(itemstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
This determines the count of a treasure by taking the various different
|
||||||
|
possible types of the count value into account
|
||||||
|
This function assumes that the treasure table is valid.
|
||||||
|
returns: the count
|
||||||
|
]]
|
||||||
|
function treasurer.determine_count(treasure)
|
||||||
|
if(type(treasure.count)=="number") then
|
||||||
|
return treasure.count
|
||||||
|
else
|
||||||
|
local min,max,prob = treasure.count[1], treasure.count[2], treasure.count[3]
|
||||||
|
if(prob == nil) then
|
||||||
|
return(math.floor(min + math.random() * (max-min)))
|
||||||
|
else
|
||||||
|
return(math.floor(min + prob() * (max-min)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
This determines the wear of a treasure by taking the various different
|
||||||
|
possible types of the wear value into account.
|
||||||
|
This function assumes that the treasure table is valid.
|
||||||
|
returns: the count
|
||||||
|
]]
|
||||||
|
function treasurer.determine_wear(treasure)
|
||||||
|
if(type(treasure.wear)=="number") then
|
||||||
|
return treasure.wear
|
||||||
|
else
|
||||||
|
local min,max,prob = treasure.wear[1], treasure.wear[2], treasure.wear[3]
|
||||||
|
if(prob == nil) then
|
||||||
|
return(math.floor(min + math.random() * (max-min)))
|
||||||
|
else
|
||||||
|
return(math.floor(min + prob() * (max-min)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user