Upload files to ''
parent
ed97d01da8
commit
b33b216fb6
18
README.md
18
README.md
|
@ -1,3 +1,17 @@
|
|||
# sumo_with_spectate
|
||||
# sumo
|
||||
|
||||
adds a spectate functionality, which is in beta phase. Needs testing. For now, you can only spectate 1 player until they die, then you switch. Also, you die when the player you are spectating dies.
|
||||
Knock other players off the platform to win
|
||||
|
||||
![](screenshot.png)
|
||||
|
||||
Contributors: Zughy, MisterE
|
||||
|
||||
Schematics for arenas can be found here:
|
||||
|
||||
https://notabug.org/MisterE123/sumo_arenas
|
||||
|
||||
|
||||
^
|
||||
// \\
|
||||
// ! \\ Caution: This mod gives players the interact priv when they join the server. This is because interact is temporarily revoked during spectation mode.
|
||||
-------
|
||||
|
|
|
@ -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,51 @@
|
|||
ChatCmdBuilder.new("sumo", function(cmd)
|
||||
|
||||
-- create arena
|
||||
cmd:sub("create :arena", function(name, arena_name)
|
||||
arena_lib.create_arena(name, "sumo", arena_name)
|
||||
end)
|
||||
|
||||
cmd:sub("create :arena :minplayers:int :maxplayers:int", function(name, arena_name, min_players, max_players)
|
||||
arena_lib.create_arena(name, "sumo", arena_name, min_players, max_players)
|
||||
end)
|
||||
|
||||
-- remove arena
|
||||
cmd:sub("remove :arena", function(name, arena_name)
|
||||
arena_lib.remove_arena(name, "sumo", arena_name)
|
||||
end)
|
||||
|
||||
-- list of the arenas
|
||||
cmd:sub("list", function(name)
|
||||
arena_lib.print_arenas(name, "sumo")
|
||||
end)
|
||||
|
||||
-- enter editor mode
|
||||
cmd:sub("edit :arena", function(sender, arena)
|
||||
arena_lib.enter_editor(sender, "sumo", arena)
|
||||
end)
|
||||
|
||||
-- enable and disable arenas
|
||||
cmd:sub("enable :arena", function(name, arena)
|
||||
arena_lib.enable_arena(name, "sumo", arena)
|
||||
end)
|
||||
|
||||
cmd:sub("disable :arena", function(name, arena)
|
||||
arena_lib.disable_arena(name, "sumo", arena)
|
||||
end)
|
||||
|
||||
end, {
|
||||
description = [[
|
||||
|
||||
(/help sumo)
|
||||
|
||||
Use this to configure your arena:
|
||||
- create <arena name> [min players] [max players]
|
||||
- edit <arena name>
|
||||
- enable <arena name>
|
||||
|
||||
Other commands:
|
||||
- remove <arena name>
|
||||
- disable <arena>
|
||||
]],
|
||||
privs = { sumo_admin = true }
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
A minigame for arena_lib where you punch the other players with your stick to knock them off the platform or island. Some advanced uses of the stick include vaulting yourself and throwing otehr players over your shoulder.
|
|
@ -0,0 +1,49 @@
|
|||
sumo = {}
|
||||
|
||||
-- local value settings
|
||||
|
||||
local player_speed = 2 -- when in the minigame
|
||||
local player_jump = 1.3 -- when in the minigame
|
||||
|
||||
|
||||
|
||||
arena_lib.register_minigame("sumo", {
|
||||
prefix = "[Sumo] ",
|
||||
hub_spawn_point = { x = 0, y = 20, z = 0 },
|
||||
show_minimap = false,
|
||||
time_mode = 2,
|
||||
load_time = 1,
|
||||
celebration_time = 5,
|
||||
join_while_in_progress = false,
|
||||
keep_inventory = false,
|
||||
in_game_physics = {
|
||||
speed = player_speed,
|
||||
jump = player_jump,
|
||||
sneak = false,
|
||||
},
|
||||
|
||||
hotbar = {
|
||||
slots = 1,
|
||||
background_image = "sumo_gui_hotbar.png"
|
||||
},
|
||||
|
||||
disabled_damage_types = {"punch","fall"},
|
||||
|
||||
player_properties = {
|
||||
textures = "",
|
||||
watching = "",
|
||||
playing = true,
|
||||
collisionbox = {},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
dofile(minetest.get_modpath("sumo") .. "/commands.lua")
|
||||
dofile(minetest.get_modpath("sumo") .. "/items.lua")
|
||||
dofile(minetest.get_modpath("sumo") .. "/minigame_manager.lua")
|
||||
dofile(minetest.get_modpath("sumo") .. "/nodes.lua")
|
||||
dofile(minetest.get_modpath("sumo") .. "/privs.lua")
|
||||
|
||||
if not minetest.get_modpath("lib_chatcmdbuilder") then
|
||||
dofile(minetest.get_modpath("sumo") .. "/chatcmdbuilder.lua")
|
||||
end
|
|
@ -0,0 +1,92 @@
|
|||
local stick_knockback = 30 --multiplier for how hard the stick hits
|
||||
local stick_vault_reach = 3 -- how close to the pointed node must the player be to vault
|
||||
local stick_vault_timeout = 1 -- int timer for how long the vault cannot be used after it is used
|
||||
local allow_swap_distance = 4 -- if an opponent is within this distance, then if the player uses the pushstick with the shift key pressed, the players switch positions.
|
||||
|
||||
|
||||
minetest.register_craftitem("sumo:pushstick", {
|
||||
description = "Push Stick",
|
||||
inventory_image = "default_stick.png",
|
||||
stack_max = 1,
|
||||
wield_scale = {x = 2, y = 2, z = 2},
|
||||
on_drop = function() end,
|
||||
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local sound = 'swish'..math.random(1,4)
|
||||
minetest.sound_play(sound, {
|
||||
pos = user:get_pos(),
|
||||
max_hear_distance = 5,
|
||||
gain = 10.0,
|
||||
})
|
||||
|
||||
if pointed_thing == nil then return end
|
||||
if pointed_thing.type == 'object' then
|
||||
if minetest.is_player(pointed_thing.ref) == true then
|
||||
|
||||
local dir = user:get_look_dir()
|
||||
local keys = user:get_player_control()
|
||||
local swap = false
|
||||
local hitted_pos = pointed_thing.ref:get_pos()
|
||||
local hitter_pos = user:get_pos()
|
||||
if keys.sneak and vector.distance(hitted_pos,hitter_pos) < allow_swap_distance then
|
||||
swap = true
|
||||
user:move_to(hitted_pos, true)
|
||||
pointed_thing.ref:move_to(hitter_pos, true)
|
||||
pointed_thing.ref:add_player_velocity(vector.multiply({x = -dir.x, y = dir.y, z= -dir.z}, stick_knockback/2))
|
||||
else
|
||||
pointed_thing.ref:add_player_velocity(vector.multiply(dir, stick_knockback))
|
||||
if not swap then
|
||||
local sound = 'thwack'..math.random(1,3)
|
||||
minetest.sound_play(sound, {
|
||||
pos = user:get_pos(),
|
||||
max_hear_distance = 10,
|
||||
gain = 10.0,
|
||||
})
|
||||
local sound = 'hurt'..math.random(1,2)
|
||||
minetest.sound_play(sound, {
|
||||
to_player = pointed_thing.ref:get_player_name(),
|
||||
pos = user:get_pos(),
|
||||
gain = 10.0,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing == nil then return end
|
||||
if pointed_thing.type == 'node' then
|
||||
|
||||
if vector.distance(pointed_thing.under, placer:get_pos()) < stick_vault_reach then
|
||||
local first_use = false
|
||||
local imeta = itemstack:get_meta()
|
||||
local old_time = imeta:get_int('old_time')
|
||||
local current_time = minetest.get_gametime()
|
||||
if old_time == 0 or old_time == nil then
|
||||
first_use = true
|
||||
end
|
||||
if first_use or current_time > old_time + stick_vault_timeout then
|
||||
local lookvect = placer:get_look_dir()
|
||||
local pushvect = vector.normalize( {x=lookvect.x, z=lookvect.z, y= math.sqrt(1-(lookvect.y*lookvect.y))})
|
||||
--gives a unit vector that is 90 deg offset in the vert direction
|
||||
local force = 10 * vector.length(vector.normalize( {x=lookvect.x, z=lookvect.z, y= 0}))
|
||||
|
||||
placer:add_player_velocity(vector.multiply(pushvect, force))
|
||||
--update the staff time for next check
|
||||
local sound = 'jump'..math.random(1,2)
|
||||
minetest.sound_play(sound, {
|
||||
pos = placer:get_pos(),
|
||||
max_hear_distance = 10,
|
||||
gain = 10.0,
|
||||
})
|
||||
|
||||
imeta:set_int('old_time', current_time)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
})
|
|
@ -0,0 +1,126 @@
|
|||
minetest.register_node("sumo:player_killer_air", {
|
||||
description = "Sumo Arena Player Killer Air",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
|
||||
walkable = false,
|
||||
pointable = true,
|
||||
diggable = true,
|
||||
buildable_to = false,
|
||||
drop = "",
|
||||
damage_per_second = 40,
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("sumo:fullclip", {
|
||||
description = "Player Blocker (sumo)",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
|
||||
walkable = true,
|
||||
pointable = true,
|
||||
diggable = false,
|
||||
buildable_to = false,
|
||||
drop = "",
|
||||
damage_per_second = 40,
|
||||
groups = {},
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("sumo:player_killer_water_source", {
|
||||
description = "Sumo Arena Player Killer Water Source",
|
||||
drawtype = "liquid",
|
||||
waving = 3,
|
||||
tiles = {
|
||||
{
|
||||
name = "default_water_source_animated.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "default_water_source_animated.png",
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
damage_per_second = 40,
|
||||
alpha = 191,
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
liquidtype = "source",
|
||||
liquid_alternative_flowing = "sumo:player_killer_water_flowing",
|
||||
liquid_alternative_source = "sumo:player_killer_water_source",
|
||||
liquid_viscosity = 1,
|
||||
post_effect_color = {a = 103, r = 30, g = 60, b = 90},
|
||||
groups = {water = 3, liquid = 3, cools_lava = 1},
|
||||
sounds = default.node_sound_water_defaults(),
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("sumo:player_killer_water_flowing", {
|
||||
description = "Sumo Arena Player Killer Water Flowing",
|
||||
drawtype = "flowingliquid",
|
||||
waving = 3,
|
||||
tiles = {"default_water.png"},
|
||||
special_tiles = {
|
||||
{
|
||||
name = "default_water_flowing_animated.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 0.5,
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "default_water_flowing_animated.png",
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 0.5,
|
||||
},
|
||||
},
|
||||
},
|
||||
damage_per_second = 200,
|
||||
alpha = 191,
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
liquidtype = "flowing",
|
||||
liquid_alternative_flowing = "sumo:player_killer_water_flowing",
|
||||
liquid_alternative_source = "sumo:player_killer_water_source",
|
||||
liquid_viscosity = 1,
|
||||
post_effect_color = {a = 103, r = 30, g = 60, b = 90},
|
||||
groups = {water = 3, liquid = 3, not_in_creative_inventory = 1,
|
||||
cools_lava = 1},
|
||||
sounds = default.node_sound_water_defaults(),
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
minetest.register_privilege("sumo_admin", {
|
||||
description = "With this you can use /sumo create, edit"
|
||||
})
|
|
@ -0,0 +1,31 @@
|
|||
Sumo mod by MisterE for use with arena_lib (minigame_lib) You should be familiar with how to set up arena_lib arenas.
|
||||
|
||||
Code snippets from https://gitlab.com/zughy-friends-minetest/arena_lib/-/blob/master/DOCS.md and from Zughy's minigames
|
||||
|
||||
|
||||
to set up an arena, create a confined space that floats in the air, with lava or other damage blocks beneath. Set the spawners on the platform. You can use mesecons to make the board more interesting.
|
||||
|
||||
In this game, each player gets a tool that pushes other players... the goal is to knowck all other players off and be the last one standing. Each player gets 3 lives
|
||||
|
||||
|
||||
Basic setup:
|
||||
|
||||
1) type /sumo create <arena_name>
|
||||
2) type /sumo edit <arena_name>
|
||||
3) use the editor to place a minigame sign, assign it to your minigame.
|
||||
4) while in the editor, move to where your arena will be.
|
||||
5) Make your arena. There should be some type of platform, with a lava pool underneath to kill players that fall off.
|
||||
6) using the editor tools, mark player spawner locations. Protect the arena.
|
||||
7) exit the editor mode
|
||||
8) type /minigamesettings sumo
|
||||
9) change the hub spawnpoint to be next to the signs.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 385 KiB |
Loading…
Reference in New Issue