mirror of
https://github.com/a-bad-dev/simple-shooter-game.git
synced 2026-06-08 20:12:11 +00:00
Split the main mod into several smaller mods
yes, this means m o r e g l o b a l s
This commit is contained in:
parent
44c1be6a55
commit
feba0eac84
5 changed files with 268 additions and 263 deletions
14
mods/game/autoheal/init.lua
Normal file
14
mods/game/autoheal/init.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
-- Autohealing mod for SSG
|
||||
local timer = 0
|
||||
core.register_globalstep(function(dtime)
|
||||
timer = timer + dtime
|
||||
|
||||
if timer >= 10 then
|
||||
timer = 0
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
if alive_players[player:get_player_name()] == "alive" then
|
||||
player:set_hp(math.min(player:get_hp() + 2, 20))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
2
mods/game/autoheal/mod.conf
Normal file
2
mods/game/autoheal/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
name = autoheal
|
||||
description = Autohealing (gaining a few HP every second) mod for SSG
|
||||
243
mods/game/functions/init.lua
Normal file
243
mods/game/functions/init.lua
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
-- Functions for SSG
|
||||
function make_player_invisible(player) -- Hide a player (pre-match and spectator)
|
||||
save_player_data(player)
|
||||
player:set_properties({
|
||||
pointable = false,
|
||||
visual = "mesh",
|
||||
textures = {"blank.png"},
|
||||
})
|
||||
|
||||
playertag.set(player, playertag.TYPE_BUILTIN, {a = 0})
|
||||
end
|
||||
|
||||
function give_player_items(player) -- Give the player their initial stuff
|
||||
local class = player:get_meta():get_string("class")
|
||||
local inv = player:get_inventory()
|
||||
|
||||
inv:set_list("main", {})
|
||||
|
||||
if class == "sniper" then
|
||||
inv:add_item("main", "ctf_ranged:m200_loaded")
|
||||
inv:add_item("main", "default:sword_stone")
|
||||
inv:add_item("main", "ctf_ranged:ammo 100")
|
||||
elseif class == "assault" then
|
||||
inv:add_item("main", "ctf_ranged:ak47_loaded")
|
||||
inv:add_item("main", "ctf_ranged:glock17_loaded")
|
||||
inv:add_item("main", "ctf_ranged:ammo 100")
|
||||
elseif class == "shotgun" then
|
||||
inv:add_item("main", "ctf_ranged:benelli_loaded")
|
||||
inv:add_item("main", "ctf_ranged:glock17_loaded")
|
||||
inv:add_item("main", "ctf_ranged:ammo 100")
|
||||
end
|
||||
end
|
||||
|
||||
function set_player_mode(player, mode) -- Set player mode (spectator, pre-match, normal, etc)
|
||||
player:get_meta():set_string("mode", mode)
|
||||
|
||||
local player_name = player:get_player_name()
|
||||
local privs = core.get_player_privs(player_name)
|
||||
|
||||
if mode == "normal" then
|
||||
player:set_properties({
|
||||
pointable = true, -- allow players to be killable after the match starts
|
||||
})
|
||||
|
||||
load_player_data(player)
|
||||
privs.noclip, privs.fast, privs.fly, privs.interact = false, false, false, true
|
||||
|
||||
playertag.set(player, playertag.TYPE_ENTITY, {a = 255, r = 255, g = 255, b = 255})
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,4]
|
||||
list[current_player;main;0,0;8,1;]
|
||||
list[current_player;main;0,1.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
player:hud_set_flags({
|
||||
hotbar = true,
|
||||
healthbar = true,
|
||||
breathbar = true,
|
||||
})
|
||||
elseif mode == "spectator" then
|
||||
privs.noclip, privs.fast, privs.fly, privs.interact = true, true, true, false
|
||||
|
||||
make_player_invisible(player)
|
||||
|
||||
core.chat_send_player(player_name, core.colorize("blue", "You are now a spectator."))
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,4]
|
||||
list[current_player;main;0,0;8,1;]
|
||||
list[current_player;main;0,1.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
player:hud_set_flags({
|
||||
hotbar = false,
|
||||
healthbar = false,
|
||||
breathbar = false,
|
||||
})
|
||||
|
||||
elseif mode == "pre_match" then
|
||||
privs.noclip, privs.fast, privs.fly, privs.interact = false, true, false, false -- allow fast movement to get to a specific point on the large map
|
||||
|
||||
make_player_invisible(player)
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,6]
|
||||
|
||||
label[3,0.1;Change class:]
|
||||
|
||||
button[0.3,1;2.5,1;class_sniper;Long-range]
|
||||
button[2.8,1;2.5,1;class_assault;Mid-range]
|
||||
button[5.3,1;2.5,1;class_shotgun;Short-range]
|
||||
|
||||
list[current_player;main;0,2;8,1;]
|
||||
list[current_player;main;0,3.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
player:hud_set_flags({
|
||||
hotbar = true,
|
||||
healthbar = false,
|
||||
breathbar = false,
|
||||
})
|
||||
end
|
||||
|
||||
core.change_player_privs(player_name, privs)
|
||||
end
|
||||
|
||||
function start_match() -- Start the match
|
||||
if match_state ~= "not_started" then
|
||||
return
|
||||
end
|
||||
|
||||
set_match_state("pre_match")
|
||||
|
||||
map_data = place_map(map_data.name or "forest") -- default to forest if no map is specified
|
||||
|
||||
core.chat_send_all(core.colorize("green", "Match about to start in 30 seconds!\nOpen inventory to change class!"))
|
||||
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
set_player_mode(player, "pre_match")
|
||||
give_player_items(player)
|
||||
|
||||
player:set_pos({x = map_data.spawn_x, y = map_data.spawn_y, z = map_data.spawn_z})
|
||||
|
||||
player:set_hp(20)
|
||||
end
|
||||
|
||||
for i = 10, 1, -1 do -- count down from 10 to 1 (yes you are free to set me on fire for this horrible solution)
|
||||
core.after(20 + i, function()
|
||||
core.chat_send_all(core.colorize("green", "Match starts in " .. (11 - i) .. " seconds."))
|
||||
end)
|
||||
end
|
||||
|
||||
core.after(30, function()
|
||||
set_match_state("in_progress")
|
||||
core.chat_send_all(core.colorize("green", "Match started!"))
|
||||
|
||||
remove_barrier(map_data.size_x, map_data.barrier_level, map_data.size_z)
|
||||
|
||||
alive_players = {}
|
||||
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
local player_name = player:get_player_name()
|
||||
inv = player:get_inventory()
|
||||
|
||||
inv:set_list("main", {})
|
||||
|
||||
give_player_items(player)
|
||||
|
||||
player:set_properties({
|
||||
pointable = true, -- allow players to be killable after the match starts
|
||||
})
|
||||
alive_players[player_name] = "alive"
|
||||
|
||||
set_player_mode(player, "normal")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function end_match() -- End the match
|
||||
set_match_state("not_started")
|
||||
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
player:set_pos(spawn_pos)
|
||||
player:get_inventory():set_list("main", {})
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,4]
|
||||
list[current_player;main;0,0;8,1;]
|
||||
list[current_player;main;0,1.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
|
||||
player:set_properties({pointable = false})
|
||||
|
||||
set_player_mode(player, "normal")
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function set_match_state(state) -- why on earth does this function exist
|
||||
match_state = state
|
||||
end
|
||||
|
||||
function save_player_data(player) -- Save the player's skin storing it in their metadata
|
||||
local skins = player:get_properties().textures
|
||||
|
||||
-- probably the invisible skin so dont save it
|
||||
if skins[1] == "blank.png" then
|
||||
return
|
||||
end
|
||||
|
||||
player:get_meta():set_string("skin", core.serialize(skins))
|
||||
end
|
||||
|
||||
function load_player_data(player) -- Load the player's skin stored in their metadata
|
||||
local skins = core.deserialize(player:get_meta():get_string("skin"))
|
||||
|
||||
player:set_properties({
|
||||
visual = "mesh",
|
||||
textures = skins
|
||||
})
|
||||
end
|
||||
|
||||
function kill_player(player, reason) -- Handle killed/disconnected players properly
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
if alive_players[player_name] ~= "alive" or match_state ~= "in_progress" then
|
||||
return
|
||||
end
|
||||
|
||||
alive_players[player_name] = "dead"
|
||||
|
||||
local alive_player_names = get_alive_players()
|
||||
|
||||
local message = string.format("%s has been eliminated! (%s) %d player%s left!", player_name, reason, #alive_player_names, #alive_player_names == 1 and "" or "s")
|
||||
core.chat_send_all(core.colorize("red", message))
|
||||
if #alive_player_names == 1 then
|
||||
local winner_name = alive_player_names[1]
|
||||
core.chat_send_all(core.colorize("green", winner_name .. " is the winner!"))
|
||||
|
||||
set_match_state("post_match")
|
||||
|
||||
core.after(5, end_match)
|
||||
end
|
||||
end
|
||||
|
||||
function get_alive_players() -- Get the names of the alive players
|
||||
local alive_players_names = {}
|
||||
|
||||
for player_name, _ in pairs(alive_players) do
|
||||
if alive_players[player_name] == "alive" then
|
||||
table.insert(alive_players_names, player_name)
|
||||
end
|
||||
end
|
||||
|
||||
return alive_players_names
|
||||
end
|
||||
2
mods/game/functions/mod.conf
Normal file
2
mods/game/functions/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
name = functions
|
||||
description = Holds all the global functions for Simple Shooter Game
|
||||
|
|
@ -1,253 +1,10 @@
|
|||
-- Main mod for SSG
|
||||
local alive_players = {}
|
||||
local map_data = {} -- constrict the map data to this file
|
||||
|
||||
local spawn_pos = vector.new(-100, -9.6, -100)
|
||||
|
||||
local match_state = "not_started" -- not_started, pre_match, in_progress, post_match
|
||||
|
||||
local function save_player_data(player)
|
||||
local skins = player:get_properties().textures
|
||||
|
||||
-- probably the invisible skin so dont save it
|
||||
if skins[1] == "blank.png" then
|
||||
return
|
||||
end
|
||||
|
||||
player:get_meta():set_string("skin", core.serialize(skins))
|
||||
end
|
||||
|
||||
local function load_player_data(player)
|
||||
local skins = core.deserialize(player:get_meta():get_string("skin"))
|
||||
|
||||
player:set_properties({
|
||||
visual = "mesh",
|
||||
textures = skins
|
||||
})
|
||||
end
|
||||
|
||||
function make_player_invisible(player)
|
||||
save_player_data(player)
|
||||
player:set_properties({
|
||||
pointable = false,
|
||||
visual = "mesh",
|
||||
textures = {"blank.png"},
|
||||
})
|
||||
|
||||
playertag.set(player, playertag.TYPE_BUILTIN, {a = 0})
|
||||
end
|
||||
|
||||
function give_player_items(player)
|
||||
local class = player:get_meta():get_string("class")
|
||||
local inv = player:get_inventory()
|
||||
|
||||
inv:set_list("main", {})
|
||||
|
||||
if class == "sniper" then
|
||||
inv:add_item("main", "ctf_ranged:m200_loaded")
|
||||
inv:add_item("main", "default:sword_stone")
|
||||
inv:add_item("main", "ctf_ranged:ammo 100")
|
||||
elseif class == "assault" then
|
||||
inv:add_item("main", "ctf_ranged:ak47_loaded")
|
||||
inv:add_item("main", "ctf_ranged:glock17_loaded")
|
||||
inv:add_item("main", "ctf_ranged:ammo 100")
|
||||
elseif class == "shotgun" then
|
||||
inv:add_item("main", "ctf_ranged:benelli_loaded")
|
||||
inv:add_item("main", "ctf_ranged:glock17_loaded")
|
||||
inv:add_item("main", "ctf_ranged:ammo 100")
|
||||
end
|
||||
end
|
||||
|
||||
function set_player_mode(player, mode)
|
||||
player:get_meta():set_string("mode", mode)
|
||||
|
||||
local player_name = player:get_player_name()
|
||||
local privs = core.get_player_privs(player_name)
|
||||
|
||||
if mode == "normal" then
|
||||
player:set_properties({
|
||||
pointable = true, -- allow players to be killable after the match starts
|
||||
})
|
||||
|
||||
load_player_data(player)
|
||||
privs.noclip, privs.fast, privs.fly, privs.interact = false, false, false, true
|
||||
|
||||
playertag.set(player, playertag.TYPE_ENTITY, {a = 255, r = 255, g = 255, b = 255})
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,4]
|
||||
list[current_player;main;0,0;8,1;]
|
||||
list[current_player;main;0,1.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
player:hud_set_flags({
|
||||
hotbar = true,
|
||||
healthbar = true,
|
||||
breathbar = true,
|
||||
})
|
||||
elseif mode == "spectator" then
|
||||
privs.noclip, privs.fast, privs.fly, privs.interact = true, true, true, false
|
||||
|
||||
make_player_invisible(player)
|
||||
|
||||
core.chat_send_player(player_name, core.colorize("blue", "You are now a spectator."))
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,4]
|
||||
list[current_player;main;0,0;8,1;]
|
||||
list[current_player;main;0,1.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
player:hud_set_flags({
|
||||
hotbar = false,
|
||||
healthbar = false,
|
||||
breathbar = false,
|
||||
})
|
||||
|
||||
elseif mode == "pre_match" then
|
||||
privs.noclip, privs.fast, privs.fly, privs.interact = false, true, false, false -- allow fast movement to get to a specific point on the large map
|
||||
|
||||
make_player_invisible(player)
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,6]
|
||||
|
||||
label[3,0.1;Change class:]
|
||||
|
||||
button[0.3,1;2.5,1;class_sniper;Long-range]
|
||||
button[2.8,1;2.5,1;class_assault;Mid-range]
|
||||
button[5.3,1;2.5,1;class_shotgun;Short-range]
|
||||
|
||||
list[current_player;main;0,2;8,1;]
|
||||
list[current_player;main;0,3.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
player:hud_set_flags({
|
||||
hotbar = true,
|
||||
healthbar = false,
|
||||
breathbar = false,
|
||||
})
|
||||
end
|
||||
|
||||
core.change_player_privs(player_name, privs)
|
||||
end
|
||||
|
||||
function start_match()
|
||||
if match_state ~= "not_started" then
|
||||
return
|
||||
end
|
||||
|
||||
set_match_state("pre_match")
|
||||
|
||||
map_data = place_map(map_data.name or "forest") -- default to forest if no map is specified
|
||||
|
||||
core.chat_send_all(core.colorize("green", "Match about to start in 30 seconds!\nOpen inventory to change class!"))
|
||||
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
set_player_mode(player, "pre_match")
|
||||
give_player_items(player)
|
||||
|
||||
player:set_pos({x = map_data.spawn_x, y = map_data.spawn_y, z = map_data.spawn_z})
|
||||
|
||||
player:set_hp(20)
|
||||
end
|
||||
|
||||
for i = 10, 1, -1 do -- count down from 10 to 1 (yes you are free to set me on fire for this horrible solution)
|
||||
core.after(20 + i, function()
|
||||
core.chat_send_all(core.colorize("green", "Match starts in " .. (11 - i) .. " seconds."))
|
||||
end)
|
||||
end
|
||||
|
||||
core.after(30, function()
|
||||
set_match_state("in_progress")
|
||||
core.chat_send_all(core.colorize("green", "Match started!"))
|
||||
|
||||
remove_barrier(map_data.size_x, map_data.barrier_level, map_data.size_z)
|
||||
|
||||
alive_players = {}
|
||||
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
local player_name = player:get_player_name()
|
||||
inv = player:get_inventory()
|
||||
|
||||
inv:set_list("main", {})
|
||||
|
||||
give_player_items(player)
|
||||
|
||||
player:set_properties({
|
||||
pointable = true, -- allow players to be killable after the match starts
|
||||
})
|
||||
alive_players[player_name] = "alive"
|
||||
|
||||
set_player_mode(player, "normal")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function end_match()
|
||||
set_match_state("not_started")
|
||||
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
player:set_pos(spawn_pos)
|
||||
player:get_inventory():set_list("main", {})
|
||||
|
||||
player:set_inventory_formspec([[
|
||||
size[8,4]
|
||||
list[current_player;main;0,0;8,1;]
|
||||
list[current_player;main;0,1.25;8,3;8]
|
||||
listring[current_player;main]
|
||||
]])
|
||||
|
||||
|
||||
player:set_properties({pointable = false})
|
||||
|
||||
set_player_mode(player, "normal")
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function set_match_state(state)
|
||||
match_state = state
|
||||
end
|
||||
|
||||
local function get_alive_players()
|
||||
local alive_players_names = {}
|
||||
|
||||
for player_name, _ in pairs(alive_players) do
|
||||
if alive_players[player_name] == "alive" then
|
||||
table.insert(alive_players_names, player_name)
|
||||
end
|
||||
end
|
||||
|
||||
return alive_players_names
|
||||
end
|
||||
|
||||
local function kill_player(player, reason)
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
if alive_players[player_name] ~= "alive" or match_state ~= "in_progress" then
|
||||
return
|
||||
end
|
||||
|
||||
alive_players[player_name] = "dead"
|
||||
|
||||
local alive_player_names = get_alive_players()
|
||||
|
||||
local message = string.format("%s has been eliminated! (%s) %d player%s left!", player_name, reason, #alive_player_names, #alive_player_names == 1 and "" or "s")
|
||||
core.chat_send_all(core.colorize("red", message))
|
||||
if #alive_player_names == 1 then
|
||||
local winner_name = alive_player_names[1]
|
||||
core.chat_send_all(core.colorize("green", winner_name .. " is the winner!"))
|
||||
|
||||
set_match_state("post_match")
|
||||
|
||||
core.after(5, end_match)
|
||||
end
|
||||
end
|
||||
-- Variables
|
||||
alive_players = {}
|
||||
map_data = {}
|
||||
spawn_pos = vector.new(-100, -9.6, -100)
|
||||
match_state = "not_started" -- not_started, pre_match, in_progress, post_match
|
||||
|
||||
local diggable_groups = {
|
||||
"snappy",
|
||||
|
|
@ -257,6 +14,7 @@ local diggable_groups = {
|
|||
"oddly_breakable_by_hand",
|
||||
}
|
||||
|
||||
-- `core.xxx` things
|
||||
core.register_on_mods_loaded(function()
|
||||
for itemname, _ in pairs(core.registered_nodes) do
|
||||
local node = core.registered_nodes[itemname]
|
||||
|
|
@ -326,20 +84,6 @@ core.register_on_respawnplayer(function(player)
|
|||
return true
|
||||
end)
|
||||
|
||||
local timer = 0
|
||||
core.register_globalstep(function(dtime)
|
||||
timer = timer + dtime
|
||||
|
||||
if timer >= 10 then
|
||||
timer = 0
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
if alive_players[player:get_player_name()] == "alive" then
|
||||
player:set_hp(math.min(player:get_hp() + 2, 20))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_on_player_receive_fields(function(player, formname, fields)
|
||||
|
||||
if match_state ~= "pre_match" then
|
||||
|
|
@ -358,5 +102,5 @@ core.register_on_player_receive_fields(function(player, formname, fields)
|
|||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Privileges
|
||||
core.register_privilege("match_manager", {description = "Can manage the match", give_to_singleplayer = true})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue