mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-23 02:51:06 +01:00
Add loot API and use it in tsm_railcorridors
This commit is contained in:
parent
ba2d83eff9
commit
49bd956da8
5 changed files with 132 additions and 63 deletions
1
mods/CORE/mcl_loot/description.txt
Normal file
1
mods/CORE/mcl_loot/description.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
API for filling a chest with random treasures.
|
89
mods/CORE/mcl_loot/init.lua
Normal file
89
mods/CORE/mcl_loot/init.lua
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
mcl_loot = {}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Select a number of itemstacks out of a pool of treasure definitions randomly.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* loot_definitions: Probabilities and information about the loot to select. Syntax:
|
||||||
|
|
||||||
|
{
|
||||||
|
stacks_min = 1, -- Mamimum number of item stacks to get
|
||||||
|
stacks_max = 3, -- Number of repetitions, maximum
|
||||||
|
items = { -- Table of possible loot items. This function selects between stacks_min and stacks_max of these.
|
||||||
|
{
|
||||||
|
itemstring = "example:item1", -- Which item to select
|
||||||
|
amount_min = 1, -- Minimum size of itemstack. Optional (default: 1)
|
||||||
|
amount_max = 10, -- Maximum size of item stack. Must not exceed item definition's stack_max. Optional (default: 1)
|
||||||
|
wear_min = 1, -- Minimum wear value. Must be at lest 1. Optional (default: no wear)
|
||||||
|
wear_max = 1, -- Maxiumum wear value. Must be at lest 1. Optional (default: no wear)
|
||||||
|
weight = 5, -- Likelihood of this item being selected
|
||||||
|
},
|
||||||
|
{ -- more tables like above, one table per item stack }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
* pr: PseudoRandom object
|
||||||
|
|
||||||
|
How weight works: The probability of a single item stack being selected is weight/total_weight, with
|
||||||
|
total_weight being the sum of all weight values in the items table.
|
||||||
|
|
||||||
|
Returns: Table of itemstrings
|
||||||
|
]]
|
||||||
|
function mcl_loot.get_loot(loot_definitions, pr)
|
||||||
|
local items = {}
|
||||||
|
|
||||||
|
local total_weight = 0
|
||||||
|
for i=1, #loot_definitions.items do
|
||||||
|
total_weight = total_weight + loot_definitions.items[i].weight
|
||||||
|
end
|
||||||
|
|
||||||
|
local stacks = pr:next(loot_definitions.stacks_min, loot_definitions.stacks_max)
|
||||||
|
for s=1, stacks do
|
||||||
|
local r = pr:next(1, total_weight)
|
||||||
|
|
||||||
|
local accumulated_weight = 0
|
||||||
|
local item
|
||||||
|
for i=1, #loot_definitions.items do
|
||||||
|
accumulated_weight = accumulated_weight + loot_definitions.items[i].weight
|
||||||
|
if accumulated_weight >= r then
|
||||||
|
item = loot_definitions.items[i]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if item then
|
||||||
|
local itemstring = item.itemstring
|
||||||
|
if item.amount_min and item.amount_max then
|
||||||
|
itemstring = itemstring .. " " .. pr:next(item.amount_min, item.amount_max)
|
||||||
|
end
|
||||||
|
if item.wear_min and item.wear_max then
|
||||||
|
if not item.amount_min and not item.amount_max then
|
||||||
|
itemstring = itemstring .. " 1"
|
||||||
|
end
|
||||||
|
itemstring = itemstring .. " " .. pr:next(item.wear_min, item.wear_max)
|
||||||
|
end
|
||||||
|
table.insert(items, itemstring)
|
||||||
|
else
|
||||||
|
minetest.log("error", "[mcl_loot] INTERNAL ERROR! Failed to select random loot item!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Repeat mcl_loot.get_loot multiple times for various loot_definitions.
|
||||||
|
Useful for filling chests.
|
||||||
|
|
||||||
|
* multi_loot_definitions: Table of loot_definitions (see mcl_loot.get_loot)
|
||||||
|
* pr: PseudoRandom object
|
||||||
|
|
||||||
|
Returns: Table of itemstrings ]]
|
||||||
|
function mcl_loot.get_multi_loot(multi_loot_definitions, pr)
|
||||||
|
local items = {}
|
||||||
|
for m=1, #multi_loot_definitions do
|
||||||
|
local group = mcl_loot.get_loot(multi_loot_definitions[m], pr)
|
||||||
|
for g=1, #group do
|
||||||
|
table.insert(items, group[g])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return items
|
||||||
|
end
|
1
mods/CORE/mcl_loot/mod.conf
Normal file
1
mods/CORE/mcl_loot/mod.conf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
name = mcl_loot
|
|
@ -1,5 +1,6 @@
|
||||||
mcl_init
|
mcl_init
|
||||||
mcl_util
|
mcl_util
|
||||||
mcl_core
|
mcl_core
|
||||||
|
mcl_loot
|
||||||
mcl_tnt
|
mcl_tnt
|
||||||
mcl_farming
|
mcl_farming
|
||||||
|
|
|
@ -30,69 +30,46 @@ end
|
||||||
-- MineClone 2's treasure function. Gets all treasures for a single chest.
|
-- MineClone 2's treasure function. Gets all treasures for a single chest.
|
||||||
-- Based on information from Minecraft Wiki.
|
-- Based on information from Minecraft Wiki.
|
||||||
function tsm_railcorridors.get_treasures(pr)
|
function tsm_railcorridors.get_treasures(pr)
|
||||||
local items = {}
|
local items = mcl_loot.get_multi_loot({
|
||||||
-- First roll
|
{
|
||||||
local r1 = pr:next(1,71)
|
stacks_min = 1,
|
||||||
if r1 <= 30 then
|
stacks_max = 1,
|
||||||
table.insert(items, "mobs:nametag")
|
items = {
|
||||||
elseif r1 <= 50 then
|
{ itemstring = "mobs:nametag", weight = 30 },
|
||||||
table.insert(items, "mcl_core:apple_gold")
|
{ itemstring = "mcl_core:apple_gold", weight = 20 },
|
||||||
elseif r1 <= 60 then
|
{ itemstring = "mcl_books:book", weight = 10 }, -- TODO: Enchanted Book
|
||||||
-- TODO: Enchanted Book
|
{ itemstring = "", weight = 5},
|
||||||
table.insert(items, "mcl_books:book")
|
{ itemstring = "mcl_core:pick_iron", weight = 5 },
|
||||||
elseif r1 <= 65 then
|
{ itemstring = "mcl:core:apple_gold", weight = 1 }, -- TODO: Enchanted Golden Apple
|
||||||
-- Nothing!
|
}
|
||||||
elseif r1 <= 70 then
|
},
|
||||||
table.insert(items, "mcl_tools:pick_iron")
|
{
|
||||||
else
|
stacks_min = 2,
|
||||||
-- TODO: Enchanted Golden Apple
|
stacks_max = 4,
|
||||||
table.insert(items, "mcl_core:apple_gold")
|
items = {
|
||||||
end
|
{ itemstring = "mcl_farming:bread", weight = 15, amount_min = 1, amount_max = 3 },
|
||||||
|
{ itemstring = "mcl_core:coal_lump", weight = 10, amount_min = 3, amount_max = 8 },
|
||||||
-- Second roll
|
{ itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 },
|
||||||
local r2stacks = pr:next(2,4)
|
{ itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 },
|
||||||
for i=1, r2stacks do
|
{ itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 },
|
||||||
local r2 = pr:next(1,83)
|
{ itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 5 },
|
||||||
if r2 <= 15 then
|
{ itemstring = "mcl_dye:bye", weight = 5, amount_min = 4, amount_max = 9 },
|
||||||
table.insert(items, "mcl_farming:bread "..pr:next(1,3))
|
{ itemstring = "mesecons:redstone", weight = 5, amount_min = 4, amount_max = 9 },
|
||||||
elseif r2 <= 25 then
|
{ itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 3 },
|
||||||
table.insert(items, "mcl_core:coal_lump "..pr:next(3,8))
|
{ itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 2 },
|
||||||
elseif r2 <= 35 then
|
}
|
||||||
table.insert(items, "mcl_farming:beetroot_seeds "..pr:next(2,4))
|
},
|
||||||
elseif r2 <= 45 then
|
{
|
||||||
table.insert(items, "mcl_farming:melon_seeds "..pr:next(2,4))
|
stacks_min = 3,
|
||||||
elseif r2 <= 55 then
|
stacks_max = 3,
|
||||||
table.insert(items, "mcl_farming:pumpkin_seeds "..pr:next(2,4))
|
items = {
|
||||||
elseif r2 <= 65 then
|
{ itemstring = "mcl_minecarts:rail", weight = 20, amount_min = 4, amount_max = 8 },
|
||||||
table.insert(items, "mcl_core:iron_ingot "..pr:next(1,5))
|
{ itemstring = "mcl_torches:torch", weight = 15, amount_min = 1, amount_max = 16 },
|
||||||
elseif r2 <= 70 then
|
{ itemstring = "mcl_minecarts:rail", weight = 5, amount_min = 1, amount_max = 4 }, -- TODO: Activator Rail
|
||||||
table.insert(items, "mcl_dye:blue "..pr:next(4,9))
|
{ itemstring = "mcl_minecarts:rail", weight = 5, amount_min = 1, amount_max = 4 }, -- TODO: Detector Rail
|
||||||
elseif r2 <= 75 then
|
{ itemstring = "mcl_minecarts:golden_rail", weight = 5, amount_min = 1, amount_max = 4 },
|
||||||
table.insert(items, "mesecons:redstone "..pr:next(4,9))
|
}
|
||||||
elseif r2 <= 80 then
|
}}, pr)
|
||||||
table.insert(items, "mcl_core:gold_ingot "..pr:next(1,3))
|
|
||||||
else
|
|
||||||
table.insert(items, "mcl_core:diamond "..pr:next(1,2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Third roll
|
|
||||||
for i=1, 3 do
|
|
||||||
local r3 = pr:next(1,50)
|
|
||||||
if r3 <= 20 then
|
|
||||||
table.insert(items, "mcl_minecarts:rail "..pr:next(4,8))
|
|
||||||
elseif r3 <= 35 then
|
|
||||||
table.insert(items, "mcl_torches:torch "..pr:next(1,16))
|
|
||||||
elseif r3 <= 40 then
|
|
||||||
-- TODO: Activator Rail
|
|
||||||
table.insert(items, "mcl_minecarts:rail "..pr:next(1,4))
|
|
||||||
elseif r3 <= 45 then
|
|
||||||
-- TODO: Detector Rail
|
|
||||||
table.insert(items, "mcl_minecarts:rail "..pr:next(1,4))
|
|
||||||
else
|
|
||||||
table.insert(items, "mcl_minecarts:golden_rail "..pr:next(1,4))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return items
|
return items
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue