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" })