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
Loading…
Add table
Add a link
Reference in a new issue