Initial commit.
This commit is contained in:
commit
b5c753ff4d
129 changed files with 4472 additions and 0 deletions
163
mods/firefly_state/firefly_battle_mode/beacons.lua
Normal file
163
mods/firefly_state/firefly_battle_mode/beacons.lua
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
local ns = firefly
|
||||
|
||||
--minetest.register_entity(":firefly:beacon", {
|
||||
-- initial_properties = {
|
||||
-- visual = "sprite",
|
||||
-- textures = {"blank.png"},
|
||||
-- static_save = false,
|
||||
-- },
|
||||
-- time = 0,
|
||||
-- on_step = function(e)
|
||||
-- local time = minetest.get_us_time()
|
||||
-- if time -e.time > 1000000 then
|
||||
-- e.delegate:check_nearby()
|
||||
-- e.time = time
|
||||
-- end
|
||||
-- end,
|
||||
--})
|
||||
|
||||
local beacons = {}
|
||||
|
||||
local MAX_LOYALTY = 10
|
||||
|
||||
local Beacon
|
||||
Beacon = {
|
||||
init = function(game, pos, team)
|
||||
local e = {
|
||||
id = "beacon_"..minetest.get_us_time().."_"..math.random(1, 1000000),
|
||||
game = game,
|
||||
pos = game.map.pos +pos,
|
||||
team = team or "__neutral",
|
||||
loyalty = MAX_LOYALTY,
|
||||
nearby = {},
|
||||
}
|
||||
setmetatable(e, Beacon)
|
||||
|
||||
beacons[e.id] = e
|
||||
|
||||
e:rebuild()
|
||||
|
||||
e._timer = function() e:check_nearby() end
|
||||
ns.timer:listen("every_second", e._timer)
|
||||
|
||||
-- minetest.set_node(e.pos, {name = "beacon"})
|
||||
-- minetest.get_meta(e.pos):set_string("beacon", e.id)
|
||||
-- minetest.get_node_timer(e.pos):start(1)
|
||||
|
||||
return e
|
||||
end,
|
||||
deinit = function(e)
|
||||
ns.timer:unlisten("every_second", e._timer)
|
||||
beacons[e.id] = nil
|
||||
end,
|
||||
rebuild = function(e)
|
||||
for x = e.pos.x -1, e.pos.x +1 do
|
||||
for z = e.pos.z -1, e.pos.z +1 do
|
||||
minetest.set_node(vector.new(x, e.pos.y -1, z), {name = "colored_glass", param2 = e.team == "__neutral" and 0 or e.team == "red" and 1 or 2})
|
||||
end
|
||||
end
|
||||
end,
|
||||
check_nearby = function(e)
|
||||
local team = e.game.teams[e.team]
|
||||
|
||||
-- Give score to the controlling team, if there is one.
|
||||
if team then
|
||||
e.game:add_score(e.team, 1)
|
||||
end
|
||||
|
||||
local not_nearby = table.copy(e.nearby)
|
||||
local enemies_near = {}
|
||||
local ally_near
|
||||
for _, m in pairs(ns.players) do
|
||||
if ns.manhattan_distance(m.pos, e.pos) < 3 then
|
||||
if not e.nearby[m.name] then
|
||||
ns.add_hud_bar(m, "beacon_status", {
|
||||
max = MAX_LOYALTY,
|
||||
min = 0,
|
||||
title = "Beacon",
|
||||
-- Charge-down if we are controlled by someone, but charge-up if contested.
|
||||
value = e.team == "__neutral" and MAX_LOYALTY -e.loyalty or e.loyalty,
|
||||
color = e.team == "__neutral" and "#fff" or e.game.teams[e.team].color,
|
||||
})
|
||||
end
|
||||
e.nearby[m.name] = true
|
||||
not_nearby[m.name] = nil
|
||||
if m.team ~= e.team then
|
||||
table.insert(enemies_near, m)
|
||||
else
|
||||
ally_near = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for name in pairs(not_nearby) do
|
||||
e.nearby[name] = nil
|
||||
ns.remove_hud_bar(ns.players[name], "beacon_status")
|
||||
end
|
||||
|
||||
-- If an enemy is near, weaken our team loyalty (but not if someone from out team is also near).
|
||||
if #enemies_near > 0 and not ally_near then
|
||||
-- Interference from competing enemy teams will also prevent us from losing loyalty, if we are contested.
|
||||
local team
|
||||
if e.team == "__neutral" then
|
||||
for i = 1, #enemies_near do
|
||||
local m = enemies_near[i]
|
||||
if team and m.team ~= team then
|
||||
team = nil
|
||||
break
|
||||
end
|
||||
team = m.team
|
||||
end
|
||||
if team then
|
||||
e:set_loyalty(e.loyalty -1)
|
||||
end
|
||||
-- Otherwise, we only care that at least one enemy is near.
|
||||
else
|
||||
e:set_loyalty(e.loyalty -1)
|
||||
end
|
||||
|
||||
-- If this dropped our loyalty to zero, we must switch teams.
|
||||
if e.loyalty <= 0 then
|
||||
e:switch_team(team)
|
||||
end
|
||||
-- If no enemies are near, we can rebuild loyalty.
|
||||
elseif e.loyalty < MAX_LOYALTY then
|
||||
-- Loyalty is rebuilt faster if an ally is near.
|
||||
e:set_loyalty(e.loyalty +(ally_near and 2 or 1))
|
||||
end
|
||||
end,
|
||||
set_loyalty = function(e, value)
|
||||
e.loyalty = value
|
||||
-- Update the status bar seen by nearby players.
|
||||
for name in pairs(e.nearby) do
|
||||
ns.change_hud_bar(ns.players[name], "beacon_status",{
|
||||
value = e.team == "__neutral" and MAX_LOYALTY -e.loyalty or e.loyalty,
|
||||
})
|
||||
end
|
||||
end,
|
||||
switch_team = function(e, team)
|
||||
-- If we are switching from a non-contested state, we must enter a contested state before we can be assigned a new team.
|
||||
if team and e.team ~= "__neutral" then
|
||||
team = "__neutral"
|
||||
end
|
||||
|
||||
-- If we didn't get a team, we weren't contested, but should be.
|
||||
e.team = team or "__neutral"
|
||||
|
||||
-- Reset our loyalty.
|
||||
e.loyalty = MAX_LOYALTY
|
||||
|
||||
-- We don't use set_loyalty to update the status bar because we also change the color.
|
||||
for name in pairs(e.nearby) do
|
||||
ns.change_hud_bar(ns.players[name], "beacon_status", {
|
||||
value = e.team == "__neutral" and MAX_LOYALTY -e.loyalty or e.loyalty,
|
||||
color = e.team == "__neutral" and "#fff" or e.game.teams[e.team].color or "#48d",
|
||||
})
|
||||
end
|
||||
|
||||
e:rebuild()
|
||||
end,
|
||||
}
|
||||
Beacon.__index = Beacon
|
||||
|
||||
return Beacon
|
||||
168
mods/firefly_state/firefly_battle_mode/init.lua
Normal file
168
mods/firefly_state/firefly_battle_mode/init.lua
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
local ns = firefly
|
||||
|
||||
|
||||
local Beacon = include "beacons.lua"
|
||||
|
||||
local BattleMode = {
|
||||
name = "battle"
|
||||
}
|
||||
BattleMode.__index = BattleMode
|
||||
|
||||
function BattleMode.init(map, players)
|
||||
local e = {
|
||||
map = map,
|
||||
players = {},
|
||||
beacons = {},
|
||||
teams = {},
|
||||
victory_conditions = {
|
||||
max_score = 100,
|
||||
}
|
||||
}
|
||||
|
||||
setmetatable(e, BattleMode)
|
||||
|
||||
local teams_list = {}
|
||||
|
||||
for name, def in pairs(e.map.teams) do
|
||||
e.teams[name] = {
|
||||
color = def.color,
|
||||
label = def.label,
|
||||
score = 0,
|
||||
players = {},
|
||||
}
|
||||
table.insert(teams_list, name)
|
||||
end
|
||||
|
||||
for i = 1, #players do
|
||||
local m = ns.players[players[i]]
|
||||
local team = teams_list[math.random(1, #teams_list)]
|
||||
e:add_player(team, m)
|
||||
e.players[m.name] = m
|
||||
end
|
||||
|
||||
for _, x in ipairs(map.beacons) do
|
||||
table.insert(e.beacons, Beacon.init(e, x.pos or x, x.team))
|
||||
end
|
||||
|
||||
return e
|
||||
end
|
||||
|
||||
function BattleMode.deinit(e)
|
||||
for i = 1, #e.beacons do
|
||||
e.beacons[i]:deinit()
|
||||
end
|
||||
|
||||
for name, m in pairs(e.players) do
|
||||
for name, def in pairs(e.map.teams) do
|
||||
ns.remove_hud_bar(m, name.."_team_score")
|
||||
end
|
||||
ns.remove_hud_bar(m, "beacon_status")
|
||||
m.player:set_pos(vector.new(0, 12, 0))
|
||||
end
|
||||
end
|
||||
|
||||
function BattleMode.add_player(e, team, m)
|
||||
m.game = e
|
||||
|
||||
m.player:set_pos(vector.new(math.random(e.map.pos.x, e.map.pos.x +e.map.size.x), e.map.pos.y +2, math.random(e.map.pos.z, e.map.pos.z +e.map.size.z)))
|
||||
|
||||
local players_in_team = #e.teams[team].players
|
||||
for name, def in pairs(e.map.teams) do
|
||||
ns.add_hud_bar(m, name.."_team_score", {
|
||||
max = e.victory_conditions.max_score,
|
||||
value = 0,
|
||||
title = def.label or string.upper(string.sub(name, 1, 1))..string.sub(name, 2).." Team",
|
||||
color = def.color
|
||||
})
|
||||
-- If the random choice would result in another team having two fewer players than this one, the player should be added to the underdog team instead.
|
||||
if #e.teams[name].players < players_in_team then
|
||||
team = name
|
||||
end
|
||||
end
|
||||
|
||||
m.team = team
|
||||
table.insert(e.teams[team].players, m)
|
||||
end
|
||||
|
||||
function BattleMode.remove_player(e, m)
|
||||
|
||||
end
|
||||
|
||||
function BattleMode.add_score(e, team, amount)
|
||||
if e.game_over then return end
|
||||
e.teams[team].score = e.teams[team].score +amount
|
||||
|
||||
-- Reflect the new score on players' HUD.
|
||||
for name, m in pairs(e.players) do
|
||||
ns.change_hud_bar(m, team.."_team_score", {
|
||||
value = e.teams[team].score
|
||||
})
|
||||
end
|
||||
|
||||
if e.victory_conditions.max_score and e.teams[team].score >= e.victory_conditions.max_score then
|
||||
e:declare_victory(team)
|
||||
end
|
||||
end
|
||||
|
||||
function BattleMode.declare_victory(e, team)
|
||||
e.game_over = true
|
||||
say("The "..team.." team has won the match!")
|
||||
minetest.after(10, function()
|
||||
e:deinit()
|
||||
end)
|
||||
end
|
||||
|
||||
function BattleMode.tick(e)
|
||||
|
||||
end
|
||||
|
||||
ns.register_mode(BattleMode)
|
||||
|
||||
local c_dirt_grass = minetest.get_content_id("dirt_grass")
|
||||
local c_grass = minetest.get_content_id("grass")
|
||||
|
||||
ns.register_map {
|
||||
name = "battle_test",
|
||||
mode = "battle",
|
||||
preview = "firefly_map_preview_battle_test.gltf",
|
||||
preview_image = "firefly_battle_map_test.png",
|
||||
size = vector.new(50, 50, 50),
|
||||
beacons = {
|
||||
vector.new(5, 1, 5),
|
||||
vector.new(45, 1, 45),
|
||||
{pos = vector.new(25, 2, 25), team = "red"}
|
||||
},
|
||||
teams = {
|
||||
red = {
|
||||
color = "#9b3c3c",
|
||||
spawnpoint = vector.new(5, 2, 45)
|
||||
},
|
||||
blue = {
|
||||
spawnpoint = vector.new(45, 2, 5)
|
||||
}
|
||||
},
|
||||
generate = function(minp, maxp)
|
||||
local vm = minetest.get_voxel_manip(minp, maxp)
|
||||
local va = VoxelArea(vm:get_emerged_area())
|
||||
|
||||
local data = vm:get_data()
|
||||
|
||||
for x = minp.x, maxp.x do
|
||||
for z = minp.z, maxp.z do
|
||||
data[va:index(x, minp.y, z)] = c_dirt_grass
|
||||
if math.random() < 0.4 then
|
||||
data[va:index(x, minp.y +1, z)] = c_grass
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vm:set_data(data)
|
||||
|
||||
vm:write_to_map()
|
||||
end
|
||||
}
|
||||
|
||||
ns.register_game_maker("battle", {
|
||||
texture = "firefly_sand.png",
|
||||
mode = "battle"
|
||||
})
|
||||
2
mods/firefly_state/firefly_battle_mode/mod.conf
Normal file
2
mods/firefly_state/firefly_battle_mode/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
name = firefly_battle_mode
|
||||
depends = firefly_lobby
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 912 KiB |
File diff suppressed because one or more lines are too long
404
mods/firefly_state/firefly_lobby/game_maker.lua
Normal file
404
mods/firefly_state/firefly_lobby/game_maker.lua
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
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
|
||||
|
||||
|
||||
20
mods/firefly_state/firefly_lobby/init.lua
Normal file
20
mods/firefly_state/firefly_lobby/init.lua
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
local ns = firefly
|
||||
|
||||
ns.register_player_state {
|
||||
name = "lobby_main",
|
||||
on_enter = function(m)
|
||||
|
||||
end,
|
||||
on_leave = function(m)
|
||||
|
||||
end
|
||||
}
|
||||
|
||||
Player:listen('init', function(m)
|
||||
ns.set_player_state(m, "lobby_main")
|
||||
end)
|
||||
|
||||
|
||||
include "game_maker.lua"
|
||||
|
||||
minetest.register_mapgen_script(minetest.get_modpath(minetest.get_current_modname()).."/mapgen.lua")
|
||||
73
mods/firefly_state/firefly_lobby/mapgen.lua
Normal file
73
mods/firefly_state/firefly_lobby/mapgen.lua
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
local REALM_START = vector.new(-500, -500, -500)
|
||||
local REALM_END = vector.new(500, 500, 500)
|
||||
|
||||
local function intersection(min, max, b, c)
|
||||
return min.x < c.x and max.x > b.x and
|
||||
min.y < c.y and max.y > b.y and
|
||||
min.z < c.z and max.z > b.z
|
||||
end
|
||||
|
||||
local vm_data = {}
|
||||
|
||||
local np_surface = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x = 100, y = 100, z = 100},
|
||||
seed = 12345,
|
||||
octaves = 4,
|
||||
persist = 0.6
|
||||
}
|
||||
local n_surface = {}
|
||||
|
||||
local np_thickness = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x = 250, y = 250, z = 250},
|
||||
seed = 3579044,
|
||||
octaves = 4,
|
||||
persist = 0.6
|
||||
}
|
||||
local n_thickness = {}
|
||||
|
||||
|
||||
local c_chest = minetest.get_content_id("chest_with_everything:chest")
|
||||
|
||||
local c_air = minetest.get_content_id("air")
|
||||
local c_stone = minetest.get_content_id("stone")
|
||||
minetest.register_on_generated(function(vm, min, max)
|
||||
-- AABB intersection, to determine whether this block should be considered for this mapgen.
|
||||
if not intersection(min, max, REALM_START, REALM_END) then return end
|
||||
local va = VoxelArea(vm:get_emerged_area())
|
||||
|
||||
local sides2d = {x = max.x - min.x + 1, y = max.z - min.z + 1}
|
||||
local surface = minetest.get_perlin_map(np_surface, sides2d)
|
||||
surface:get_2d_map_flat({x = min.x, y = min.z}, n_surface)
|
||||
|
||||
local thickness = minetest.get_perlin_map(np_thickness, sides2d)
|
||||
thickness:get_2d_map_flat({x = min.x, y = min.z}, n_thickness)
|
||||
|
||||
vm:get_data(vm_data)
|
||||
local ni = 1
|
||||
for z = min.z, max.z do
|
||||
for x = min.x, max.x do
|
||||
local r = math.sqrt(x *x + z *z)
|
||||
local bottom = -(3 +n_thickness[ni] *5 +((1 -(r /100))^0.5 *50))
|
||||
local top = (n_surface[ni] +1) *8 *(1 -(math.max(0, r -90) /10))^0.5
|
||||
|
||||
for y = min.y, max.y do
|
||||
if y > bottom and y < top then
|
||||
local vi = va:index(x, y, z)
|
||||
|
||||
vm_data[vi] = c_stone
|
||||
end
|
||||
if x == 0 and z == 0 and y == math.round(top) then
|
||||
local vi = va:index(x, y, z)
|
||||
vm_data[vi] = c_chest
|
||||
end
|
||||
end
|
||||
ni = ni +1
|
||||
end
|
||||
end
|
||||
vm:set_data(vm_data)
|
||||
end)
|
||||
2
mods/firefly_state/firefly_lobby/mod.conf
Normal file
2
mods/firefly_state/firefly_lobby/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
name = firefly_lobby
|
||||
depends = firefly_state
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"asset":{"version":"2.0","generator":"Blockbench 4.12.5 glTF exporter"},"scenes":[{"nodes":[2],"name":"blockbench_export"}],"scene":0,"nodes":[{"translation":[0,0,-1.25],"name":"cube","mesh":0},{"translation":[0,-5,-1.25],"name":"cube","mesh":1},{"children":[0,1]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":840,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1128,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1416,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":1608,"byteLength":72,"target":34963}],"buffers":[{"byteLength":1680,"uri":"data:application/octet-stream;base64,AACgQAAAjEAAACA/AACgQAAAjEAAACC/AACgQAAAcMAAACA/AACgQAAAcMAAACC/AACgwAAAjEAAACC/AACgwAAAjEAAACA/AACgwAAAcMAAACC/AACgwAAAcMAAACA/AACgwAAAjEAAACC/AACgQAAAjEAAACC/AACgwAAAjEAAACA/AACgQAAAjEAAACA/AACgwAAAcMAAACA/AACgQAAAcMAAACA/AACgwAAAcMAAACC/AACgQAAAcMAAACC/AACgwAAAjEAAACA/AACgQAAAjEAAACA/AACgwAAAcMAAACA/AACgQAAAcMAAACA/AACgQAAAjEAAACC/AACgwAAAjEAAACC/AACgQAAAcMAAACC/AACgwAAAcMAAACC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAPwAAAD8AABA/AAAAPwAAAD8AAGg/AAAQPwAAaD8AABA/AAAAPwAAID8AAAA/AAAQPwAAaD8AACA/AABoPwAAgD8AAKA+AAAAPwAAoD4AAIA/AACAPgAAAD8AAIA+AACAPwAAoD4AAAA/AACgPgAAgD8AAMA+AAAAPwAAwD4AAAAAAADQPgAAAD8AANA+AAAAAAAAUD8AAAA/AABQPwAAAAAAAAAAAAAAPwAAAAAAAAAAAADQPgAAAD8AANA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAACgQAAAoD8AAKA/AACgQAAAoD8AAKC/AACgQAAAAAAAAKA/AACgQAAAAAAAAKC/AACgwAAAoD8AAKC/AACgwAAAoD8AAKA/AACgwAAAAAAAAKC/AACgwAAAAAAAAKA/AACgwAAAoD8AAKC/AACgQAAAoD8AAKC/AACgwAAAoD8AAKA/AACgQAAAoD8AAKA/AACgwAAAAAAAAKA/AACgQAAAAAAAAKA/AACgwAAAAAAAAKC/AACgQAAAAAAAAKC/AACgwAAAoD8AAKA/AACgQAAAoD8AAKA/AACgwAAAAAAAAKA/AACgQAAAAAAAAKA/AACgQAAAoD8AAKC/AACgwAAAoD8AAKC/AACgQAAAAAAAAKC/AACgwAAAAAAAAKC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAgPwAAAD8AAEA/AAAAPwAAID8AABA/AABAPwAAED8AACA/AAAQPwAAQD8AABA/AAAgPwAAID8AAEA/AAAgPwAAgD8AAAA+AAAAPwAAAD4AAIA/AAAAAAAAAD8AAAAAAACAPwAAAD4AAAA/AAAAPgAAgD8AAIA+AAAAPwAAgD4AAAA/AADgPgAAgD8AAOA+AAAAPwAAAD8AAIA/AAAAPwAAAD8AAMA+AACAPwAAwD4AAAA/AADgPgAAgD8AAOA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUA"}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[5,4.375,0.625],"min":[-5,-3.75,-0.625],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[1,0.90625],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":24,"max":[5,1.25,1.25],"min":[-5,0,-1.25],"type":"VEC3"},{"bufferView":5,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":24,"max":[1,0.625],"min":[0.5,0],"type":"VEC2"},{"bufferView":7,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0,"source":0,"name":"texture"}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","name":"texture","uri":"texture.png"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":4,"NORMAL":5,"TEXCOORD_0":6},"indices":7,"material":0}]}]}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"asset":{"version":"2.0","generator":"Blockbench 4.12.5 glTF exporter"},"scenes":[{"nodes":[1],"name":"blockbench_export"}],"scene":0,"nodes":[{"translation":[0,-5,-4.375],"name":"cube","mesh":0},{"children":[0]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AADIQQAA8EEAACA/AADIQQAA8EEAACC/AADIQQAAAAAAACA/AADIQQAAAAAAACC/AADIwQAA8EEAACC/AADIwQAA8EEAACA/AADIwQAAAAAAACC/AADIwQAAAAAAACA/AADIwQAA8EEAACC/AADIQQAA8EEAACC/AADIwQAA8EEAACA/AADIQQAA8EEAACA/AADIwQAAAAAAACA/AADIQQAAAAAAACA/AADIwQAAAAAAACC/AADIQQAAAAAAACC/AADIwQAA8EEAACA/AADIQQAA8EEAACA/AADIwQAAAAAAACA/AADIQQAAAAAAACA/AADIQQAA8EEAACC/AADIwQAA8EEAACC/AADIQQAAAAAAACC/AADIwQAAAAAAACC/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACgPgAAgDwAAKQ+AACAPAAAoD4AAFA+AACkPgAAUD4AAKA+AABQPgAApD4AAFA+AACgPgAAyD4AAKQ+AADIPgAAID8AAAA8AACgPgAAADwAACA/AAAAAAAAoD4AAAAAAAAgPwAAADwAAKA+AAAAPAAAID8AAIA8AACgPgAAgDwAAAAAAABAPgAAoD4AAEA+AAAAAAAAwD4AAKA+AADAPgAAAAAAAAAAAACgPgAAAAAAAAAAAABAPgAAoD4AAEA+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUA"}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[25,30,0.625],"min":[-25,0,-0.625],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[0.625,0.390625],"min":[0,0],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0,"source":0,"name":"texture"}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"images":[{"mimeType":"image/png","name":"firefly_screen.png","uri":"firefly_screen.png"}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]}]}
|
||||
BIN
mods/firefly_state/firefly_lobby/textures/firefly_choose_map.png
Normal file
BIN
mods/firefly_state/firefly_lobby/textures/firefly_choose_map.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 279 B |
Binary file not shown.
|
After Width: | Height: | Size: 278 B |
Binary file not shown.
|
After Width: | Height: | Size: 304 B |
BIN
mods/firefly_state/firefly_lobby/textures/firefly_screen.png
Normal file
BIN
mods/firefly_state/firefly_lobby/textures/firefly_screen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 771 B |
75
mods/firefly_state/firefly_state/init.lua
Normal file
75
mods/firefly_state/firefly_state/init.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
local ns = firefly
|
||||
|
||||
ns.states = {}
|
||||
ns.modes = {}
|
||||
ns.games = {}
|
||||
|
||||
function ns.register_player_state(def)
|
||||
ns.states[def.name] = def
|
||||
ns["players_in_"..def.name.."_state"] = {}
|
||||
end
|
||||
|
||||
function ns.set_player_state(m, name)
|
||||
if not ns.states[name] then return end
|
||||
if m.state and ns.states[m.state].on_leave then
|
||||
ns.states[m.state].on_leave(m)
|
||||
ns["players_in_"..m.state.."_state"][m.name] = nil
|
||||
end
|
||||
m.state = name
|
||||
if ns.states[name].on_enter then
|
||||
ns.states[name].on_enter(m)
|
||||
ns["players_in_"..m.state.."_state"][m.name] = m
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
{
|
||||
init = function(map, players) end, -- Should create and return an instance of this mode with the specified players.
|
||||
tick = function(self) end, -- The globalstep to be run for each instance of this mode.
|
||||
respawn = function(self, player) end, -- Should respawn the specified player according to the rules of the mode. Note that there is no way to prevent a player from respawning.
|
||||
|
||||
}
|
||||
--]]
|
||||
function ns.register_mode(def)
|
||||
if not def.maps then def.maps = {} end
|
||||
def.__index = def
|
||||
ns.modes[def.name] = def
|
||||
end
|
||||
|
||||
function ns.register_map(def)
|
||||
ns.modes[def.mode].maps[def.name] = def
|
||||
end
|
||||
|
||||
function ns.start_game(mode, map, players)
|
||||
if not ns.games[mode] then ns.games[mode] = {} end
|
||||
local def = ns.modes[mode].maps[map]
|
||||
local pos = vector.new(-30000, 20000, -30000)
|
||||
Promise(function(resolve)
|
||||
if def.schem then
|
||||
-- TODO
|
||||
resolve()
|
||||
elseif def.generate then
|
||||
minetest.emerge_area(pos, pos +def.size, function(_, _, left)
|
||||
if left == 0 then
|
||||
def.generate(pos, pos +def.size)
|
||||
resolve()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end):after(function()
|
||||
|
||||
local game = ns.modes[mode].init(setmetatable({pos = pos}, {__index = def}), players)
|
||||
ns.games[mode][#ns.games +1] = game
|
||||
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
for _, games in pairs(ns.games) do
|
||||
for i = 1, #games do
|
||||
games[i]:tick()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
2
mods/firefly_state/firefly_state/mod.conf
Normal file
2
mods/firefly_state/firefly_state/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
name = firefly_state
|
||||
depends = firefly_player, firefly_world
|
||||
0
mods/firefly_state/modpack.conf
Normal file
0
mods/firefly_state/modpack.conf
Normal file
Loading…
Add table
Add a link
Reference in a new issue