Sistema chest iniziato
commit
dc71074afd
|
@ -0,0 +1,30 @@
|
|||
arena_lib.on_load("skywars", function(arena)
|
||||
|
||||
skywars.place_chests(arena)
|
||||
skywars.fill_chests(arena)
|
||||
|
||||
end)
|
||||
|
||||
arena_lib.on_join("skywars", function(p_name, arena)
|
||||
|
||||
end)
|
||||
|
||||
arena_lib.on_start("skywars", function(arena)
|
||||
|
||||
end)
|
||||
|
||||
arena_lib.on_celebration("skywars", function(arena, winner_name)
|
||||
|
||||
end)
|
||||
|
||||
arena_lib.on_end("skywars", function(arena, players)
|
||||
|
||||
end)
|
||||
|
||||
arena_lib.on_death("skywars", function(arena, p_name, reason)
|
||||
|
||||
end)
|
||||
|
||||
arena_lib.on_quit("skywars", function(arena)
|
||||
|
||||
end)
|
|
@ -0,0 +1,2 @@
|
|||
--Registra un nodo chest dedicato in modo tale che se viene rimosso cicla nelle arene e si toglie da
|
||||
--sola dalle chests delle properties.
|
|
@ -0,0 +1,55 @@
|
|||
--Il necessario per impostare dove sono le chest nelle mappe. Vedi MOBA con gli spawner.
|
||||
local mod = "skywars"
|
||||
|
||||
ChatCmdBuilder.new("skywars", function(cmd)
|
||||
|
||||
cmd:sub("addchest :arena", function(sender, arena_name)
|
||||
local id, arena = arena_lib.get_arena_by_name("skywars", arena_name)
|
||||
local pos = vector.floor(minetest.get_player_by_name(sender):get_pos())
|
||||
|
||||
table.insert(arena.chests, pos)
|
||||
|
||||
end)
|
||||
|
||||
cmd:sub("removechest :arena", function(sender, arena_name)
|
||||
local id, arena = arena_lib.get_arena_by_name("skywars", arena_name)
|
||||
local pos = vector.floor(minetest.get_player_by_name(sender):get_pos())
|
||||
|
||||
table.remove(arena.chests, pos)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
|
||||
|
||||
function skywars.fill_chests(arena)
|
||||
for chest_pos in arena.chests do
|
||||
fill_chest_inv(chest_pos, arena)
|
||||
end
|
||||
end
|
||||
|
||||
local function fill_chest_inv(chest_pos, arena)
|
||||
local t_min = 4 -- minimum amount of treasures found in a chest
|
||||
local t_max = 7 -- maximum amount of treasures found in a chest
|
||||
local treasure_amount = math.ceil(math.random(t_min, t_max))
|
||||
|
||||
local minp = 0 --scale*4 -- minimal preciousness: 0..4
|
||||
local maxp = 10 --scale*4+2.1 -- maximum preciousness: 2.1..6.1
|
||||
|
||||
local treasures = skywars.select_random_treasures(treasure_amount, minp, maxp, arena)
|
||||
|
||||
local meta = minetest.get_meta(chest_pos)
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
for i=1, #treasures do
|
||||
inv:set_stack("main", i, treasures[i])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function skywars.place_chests(arena)
|
||||
for chest_pos in arena.chests do
|
||||
minetest.set_node(chest_pos, "default:chest")
|
||||
end
|
||||
end
|
|
@ -0,0 +1,109 @@
|
|||
--Il necessario per aggiungere items possibili alle chest.
|
||||
local mod = "skywars"
|
||||
|
||||
ChatCmdBuilder.new("skywars", function(cmd)
|
||||
|
||||
cmd:sub("addtreasure :treasure :rarity :preciousness :count :arena", function(sender, treasure_name, rarity, preciousness, count, arena_name)
|
||||
local id, arena = arena_lib.get_arena_by_name("skywars", arena_name)
|
||||
|
||||
table.insert(arena.treasures, {name = treasure_name, rarity = rarity, count = count, preciousness = preciousness})
|
||||
|
||||
end)
|
||||
|
||||
cmd:sub("removetreasure :treasure :arena", function(sender, treasure_name, arena_name)
|
||||
local id, arena = arena_lib.get_arena_by_name("skywars", arena_name)
|
||||
|
||||
table.remove(arena.treasures, {name = treasure_name, rarity, preciousness})
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
|
||||
function skywars.select_random_treasures(treasure_amount, min_preciousness, max_preciousness, arena)
|
||||
if #arena.treasures == 0 and treasure_amount >= 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 treasure_amount == nil then treasure_amount = 1 end
|
||||
local sum = 0
|
||||
local cumulate = {}
|
||||
local randoms = {}
|
||||
|
||||
-- copy treasures into helper table
|
||||
local p_treasures = {}
|
||||
|
||||
for i=1,#arena.treasures do
|
||||
table.insert(p_treasures, #arena.treasures[i])
|
||||
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] = 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
|
||||
|
||||
|
||||
|
||||
local function treasure_to_itemstack(treasure)
|
||||
local itemstack = {}
|
||||
itemstack.name = treasure.name
|
||||
itemstack.count = determine_count(treasure)
|
||||
|
||||
return ItemStack(itemstack)
|
||||
end
|
||||
|
||||
|
||||
local function 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
|
|
@ -0,0 +1,3 @@
|
|||
--Crea i file delle mappe con world edit e li salva.
|
||||
--Le mappe avranno delle proprietà settate per sapere dove siano le chest e fare i refill.
|
||||
--Le posizioni delle chest possono essere salvate sulle properties della mappa come faccio per gli spawner sul MOBA.
|
|
@ -0,0 +1 @@
|
|||
--Carica il file della mappa quando inizia/finisce la partita, devo ancora decidermi.
|
|
@ -0,0 +1,306 @@
|
|||
ChatCmdBuilder = {}
|
||||
|
||||
function ChatCmdBuilder.new(name, func, def)
|
||||
def = def or {}
|
||||
local cmd = ChatCmdBuilder.build(func)
|
||||
cmd.def = def
|
||||
def.func = cmd.run
|
||||
minetest.register_chatcommand(name, def)
|
||||
return cmd
|
||||
end
|
||||
|
||||
local STATE_READY = 1
|
||||
local STATE_PARAM = 2
|
||||
local STATE_PARAM_TYPE = 3
|
||||
local bad_chars = {}
|
||||
bad_chars["("] = true
|
||||
bad_chars[")"] = true
|
||||
bad_chars["."] = true
|
||||
bad_chars["%"] = true
|
||||
bad_chars["+"] = true
|
||||
bad_chars["-"] = true
|
||||
bad_chars["*"] = true
|
||||
bad_chars["?"] = true
|
||||
bad_chars["["] = true
|
||||
bad_chars["^"] = true
|
||||
bad_chars["$"] = true
|
||||
local function escape(char)
|
||||
if bad_chars[char] then
|
||||
return "%" .. char
|
||||
else
|
||||
return char
|
||||
end
|
||||
end
|
||||
|
||||
local dprint = function() end
|
||||
|
||||
ChatCmdBuilder.types = {
|
||||
pos = "%(? *(%-?[%d.]+) *, *(%-?[%d.]+) *, *(%-?[%d.]+) *%)?",
|
||||
text = "(.+)",
|
||||
number = "(%-?[%d.]+)",
|
||||
int = "(%-?[%d]+)",
|
||||
word = "([^ ]+)",
|
||||
alpha = "([A-Za-z]+)",
|
||||
modname = "([a-z0-9_]+)",
|
||||
alphascore = "([A-Za-z_]+)",
|
||||
alphanumeric = "([A-Za-z0-9]+)",
|
||||
username = "([A-Za-z0-9-_]+)",
|
||||
}
|
||||
|
||||
function ChatCmdBuilder.build(func)
|
||||
local cmd = {
|
||||
_subs = {}
|
||||
}
|
||||
function cmd:sub(route, func, def)
|
||||
dprint("Parsing " .. route)
|
||||
|
||||
def = def or {}
|
||||
if string.trim then
|
||||
route = string.trim(route)
|
||||
end
|
||||
|
||||
local sub = {
|
||||
pattern = "^",
|
||||
params = {},
|
||||
func = func
|
||||
}
|
||||
|
||||
-- End of param reached: add it to the pattern
|
||||
local param = ""
|
||||
local param_type = ""
|
||||
local should_be_eos = false
|
||||
local function finishParam()
|
||||
if param ~= "" and param_type ~= "" then
|
||||
dprint(" - Found param " .. param .. " type " .. param_type)
|
||||
|
||||
local pattern = ChatCmdBuilder.types[param_type]
|
||||
if not pattern then
|
||||
error("Unrecognised param_type=" .. param_type)
|
||||
end
|
||||
|
||||
sub.pattern = sub.pattern .. pattern
|
||||
|
||||
table.insert(sub.params, param_type)
|
||||
|
||||
param = ""
|
||||
param_type = ""
|
||||
end
|
||||
end
|
||||
|
||||
-- Iterate through the route to find params
|
||||
local state = STATE_READY
|
||||
local catching_space = false
|
||||
local match_space = " " -- change to "%s" to also catch tabs and newlines
|
||||
local catch_space = match_space.."+"
|
||||
for i = 1, #route do
|
||||
local c = route:sub(i, i)
|
||||
if should_be_eos then
|
||||
error("Should be end of string. Nothing is allowed after a param of type text.")
|
||||
end
|
||||
|
||||
if state == STATE_READY then
|
||||
if c == ":" then
|
||||
dprint(" - Found :, entering param")
|
||||
state = STATE_PARAM
|
||||
param_type = "word"
|
||||
catching_space = false
|
||||
elseif c:match(match_space) then
|
||||
print(" - Found space")
|
||||
if not catching_space then
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
end
|
||||
else
|
||||
catching_space = false
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
end
|
||||
elseif state == STATE_PARAM then
|
||||
if c == ":" then
|
||||
dprint(" - Found :, entering param type")
|
||||
state = STATE_PARAM_TYPE
|
||||
param_type = ""
|
||||
elseif c:match(match_space) then
|
||||
print(" - Found whitespace, leaving param")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
elseif c:match("%W") then
|
||||
dprint(" - Found nonalphanum, leaving param")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
else
|
||||
param = param .. c
|
||||
end
|
||||
elseif state == STATE_PARAM_TYPE then
|
||||
if c:match(match_space) then
|
||||
print(" - Found space, leaving param type")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
elseif c:match("%W") then
|
||||
dprint(" - Found nonalphanum, leaving param type")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
else
|
||||
param_type = param_type .. c
|
||||
end
|
||||
end
|
||||
end
|
||||
dprint(" - End of route")
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. "$"
|
||||
dprint("Pattern: " .. sub.pattern)
|
||||
|
||||
table.insert(self._subs, sub)
|
||||
end
|
||||
|
||||
if func then
|
||||
func(cmd)
|
||||
end
|
||||
|
||||
cmd.run = function(name, param)
|
||||
for i = 1, #cmd._subs do
|
||||
local sub = cmd._subs[i]
|
||||
local res = { string.match(param, sub.pattern) }
|
||||
if #res > 0 then
|
||||
local pointer = 1
|
||||
local params = { name }
|
||||
for j = 1, #sub.params do
|
||||
local param = sub.params[j]
|
||||
if param == "pos" then
|
||||
local pos = {
|
||||
x = tonumber(res[pointer]),
|
||||
y = tonumber(res[pointer + 1]),
|
||||
z = tonumber(res[pointer + 2])
|
||||
}
|
||||
table.insert(params, pos)
|
||||
pointer = pointer + 3
|
||||
elseif param == "number" or param == "int" then
|
||||
table.insert(params, tonumber(res[pointer]))
|
||||
pointer = pointer + 1
|
||||
else
|
||||
table.insert(params, res[pointer])
|
||||
pointer = pointer + 1
|
||||
end
|
||||
end
|
||||
if table.unpack then
|
||||
-- lua 5.2 or later
|
||||
return sub.func(table.unpack(params))
|
||||
else
|
||||
-- lua 5.1 or earlier
|
||||
return sub.func(unpack(params))
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, "Invalid command"
|
||||
end
|
||||
|
||||
return cmd
|
||||
end
|
||||
|
||||
local function run_tests()
|
||||
if not (ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("bar :one and :two:word", function(name, one, two)
|
||||
if name == "singleplayer" and one == "abc" and two == "def" then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end)).run("singleplayer", "bar abc and def") then
|
||||
error("Test 1 failed")
|
||||
end
|
||||
|
||||
local move = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("move :target to :pos:pos", function(name, target, pos)
|
||||
if name == "singleplayer" and target == "player1" and
|
||||
pos.x == 0 and pos.y == 1 and pos.z == 2 then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end).run
|
||||
if not move("singleplayer", "move player1 to 0,1,2") then
|
||||
error("Test 2 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to (0,1,2)") then
|
||||
error("Test 3 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0, 1,2") then
|
||||
error("Test 4 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0 ,1, 2") then
|
||||
error("Test 5 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0, 1, 2") then
|
||||
error("Test 6 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0 ,1 ,2") then
|
||||
error("Test 7 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to ( 0 ,1 ,2)") then
|
||||
error("Test 8 failed")
|
||||
end
|
||||
if move("singleplayer", "move player1 to abc,def,sdosd") then
|
||||
error("Test 9 failed")
|
||||
end
|
||||
if move("singleplayer", "move player1 to abc def sdosd") then
|
||||
error("Test 10 failed")
|
||||
end
|
||||
|
||||
if not (ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("does :one:int plus :two:int equal :three:int", function(name, one, two, three)
|
||||
if name == "singleplayer" and one + two == three then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end)).run("singleplayer", "does 1 plus 2 equal 3") then
|
||||
error("Test 11 failed")
|
||||
end
|
||||
|
||||
local checknegint = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checknegint :x:int", function(name, x)
|
||||
return x
|
||||
end)
|
||||
end).run
|
||||
if checknegint("checker","checknegint -2") ~= -2 then
|
||||
error("Test 12 failed")
|
||||
end
|
||||
|
||||
local checknegnumber = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checknegnumber :x:number", function(name, x)
|
||||
return x
|
||||
end)
|
||||
end).run
|
||||
if checknegnumber("checker","checknegnumber -3.3") ~= -3.3 then
|
||||
error("Test 13 failed")
|
||||
end
|
||||
|
||||
local checknegpos = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checknegpos :pos:pos", function(name, pos)
|
||||
return pos
|
||||
end)
|
||||
end).run
|
||||
local negpos = checknegpos("checker","checknegpos (-13.3,-4.6,-1234.5)")
|
||||
if negpos.x ~= -13.3 or negpos.y ~= -4.6 or negpos.z ~= -1234.5 then
|
||||
error("Test 14 failed")
|
||||
end
|
||||
|
||||
local checktypes = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checktypes :int:int :number:number :pos:pos :word:word :text:text", function(name, int, number, pos, word, text)
|
||||
return int, number, pos.x, pos.y, pos.z, word, text
|
||||
end)
|
||||
end).run
|
||||
local int, number, posx, posy, posz, word, text
|
||||
int, number, posx, posy, posz, word, text = checktypes("checker","checktypes -1 -2.4 (-3,-5.3,6.12) some text to finish off with")
|
||||
--dprint(int, number, posx, posy, posz, word, text)
|
||||
if int ~= -1 or number ~= -2.4 or posx ~= -3 or posy ~= -5.3 or posz ~= 6.12 or word ~= "some" or text ~= "text to finish off with" then
|
||||
error("Test 15 failed")
|
||||
end
|
||||
dprint("All tests passed")
|
||||
|
||||
end
|
||||
if not minetest then
|
||||
run_tests()
|
||||
end
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
|
||||
|
||||
local mod = "skywars"
|
||||
|
||||
ChatCmdBuilder.new("skywars", function(cmd)
|
||||
|
||||
cmd:sub("create :arena", function(sender, arena_name)
|
||||
arena_lib.create_arena(sender, mod, arena_name)
|
||||
end)
|
||||
|
||||
cmd:sub("create :arena :minplayers:int :maxplayers:int", function(sender, arena_name, min_players, max_players)
|
||||
arena_lib.create_arena(sender, mod, arena_name, min_players, max_players)
|
||||
end)
|
||||
|
||||
cmd:sub("create :arena :minplayers:int :maxplayers:int :killcap:int", function(sender, arena_name, min_players, max_players)
|
||||
arena_lib.create_arena(sender, mod, arena_name, min_players, max_players)
|
||||
local id, arena = arena_lib.get_arena_by_name("moba", arena_name)
|
||||
end)
|
||||
|
||||
-- rimozione arene
|
||||
cmd:sub("remove :arena", function(sender, arena_name)
|
||||
arena_lib.remove_arena(sender, mod, arena_name)
|
||||
end)
|
||||
|
||||
-- lista arene
|
||||
cmd:sub("list", function(sender)
|
||||
arena_lib.print_arenas(sender, mod)
|
||||
end)
|
||||
|
||||
-- info su un'arena specifica
|
||||
cmd:sub("info :arena", function(sender, arena_name)
|
||||
arena_lib.print_arena_info(sender, mod, arena_name)
|
||||
end)
|
||||
|
||||
-- info su stats partita
|
||||
cmd:sub("score :arena", function(sender, arena_name)
|
||||
arena_lib.print_arena_stats(sender, mod, arena_name)
|
||||
end)
|
||||
|
||||
-- modifiche arena
|
||||
--editor
|
||||
cmd:sub("edit :arena", function(sender, arena)
|
||||
arena_lib.enter_editor(sender, mod, arena)
|
||||
end)
|
||||
|
||||
--inline
|
||||
-- cartello arena
|
||||
cmd:sub("setsign :arena", function(sender, arena)
|
||||
arena_lib.set_sign(sender, nil, nil, mod, arena)
|
||||
end)
|
||||
|
||||
-- spawner (ie. deleteall)
|
||||
cmd:sub("setspawn :arena :param:text :ID:int", function(sender, arena, param, ID)
|
||||
arena_lib.set_spawner(sender, mod, arena, param, ID)
|
||||
end)
|
||||
|
||||
cmd:sub("setspawn :arena", function(sender, arena)
|
||||
arena_lib.set_spawner(sender, mod, arena)
|
||||
end)
|
||||
|
||||
-- abilitazione e disabilitazione arene
|
||||
cmd:sub("enable :arena", function(sender, arena)
|
||||
arena_lib.enable_arena(sender, mod, arena)
|
||||
end)
|
||||
|
||||
cmd:sub("disable :arena", function(sender, arena)
|
||||
arena_lib.disable_arena(sender, mod, arena)
|
||||
end)
|
||||
|
||||
end)
|
|
@ -0,0 +1 @@
|
|||
arena_lib
|
|
@ -0,0 +1,29 @@
|
|||
skywars = {}
|
||||
|
||||
arena_lib.register_minigame("skywars", {
|
||||
prefix = "[Skywars] ",
|
||||
hub_spawn_point = { x = 8, y = 6, z = 4 },
|
||||
join_while_in_progress = false,
|
||||
celebration_time = 5,
|
||||
properties = {
|
||||
chests = {},
|
||||
treasures = {}, --items da mettere nelle chest
|
||||
},
|
||||
temp_properties = {
|
||||
kill_leader = "",
|
||||
first_blood = "",
|
||||
},
|
||||
player_properties = {
|
||||
killstreak = 0,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
dofile(minetest.get_modpath("skywars") .. "/chatcmdbuilder.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/commands.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/_chest_handler/chest_setter.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/_chest_handler/chest.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/_chest_handler/treasures.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_create.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_gen.lua")
|
||||
dofile(minetest.get_modpath("skywars") .. "/_arena_lib/arena_manager.lua")
|
Loading…
Reference in New Issue