2017-07-27 03:42:24 -07:00
|
|
|
----------------------------------------------------------------------
|
2020-08-29 18:08:20 -07:00
|
|
|
-- Eggwars by wilkgr --
|
|
|
|
-- with additional code by shivajiva101@hotmail.com --
|
2017-07-27 03:42:24 -07:00
|
|
|
-- Licensed under the AGPL v3 --
|
|
|
|
-- You MUST make any changes you make open source --
|
|
|
|
-- even if you just run it on your server without publishing it --
|
2020-08-12 09:08:29 -07:00
|
|
|
-- Supports a maximum of 8 players per instance and 8 concurrent --
|
|
|
|
-- instances for a max of 64 players --
|
2017-07-27 03:42:24 -07:00
|
|
|
----------------------------------------------------------------------
|
2017-07-23 21:21:01 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.set_mapgen_params({mgname = "singlenode"})
|
|
|
|
math.randomseed(os.time())
|
|
|
|
|
2017-07-23 17:55:17 -07:00
|
|
|
eggwars = {}
|
2020-08-12 09:08:29 -07:00
|
|
|
eggwars.arena = {}
|
|
|
|
eggwars.armor = minetest.get_modpath("3d_armor") ~= nil
|
|
|
|
eggwars.bows = minetest.get_modpath("bows") ~= nil
|
2020-09-18 12:26:42 -07:00
|
|
|
eggwars.playertag = minetest.get_modpath("playertag") ~= nil
|
2020-09-20 11:21:19 -07:00
|
|
|
eggwars.gauges = minetest.get_modpath("gauges") ~= nil
|
2020-08-12 09:08:29 -07:00
|
|
|
eggwars.match = {}
|
|
|
|
eggwars.player = {}
|
|
|
|
|
|
|
|
---------------------
|
|
|
|
-- Local Variables --
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
local mod_data = minetest.get_mod_storage() -- mod storage
|
2017-07-27 03:42:24 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
local arena_pos = {
|
2020-08-27 13:16:24 -07:00
|
|
|
{x = 0, y = 0, z = 0},
|
|
|
|
{x = 1000, y = 0, z = 0},
|
|
|
|
{x = 0, y = 0, z = 1000},
|
|
|
|
{x = 1000, y = 0, z = 1000},
|
|
|
|
{x = -1000, y = 0, z = 0},
|
|
|
|
{x = 0, y = 0, z = -1000},
|
|
|
|
{x = -1000, y = 0, z = -1000},
|
|
|
|
{x = -2000, y = 0, z = 0}
|
2017-07-25 03:40:58 -07:00
|
|
|
}
|
2020-08-12 09:08:29 -07:00
|
|
|
local loaded = minetest.deserialize(mod_data:get_string('loaded')) or {arena = {}}
|
|
|
|
local lobby = {
|
2020-08-27 13:16:24 -07:00
|
|
|
insert_offset = {x = -42, y = -14, z = -30},
|
|
|
|
pos = {x = 0, y = 1000, z = 0},
|
|
|
|
region = {
|
|
|
|
p1 = {x = -83, y = 980, z = -83},
|
|
|
|
p2 = {x = 83, y = 1030, z = 83}
|
|
|
|
}
|
2020-08-12 09:08:29 -07:00
|
|
|
}
|
2020-08-12 09:49:02 -07:00
|
|
|
local min_match_players = 4 -- min players needed for a match (default = 4)
|
2020-08-17 14:52:26 -07:00
|
|
|
local owner = minetest.settings:get('name')
|
2020-08-12 09:08:29 -07:00
|
|
|
local MP = minetest.get_modpath("eggwars")
|
|
|
|
local WP = minetest.get_worldpath()
|
|
|
|
local registered_players = {} -- temp prematch buffer
|
|
|
|
local schempath = MP.."/schems/"
|
2020-09-01 16:09:18 -07:00
|
|
|
local stats = minetest.deserialize(mod_data:get_string('statistics')) or {}
|
2020-10-11 12:09:00 -07:00
|
|
|
local dev = false -- set this to true if testing locally
|
|
|
|
local reload = dev == false
|
2020-08-12 09:08:29 -07:00
|
|
|
local tmp_tbl, tmp_hud = {}, {}
|
|
|
|
local r_rate = 5
|
|
|
|
|
|
|
|
stats.rankings = stats.rankings or {}
|
|
|
|
|
2020-09-01 16:09:18 -07:00
|
|
|
if reload then loaded = {
|
|
|
|
arena = {}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
dofile(MP .. "/register_arena.lua")
|
|
|
|
dofile(MP.."/register_nodes.lua")
|
|
|
|
dofile(MP.."/shop.lua")
|
|
|
|
dofile(MP .. "/extender.lua")
|
|
|
|
dofile(MP .. "/tools.lua")
|
2020-09-16 06:52:29 -07:00
|
|
|
dofile(MP .. "/sprint.lua")
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
----------------------
|
|
|
|
-- Helper Functions --
|
|
|
|
----------------------
|
2017-03-28 02:08:05 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
--- Sets server conf settings
|
2020-08-12 09:08:29 -07:00
|
|
|
-- @return nothing
|
2020-08-17 12:26:52 -07:00
|
|
|
local function set_settings()
|
2020-09-16 07:40:10 -07:00
|
|
|
minetest.settings:set('player_transfer_distance', 12)
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.settings:set('time_speed', 0)
|
2020-08-18 11:08:41 -07:00
|
|
|
minetest.settings:write()
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.set_timeofday(0.5) -- noon
|
2017-03-29 18:11:07 -07:00
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Remove objects and replace region with air
|
|
|
|
-- @param pos1 - vector table
|
|
|
|
-- @param pos2 - vector table
|
|
|
|
-- @return nothing
|
|
|
|
local function clean(pos1, pos2)
|
2020-08-18 11:08:41 -07:00
|
|
|
eggwars.clear_nodes(pos1, pos2)
|
|
|
|
eggwars.fixlight(pos1, pos2)
|
2020-08-12 09:08:29 -07:00
|
|
|
eggwars.clear_objects(pos1, pos2)
|
2017-03-29 18:11:07 -07:00
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Remove objects and replace region with air
|
|
|
|
-- @param pos - vector table
|
|
|
|
-- @param region - vector pair table
|
|
|
|
-- @return nothing
|
2020-08-27 13:16:24 -07:00
|
|
|
-- local function clear(pos, region)
|
|
|
|
-- local p1 = vector.add(pos, region.p1)
|
|
|
|
-- local p2 = vector.add(pos, region.p2)
|
|
|
|
-- clean(p1, p2)
|
|
|
|
-- end
|
2018-06-25 02:34:16 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Save persistant data
|
|
|
|
-- @return nothing
|
|
|
|
local function save_persistant()
|
2020-09-01 16:09:18 -07:00
|
|
|
mod_data:set_string('statistics', minetest.serialize(stats))
|
|
|
|
mod_data:set_string('dirty', reload)
|
2020-08-12 09:08:29 -07:00
|
|
|
mod_data:set_string('loaded', minetest.serialize(loaded))
|
|
|
|
end
|
2017-03-29 18:11:07 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Create and return a unique integer
|
|
|
|
-- @param tbl temp table
|
|
|
|
-- @param from - start integer
|
|
|
|
-- @param to - end integer
|
|
|
|
-- @return random unique integer between from & to
|
|
|
|
local function my_random(tbl, from, to)
|
|
|
|
local num = math.random (from, to)
|
|
|
|
if tbl[num] then num = my_random(tbl, from, to) end
|
2020-08-27 13:16:24 -07:00
|
|
|
tbl[num] = num
|
|
|
|
return num
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Generate a random unique list for the trader name order
|
|
|
|
-- @return table of unique random integers
|
|
|
|
local function gen_trader_order()
|
|
|
|
local tbl = {}
|
2020-08-27 13:16:24 -07:00
|
|
|
for i = 1, 8 do
|
|
|
|
tbl[#tbl + 1] = my_random(tmp_tbl, 1, 8)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
tmp_tbl = {}
|
|
|
|
return tbl
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Finds first unused arena index
|
|
|
|
-- @return integer index or nil if all arenas are in use!
|
|
|
|
local function next_index()
|
2020-08-18 11:08:41 -07:00
|
|
|
for i, _ in ipairs(arena_pos) do
|
|
|
|
local used
|
|
|
|
for _, v in pairs(eggwars.match) do
|
|
|
|
if v.id == i then
|
|
|
|
used = true
|
|
|
|
break -- jump to the outer loop
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not used then return i end
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Check path for correct file presence
|
|
|
|
-- @param path: folder to check
|
|
|
|
-- @param name: filename without extension
|
|
|
|
-- @return truth table including count
|
|
|
|
local function check_files(path, name)
|
|
|
|
|
|
|
|
local extension, file, err
|
|
|
|
local list = {}
|
|
|
|
list.n = 0
|
|
|
|
extension = {"mts", "ewm"}
|
|
|
|
|
|
|
|
for _, entry in ipairs(extension) do
|
|
|
|
local filename = path .. name .. "." .. entry
|
2020-08-27 13:16:24 -07:00
|
|
|
file, err = io.open(filename, "rb")
|
2020-08-12 09:08:29 -07:00
|
|
|
if err then
|
|
|
|
list[entry] = false
|
|
|
|
else
|
|
|
|
file:close()
|
|
|
|
list[entry] = true
|
|
|
|
list.n = list.n + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return list
|
2020-08-27 13:16:24 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Inserts & protects the lobby in a new instance
|
|
|
|
-- @return nothing
|
|
|
|
local function add_lobby()
|
2020-08-18 11:08:41 -07:00
|
|
|
-- calculate insertion pos, place schema, protect & save to settings
|
|
|
|
local pos = vector.add(lobby.pos, lobby.insert_offset)
|
|
|
|
minetest.place_schematic(pos, schempath.."lobby.mts")
|
|
|
|
eggwars.protect(lobby.region.p1, lobby.region.p2, false)
|
|
|
|
loaded.lobby = true
|
|
|
|
save_persistant()
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
-- lobby loading
|
|
|
|
if not loaded.lobby then
|
|
|
|
minetest.after(0, add_lobby)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Add match status flags to players HUD
|
|
|
|
-- @param key - match key string
|
|
|
|
-- @return nothing
|
|
|
|
local function gen_match_hud(key)
|
|
|
|
|
|
|
|
local match = eggwars.match[key]
|
|
|
|
local pos = - (0.5 * (#match.player * 20) - 2)
|
|
|
|
local result = {}
|
2020-08-27 13:16:24 -07:00
|
|
|
for _, def in pairs(match.hud_img) do
|
2020-08-12 09:08:29 -07:00
|
|
|
local ndef = {
|
|
|
|
hud_elem_type = 'image',
|
2020-08-27 13:16:24 -07:00
|
|
|
position = {x = 0.5, y = 1},
|
|
|
|
scale = {x = 1, y = 1},
|
2020-08-20 14:52:59 -07:00
|
|
|
text = def[1],
|
2020-08-27 13:16:24 -07:00
|
|
|
alignment = {x = 0, y = 0}, -- table reqd
|
|
|
|
offset = {x = pos, y = -100}
|
2020-08-12 09:08:29 -07:00
|
|
|
}
|
|
|
|
table.insert(result, ndef)
|
|
|
|
pos = pos + 20
|
|
|
|
end
|
|
|
|
|
|
|
|
for k, def in pairs(match.player) do
|
|
|
|
local player = minetest.get_player_by_name(k)
|
|
|
|
for i, v in ipairs(result) do
|
|
|
|
def.hud_id[i] = player:hud_add(v)
|
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
-- Add Lozenge
|
2020-08-12 09:08:29 -07:00
|
|
|
def.pil = player:hud_add({
|
|
|
|
hud_elem_type = 'image',
|
2020-08-27 13:16:24 -07:00
|
|
|
position = {x = 0, y = 1},
|
|
|
|
scale = {x = 1, y = 0.5},
|
2020-08-12 09:08:29 -07:00
|
|
|
text = 'eggwars_pil.png',
|
2020-08-27 13:16:24 -07:00
|
|
|
alignment = {x = 0, y = 0}, -- table reqd
|
|
|
|
offset = {x = 70, y = -20}
|
2020-08-12 09:08:29 -07:00
|
|
|
})
|
|
|
|
-- Add match time element
|
|
|
|
def.remaining = player:hud_add({
|
|
|
|
hud_elem_type = 'text',
|
2020-08-27 13:16:24 -07:00
|
|
|
position = {x = 0, y = 1},
|
|
|
|
scale = {x = 128, y = 64},
|
2020-08-12 09:08:29 -07:00
|
|
|
text = 'Remaining: ' .. match.hud_time .. 'm',
|
|
|
|
number = '0x00FF00',
|
2020-08-27 13:16:24 -07:00
|
|
|
alignment = {x = 0, y = 0}, -- table reqd
|
|
|
|
offset = {x = 70, y = -20}
|
2020-08-12 09:08:29 -07:00
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-08-29 18:08:20 -07:00
|
|
|
--- Remove player hud match elements
|
|
|
|
-- @param name - players name string
|
|
|
|
-- @param key - match key string
|
|
|
|
-- @return nothing
|
|
|
|
local function remove_player_hud(name)
|
|
|
|
local obj = minetest.get_player_by_name(name)
|
|
|
|
if not obj then return end
|
|
|
|
local key = eggwars.player[name]
|
|
|
|
local def = eggwars.match[key].player[name]
|
|
|
|
for _, v in ipairs(def.hud_id) do
|
|
|
|
obj:hud_remove(v)
|
|
|
|
end
|
|
|
|
obj:hud_remove(def.remaining)
|
|
|
|
obj:hud_remove(def.pil)
|
2020-09-22 11:25:04 -07:00
|
|
|
obj:hud_remove(def.waypoint)
|
2020-08-29 18:08:20 -07:00
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Remove match status flags from players HUD
|
|
|
|
-- @param key - arena key string
|
|
|
|
-- @return nothing
|
|
|
|
local function remove_match_hud(key)
|
2020-08-29 18:08:20 -07:00
|
|
|
for k, _ in pairs(eggwars.match[key].player) do
|
|
|
|
remove_player_hud(k)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-08-29 18:08:20 -07:00
|
|
|
--- Add an image to a players HUD that removes itself
|
2020-08-12 09:08:29 -07:00
|
|
|
-- @param player - object
|
|
|
|
-- @param image_string - filename of image
|
|
|
|
-- @param timer - time in seconds it displays
|
|
|
|
-- @return nothing
|
2020-09-18 08:47:58 -07:00
|
|
|
function eggwars.add_tmp_image(name, image_string, timer)
|
2020-09-18 13:15:54 -07:00
|
|
|
local player = minetest.get_player_by_name(name)
|
2020-08-12 09:08:29 -07:00
|
|
|
tmp_hud[name] = player:hud_add({
|
|
|
|
hud_elem_type = 'image',
|
2020-08-27 13:16:24 -07:00
|
|
|
position = {x = 0.5, y = 0.5},
|
|
|
|
scale = {x = 1, y = 1},
|
2020-08-12 09:08:29 -07:00
|
|
|
text = image_string,
|
2020-08-27 13:16:24 -07:00
|
|
|
alignment = {x = 0, y = 0}, -- table reqd
|
|
|
|
offset = {x = 0, y = 0}
|
2020-08-12 09:08:29 -07:00
|
|
|
})
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.after(timer, function(pname)
|
2020-08-29 18:08:20 -07:00
|
|
|
eggwars.remove_tmp_image(pname)
|
2020-08-12 09:08:29 -07:00
|
|
|
end, name)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Remove recipes blocked in arena defs
|
|
|
|
-- NOTE: this function MUST NOT be run with minetest.after it will
|
|
|
|
-- cause a SIGSEGV error on server shutdown!!!
|
|
|
|
-- @return nothing
|
|
|
|
local function modify_recipes()
|
|
|
|
for i, arena in ipairs(eggwars.arena) do
|
|
|
|
for j, v in ipairs(arena.blocked_recipes) do
|
|
|
|
minetest.clear_craft(v)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
modify_recipes()
|
|
|
|
|
|
|
|
--- Make non expempt nodes unbreakable
|
|
|
|
-- @return nothing
|
|
|
|
local function modify_game()
|
|
|
|
-- create a list of exempt nodes from the registered arenas
|
|
|
|
local exempt_node = {}
|
|
|
|
for _, arena in ipairs(eggwars.arena) do
|
2020-08-27 13:16:24 -07:00
|
|
|
for _, v in ipairs(arena.exempt_nodes) do
|
2020-08-12 09:08:29 -07:00
|
|
|
table.insert(exempt_node, v)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- parse registered nodes
|
|
|
|
for item, def in pairs(minetest.registered_nodes) do
|
|
|
|
local modify = true
|
2020-08-27 13:16:24 -07:00
|
|
|
for i, v in ipairs(exempt_node) do
|
2020-08-12 09:08:29 -07:00
|
|
|
if string.find(item, v) then
|
|
|
|
modify = false
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if modify then
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.override_item(item, {groups = {unbreakable = 1}, })
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Provides match events based on time
|
|
|
|
-- @return nothing
|
|
|
|
local function match_timer()
|
|
|
|
-- process each match
|
|
|
|
for key, def in pairs(eggwars.match) do
|
|
|
|
def.tmr = def.tmr + r_rate
|
|
|
|
if not def.sd and def.tmr >= def.suddendeath then
|
|
|
|
def.sd = true
|
|
|
|
for k, v in pairs(def.player) do
|
|
|
|
-- remove remaining eggs
|
|
|
|
if v.egg then
|
|
|
|
minetest.remove_node(v.eggpos)
|
|
|
|
v.egg = false
|
|
|
|
minetest.sound_play("eggwars_out", {
|
|
|
|
to_player = k,
|
|
|
|
gain = 1.0,
|
|
|
|
})
|
2020-08-20 16:49:04 -07:00
|
|
|
eggwars.update_hud(key, v.id)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
minetest.sound_play("eggwars_sudden", {
|
|
|
|
to_player = k,
|
|
|
|
gain = 1.0,
|
|
|
|
})
|
2020-09-18 08:47:58 -07:00
|
|
|
eggwars.add_tmp_image(k, 'eggwars_suddendeath.png', 5)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
if def.sd and def.tmr >= def.max_time then
|
|
|
|
for k, v in pairs(def.player) do
|
|
|
|
minetest.sound_play("eggwars_time_over", {
|
2020-08-27 13:16:24 -07:00
|
|
|
to_player = k,
|
|
|
|
gain = 1.0,
|
|
|
|
})
|
2020-09-18 08:47:58 -07:00
|
|
|
eggwars.add_tmp_image(k, 'eggwars_timeover.png', 5)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
eggwars.end_match(key)
|
|
|
|
end
|
2020-09-14 11:02:45 -07:00
|
|
|
for k, v in pairs(def.player) do
|
|
|
|
local player = minetest.get_player_by_name(k)
|
|
|
|
local hp = player:get_hp()
|
|
|
|
if hp > 0 and v.alive then
|
|
|
|
local res = hp + 1
|
|
|
|
local max = player:get_properties().hp_max
|
|
|
|
if res > max then
|
|
|
|
res = max
|
|
|
|
end
|
|
|
|
if hp ~= res then
|
|
|
|
player:set_hp(res)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
-- finally retrigger
|
|
|
|
minetest.after(r_rate, match_timer)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Initialises stats for a new player
|
|
|
|
-- @param name - players name string
|
|
|
|
-- @return nothing
|
|
|
|
local function initialise_stats(name)
|
|
|
|
stats.player = stats.player or {}
|
|
|
|
if not stats.player[name] then
|
|
|
|
stats.player[name] = {
|
|
|
|
damage = 0,
|
|
|
|
eggs = 0,
|
|
|
|
falls = 0,
|
|
|
|
kills = 0,
|
|
|
|
pb = {
|
|
|
|
time = 0, -- utc
|
|
|
|
kills = 0,
|
|
|
|
falls = 0,
|
|
|
|
damage = 0
|
|
|
|
},
|
|
|
|
plays = 0,
|
|
|
|
rank = 0,
|
|
|
|
wins = 0,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Displays match results as a formspec
|
2020-10-11 12:09:00 -07:00
|
|
|
-- @param match - table of ranked match players
|
2020-08-12 09:08:29 -07:00
|
|
|
-- @param arena_id - integer index of arena
|
|
|
|
-- @return nothing
|
2020-10-11 12:09:00 -07:00
|
|
|
local function display_match_results(match, arena_id)
|
2020-08-12 09:08:29 -07:00
|
|
|
local get_player_by_name = minetest.get_player_by_name
|
|
|
|
local fs = {
|
|
|
|
'size[8,6]',
|
|
|
|
'label[0,0;Rank]',
|
|
|
|
'label[1,0;Name]',
|
|
|
|
'label[4,0;Kills]',
|
|
|
|
'label[5,0;Points]',
|
|
|
|
'label[6.1,0;Eggs]',
|
|
|
|
'label[7,0;Falls]'
|
|
|
|
}
|
2020-10-11 12:09:00 -07:00
|
|
|
for i, v in ipairs(match) do
|
2020-08-12 09:08:29 -07:00
|
|
|
local c = eggwars.arena[arena_id].colour[v.id]
|
2020-08-27 13:16:24 -07:00
|
|
|
fs[#fs + 1] = 'label[0,'..(0.5 * i)..';'..eggwars.colorize(c, i)..']'
|
|
|
|
fs[#fs + 1] = 'label[1,'..(0.5 * i)..';'..eggwars.colorize(c, v.name)..']'
|
|
|
|
fs[#fs + 1] = 'label[4,'..(0.5 * i)..';'..eggwars.colorize(c, v.kills)..']'
|
|
|
|
fs[#fs + 1] = 'label[5,'..(0.5 * i)..';'..eggwars.colorize(c, v.damage)..']'
|
|
|
|
fs[#fs + 1] = 'label[6.1,'..(0.5 * i)..';'..eggwars.colorize(c, v.eggs)..']'
|
|
|
|
fs[#fs + 1] = 'label[7,'..(0.5 * i)..';'..eggwars.colorize(c, v.falls)..']'
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
fs[#fs + 1] = 'button_exit[3,5;2,1;btn_e;OK]'
|
2020-08-12 09:08:29 -07:00
|
|
|
local res = table.concat(fs)
|
2020-10-11 12:09:00 -07:00
|
|
|
for i, v in ipairs(match) do
|
2020-08-12 09:08:29 -07:00
|
|
|
local player = get_player_by_name(v.name)
|
|
|
|
if player then
|
|
|
|
minetest.show_formspec(v.name, '', res)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-09-05 14:36:54 -07:00
|
|
|
--- Displays stats as a formspec
|
|
|
|
-- @param name - name of player requesting info
|
|
|
|
-- @return nothing
|
|
|
|
local function display_stats(name)
|
|
|
|
local fs = {
|
|
|
|
'size[9,7]',
|
|
|
|
'label[0,0;Rank]',
|
|
|
|
'label[1,0;Name]',
|
|
|
|
'label[4,0;Wins]',
|
|
|
|
'label[5,0;Kills]',
|
|
|
|
'label[6,0;Points]',
|
|
|
|
'label[7.1,0;Eggs]',
|
|
|
|
'label[8,0;Falls]'
|
|
|
|
}
|
|
|
|
for i,v in ipairs(stats.rankings) do
|
2020-09-05 15:01:30 -07:00
|
|
|
local c = 'lime'
|
|
|
|
fs[#fs + 1] = 'label[0,'..(0.5 * i)..';'.. minetest.colorize(c, i) ..']'
|
|
|
|
fs[#fs + 1] = 'label[1,'..(0.5 * i)..';'.. minetest.colorize(c, v.name) ..']'
|
|
|
|
fs[#fs + 1] = 'label[4,'..(0.5 * i)..';'.. minetest.colorize(c, v.wins) ..']'
|
|
|
|
fs[#fs + 1] = 'label[5,'..(0.5 * i)..';'.. minetest.colorize(c, v.kills) ..']'
|
|
|
|
fs[#fs + 1] = 'label[6,'..(0.5 * i)..';'.. minetest.colorize(c, v.damage) ..']'
|
|
|
|
fs[#fs + 1] = 'label[7.1,'..(0.5 * i)..';'.. minetest.colorize(c, v.eggs) ..']'
|
|
|
|
fs[#fs + 1] = 'label[8,'..(0.5 * i)..';'.. minetest.colorize(c, v.falls) ..']'
|
2020-09-05 14:36:54 -07:00
|
|
|
if i == 10 then break end
|
|
|
|
end
|
|
|
|
fs[#fs + 1] = 'button_exit[3.5,6;2,1;btn_e;OK]'
|
|
|
|
local res = table.concat(fs)
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
|
|
if player then
|
|
|
|
minetest.show_formspec(name, '', res)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Updates match players game time hud display every minute
|
|
|
|
-- @return nothing
|
|
|
|
local function update_hud_time()
|
2020-08-18 11:08:41 -07:00
|
|
|
for key, match in pairs(eggwars.match) do
|
|
|
|
match.hud_time = match.hud_time - 1
|
2020-08-19 14:19:29 -07:00
|
|
|
eggwars.update_hud(key)
|
2020-08-18 11:08:41 -07:00
|
|
|
end
|
|
|
|
minetest.after(60, update_hud_time)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
--- Spawns a player in the first pair of vertical air nodes above minp
|
|
|
|
-- @return vector
|
2020-08-12 09:08:29 -07:00
|
|
|
local function safe_spawn(minp)
|
2020-08-27 13:16:24 -07:00
|
|
|
local maxp = vector.new(minp.x, minp.y + 20, minp.z)
|
2020-08-12 09:08:29 -07:00
|
|
|
local pos = minetest.find_nodes_in_area(minp, maxp, 'air')
|
|
|
|
local res = minp
|
2020-08-27 13:16:24 -07:00
|
|
|
for i, v in ipairs(pos) do
|
2020-08-18 17:50:39 -07:00
|
|
|
if i > 1 and res.y == v.y - 1 then
|
2020-08-12 09:08:29 -07:00
|
|
|
return res -- 2 vertical air nodes
|
|
|
|
else
|
|
|
|
res = v
|
|
|
|
end
|
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
return minp -- failed search
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
2020-08-29 18:08:20 -07:00
|
|
|
--- Removes a player from a match
|
|
|
|
-- @param name - player name strings
|
|
|
|
-- @return nothing
|
2020-08-29 15:39:47 -07:00
|
|
|
local function remove_match_player(name)
|
|
|
|
if eggwars.player[name] then
|
|
|
|
local key, match, player, count
|
|
|
|
key = eggwars.player[name]
|
|
|
|
match = eggwars.match[key]
|
|
|
|
player = match.player[name]
|
|
|
|
if match.alive == 1 then
|
|
|
|
eggwars.end_match(key)
|
|
|
|
else
|
2020-09-05 14:24:59 -07:00
|
|
|
if player.egg then
|
|
|
|
minetest.remove_node(player.eggpos)
|
|
|
|
end
|
|
|
|
remove_player_hud(name)
|
|
|
|
count = match.alive - 1
|
|
|
|
match.alive = count
|
|
|
|
match.player[name].alive = false
|
|
|
|
match.player[name].egg = false
|
|
|
|
eggwars.match[key] = match
|
|
|
|
eggwars.player[name] = nil
|
2020-09-01 16:09:18 -07:00
|
|
|
player = minetest.get_player_by_name(name)
|
|
|
|
player:set_pos(lobby.pos)
|
2020-08-29 15:39:47 -07:00
|
|
|
local msg = name .. " quit the match!"
|
|
|
|
eggwars.chat_send_match(key, msg)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-09-01 16:09:18 -07:00
|
|
|
--- Return length of a keypair table
|
|
|
|
-- @param list - keypair table
|
|
|
|
-- @return integer
|
|
|
|
local function list_count(list)
|
|
|
|
local count = 0
|
|
|
|
for k, _ in pairs(list) do
|
|
|
|
count = count + 1
|
|
|
|
end
|
|
|
|
return count
|
|
|
|
end
|
|
|
|
|
2020-09-15 14:57:04 -07:00
|
|
|
--- Add entities to a match
|
|
|
|
-- @param key - match key string
|
|
|
|
-- @return nothing
|
|
|
|
local function add_match_entities(key)
|
|
|
|
|
|
|
|
local uid = os.time()
|
|
|
|
eggwars.match[key].uid = uid
|
|
|
|
|
|
|
|
local match = eggwars.match[key]
|
|
|
|
local def = eggwars.arena[match.arena]
|
|
|
|
local rnd_list = gen_trader_order()
|
|
|
|
|
|
|
|
local pos = arena_pos[match.id]
|
|
|
|
|
|
|
|
for name, data in pairs(match.player) do
|
|
|
|
local id = data.id
|
|
|
|
local sp = vector.add(pos, def.island[id])
|
|
|
|
-- Add spawner bot
|
|
|
|
local adj = vector.add(sp, def.bot.offset[id])
|
|
|
|
local staticdata = minetest.serialize({uid = uid, owner = name})
|
|
|
|
local obj = minetest.add_entity(adj, 'eggwars:bot', staticdata)
|
|
|
|
local yaw = ((math.pi * def.bot.yaw[id]) / 180)
|
|
|
|
obj:set_yaw(yaw)
|
|
|
|
-- Add trader
|
|
|
|
local trader_name = 'Trader '.. def.trader.names[rnd_list[id]]
|
|
|
|
staticdata = minetest.serialize({owner = name, nametag = trader_name, uid = uid})
|
|
|
|
adj = vector.add(sp, def.trader.offset[id])
|
|
|
|
obj = minetest.add_entity(adj, 'eggwars:trader', staticdata)
|
|
|
|
yaw = ((math.pi * def.trader.yaw[id]) / 180)
|
|
|
|
obj:set_yaw(yaw)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-08-19 12:28:51 -07:00
|
|
|
-------------------
|
|
|
|
-- API Functions --
|
|
|
|
-------------------
|
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
--- Removes a temp player hud image
|
2020-08-12 09:08:29 -07:00
|
|
|
-- @param name - players name
|
|
|
|
-- @return nothing
|
2020-08-29 18:08:20 -07:00
|
|
|
eggwars.remove_tmp_image = function(name)
|
2020-08-12 09:08:29 -07:00
|
|
|
if tmp_hud[name] then
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
|
|
player:hud_remove(tmp_hud[name])
|
|
|
|
tmp_hud[name] = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
--- Update match status in players HUD
|
2020-08-19 12:28:51 -07:00
|
|
|
-- @param key - arena key string
|
2020-08-27 13:16:24 -07:00
|
|
|
-- @param id - hud element index, if omitted time is updated
|
2020-08-19 12:28:51 -07:00
|
|
|
-- @return nothing
|
|
|
|
eggwars.update_hud = function(key, id)
|
2020-08-20 14:52:59 -07:00
|
|
|
local match = eggwars.match[key]
|
|
|
|
for k, def in pairs(match.player) do
|
2020-08-19 12:28:51 -07:00
|
|
|
local obj = minetest.get_player_by_name(k)
|
|
|
|
if not id then
|
|
|
|
obj:hud_change(def.remaining, 'text', 'Remaining: ' ..
|
2020-08-27 13:16:24 -07:00
|
|
|
eggwars.match[key].hud_time .. 'm')
|
2020-08-19 12:28:51 -07:00
|
|
|
else
|
2020-08-20 14:52:59 -07:00
|
|
|
obj:hud_change(def.hud_id[id], 'text', match.hud_img[id][2])
|
2020-08-19 12:28:51 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
--- Reset arena by index
|
|
|
|
-- @param arena integer index of registered arena
|
|
|
|
-- @param n integer index of arena instance
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.reset = function(arena, n)
|
|
|
|
local def = eggwars.arena[arena]
|
2020-08-18 11:08:41 -07:00
|
|
|
local pos = arena_pos[n]
|
|
|
|
local p1 = vector.add(pos, def.region.p1)
|
|
|
|
local p2 = vector.add(pos, def.region.p2)
|
|
|
|
clean(p1, p2)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Spawn hub islands for an arena instance
|
|
|
|
-- @param arena integer index of registered arena
|
|
|
|
-- @param n integer index of arena
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.centrespawn = function(id, n)
|
|
|
|
local def = eggwars.arena[id]
|
2020-08-18 11:08:41 -07:00
|
|
|
local spwn = arena_pos[n]
|
|
|
|
local p1 = vector.add(spwn, def.hub.offset)
|
|
|
|
minetest.place_schematic(p1, schempath .. def.hub.schem)
|
2020-08-12 09:08:29 -07:00
|
|
|
-- place satellites
|
2020-08-27 13:16:24 -07:00
|
|
|
for i, v in ipairs(def.satellite.pos) do
|
2020-08-12 09:08:29 -07:00
|
|
|
p1 = vector.add(vector.add(spwn, v), def.satellite.offset)
|
|
|
|
minetest.place_schematic(p1, schempath ..
|
2020-08-27 13:16:24 -07:00
|
|
|
def.satellite.schem)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Spawn island at pos, indexed by n
|
|
|
|
-- @param arena integer index of registered arena
|
|
|
|
-- @param pos vector table
|
|
|
|
-- @param n integer index of island coords
|
|
|
|
-- @return spawn vector
|
|
|
|
eggwars.islandspawn = function(arena, pos, n)
|
|
|
|
local def = eggwars.arena[arena].island
|
2020-08-18 11:08:41 -07:00
|
|
|
local p1 = vector.add(pos, def.offset)
|
|
|
|
minetest.place_schematic(p1, schempath .. def.schem, def.rotate[n])
|
|
|
|
return pos
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Creates & protects an arena type in the world
|
|
|
|
-- @param id - arena index
|
|
|
|
-- @param n - arena position indexeggwars.match[key]
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.create_arena = function(id, n)
|
|
|
|
local def = eggwars.arena[id]
|
|
|
|
local pos = arena_pos[n]
|
|
|
|
eggwars.centrespawn(id, n)
|
|
|
|
for i = 1, #def.island do
|
|
|
|
local sp = vector.add(pos, def.island[i])
|
|
|
|
eggwars.islandspawn(id, sp, i)
|
|
|
|
end
|
|
|
|
local v = {
|
2020-08-18 11:08:41 -07:00
|
|
|
p1 = vector.add(pos, def.region.p1),
|
|
|
|
p2 = vector.add(pos, def.region.p2)
|
|
|
|
}
|
|
|
|
eggwars.protect(v.p1, v.p2, false)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Deletes an arena from the world
|
|
|
|
-- @param id - arena index
|
|
|
|
-- @param n - arena position index
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.delete_arena = function(arena, n)
|
|
|
|
local def = eggwars.arena[arena]
|
|
|
|
local pos = arena_pos[n]
|
|
|
|
local v = {
|
2020-08-18 11:08:41 -07:00
|
|
|
p1 = vector.add(pos, def.region.p1),
|
|
|
|
p2 = vector.add(pos, def.region.p2)
|
|
|
|
}
|
2020-08-12 09:08:29 -07:00
|
|
|
eggwars.reset(arena, n)
|
|
|
|
eggwars.delete_area(v.p1, v.p2)
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Creates a match instance from registered_players table
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.begin_match = function ()
|
2020-08-18 11:08:41 -07:00
|
|
|
-- A match consists of an instance of a registered arena between 4-8 players
|
2020-08-12 09:08:29 -07:00
|
|
|
-- match.alive - players alive count
|
2020-08-18 11:08:41 -07:00
|
|
|
-- match.arena - registered arena index
|
2020-08-20 14:52:59 -07:00
|
|
|
-- match.hud_img - egg images table
|
2020-08-12 09:08:29 -07:00
|
|
|
-- match.hud_time - remaining time in minutes
|
2020-08-18 11:08:41 -07:00
|
|
|
-- match.id - arena instance index
|
2020-08-12 09:08:29 -07:00
|
|
|
-- match.player[name]
|
|
|
|
-- alive = bool status
|
|
|
|
-- color = {r,g,b}
|
|
|
|
-- damage = hp damage
|
|
|
|
-- egg = bool - false if dug
|
|
|
|
-- eggpos = pos of players egg
|
|
|
|
-- eggs = eggs destroyed count
|
|
|
|
-- falls = fall count
|
2020-08-27 13:16:24 -07:00
|
|
|
-- hud_id = hud element ref table
|
2020-08-12 09:08:29 -07:00
|
|
|
-- id = integer - player index in the instance
|
|
|
|
-- kills = kill count
|
|
|
|
-- rate = gold spawner rate in seconds
|
|
|
|
-- shop_items = table of available items
|
|
|
|
-- spawn = spawn point
|
|
|
|
-- spawner = pos of gold spawner
|
|
|
|
-- trader = entity obj
|
2020-10-11 12:09:00 -07:00
|
|
|
-- winner = integer
|
2020-08-12 09:08:29 -07:00
|
|
|
--
|
2020-08-27 13:16:24 -07:00
|
|
|
-- match.spawners - diamond and ruby spawner positions
|
2020-08-12 09:08:29 -07:00
|
|
|
-- match.stats - match statistics
|
|
|
|
-- match.tmr - match timer
|
2020-08-18 11:08:41 -07:00
|
|
|
-- match.uid - match id
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
local match = {}
|
2020-08-27 13:16:24 -07:00
|
|
|
local n = next_index() -- arena pos index
|
2020-08-12 09:08:29 -07:00
|
|
|
local pos = arena_pos[n] -- base vector
|
2020-09-15 14:57:04 -07:00
|
|
|
local arena, def, key, spwnr, adj, hud_img
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
-- Load nonexistant arena into the map or use saved type
|
|
|
|
if not loaded.arena[n] then
|
|
|
|
arena = math.random(1, #eggwars.arena)
|
|
|
|
def = {
|
|
|
|
arena = arena,
|
|
|
|
pos = pos,
|
|
|
|
id = n
|
|
|
|
}
|
|
|
|
eggwars.create_arena(arena, n)
|
|
|
|
loaded.arena[n] = def
|
|
|
|
else
|
|
|
|
arena = loaded.arena[n].arena
|
|
|
|
end
|
|
|
|
|
|
|
|
def = eggwars.arena[arena]
|
2020-09-15 14:57:04 -07:00
|
|
|
|
|
|
|
key = 'a' .. n
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
match.alive = #registered_players
|
|
|
|
match.arena = arena
|
|
|
|
match.id = n
|
|
|
|
match.player = {}
|
|
|
|
match.spawners = {}
|
2020-08-20 14:52:59 -07:00
|
|
|
match.hud_img = {}
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
for id, name in ipairs(registered_players) do
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
local player = minetest.get_player_by_name(name)
|
|
|
|
local sp = vector.add(pos, def.island[id])
|
|
|
|
local colour = def.colour[id]
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
adj = sp
|
|
|
|
spwnr = def.spawners.gold.rate
|
|
|
|
eggwars.player[name] = key
|
|
|
|
|
|
|
|
hud_img = {}
|
|
|
|
hud_img[1] = ('eggwars_%s.png'):format(def.cs[id][3])
|
|
|
|
hud_img[2] = ('eggwars_out_%s.png'):format(def.cs[id][3])
|
2020-08-20 14:52:59 -07:00
|
|
|
table.insert(match.hud_img, hud_img)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
match.player[name] = {}
|
2020-08-12 09:08:29 -07:00
|
|
|
match.player[name].alive = true
|
2020-08-18 11:08:41 -07:00
|
|
|
match.player[name].color = colour
|
2020-08-12 09:08:29 -07:00
|
|
|
match.player[name].damage = 0
|
|
|
|
match.player[name].egg = true
|
|
|
|
match.player[name].eggs = 0
|
|
|
|
match.player[name].falls = 0
|
|
|
|
match.player[name].hud_id = {}
|
|
|
|
match.player[name].id = id
|
|
|
|
match.player[name].kills = 0
|
2020-08-18 11:08:41 -07:00
|
|
|
match.player[name].rate = spwnr
|
|
|
|
match.player[name].shop_items = {}
|
2020-08-12 09:08:29 -07:00
|
|
|
match.player[name].spawn = sp
|
2020-10-11 12:09:00 -07:00
|
|
|
match.player[name].winner = 0
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
initialise_stats(name)
|
|
|
|
|
2020-09-18 12:26:42 -07:00
|
|
|
if not eggwars.playertag then
|
|
|
|
player:set_nametag_attributes({color = colour})
|
|
|
|
end
|
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
adj.y = adj.y + 2
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
player:set_pos(adj) -- set player position first
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
-- Add gold spawner and initialise node timer
|
|
|
|
adj = vector.add(sp, def.spawners.gold[id])
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.set_node(adj, {name = 'eggwars:gold_spawner'})
|
2020-08-18 11:08:41 -07:00
|
|
|
minetest.get_node_timer(adj):start(spwnr)
|
|
|
|
match.player[name].spawner = adj
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
-- Add egg
|
|
|
|
adj = vector.add(sp, def.egg_offset[id])
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.set_node(adj, {name = 'eggwars:egg' .. id})
|
2020-08-18 11:08:41 -07:00
|
|
|
match.player[name].eggpos = adj
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-17 11:26:43 -07:00
|
|
|
-- set egg metadata
|
2020-08-18 11:08:41 -07:00
|
|
|
local meta = minetest.get_meta(adj)
|
|
|
|
meta:set_string('owner', name)
|
|
|
|
meta:set_string('infotext', name .. "'s egg")
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-10-11 12:09:00 -07:00
|
|
|
if eggwars.gauges then gauges.add(player) end -- luacheck: ignore
|
2020-09-22 11:29:47 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
-- Create players shop items table
|
|
|
|
match.player[name].shop_items = {
|
|
|
|
-- Add players wool colour
|
|
|
|
{
|
|
|
|
name = {
|
2020-08-27 13:16:24 -07:00
|
|
|
name = "wool:" .. def.cs[id][3],
|
|
|
|
count = 20,
|
|
|
|
wear = 0,
|
|
|
|
metadata = ""
|
2020-08-12 09:08:29 -07:00
|
|
|
},
|
|
|
|
description = def.cs[id][1] .. " Wool",
|
|
|
|
image = 'wool_' .. def.cs[id][3] .. '.png',
|
2020-10-11 12:09:00 -07:00
|
|
|
cost = {name = "default:gold_ingot",
|
|
|
|
count = 5,
|
|
|
|
wear = 0,
|
|
|
|
metadata = ""
|
|
|
|
},
|
2020-08-12 09:08:29 -07:00
|
|
|
entry = 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
-- Add the registered shop items
|
2020-08-27 13:16:24 -07:00
|
|
|
for j = 1, #eggwars.shop_items do -- add the rest
|
2020-08-12 09:08:29 -07:00
|
|
|
table.insert(match.player[name].shop_items, eggwars.shop_items[j])
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Give arena privs
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.set_player_privs(name, {interact = true, shout = true})
|
2020-09-22 11:29:47 -07:00
|
|
|
|
2020-10-11 12:09:00 -07:00
|
|
|
-- Set playertag colour
|
|
|
|
if eggwars.playertag then
|
|
|
|
playertag.set(player, 1, def.cs[id][2]) -- luacheck: ignore
|
|
|
|
end
|
2020-09-22 11:29:47 -07:00
|
|
|
|
2020-09-22 11:25:04 -07:00
|
|
|
-- Add home waypoint
|
|
|
|
sp.y = sp.y - 4
|
|
|
|
match.player[name].waypoint = player:hud_add({
|
|
|
|
hud_elem_type = "waypoint",
|
|
|
|
name = 'Home',
|
|
|
|
text = "m",
|
|
|
|
number = def.cs[id][4],
|
|
|
|
world_pos = sp,
|
|
|
|
})
|
2020-08-18 11:08:41 -07:00
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-10-11 12:09:00 -07:00
|
|
|
-- Add diamond spawners
|
2020-08-12 09:08:29 -07:00
|
|
|
spwnr = def.spawners.diamond.rate
|
|
|
|
for idx, v in ipairs(def.spawners.diamond) do
|
|
|
|
adj = vector.add(pos, v)
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.set_node(adj, {name = 'eggwars:diamond_spawner'})
|
|
|
|
minetest.get_node_timer(adj):start(spwnr)
|
2020-08-12 09:08:29 -07:00
|
|
|
table.insert(match.spawners, adj)
|
|
|
|
end
|
|
|
|
|
2020-10-11 12:09:00 -07:00
|
|
|
-- Add ruby spawners
|
2020-08-12 09:08:29 -07:00
|
|
|
spwnr = def.spawners.ruby.rate
|
|
|
|
for idx, v in ipairs(def.spawners.ruby) do
|
|
|
|
adj = vector.add(pos, v)
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.set_node(adj, {name = 'eggwars:ruby_spawner'})
|
|
|
|
minetest.get_node_timer(adj):start(spwnr)
|
2020-08-12 09:08:29 -07:00
|
|
|
table.insert(match.spawners, adj)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- initialise match timer vars
|
|
|
|
match.tmr = 0
|
|
|
|
match.max_time = def.timer.max_time
|
|
|
|
match.hud_time = match.max_time / 60 -- minutes
|
|
|
|
match.suddendeath = def.timer.suddendeath
|
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
-- store match
|
|
|
|
eggwars.match[key] = match
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
-- Add hud to match players
|
|
|
|
gen_match_hud(key)
|
|
|
|
|
|
|
|
-- persist dirty state in case of crash
|
2020-09-01 16:09:18 -07:00
|
|
|
reload = true
|
2020-08-12 09:08:29 -07:00
|
|
|
save_persistant()
|
|
|
|
|
2020-09-15 14:57:04 -07:00
|
|
|
minetest.after(5, function(param)
|
|
|
|
add_match_entities(param)
|
|
|
|
end, key)
|
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
registered_players = {} -- reset
|
2017-03-29 18:11:07 -07:00
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
--- Ends and cleans up a match instance
|
|
|
|
-- @param key - match key string
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.end_match = function(key)
|
|
|
|
|
|
|
|
local def = eggwars.match[key]
|
2020-10-11 12:09:00 -07:00
|
|
|
local match = {}
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
remove_match_hud(key)
|
2020-08-20 14:52:59 -07:00
|
|
|
eggwars.match[key].uid = 0
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
for _, pos in ipairs(def.spawners) do
|
|
|
|
minetest.get_node_timer(pos):stop()
|
|
|
|
local w = minetest.get_objects_inside_radius(pos, 2)
|
|
|
|
for _, obj in ipairs(w) do
|
|
|
|
if not obj:is_player() then
|
|
|
|
obj:remove()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
minetest.remove_node(pos)
|
|
|
|
end
|
|
|
|
|
|
|
|
for name, pdef in pairs(def.player) do
|
2020-10-11 12:09:00 -07:00
|
|
|
|
|
|
|
--stop gold spawner
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.get_node_timer(pdef.spawner):stop()
|
2020-10-11 12:09:00 -07:00
|
|
|
|
|
|
|
-- remove objects around spawner
|
2020-08-12 09:08:29 -07:00
|
|
|
local w = minetest.get_objects_inside_radius(pdef.spawner, 2)
|
|
|
|
for _, obj in ipairs(w) do
|
|
|
|
if not obj:is_player() then
|
|
|
|
obj:remove()
|
|
|
|
end
|
|
|
|
end
|
2020-10-11 12:09:00 -07:00
|
|
|
|
|
|
|
-- remove spawner
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.remove_node(pdef.spawner)
|
2020-10-11 12:09:00 -07:00
|
|
|
|
|
|
|
-- Update global stats
|
2020-08-12 09:08:29 -07:00
|
|
|
local s = stats.player[name]
|
|
|
|
s.kills = s.kills + pdef.kills
|
|
|
|
s.falls = s.falls + pdef.falls
|
|
|
|
s.damage = s.damage + pdef.damage
|
|
|
|
s.plays = s.plays + 1
|
2020-10-11 12:09:00 -07:00
|
|
|
s.wins = s.wins + pdef.winner
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
-- rank match player
|
2020-10-11 12:09:00 -07:00
|
|
|
local record = {
|
2020-08-12 09:08:29 -07:00
|
|
|
damage = pdef.damage,
|
|
|
|
eggs = pdef.eggs,
|
|
|
|
falls = pdef.falls,
|
|
|
|
id = pdef.id, -- colour ref
|
|
|
|
kills = pdef.kills,
|
|
|
|
name = name,
|
2020-10-11 12:09:00 -07:00
|
|
|
win = pdef.winner
|
2020-08-12 09:08:29 -07:00
|
|
|
}
|
2020-10-11 12:09:00 -07:00
|
|
|
table.insert(match, record)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
|
|
if player then
|
|
|
|
-- reset spectator
|
|
|
|
if not pdef.alive then
|
|
|
|
minetest.sound_play("eggwars_game_over", {
|
|
|
|
to_player = name,
|
|
|
|
gain = 0.5
|
|
|
|
})
|
2020-09-22 11:29:47 -07:00
|
|
|
if not eggwars.playertag then
|
2020-09-18 12:26:42 -07:00
|
|
|
player:set_nametag_attributes({
|
|
|
|
color = {a = 255, r = 255, g = 255, b = 255}}) --Make nametag visible
|
|
|
|
else
|
2020-10-11 12:09:00 -07:00
|
|
|
playertag.set(player, 1) -- luacheck: ignore
|
2020-09-18 12:26:42 -07:00
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
player:set_properties({visual_size = {x = 1, y = 1, z = 1}}) --Make player visible
|
2020-08-12 09:08:29 -07:00
|
|
|
else
|
|
|
|
-- reset player
|
|
|
|
if eggwars.armor then eggwars.clear_armor(player) end
|
|
|
|
eggwars.clear_inventory(player)
|
2020-10-11 12:09:00 -07:00
|
|
|
if pdef.winner == 1 then
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.chat_send_all(minetest.colorize(
|
|
|
|
"green", "*** " .. name .. " won their match!")
|
|
|
|
)
|
2020-09-18 08:47:58 -07:00
|
|
|
eggwars.add_tmp_image(name, 'eggwars_winner.png', 5)
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.sound_play("eggwars_winner", {
|
2020-08-27 13:16:24 -07:00
|
|
|
to_player = pdef.name,
|
2020-08-12 09:08:29 -07:00
|
|
|
gain = 0.5
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.set_player_privs(name, {shout = true}) -- set lobby privs
|
2020-08-12 09:08:29 -07:00
|
|
|
player:set_pos(lobby.pos) -- move player
|
|
|
|
end
|
|
|
|
stats.player[name] = s
|
|
|
|
eggwars.player[name] = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
-- rank winner
|
2020-10-11 12:09:00 -07:00
|
|
|
table.sort(match, function(a, b)
|
|
|
|
return a.winner > b.winner
|
|
|
|
end)
|
|
|
|
if match[1].winner == 0 then
|
|
|
|
-- on kills
|
|
|
|
table.sort(stats.rankings, function(a, b)
|
|
|
|
return a.kills > b.kills
|
|
|
|
end)
|
|
|
|
-- check winner
|
|
|
|
if match[1].kills == 0 then
|
|
|
|
-- resort for damage
|
|
|
|
table.sort(stats.rankings, function(a, b)
|
|
|
|
return a.damage > b.damage
|
|
|
|
end)
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
2020-10-11 12:09:00 -07:00
|
|
|
local tmp = match[1]
|
|
|
|
|
|
|
|
if tmp.winner == 1 then
|
|
|
|
local rank = {
|
|
|
|
damage = tmp.damage,
|
|
|
|
eggs = tmp.eggs,
|
|
|
|
falls = tmp.falls,
|
|
|
|
kills = tmp.kills,
|
|
|
|
name = tmp.name,
|
|
|
|
wins = stats.player[tmp.name].wins
|
|
|
|
}
|
|
|
|
local new_entry = true
|
|
|
|
for i,v in ipairs(stats.rankings) do
|
|
|
|
if v.name == rank.name then
|
|
|
|
-- update entry
|
|
|
|
new_entry = false
|
|
|
|
v.damage = v.damage + rank.damage
|
|
|
|
v.eggs = v.eggs + rank.eggs
|
|
|
|
v.falls = v.falls + rank.falls
|
|
|
|
v.kills = v.kills + rank.kills
|
|
|
|
v.wins = rank.wins
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if new_entry then
|
|
|
|
table.insert(stats.rankings, rank)
|
|
|
|
end
|
|
|
|
|
|
|
|
if #stats.rankings > 1 then
|
|
|
|
table.sort(stats.rankings, function(a, b)
|
|
|
|
return a.wins > b.wins
|
|
|
|
end)
|
|
|
|
if #stats.rankings > 20 then
|
|
|
|
table.remove(stats.rankings, #stats.rankings)
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
eggwars.reset(def.arena, def.id)
|
|
|
|
|
2020-09-01 16:09:18 -07:00
|
|
|
-- remove match
|
2020-08-12 09:08:29 -07:00
|
|
|
eggwars.match[key] = nil
|
2020-09-01 16:09:18 -07:00
|
|
|
-- check if this is the last match
|
|
|
|
if list_count(eggwars.match) == 0 then reload = false end
|
|
|
|
-- store data
|
2020-08-12 09:08:29 -07:00
|
|
|
save_persistant()
|
2020-09-01 16:09:18 -07:00
|
|
|
-- finally
|
2020-10-11 12:09:00 -07:00
|
|
|
display_match_results(match, def.arena)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Colour a message string using rgb
|
|
|
|
-- @param rgb - rgb table
|
|
|
|
-- @param msg - string to colour
|
|
|
|
-- @return a minetest colorized string
|
|
|
|
eggwars.colorize = function(rgb, msg)
|
2020-08-18 14:17:36 -07:00
|
|
|
|
2020-08-18 11:08:41 -07:00
|
|
|
local red = string.format('%x', rgb.r)
|
|
|
|
local green = string.format('%x', rgb.g)
|
|
|
|
local blue = string.format('%x', rgb.b)
|
|
|
|
-- modify if reqd
|
|
|
|
if red:len() == 1 then red = 0 .. red end
|
|
|
|
if green:len() == 1 then green = 0 .. green end
|
|
|
|
if blue:len() == 1 then blue = 0 .. blue end
|
|
|
|
-- And now concatenate it too
|
|
|
|
local colour = "#" .. red .. green .. blue
|
|
|
|
return minetest.colorize(colour, msg)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Broadcast match chat
|
|
|
|
-- @return nothing
|
|
|
|
eggwars.chat_send_match = function(key, msg)
|
|
|
|
local def = eggwars.match[key].player
|
2020-08-18 11:08:41 -07:00
|
|
|
for name, _ in pairs(def) do
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.chat_send_player(name, msg)
|
2020-08-18 11:08:41 -07:00
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
-----------------------------------------
|
|
|
|
-- Registered chat commands --
|
|
|
|
-----------------------------------------
|
|
|
|
minetest.register_chatcommand('admin', {
|
2020-08-27 13:16:24 -07:00
|
|
|
description = 'gamehub management tool',
|
|
|
|
params = '{load|save} [name]',
|
|
|
|
func = function(name, param)
|
|
|
|
-- secure access
|
|
|
|
if not minetest.get_player_privs(name).server and name == owner then
|
|
|
|
return false, "Insufficient privs!"
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
local cmd, fn, pos1, pos2, helper, list, player
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
helper = [[Usage:
|
2020-08-12 09:08:29 -07:00
|
|
|
/admin load <filename>
|
|
|
|
/admin save <filename> <pos1> <pos2>
|
|
|
|
]]
|
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
list = {}
|
|
|
|
player = minetest.get_player_by_name(name)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if not player then
|
|
|
|
return false, "You need to be playing to use this command!"
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
for word in param:gmatch("%S+") do
|
|
|
|
list[#list + 1] = word
|
|
|
|
end
|
|
|
|
local qty = #list
|
|
|
|
if qty < 2 or qty == 3 or qty > 4 then
|
|
|
|
return false
|
|
|
|
elseif qty == 4 then
|
|
|
|
pos1 = minetest.string_to_pos(list[3])
|
|
|
|
pos2 = minetest.string_to_pos(list[4])
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
cmd = list[1]
|
|
|
|
fn = list[2]
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if cmd == 'load' then
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
-- last entry takes precedence
|
|
|
|
local folders = {
|
|
|
|
MP .. "/schems/", -- read-only
|
|
|
|
WP .. "/schems/"
|
|
|
|
}
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
local path, folder, file, err, msg
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
msg = {}
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
for i, v in ipairs(folders) do
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
local check = check_files(v, fn)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if check.n > 0 then
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
folder = v
|
|
|
|
msg[#msg + 1] = "file(s) found in " .. v
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
elseif check.n == 0 then
|
|
|
|
msg[#msg + 1] = "no match found in " .. v
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.chat_send_player(name, table.concat(msg, "\n"))
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
check.n = nil -- reset
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if not folder then return end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
path = folder .. fn .. ".mts"
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
-- add mts using player current pos
|
|
|
|
local pos = vector.round(player:get_pos())
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
err = minetest.place_schematic(pos, path, nil, nil, true)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if err == nil then
|
|
|
|
minetest.chat_send_player(name, "could not open file " .. path)
|
|
|
|
return
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
-- add nodes with metadata
|
|
|
|
path = folder .. fn .. ".ewm"
|
|
|
|
file, err = io.open(path, "rb")
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if err then
|
|
|
|
minetest.chat_send_player(name, "could not open meta file "
|
|
|
|
.. fn .. ".ewm")
|
|
|
|
return
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
local value = file:read("*a")
|
|
|
|
file:close()
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
local count = eggwars.deserialize(pos, value)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.chat_send_player(name, "replaced " .. count ..
|
|
|
|
" nodes...")
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
elseif cmd == 'save' then
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
-- serialize metadata
|
|
|
|
local result, count = eggwars.serialize_meta(pos1, pos2)
|
|
|
|
local path = WP .. "/schems"
|
|
|
|
local filename = path .. "/" .. fn .. ".ewm"
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
if count > 0 then
|
2020-08-12 09:08:29 -07:00
|
|
|
|
|
|
|
local file, err = io.open(filename, "wb")
|
|
|
|
|
|
|
|
if err ~= nil then
|
|
|
|
minetest.log(name, "Could not save file to \"" .. filename .. "\"")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
file:write(result)
|
|
|
|
file:flush()
|
|
|
|
file:close()
|
|
|
|
|
|
|
|
minetest.chat_send_player(name, "Saved " .. count ..
|
|
|
|
" nodes to \"" .. filename .. "\"")
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
-- create schematic
|
|
|
|
filename = path .. "/" .. fn .. ".mts"
|
|
|
|
minetest.create_schematic(pos1, pos2, nil, filename)
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.chat_send_player(name, "Saved \"" .. filename .. "\"")
|
2020-08-12 09:08:29 -07:00
|
|
|
|
2020-08-27 13:16:24 -07:00
|
|
|
else
|
|
|
|
return true, helper
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
})
|
|
|
|
|
|
|
|
-- register for a match
|
|
|
|
minetest.register_chatcommand("r", {
|
2020-08-27 13:16:24 -07:00
|
|
|
params = "",
|
|
|
|
description = "Join match",
|
|
|
|
func = function(name, param)
|
|
|
|
if #registered_players < 8 then -- max 8 players in a match
|
|
|
|
if #eggwars.match < 8 then -- max 8 matches on the server
|
|
|
|
for i, v in ipairs(registered_players) do
|
2020-09-04 15:56:23 -07:00
|
|
|
if registered_players[i] == name then
|
2020-08-18 11:08:41 -07:00
|
|
|
return true, "You have already registered"
|
2017-07-28 04:15:28 -07:00
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
2020-08-29 18:08:20 -07:00
|
|
|
eggwars.remove_tmp_image(name)
|
2020-08-27 13:16:24 -07:00
|
|
|
registered_players[#registered_players + 1] = name
|
|
|
|
|
|
|
|
if #registered_players == 8 then
|
|
|
|
eggwars.begin_match();
|
2020-08-18 11:08:41 -07:00
|
|
|
else
|
2020-08-27 13:16:24 -07:00
|
|
|
minetest.chat_send_all(#registered_players ..
|
|
|
|
"/8 players have registered! Use /register to join.");
|
2017-07-28 04:15:28 -07:00
|
|
|
end
|
|
|
|
else
|
2020-08-27 13:16:24 -07:00
|
|
|
return true, "Sorry the max number of games are running." ..
|
|
|
|
"Please use /start once a match finishes."
|
2017-07-28 04:34:52 -07:00
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
else
|
|
|
|
return true, "Sorry. 8 players have already registered." ..
|
|
|
|
"Try registering after their game has begun."
|
|
|
|
end
|
|
|
|
end,
|
2017-07-28 04:15:28 -07:00
|
|
|
})
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
-- start match
|
|
|
|
minetest.register_chatcommand("s", {
|
2020-08-27 13:16:24 -07:00
|
|
|
params = "",
|
|
|
|
description = "Starts match if min match players is satisfied",
|
|
|
|
func = function(name, param)
|
|
|
|
if #registered_players >= min_match_players or name == owner then
|
|
|
|
eggwars.begin_match()
|
|
|
|
end
|
|
|
|
end
|
2017-10-30 18:08:28 -07:00
|
|
|
})
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
-- quit match
|
|
|
|
minetest.register_chatcommand("q", {
|
2020-08-27 13:16:24 -07:00
|
|
|
params = "",
|
|
|
|
description = "Quit the match you are playing",
|
|
|
|
func = function(name, param)
|
2020-08-29 15:39:47 -07:00
|
|
|
-- queued?
|
2020-08-27 13:16:24 -07:00
|
|
|
if #registered_players > 0 then
|
2020-08-29 15:39:47 -07:00
|
|
|
local idx
|
2020-08-27 13:16:24 -07:00
|
|
|
for i, v in ipairs(registered_players) do
|
2020-08-29 15:39:47 -07:00
|
|
|
if v.name == name then
|
|
|
|
idx = i
|
|
|
|
break
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
|
|
|
end
|
2020-08-29 15:39:47 -07:00
|
|
|
table.remove(registered_players, idx)
|
|
|
|
return true, "you have been removed from the queue!"
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
2020-08-29 15:39:47 -07:00
|
|
|
remove_match_player(name)
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
})
|
2017-11-01 15:36:33 -07:00
|
|
|
|
2020-09-05 14:36:54 -07:00
|
|
|
-- show stats formspec
|
|
|
|
minetest.register_chatcommand("stats", {
|
|
|
|
params = "",
|
|
|
|
description = "Shows server game statistics",
|
|
|
|
func = function(name, param)
|
|
|
|
display_stats(name)
|
|
|
|
end
|
|
|
|
})
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
-- end match - development
|
|
|
|
minetest.register_chatcommand("e", {
|
2020-08-27 13:16:24 -07:00
|
|
|
params = "",
|
|
|
|
description = "End the game",
|
|
|
|
func = function(name, param)
|
2020-08-29 18:08:20 -07:00
|
|
|
if name == owner then
|
|
|
|
local key = eggwars.player[name]
|
|
|
|
if key then
|
|
|
|
eggwars.end_match(key)
|
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
end
|
|
|
|
end
|
2020-08-12 09:08:29 -07:00
|
|
|
})
|
2017-11-01 15:36:33 -07:00
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
-- list players
|
2017-11-01 15:36:33 -07:00
|
|
|
minetest.register_chatcommand("who", {
|
2020-08-27 13:16:24 -07:00
|
|
|
params = "",
|
|
|
|
description = "List players in matches",
|
|
|
|
func = function(name, param)
|
|
|
|
local text = {}
|
|
|
|
for k, v in pairs(eggwars.match) do
|
|
|
|
text[#text + 1] = "Players in match: " .. k .. " "
|
|
|
|
for key, def in pairs(v.player) do
|
|
|
|
text[#text + 1] = eggwars.colorize(def.color, key)
|
2020-08-12 09:08:29 -07:00
|
|
|
end
|
2020-08-27 13:16:24 -07:00
|
|
|
text[#text + 1] = '\n'
|
|
|
|
end
|
|
|
|
return true, table.concat(text)
|
|
|
|
end
|
2017-11-01 15:36:33 -07:00
|
|
|
})
|
|
|
|
|
2020-08-29 15:39:47 -07:00
|
|
|
-------------------------------------
|
|
|
|
-- Registered callbacks --
|
|
|
|
-------------------------------------
|
|
|
|
|
|
|
|
minetest.register_on_dieplayer(function(player, reason)
|
|
|
|
|
|
|
|
local name = player:get_player_name()
|
|
|
|
local key = eggwars.player[name]
|
|
|
|
local def = eggwars.match[key]
|
|
|
|
|
|
|
|
if def then
|
|
|
|
if def.player[name].alive and not def.player[name].egg then
|
|
|
|
minetest.chat_send_all("*** "..name.." is " ..
|
|
|
|
minetest.colorize('red', 'OUT'))
|
|
|
|
|
|
|
|
-- set privs for spectating
|
|
|
|
minetest.set_player_privs(name, {fly = true, fast = true, shout = true})
|
2020-09-18 08:47:58 -07:00
|
|
|
eggwars.add_tmp_image(name, 'eggwars_out.png', 5)
|
2020-08-29 15:39:47 -07:00
|
|
|
|
|
|
|
-- record the kill
|
|
|
|
local killer
|
|
|
|
if reason.object then
|
|
|
|
killer = reason.object:get_player_name()
|
|
|
|
local upd = def.player[killer].kills + 1
|
|
|
|
def.player[killer].kills = upd
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Make nametag invisible
|
2020-09-18 12:26:42 -07:00
|
|
|
if not eggwars.playertag then
|
|
|
|
player:set_nametag_attributes({color = {a = 0, r = 0, g = 0, b = 0}})
|
|
|
|
else
|
2020-10-11 12:09:00 -07:00
|
|
|
playertag.set(player, 0, {a=0,r=0,g=0,b=0}) -- luacheck: ignore
|
2020-09-18 12:26:42 -07:00
|
|
|
end
|
2020-08-29 15:39:47 -07:00
|
|
|
player:set_properties({visual_size = {x = 0, y = 0}}) --Make player invisible
|
|
|
|
|
2020-10-11 12:09:00 -07:00
|
|
|
if eggwars.gauges then gauges.remove(name) end -- luacheck: ignore
|
2020-09-22 11:29:47 -07:00
|
|
|
|
2020-08-29 15:39:47 -07:00
|
|
|
if eggwars.armor then eggwars.clear_armor(player) end
|
|
|
|
def.player[name].alive = false
|
|
|
|
def.alive = def.alive - 1
|
|
|
|
|
|
|
|
eggwars.clear_inventory(player)
|
|
|
|
|
|
|
|
eggwars.match[key] = def
|
|
|
|
|
|
|
|
eggwars.update_hud(key, def.player[name].id)
|
|
|
|
|
|
|
|
-- Are we down to 1 player alive yet?
|
|
|
|
if def.alive == 1 then
|
2020-10-11 12:09:00 -07:00
|
|
|
if killer then def.player[killer].winner = 1 end
|
2020-08-29 15:39:47 -07:00
|
|
|
eggwars.end_match(key)
|
|
|
|
end
|
2020-09-18 12:26:42 -07:00
|
|
|
elseif def.player[name].alive and def.player[name].egg then
|
2020-08-29 15:39:47 -07:00
|
|
|
-- Clean inventory & announce
|
|
|
|
eggwars.clear_inventory(player)
|
|
|
|
minetest.chat_send_all("*** " ..
|
|
|
|
name.." paid Hades a visit and was revived by their egg.")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
minetest.register_on_respawnplayer(function(player)
|
|
|
|
local name = player:get_player_name()
|
|
|
|
local pos = lobby.pos -- initialise with lobby vector
|
|
|
|
-- match override
|
|
|
|
if eggwars.player[name] then
|
|
|
|
local key = eggwars.player[name]
|
|
|
|
local match = eggwars.match[key]
|
|
|
|
pos = match.player[name].spawn
|
|
|
|
end
|
|
|
|
player:set_pos(safe_spawn(pos))
|
|
|
|
return true
|
|
|
|
-- Wait for respawn before moving
|
|
|
|
--minetest.after(0.1, function () player:set_pos(pos) end)
|
|
|
|
end)
|
|
|
|
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
|
|
-- handle the player - no items or interact in the hub
|
|
|
|
if eggwars.armor then eggwars.clear_armor(player) end
|
|
|
|
eggwars.clear_inventory(player)
|
|
|
|
local name = player:get_player_name()
|
|
|
|
minetest.set_player_privs(name, {shout = true}) --
|
|
|
|
player:set_pos(lobby.pos)
|
2020-09-18 08:47:58 -07:00
|
|
|
eggwars.add_tmp_image(name, 'eggwars_welcome.png', 10)
|
2020-08-29 15:39:47 -07:00
|
|
|
end)
|
|
|
|
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
|
|
-- Handle players exiting during a match
|
|
|
|
local name = player:get_player_name()
|
|
|
|
remove_match_player(name)
|
|
|
|
if tmp_hud[name] then tmp_hud[name] = nil end
|
|
|
|
end)
|
|
|
|
|
|
|
|
minetest.register_on_chat_message(function(name, message)
|
|
|
|
-- Let's colour the chat!
|
|
|
|
local txt = "<" .. name .. "> " .. message
|
|
|
|
if eggwars.player[name] then
|
|
|
|
local key = eggwars.player[name]
|
|
|
|
local def = eggwars.match[key]
|
|
|
|
txt = eggwars.colorize(def.player[name].color, message)
|
|
|
|
eggwars.chat_send_match(key, txt)
|
|
|
|
else
|
|
|
|
-- player in lobby
|
|
|
|
minetest.chat_send_all(txt) -- broadcast
|
|
|
|
end
|
|
|
|
return true -- return as handled!
|
|
|
|
end)
|
|
|
|
|
|
|
|
minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
|
|
|
if player then
|
|
|
|
local name = player:get_player_name()
|
|
|
|
local key = eggwars.player[name]
|
|
|
|
local match = eggwars.match[key]
|
|
|
|
if eggwars.player[name] and reason.object then
|
|
|
|
local pname = reason.object:get_player_name()
|
2020-09-15 05:02:16 -07:00
|
|
|
local damage = match.player[pname].damage - hp_change
|
2020-08-29 15:39:47 -07:00
|
|
|
eggwars.match[key].player[pname].damage = damage
|
2020-09-15 08:36:44 -07:00
|
|
|
elseif eggwars.player[name] and reason.type == 'fall'
|
|
|
|
and match.player[name].alive then
|
2020-08-29 15:39:47 -07:00
|
|
|
local falls = match.player[name].falls + 1
|
|
|
|
eggwars.match[key].player[name].falls = falls
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end, false)
|
|
|
|
|
2020-09-25 08:07:54 -07:00
|
|
|
|
|
|
|
-- knockback override for match players
|
|
|
|
local old_calculate_knockback = minetest.calculate_knockback
|
2020-10-11 12:09:00 -07:00
|
|
|
function minetest.calculate_knockback(player, ...) -- luacheck: ignore
|
2020-09-25 08:07:54 -07:00
|
|
|
if eggwars.player[player:get_player_name()] then
|
|
|
|
return 3
|
|
|
|
end
|
|
|
|
return old_calculate_knockback(player, ...)
|
|
|
|
end
|
|
|
|
|
2020-08-12 09:08:29 -07:00
|
|
|
-- run functions after all mods are loaded!
|
|
|
|
minetest.after(0, modify_game)
|
2020-08-17 12:26:52 -07:00
|
|
|
minetest.after(0, set_settings)
|
2020-08-12 09:08:29 -07:00
|
|
|
minetest.after(0, match_timer)
|
|
|
|
minetest.after(0, update_hud_time)
|
2018-02-14 17:45:36 -08:00
|
|
|
|
2020-08-29 18:08:20 -07:00
|
|
|
minetest.log('action', '[LOADED] Eggwars mod')
|