404 lines
14 KiB
Lua
404 lines
14 KiB
Lua
local ns = firefly
|
|
|
|
local game_makers = {}
|
|
|
|
minetest.register_entity(":firefly:map_preview", {
|
|
initial_properties = {
|
|
visual = "mesh",
|
|
textures = {"[fill:1x1:0,0:#39f2"},
|
|
use_texture_alpha = true,
|
|
static_save = false
|
|
},
|
|
on_activate = function(e)
|
|
e.object:set_armor_groups{immortal = 1}
|
|
e._name = ""..math.random()
|
|
end,
|
|
on_punch = function(e, p)
|
|
e.master:set_map(e.map)
|
|
end,
|
|
dismiss = function(e)
|
|
e.object:remove()
|
|
end
|
|
})
|
|
|
|
minetest.register_entity(":firefly:game_maker_display", {
|
|
initial_properties = {
|
|
visual = "sprite",
|
|
textures = {"blank.png"},
|
|
selectionbox = {
|
|
-2.5, -0.5, 0.5,
|
|
2.5, 2.5, 6/16
|
|
}
|
|
-- pointable = false,
|
|
},
|
|
on_activate = function(e, data)
|
|
local pos = e.object:get_pos():round()
|
|
local node = minetest.get_node(pos)
|
|
if not data or not node.name:find "game_maker_" then return end
|
|
e.object:set_armor_groups{immortal = 1}
|
|
|
|
e.mode = data
|
|
|
|
e.rot = ns.facedir_to_rotation(node.param2)
|
|
e.object:set_properties {
|
|
selectionbox = ns.rotate_selectionbox({
|
|
-2.5, -0.5, 0.5,
|
|
2.5, 2.5, 6/16
|
|
}, e.rot)
|
|
}
|
|
|
|
e.label = minetest.add_entity(pos +vector.new(0, 1, 0.3):rotate(e.rot), "display")
|
|
e.label:set_rotation(e.rot)
|
|
|
|
e.players = {}
|
|
e.players_list = {}
|
|
|
|
game_makers[pos:to_string()] = e
|
|
|
|
e.pos = pos
|
|
|
|
e:show_status()
|
|
end,
|
|
on_step = function(e, dtime)
|
|
if e.state == "choose_world" then
|
|
|
|
elseif e.state == "starting" and e.timer then
|
|
e.timer = e.timer -dtime
|
|
if e.timer_display then
|
|
local tx, w = ns.texture_from_number(math.round(e.timer))
|
|
e.timer_display:set_properties {
|
|
textures = {tx},
|
|
visual_size = vector.new(w /16,1,1) *0.5
|
|
}
|
|
else
|
|
e.timer = nil
|
|
return
|
|
end
|
|
local timer = math.round(e.timer)
|
|
if timer ~= e._timer then
|
|
for _, name in pairs(e.players_list) do
|
|
ns.change_hud_bar(ns.players[name], "start_timer", {
|
|
value = math.max(timer, 0),
|
|
title = timer == 0 and "Starting..." or "Starting in "..timer.."..."
|
|
})
|
|
end
|
|
end
|
|
e._timer = timer
|
|
if e.timer <= 0 then
|
|
e:start_game()
|
|
-- e.timer = nil
|
|
-- e.timer_display:remove()
|
|
-- e.timer_display = nil
|
|
-- e.label:set_pos(e.label:get_pos():offset(0, -0.25, 0))
|
|
-- e.label:set_properties {
|
|
-- visual = "upright_sprite",
|
|
-- textures = {"[combine:102x102:0,46=firefly_punch_to_start.png", "[combine:102x102:0,46=firefly_punch_to_start.png"},
|
|
-- }
|
|
--
|
|
-- ns.start_game(e.mode, e.players_list)
|
|
--
|
|
-- for name, obj in pairs(e.players) do
|
|
-- obj:remove()
|
|
-- ns.remove_hud_bar(ns.players[name], "start_timer")
|
|
-- end
|
|
-- e.players = {}
|
|
-- e.players_list = {}
|
|
end
|
|
end
|
|
end,
|
|
add_player = function(e, name)
|
|
table.insert(e.players_list, name)
|
|
ns.add_hud_bar(ns.players[name], "start_timer", {
|
|
max = 10,
|
|
value = 0,
|
|
title = "Waiting for players..."
|
|
})
|
|
if e.state == "awaiting_players" then
|
|
local pos = e.object:get_pos() +vector.new(-#e.players_list /2 +0.5, 1, 0.3):rotate(e.rot)
|
|
local obj = minetest.add_entity(pos, "display")
|
|
obj:set_properties {
|
|
visual = "mesh",
|
|
mesh = "firefly_head.gltf",
|
|
visual_size = vector.new(1, 1, 1) *0.5,
|
|
textures = {"firefly_character.png"}
|
|
}
|
|
obj:set_rotation(e.rot:offset(0, -math.pi, 0))
|
|
e.players[name] = obj
|
|
for i, name in pairs(e.players_list) do
|
|
e.players[name]:set_pos(pos +vector.new(0.5 *(i -1), 0, 0):rotate(e.rot))
|
|
end
|
|
elseif e.state == "starting" then
|
|
|
|
end
|
|
end,
|
|
remove_player = function(e, name)
|
|
ns.remove_hud_bar(ns.players[name], "start_timer")
|
|
table.remove(e.players_list, table.indexof(e.players_list, name))
|
|
if e.state == "choose_map" then
|
|
e:dismiss_map_selector()
|
|
e.state = nil
|
|
e:show_status()
|
|
elseif #e.players_list < 1 then
|
|
if e.state == "awaiting_players" then
|
|
e:dismiss_players()
|
|
elseif e.state == "starting" then
|
|
e:dismiss_countdown()
|
|
end
|
|
e.state = nil
|
|
for i, name in pairs(e.players_list) do
|
|
e.players[name]:set_pos(pos +vector.new(0.5 *(i -1), 0, 0):rotate(e.rot))
|
|
end
|
|
e:show_status()
|
|
else
|
|
local pos = e.object:get_pos() +vector.new(-#e.players_list /2 +0.5, 1, 0):rotate(e.rot)
|
|
end
|
|
end,
|
|
show_status = function(e)
|
|
if e.map_image then
|
|
e.map_image.object:remove()
|
|
e.map_image = nil
|
|
end
|
|
|
|
e.label:set_pos(e.pos +vector.new(0, 1, 0.3):rotate(e.rot))
|
|
e.label:set_properties {
|
|
visual = "upright_sprite",
|
|
textures = {"[combine:102x102:0,46=firefly_punch_to_start.png", "[combine:102x102:0,46=firefly_punch_to_start.png"},
|
|
visual_size = vector.new(1, 1, 1) *3
|
|
}
|
|
end,
|
|
dismiss_status = function(e)
|
|
|
|
end,
|
|
show_map_selector = function(e)
|
|
e.map = nil
|
|
e.label:set_pos(e.pos +vector.new(0, 2, 0.3):rotate(e.rot))
|
|
e.label:set_properties {
|
|
visual = "upright_sprite",
|
|
textures = {"[combine:85x85:0,37.5=firefly_choose_map.png", "[combine:85x85:0,37.5=firefly_choose_map.png"},
|
|
visual_size = vector.new(1, 1, 1) *1
|
|
}
|
|
e.map_previews = {}
|
|
local pos = e.object:get_pos()
|
|
for name, x in pairs(ns.modes[e.mode].maps) do
|
|
local obj = minetest.add_entity(pos, "firefly:map_preview")
|
|
obj:set_properties {
|
|
mesh = x.preview
|
|
}
|
|
local le = obj:get_luaentity()
|
|
le.master = e
|
|
le.map = name
|
|
e.map_previews[name] = le
|
|
end
|
|
end,
|
|
set_map = function(e, map)
|
|
if not e.map then
|
|
e.confirm_map = minetest.add_entity(e.object:get_pos() +vector.new(2, 1, 0.3):rotate(e.rot), "display")
|
|
e.confirm_map:set_properties {
|
|
visual = "upright_sprite",
|
|
textures = {"[combine:85x85:0,37.5=firefly_choose_map.png", "[combine:85x85:0,37.5=firefly_choose_map.png"},
|
|
visual_size = vector.new(1, 1, 1) *1,
|
|
pointable = true
|
|
}
|
|
e.confirm_map = e.confirm_map:get_luaentity()
|
|
e.confirm_map.on_punch = function()
|
|
e:dismiss_map_selector()
|
|
e.state = "awaiting_players"
|
|
e:show_players()
|
|
end
|
|
end
|
|
|
|
e.map_image = minetest.add_entity(e.object:get_pos() +vector.new(0, 1, 0.35):rotate(e.rot), "display")
|
|
e.map_image:set_properties {
|
|
visual = "upright_sprite",
|
|
textures = {"firefly_battle_map_test.png"},
|
|
visual_size = vector.new(4.5, 2.5, 5) *0.98,
|
|
pointable = true
|
|
}
|
|
e.map_image = e.map_image:get_luaentity()
|
|
|
|
e.map = map
|
|
end,
|
|
dismiss_map_selector = function(e)
|
|
for _, x in pairs(e.map_previews) do
|
|
x:dismiss()
|
|
end
|
|
e.map_previews = nil
|
|
if e.confirm_map then
|
|
e.confirm_map.object:remove()
|
|
e.confirm_map = nil
|
|
end
|
|
end,
|
|
show_players = function(e)
|
|
e.label:set_pos(e.pos +vector.new(0, 2, 0.3):rotate(e.rot))
|
|
e.label:set_properties {
|
|
visual = "upright_sprite",
|
|
textures = {"[combine:94x94:0,42=firefly_punch_to_join.png", "[combine:94x94:0,42=firefly_punch_to_join.png"},
|
|
visual_size = vector.new(1, 1, 1) *2
|
|
}
|
|
local pos = e.object:get_pos() +vector.new(-#e.players_list /2 +0.5, 1, 0.3):rotate(e.rot)
|
|
for i = 1, #e.players_list do
|
|
local name = e.players_list[i]
|
|
local obj = minetest.add_entity(pos +vector.new(0.5 *(i -1), 0, 0):rotate(e.rot), "display")
|
|
obj:set_properties {
|
|
visual = "mesh",
|
|
mesh = "firefly_head.gltf",
|
|
visual_size = vector.new(1, 1, 1) *0.5,
|
|
textures = {"firefly_character.png"}
|
|
}
|
|
obj:set_rotation(e.rot:offset(0, -math.pi, 0))
|
|
e.players[name] = obj
|
|
end
|
|
e.begin_countdown = minetest.add_entity(pos +vector.new(2, 1, 0):rotate(e.rot), "display")
|
|
e.begin_countdown:set_properties {
|
|
visual = "upright_sprite",
|
|
textures = {"[combine:85x85:0,37.5=firefly_choose_map.png", "[combine:85x85:0,37.5=firefly_choose_map.png"},
|
|
visual_size = vector.new(1, 1, 1) *1,
|
|
pointable = true
|
|
}
|
|
e.begin_countdown = e.begin_countdown:get_luaentity()
|
|
e.begin_countdown.on_punch = function()
|
|
e:dismiss_players()
|
|
e.state = "starting"
|
|
e.timer = 10
|
|
e:show_countdown()
|
|
end
|
|
end,
|
|
dismiss_players = function(e)
|
|
for _, x in pairs(e.players) do
|
|
x:remove()
|
|
end
|
|
e.begin_countdown.object:remove()
|
|
e.begin_countdown = nil
|
|
end,
|
|
show_countdown = function(e)
|
|
local pos = e.object:get_pos()
|
|
e.timer_display = minetest.add_entity(pos +vector.new(0, 1, 0.3):rotate(e.rot), "display")
|
|
e.timer_display:set_properties {
|
|
visual = "upright_sprite",
|
|
}
|
|
e.timer_display:set_rotation(e.rot)
|
|
end,
|
|
dismiss_countdown = function(e)
|
|
e.timer_display:remove()
|
|
e.timer_display = nil
|
|
end,
|
|
start_game = function(e)
|
|
e.timer = nil
|
|
e.state = nil
|
|
|
|
e:dismiss_countdown()
|
|
|
|
for i = 1, #e.players_list do
|
|
ns.remove_hud_bar(ns.players[e.players_list[i]], "start_timer")
|
|
end
|
|
|
|
ns.start_game(e.mode, e.map, e.players_list)
|
|
|
|
e.players_list = {}
|
|
|
|
e:show_status()
|
|
end,
|
|
on_punch = function(e, p)
|
|
local name = p:get_player_name()
|
|
local m = ns.players[name]
|
|
if not e.state then
|
|
m.hosting = e
|
|
e:add_player(name)
|
|
e.state = "choose_map"
|
|
e:show_map_selector()
|
|
elseif e.state == "awaiting_players" or e.state == "starting" then
|
|
if e.players[name] then
|
|
e:remove_player(name)
|
|
else
|
|
e:add_player(name)
|
|
end
|
|
end
|
|
-- if e.players[name] then
|
|
-- e.players[name]:remove()
|
|
-- e.players[name] = nil
|
|
-- table.remove(e.players_list, table.indexof(e.players_list, name))
|
|
-- ns.remove_hud_bar(ns.players[name], "start_timer")
|
|
-- if not next(e.players_list) then
|
|
-- e.label:set_pos(e.label:get_pos():offset(0, -0.25, 0))
|
|
-- e.label:set_properties {
|
|
-- visual = "upright_sprite",
|
|
-- textures = {"[combine:102x102:0,46=firefly_punch_to_start.png", "[combine:102x102:0,46=firefly_punch_to_start.png"},
|
|
-- }
|
|
-- e.timer_display:remove()
|
|
-- e.timer_display = nil
|
|
-- end
|
|
-- else
|
|
-- if not next(e.players_list) then
|
|
-- e.label:set_pos(e.label:get_pos():offset(0, 0.25, 0))
|
|
-- e.label:set_properties {
|
|
-- visual = "upright_sprite",
|
|
-- textures = {"[combine:94x94:0,42=firefly_punch_to_join.png", "[combine:94x94:0,42=firefly_punch_to_join.png"},
|
|
-- }
|
|
-- e.timer_display = minetest.add_entity(e.object:get_pos():offset(0, 0.85, 0), "display")
|
|
-- e.timer_display:set_properties {
|
|
-- visual = "upright_sprite",
|
|
-- }
|
|
-- e.timer_display:set_rotation(e.rot)
|
|
-- end
|
|
-- local display = minetest.add_entity(e.object:get_pos():offset(0, 0, 0), "display")
|
|
-- display:set_properties {
|
|
-- visual = "mesh",
|
|
-- mesh = "firefly_head.gltf",
|
|
-- textures = ns.players[name].object:get_properties().textures,
|
|
-- visual_size = vector.new(1,1,1) *0.5
|
|
-- }
|
|
-- display:set_rotation(e.rot)
|
|
-- e.players[name] = display
|
|
-- table.insert(e.players_list, name)
|
|
-- e.timer = math.max(5, 11 -(#e.players_list)^2)
|
|
-- e._timer = e.timer
|
|
-- ns.add_hud_bar(ns.players[name], "start_timer", {
|
|
-- max = e.timer,
|
|
-- value = e.timer,
|
|
-- title = "Starting in "..e._timer.."..."
|
|
-- })
|
|
-- end
|
|
end,
|
|
get_staticdata = function(e)
|
|
return e.mode
|
|
end,
|
|
on_deactivate = function(e)
|
|
local pos = e.object:get_pos():round()
|
|
game_makers[pos:to_string()] = nil
|
|
e.label:remove()
|
|
if e.timer_display then
|
|
e.timer_display:remove()
|
|
end
|
|
end
|
|
})
|
|
|
|
Player:listen("deinit", function(m)
|
|
if m.hosting then
|
|
m.hosting:remove_player(m.name)
|
|
elseif m.joining then
|
|
m.joining:remove_player(m.name)
|
|
end
|
|
end)
|
|
|
|
function ns.register_game_maker(name, def)
|
|
local function onload(pos)
|
|
minetest.add_entity(pos, "firefly:game_maker_display", def.mode)
|
|
end
|
|
|
|
ns.register_node("game_maker_"..name, {
|
|
drawtype = "mesh",
|
|
mesh = "firefly_screen.gltf",
|
|
tiles = {"firefly_screen.png"},
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
walkable = false,
|
|
groups = {call_on_load = 1},
|
|
on_construct = onload,
|
|
on_load = onload,
|
|
on_destruct = function(pos)
|
|
game_makers[pos:to_string()].object:remove()
|
|
end,
|
|
})
|
|
end
|
|
|
|
|