Compare commits
No commits in common. "main" and "v1.1.0-alpha" have entirely different histories.
main
...
v1.1.0-alp
|
|
@ -1,4 +1,4 @@
|
||||||
# simple-shooter-game
|
# simple-shooter-game
|
||||||
A FPS game for the [Luanti game engine](https://luanti.org). Currently very WIP
|
A FPS game for the [Luanti Game Engine](https://luanti.org). Currently very WIP
|
||||||
|
|
||||||
PRs welcome!
|
PRs welcome!
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
title = Simple Shooter Game
|
title = Simple Shooter Game
|
||||||
allowed_mapgens = singlenode
|
allowed_mapgens = singlenode
|
||||||
author = a-bad-dev
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ core.register_chatcommand("start", {
|
||||||
if match_state == "pre_match" or match_state == "post_match" or match_state == "in_progress" then
|
if match_state == "pre_match" or match_state == "post_match" or match_state == "in_progress" then
|
||||||
return false, "-!- Match is already in progress!"
|
return false, "-!- Match is already in progress!"
|
||||||
end
|
end
|
||||||
|
|
||||||
local sucess = start_match(param)
|
local sucess = start_match(param)
|
||||||
|
|
||||||
if not map_data then
|
if map_data == "nope :(" then
|
||||||
return false, "-!- Map not found!"
|
return false, "-!- Map not found!"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ core.register_chatcommand("stop", {
|
||||||
privs = {match_manager = true},
|
privs = {match_manager = true},
|
||||||
description = "Terminate the match",
|
description = "Terminate the match",
|
||||||
func = function()
|
func = function()
|
||||||
if match_state ~= "post_match" and match_state ~= "not_started" then
|
if match_state ~= "pre_match" and match_state ~= "post_match" and match_state ~= "not_started" then
|
||||||
core.chat_send_all(core.colorize("red", "Match terminated."))
|
core.chat_send_all(core.colorize("red", "Match terminated."))
|
||||||
end_match()
|
end_match()
|
||||||
|
|
||||||
|
|
@ -38,16 +38,3 @@ core.register_chatcommand("stop", {
|
||||||
return false, "Match cannot be terminated at the moment."
|
return false, "Match cannot be terminated at the moment."
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
core.register_chatcommand("maps", {
|
|
||||||
params = "",
|
|
||||||
privs = {match_manager = true},
|
|
||||||
description = "List all maps",
|
|
||||||
func = function()
|
|
||||||
local list_string = "Available maps:\n"
|
|
||||||
for _, map in pairs(map_list) do
|
|
||||||
list_string = list_string .. map .. "\n"
|
|
||||||
end
|
|
||||||
return true, list_string .. "\nUse /start <map> to start a match."
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
@ -1,17 +1,3 @@
|
||||||
match_start_jobs = {}
|
|
||||||
loading_tips = {
|
|
||||||
"Open the inventory to change class!",
|
|
||||||
"Short-range is good for small/dense maps!",
|
|
||||||
"Mid-range is good on maps with long tunnels or open areas!",
|
|
||||||
"Long-range is good for maps with really open and large areas!",
|
|
||||||
"Ambushing can be powerful assuming you're not found!",
|
|
||||||
"Players may sneak up on you from behind!",
|
|
||||||
"You *can't* be shot under water!",
|
|
||||||
"The Short-range class can one-shot from 6 to 7 nodes away!",
|
|
||||||
"Using torches may allow enemies to sneak up on you in the dark!",
|
|
||||||
"e s p i o n a g e",
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Functions for SSG
|
-- Functions for SSG
|
||||||
function make_player_invisible(player) -- Hide a player (pre-match and spectator)
|
function make_player_invisible(player) -- Hide a player (pre-match and spectator)
|
||||||
save_player_data(player)
|
save_player_data(player)
|
||||||
|
|
@ -39,7 +25,7 @@ function give_player_items(player) -- Give the player their initial stuff
|
||||||
for i = 1, #map_data.classes.class_2.initial_items do
|
for i = 1, #map_data.classes.class_2.initial_items do
|
||||||
inv:add_item("main", map_data.classes.class_2.initial_items[i])
|
inv:add_item("main", map_data.classes.class_2.initial_items[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif class == "3" then
|
elseif class == "3" then
|
||||||
for i = 1, #map_data.classes.class_3.initial_items do
|
for i = 1, #map_data.classes.class_3.initial_items do
|
||||||
inv:add_item("main", map_data.classes.class_3.initial_items[i])
|
inv:add_item("main", map_data.classes.class_3.initial_items[i])
|
||||||
|
|
@ -64,18 +50,17 @@ function set_player_mode(player, mode) -- Set player mode (spectator, pre-match,
|
||||||
playertag.set(player, playertag.TYPE_ENTITY, {a = 255, r = 255, g = 255, b = 255})
|
playertag.set(player, playertag.TYPE_ENTITY, {a = 255, r = 255, g = 255, b = 255})
|
||||||
|
|
||||||
player:set_inventory_formspec([[
|
player:set_inventory_formspec([[
|
||||||
size[8,4]
|
size[8,4]
|
||||||
list[current_player;main;0,0;8,1;]
|
list[current_player;main;0,0;8,1;]
|
||||||
list[current_player;main;0,1.25;8,3;8]
|
list[current_player;main;0,1.25;8,3;8]
|
||||||
listring[current_player;main]
|
listring[current_player;main]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
player:hud_set_flags({
|
player:hud_set_flags({
|
||||||
hotbar = true,
|
hotbar = true,
|
||||||
healthbar = true,
|
healthbar = true,
|
||||||
breathbar = true,
|
breathbar = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
elseif mode == "spectator" then
|
elseif mode == "spectator" then
|
||||||
privs.noclip, privs.fast, privs.fly, privs.interact, privs.debug = true, true, true, false, true
|
privs.noclip, privs.fast, privs.fly, privs.interact, privs.debug = true, true, true, false, true
|
||||||
|
|
||||||
|
|
@ -84,10 +69,10 @@ function set_player_mode(player, mode) -- Set player mode (spectator, pre-match,
|
||||||
core.chat_send_player(player_name, core.colorize("#0574fc", "You are now a spectator."))
|
core.chat_send_player(player_name, core.colorize("#0574fc", "You are now a spectator."))
|
||||||
|
|
||||||
player:set_inventory_formspec([[
|
player:set_inventory_formspec([[
|
||||||
size[8,4]
|
size[8,4]
|
||||||
list[current_player;main;0,0;8,1;]
|
list[current_player;main;0,0;8,1;]
|
||||||
list[current_player;main;0,1.25;8,3;8]
|
list[current_player;main;0,1.25;8,3;8]
|
||||||
listring[current_player;main]
|
listring[current_player;main]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
player:hud_set_flags({
|
player:hud_set_flags({
|
||||||
|
|
@ -102,17 +87,17 @@ function set_player_mode(player, mode) -- Set player mode (spectator, pre-match,
|
||||||
make_player_invisible(player)
|
make_player_invisible(player)
|
||||||
|
|
||||||
player:set_inventory_formspec([[
|
player:set_inventory_formspec([[
|
||||||
size[8,6]
|
size[8,6]
|
||||||
|
|
||||||
label[3,0.1;Change class:]
|
label[3,0.1;Change class:]
|
||||||
|
|
||||||
button[0.3,1;2.5,1;class_sniper;]] .. map_data.classes.class_1.name .. [[]
|
button[0.3,1;2.5,1;class_sniper;]] .. map_data.classes.class_1.name .. [[]
|
||||||
button[2.8,1;2.5,1;class_assault;]] .. map_data.classes.class_2.name .. [[]
|
button[2.8,1;2.5,1;class_assault;]] .. map_data.classes.class_2.name .. [[]
|
||||||
button[5.3,1;2.5,1;class_shotgun;]] .. map_data.classes.class_3.name .. [[]
|
button[5.3,1;2.5,1;class_shotgun;]] .. map_data.classes.class_3.name .. [[]
|
||||||
|
|
||||||
list[current_player;main;0,2;8,1;]
|
list[current_player;main;0,2;8,1;]
|
||||||
list[current_player;main;0,3.25;8,3;8]
|
list[current_player;main;0,3.25;8,3;8]
|
||||||
listring[current_player;main]
|
listring[current_player;main]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
player:hud_set_flags({
|
player:hud_set_flags({
|
||||||
|
|
@ -130,72 +115,56 @@ function start_match(map) -- Start the match
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
place_map(map or "forest") -- default to forest if no map is specified
|
set_match_state("pre_match")
|
||||||
|
|
||||||
if not map_data then
|
map_data = place_map(map or "forest") -- default to forest if no map is specified
|
||||||
return nil
|
|
||||||
|
if map_data == "nope :(" then
|
||||||
|
return map_data
|
||||||
end
|
end
|
||||||
|
|
||||||
local map_loading_images = {}
|
local map_loading_images = {}
|
||||||
for _, player in pairs(core.get_connected_players()) do
|
for _, player in pairs(core.get_connected_players()) do
|
||||||
set_player_mode(player, "pre_match")
|
set_player_mode(player, "pre_match")
|
||||||
|
|
||||||
map_loading_images[player:get_player_name()] = {
|
map_loading_images[player:get_player_name()] = player:hud_add({
|
||||||
loading = player:hud_add({
|
type = "image",
|
||||||
type = "image",
|
position = {x=0.5, y=0.5},
|
||||||
position = {x=0.5, y=0.5},
|
image_scale = 100,
|
||||||
image_scale = 100,
|
text = "map_loading.png",
|
||||||
text = "map_loading.png",
|
scale = {x=-100, y=-100},
|
||||||
scale = {x=-100, y=-100},
|
z_index = 1000,
|
||||||
z_index = 1000,
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
info = player:hud_add({
|
|
||||||
type = "text",
|
|
||||||
position = {x=0.5, y=0.7},
|
|
||||||
text = loading_tips[math.random(1, #loading_tips)],
|
|
||||||
number = 0xFFFFFF,
|
|
||||||
z_index = 1000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
give_player_items(player)
|
give_player_items(player)
|
||||||
|
|
||||||
player:set_pos(map_data.spawn)
|
player:set_pos({x = map_data.spawn_x, y = map_data.spawn_y, z = map_data.spawn_z})
|
||||||
|
|
||||||
player:set_hp(20)
|
player:set_hp(20)
|
||||||
end
|
end
|
||||||
|
|
||||||
core.after(3, function()
|
core.after(5, function()
|
||||||
set_match_state("pre_match")
|
|
||||||
|
|
||||||
for _, player in pairs(core.get_connected_players()) do
|
for _, player in pairs(core.get_connected_players()) do
|
||||||
player:set_pos(map_data.spawn)
|
player:set_pos({x = map_data.spawn_x, y = map_data.spawn_y, z = map_data.spawn_z})
|
||||||
|
player:hud_remove(map_loading_images[player:get_player_name()])
|
||||||
for _, id in pairs(map_loading_images[player:get_player_name()]) do
|
|
||||||
player:hud_remove(id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if map_data.on_start then
|
|
||||||
map_data.on_start()
|
assert(loadstring(map_data.scripts.on_start or ""))()
|
||||||
end
|
|
||||||
|
|
||||||
core.chat_send_all(core.colorize("#b011f9", string.format("Match about to start in %d seconds!\nOpen inventory to change class!", map_data.start_time)))
|
core.chat_send_all(core.colorize("#b011f9", string.format("Match about to start in %d seconds!\nOpen inventory to change class!", map_data.start_time)))
|
||||||
|
|
||||||
match_start_jobs = {countdown = {}, map = nil}
|
|
||||||
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)
|
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)
|
||||||
table.insert(match_start_jobs.countdown, core.after(map_data.start_time - 10 + i, function()
|
core.after(map_data.start_time - 10 + i, function()
|
||||||
core.chat_send_all(core.colorize("green", string.format("Match starts in %d second%s.", 11 - i, 11 - i == 1 and "" or "s"))) -- <- RIP readability
|
core.chat_send_all(core.colorize("green", string.format("Match starts in %d second%s.", 11 - i, 11 - i == 1 and "" or "s"))) -- <- RIP readability
|
||||||
end))
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
match_start_jobs.map = core.after(map_data.start_time, function()
|
core.after(map_data.start_time, function()
|
||||||
match_start_jobs = nil
|
|
||||||
set_match_state("in_progress")
|
set_match_state("in_progress")
|
||||||
core.chat_send_all(core.colorize("green", "Match started!"))
|
core.chat_send_all(core.colorize("green", "Match started!"))
|
||||||
|
|
||||||
remove_barrier()
|
remove_barrier(map_data.size_x, map_data.barrier_level, map_data.size_z)
|
||||||
|
|
||||||
alive_players = {}
|
alive_players = {}
|
||||||
|
|
||||||
|
|
@ -221,31 +190,18 @@ end
|
||||||
function end_match() -- End the match
|
function end_match() -- End the match
|
||||||
set_match_state("not_started")
|
set_match_state("not_started")
|
||||||
|
|
||||||
if match_start_jobs then
|
|
||||||
match_start_jobs.map:cancel()
|
|
||||||
|
|
||||||
for _, job in pairs(match_start_jobs.countdown) do
|
|
||||||
job:cancel()
|
|
||||||
end
|
|
||||||
|
|
||||||
match_start_jobs = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if map_data.on_end then
|
|
||||||
map_data.on_end()
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, player in pairs(core.get_connected_players()) do
|
for _, player in pairs(core.get_connected_players()) do
|
||||||
player:set_pos(spawn_pos)
|
player:set_pos(spawn_pos)
|
||||||
player:get_inventory():set_list("main", {})
|
player:get_inventory():set_list("main", {})
|
||||||
|
|
||||||
player:set_inventory_formspec([[
|
player:set_inventory_formspec([[
|
||||||
size[8,4]
|
size[8,4]
|
||||||
list[current_player;main;0,0;8,1;]
|
list[current_player;main;0,0;8,1;]
|
||||||
list[current_player;main;0,1.25;8,3;8]
|
list[current_player;main;0,1.25;8,3;8]
|
||||||
listring[current_player;main]
|
listring[current_player;main]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
|
||||||
player:set_properties({pointable = false})
|
player:set_properties({pointable = false})
|
||||||
|
|
||||||
set_player_mode(player, "normal")
|
set_player_mode(player, "normal")
|
||||||
|
|
@ -265,11 +221,11 @@ function save_player_data(player) -- Save the player's skin storing it in their
|
||||||
if skins[1] == "blank.png" then
|
if skins[1] == "blank.png" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
player:get_meta():set_string("skin", core.serialize(skins))
|
player:get_meta():set_string("skin", core.serialize(skins))
|
||||||
end
|
end
|
||||||
|
|
||||||
function load_player_data(player) -- Load the player's skin stored in their metadata
|
function load_player_data(player) -- Load the player's skin stored in their metadata
|
||||||
local skins = core.deserialize(player:get_meta():get_string("skin"))
|
local skins = core.deserialize(player:get_meta():get_string("skin"))
|
||||||
|
|
||||||
player:set_properties({
|
player:set_properties({
|
||||||
|
|
@ -294,6 +250,8 @@ function kill_player(player, reason) -- Handle killed/disconnected players prope
|
||||||
if #alive_player_names == 1 then
|
if #alive_player_names == 1 then
|
||||||
local winner_name = alive_player_names[1]
|
local winner_name = alive_player_names[1]
|
||||||
core.chat_send_all(core.colorize("green", winner_name .. " is the winner!"))
|
core.chat_send_all(core.colorize("green", winner_name .. " is the winner!"))
|
||||||
|
|
||||||
|
assert(loadstring(map_data.scripts.on_end or ""))()
|
||||||
|
|
||||||
set_match_state("post_match")
|
set_match_state("post_match")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,11 @@ core.register_on_joinplayer(function(player)
|
||||||
player:get_inventory():set_list("main", {})
|
player:get_inventory():set_list("main", {})
|
||||||
|
|
||||||
player:set_inventory_formspec([[
|
player:set_inventory_formspec([[
|
||||||
size[8,4]
|
size[8,4]
|
||||||
list[current_player;main;0,0;8,1;]
|
list[current_player;main;0,0;8,1;]
|
||||||
list[current_player;main;0,1.25;8,3;8]
|
list[current_player;main;0,1.25;8,3;8]
|
||||||
listring[current_player;main]
|
listring[current_player;main]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
player:set_properties({pointable = false})
|
player:set_properties({pointable = false})
|
||||||
|
|
||||||
player:hud_set_flags({
|
player:hud_set_flags({
|
||||||
|
|
@ -60,13 +59,13 @@ end)
|
||||||
|
|
||||||
core.register_on_leaveplayer(function(player)
|
core.register_on_leaveplayer(function(player)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
kill_player(player, "left the game")
|
kill_player(player, "left the game")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
core.register_on_dieplayer(function(player)
|
core.register_on_dieplayer(function(player)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
kill_player(player, "died")
|
kill_player(player, "died")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
@ -76,9 +75,9 @@ core.register_on_respawnplayer(function(player)
|
||||||
if match_state == "in_progress" or match_state == "post_match" then
|
if match_state == "in_progress" or match_state == "post_match" then
|
||||||
set_player_mode(player, "spectator")
|
set_player_mode(player, "spectator")
|
||||||
|
|
||||||
player:set_pos(map_data.spawn)
|
player:set_pos({x = map_data.spawn_x, y = map_data.spawn_y, z = map_data.spawn_z})
|
||||||
player:get_inventory():set_list("main", {})
|
player:get_inventory():set_list("main", {})
|
||||||
|
|
||||||
player:set_properties({pointable = false})
|
player:set_properties({pointable = false})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,17 +34,23 @@ Step 8: Open the `map.lua` file in a text editor and put the following content i
|
||||||
```lua
|
```lua
|
||||||
local map_data = {
|
local map_data = {
|
||||||
name = "(Your map name here)",
|
name = "(Your map name here)",
|
||||||
size = vector.new(Your map size)
|
size_x = (Size in the X direction of your map),
|
||||||
|
size_y = (Size in the Y direction of your map),
|
||||||
|
size_z = (Size in the Z direction of your map),
|
||||||
|
|
||||||
barrier_level = (Distance from the bottom of the map to the barrier),
|
barrier_level = (Distance from the bottom of the map to the barrier),
|
||||||
|
|
||||||
spawn = vector.new(Your spawn coordinates relative to map position, can be set to nil)
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = (Amount of time in seconds before the barrier is removed),
|
start_time = (Amount of time in seconds before the barrier is removed),
|
||||||
|
|
||||||
on_start = function(),
|
scripts = {
|
||||||
on_end = function(),
|
on_start = "(Lua script to be run after /start is run, leave blank unless you know what you are doing!)",
|
||||||
on_barrier_remove = function(),
|
on_barrier_remove = "(Lua script to be run after the barrier is removed, leave blank unless you know what you are doing!)",
|
||||||
|
on_end = "(Lua script to be run after the match has ended, leave blank unless you know what you are doing!)"
|
||||||
|
},
|
||||||
|
|
||||||
classes = {
|
classes = {
|
||||||
class_1 = {
|
class_1 = {
|
||||||
|
|
@ -63,6 +69,8 @@ local map_data = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 9: Open Minetest/Luanti and create a new world with Simple Shooter Game.
|
Step 9: Open Minetest/Luanti and create a new world with Simple Shooter Game.
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,20 @@
|
||||||
-- Maps mod for SSG
|
-- Maps mod for SSG
|
||||||
|
|
||||||
local map_path = core.get_modpath("maps") .. "/maps/"
|
|
||||||
map_data = {}
|
|
||||||
|
|
||||||
map_list = core.get_dir_list(map_path, true)
|
|
||||||
table.sort(map_list)
|
|
||||||
|
|
||||||
function place_map(map)
|
function place_map(map)
|
||||||
local map_pos = vector.new(0, 0, 0)
|
local map_path = core.get_modpath("maps") .. "/maps/" .. map .. "/"
|
||||||
|
|
||||||
for i = 1, #map_list do
|
if not core.path_exists(map_path) then
|
||||||
if map_list[i] == map then
|
return "nope :("
|
||||||
map_pos = vector.new(1000 * (i - 1), 0, 0)
|
|
||||||
break
|
|
||||||
elseif i == #map_list then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
map_data = dofile(map_path .. map .. "/map.lua")
|
local map_data = dofile(map_path .. "map.lua")
|
||||||
map_data.pos = map_pos
|
core.place_schematic({x=0, y=0, z=0}, map_path .. "map.mts", 0, nil, true)
|
||||||
core.place_schematic(map_pos, map_path .. map .. "/map.mts", 0, nil, true)
|
|
||||||
|
|
||||||
if not map_data.spawn then -- set a default spawnpoint if not set
|
if map_data.spawn_x == nil or map_data.spawn_y == nil or map_data.spawn_z == nil then -- set a default spawnpoint if not set
|
||||||
map_data.spawn = vector.new(map_data.size.x / 2, map_data.barrier_level + 1, map_data.size.z / 2) + map_pos
|
map_data.spawn_x = map_data.size_x / 2
|
||||||
else
|
map_data.spawn_y = map_data.barrier_level + 1
|
||||||
map_data.spawn = map_data.spawn + map_pos
|
map_data.spawn_z = map_data.size_z / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
if map_data.start_time == nil or map_data.start_time <= 0 then
|
if map_data.start_time == nil or map_data.start_time <= 0 then
|
||||||
map_data.start_time = 30
|
map_data.start_time = 30
|
||||||
end
|
end
|
||||||
|
|
@ -38,7 +25,7 @@ function place_map(map)
|
||||||
map_data.classes.class_2 = {}
|
map_data.classes.class_2 = {}
|
||||||
map_data.classes.class_3 = {}
|
map_data.classes.class_3 = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
if map_data.classes.class_1.initial_items == nil or map_data.classes.class_1.name == nil then
|
if map_data.classes.class_1.initial_items == nil or map_data.classes.class_1.name == nil then
|
||||||
map_data.classes.class_1.initial_items = {"ctf_ranged:m200_loaded", "default:sword_stone", "ctf_ranged:ammo 99"}
|
map_data.classes.class_1.initial_items = {"ctf_ranged:m200_loaded", "default:sword_stone", "ctf_ranged:ammo 99"}
|
||||||
map_data.classes.class_1.name = "Long-range"
|
map_data.classes.class_1.name = "Long-range"
|
||||||
|
|
@ -53,15 +40,17 @@ function place_map(map)
|
||||||
map_data.classes.class_3.initial_items = {"ctf_ranged:benelli_loaded", "ctf_ranged:glock17_loaded", "ctf_ranged:ammo 99"}
|
map_data.classes.class_3.initial_items = {"ctf_ranged:benelli_loaded", "ctf_ranged:glock17_loaded", "ctf_ranged:ammo 99"}
|
||||||
map_data.classes.class_3.name = "Short-range"
|
map_data.classes.class_3.name = "Short-range"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return map_data
|
||||||
end
|
end
|
||||||
|
|
||||||
function remove_barrier()
|
function remove_barrier(x, y, z)
|
||||||
for _, player in pairs(core.get_connected_players()) do
|
for node_x = 1, x - 2 do
|
||||||
local pos = player:get_pos()
|
for node_z = 1, z - 2 do
|
||||||
player:set_pos({x=pos.x, y=map_data.barrier_level - 3.5, z=pos.z})
|
core.set_node({x = node_x, y = y - 1, z = node_z}, {name = "air"}) -- account for the fact that lua counts starting at 1... i think.... whatever, it works \_('_')_/
|
||||||
end
|
end
|
||||||
|
|
||||||
if map_data.on_barrier_remove then
|
|
||||||
map_data.on_barrier_remove()
|
|
||||||
end
|
end
|
||||||
|
assert(loadstring(map_data.scripts.on_barrier_remove or ""))()
|
||||||
|
return ""
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "1v1",
|
name = "1v1",
|
||||||
size = vector.new(41, 31, 38),
|
size_x = 41,
|
||||||
|
size_y = 31,
|
||||||
|
size_z = 38,
|
||||||
|
|
||||||
barrier_level = 27,
|
barrier_level = 27,
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 15,
|
start_time = 15,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = {
|
||||||
on_end = nil,
|
on_start = "for x=0, 40 do\nfor y=0, 17 do\nfor z=0, 37 do\ncore.set_node({x=x,y=31+y,z=z}, {name=\"default:glass\"})\nend\nend\nend",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "forest-2",
|
name = "forest-2",
|
||||||
size = vector.new(189, 71, 102),
|
size_x = 189,
|
||||||
|
size_y = 71,
|
||||||
|
size_z = 102,
|
||||||
|
|
||||||
barrier_level = 67, -- <- Y level of the barrier
|
barrier_level = 67, -- <- Y level of the barrier
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 45,
|
start_time = 45,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = { -- "temporary" hack to ensure there's nothing on top of the map
|
||||||
on_end = nil,
|
on_start = "for x=0, 188 do\nfor y=0, 4 do\nfor z=0, 101 do\ncore.set_node({x=x,y=71+y,z=z}, {name=\"air\"})\nend\nend\nend",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "forest-3",
|
name = "forest-3",
|
||||||
size = vector.new(537, 117, 244),
|
size_x = 537,
|
||||||
|
size_y = 117,
|
||||||
|
size_z = 244,
|
||||||
|
|
||||||
barrier_level = 113, -- <- Y level of the barrier
|
barrier_level = 113, -- <- Y level of the barrier
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 60,
|
start_time = 60,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = {
|
||||||
on_end = nil,
|
on_start = "",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,26 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "forest-4",
|
name = "forest-4",
|
||||||
size = vector.new(190, 69, 155),
|
size_x = 190,
|
||||||
|
size_y = 69,
|
||||||
|
size_z = 155,
|
||||||
|
|
||||||
barrier_level = 65,
|
barrier_level = 65,
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 30,
|
start_time = 30,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = {
|
||||||
on_end = nil,
|
on_start = "for x=0, 189 do\nfor y=0, 10 do\nfor z=0, 154 do\ncore.set_node({x=x,y=69+y,z=z}, {name=\"air\"})\nend\nend\nend",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
},
|
||||||
|
|
||||||
classes = {
|
classes = {
|
||||||
class_1 = {
|
class_1 = {
|
||||||
name = "Long-range",
|
name = "Long-range",
|
||||||
initial_items = {"ctf_ranged:m200_loaded", "default:sword_stone", "ctf_ranged:ammo 99", "default:torch 1"}
|
initial_items = {"ctf_ranged:m200_loaded", "default:sword_stone", "ctf_ranged:ammo 99", "default:torch 1"}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -29,3 +35,5 @@ return {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,26 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "forest",
|
name = "forest",
|
||||||
size = vector.new(155, 53, 147),
|
size_x = 155,
|
||||||
|
size_y = 53,
|
||||||
|
size_z = 147,
|
||||||
|
|
||||||
barrier_level = 49, -- <- Y level of the barrier
|
barrier_level = 49, -- <- Y level of the barrier
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 30,
|
start_time = 30,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = { -- "temporary" hack to ensure there's nothing on top of the map
|
||||||
on_end = nil,
|
on_start = "for x=0, 154 do\nfor y=0, 16 do\nfor z=0, 146 do\ncore.set_node({x=x,y=53+y,z=z}, {name=\"air\"})\nend\nend\nend",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
},
|
||||||
|
|
||||||
classes = {
|
classes = {
|
||||||
class_1 = {
|
class_1 = {
|
||||||
name = "Long-range",
|
name = "Long-range",
|
||||||
initial_items = {"ctf_ranged:m200_loaded", "default:sword_stone", "ctf_ranged:ammo 99", "default:torch 1"}
|
initial_items = {"ctf_ranged:m200_loaded", "default:sword_stone", "ctf_ranged:ammo 99", "default:torch 1"}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -29,3 +35,5 @@ return {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,22 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "mini-map",
|
name = "mini-map",
|
||||||
size = vector.new(8, 19, 8),
|
size_x = 8,
|
||||||
|
size_y = 19,
|
||||||
|
size_z = 8,
|
||||||
|
|
||||||
-- This is a ridiculous hack to prevent players from teleporting into the ground..
|
barrier_level = 15,
|
||||||
barrier_level = 19,
|
|
||||||
|
|
||||||
spawn = vector.new(4, 15, 4),
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 15,
|
start_time = 15,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = {
|
||||||
on_end = nil,
|
on_start = "",
|
||||||
on_barrier_remove = function()
|
on_barrier_remove = "",
|
||||||
local pos = map_data.pos
|
on_end = ""
|
||||||
local size = map_data.size + pos
|
}
|
||||||
|
|
||||||
for x = pos.x + 1, size.x - 2 do
|
|
||||||
for z = pos.z + 1, size.z - 2 do
|
|
||||||
core.set_node(vector.new(x, 14, z), {name = "air"})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "pine",
|
name = "pine",
|
||||||
size = vector.new(111, 64, 107),
|
size_x = 111,
|
||||||
|
size_y = 64,
|
||||||
|
size_z = 107,
|
||||||
|
|
||||||
barrier_level = 60, -- <- Y level of the barrier
|
barrier_level = 60, -- <- Y level of the barrier
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 30,
|
start_time = 30,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = {
|
||||||
on_end = nil,
|
on_start = "",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
return {
|
local map_data = {
|
||||||
name = "savanna",
|
name = "savanna",
|
||||||
size = vector.new(341, 83, 188),
|
size_x = 341,
|
||||||
|
size_y = 83,
|
||||||
|
size_z = 188,
|
||||||
|
|
||||||
barrier_level = 79, -- <- Y level of the barrier
|
barrier_level = 79, -- <- Y level of the barrier
|
||||||
|
|
||||||
spawn = nil,
|
spawn_x = nil,
|
||||||
|
spawn_y = nil,
|
||||||
|
spawn_z = nil,
|
||||||
|
|
||||||
start_time = 45,
|
start_time = 45,
|
||||||
|
|
||||||
on_start = nil,
|
scripts = {
|
||||||
on_end = nil,
|
on_start = "",
|
||||||
on_barrier_remove = nil,
|
on_barrier_remove = "",
|
||||||
|
on_end = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return map_data
|
||||||
|
|
|
||||||
27
mods/misc/ctf_guns/darkness_nerf/init.lua
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
-- Makes players glow
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
player:set_properties({glow = 3})
|
||||||
|
end)
|
||||||
|
|
||||||
|
local MIN_GLOW = 8
|
||||||
|
|
||||||
|
-- Makes dropped items glow
|
||||||
|
minetest.register_on_mods_loaded(function()
|
||||||
|
local itemdef = minetest.registered_entities["__builtin:item"]
|
||||||
|
local old_set_item = itemdef.set_item
|
||||||
|
|
||||||
|
itemdef.set_item = function(self, itemstring)
|
||||||
|
old_set_item(self, itemstring)
|
||||||
|
local iname = itemstring or self.itemstring
|
||||||
|
iname = ItemStack(iname):get_name()
|
||||||
|
|
||||||
|
if not minetest.registered_items[iname] or (minetest.registered_items[iname].light_source or 0) < MIN_GLOW then
|
||||||
|
self.object:set_properties({glow = MIN_GLOW})
|
||||||
|
else
|
||||||
|
self.object:set_properties({glow = minetest.registered_items[iname].light_source})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_entity(":__builtin:item", itemdef)
|
||||||
|
end)
|
||||||
2
mods/misc/ctf_guns/darkness_nerf/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = darkness_nerf
|
||||||
|
depends = default
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
Minetest Game mod: xpanes
|
|
||||||
=========================
|
|
||||||
See license.txt for license information.
|
|
||||||
|
|
||||||
Authors of source code
|
|
||||||
----------------------
|
|
||||||
Originally by xyz (MIT)
|
|
||||||
BlockMen (MIT)
|
|
||||||
sofar (MIT)
|
|
||||||
Various Minetest Game developers and contributors (MIT)
|
|
||||||
|
|
||||||
Authors of media (textures)
|
|
||||||
---------------------------
|
|
||||||
xyz (CC BY-SA 3.0):
|
|
||||||
All textures not mentioned below.
|
|
||||||
|
|
||||||
Gambit (CC BY-SA 3.0):
|
|
||||||
xpanes_bar.png
|
|
||||||
|
|
||||||
paramat (CC BY-SA 3.0):
|
|
||||||
xpanes_bar_top.png
|
|
||||||
|
|
||||||
Krock (CC0 1.0):
|
|
||||||
xpanes_edge.png
|
|
||||||
|
|
||||||
TumeniNodes (CC BY-SA 3.0):
|
|
||||||
xpanes_door_steel_bar.png
|
|
||||||
xpanes_item_steel_bar.png
|
|
||||||
xpanes_trapdoor_steel_bar.png
|
|
||||||
xpanes_trapdoor_steel_bar_side.png
|
|
||||||
xpanes_steel_bar_door_close.ogg
|
|
||||||
xpanes_steel_bar_door_open.ogg
|
|
||||||
|
|
@ -1,261 +0,0 @@
|
||||||
-- xpanes/init.lua
|
|
||||||
|
|
||||||
-- Load support for MT game translation.
|
|
||||||
local S = minetest.get_translator("xpanes")
|
|
||||||
|
|
||||||
|
|
||||||
local function is_pane(pos)
|
|
||||||
return minetest.get_item_group(minetest.get_node(pos).name, "pane") > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local function connects_dir(pos, name, dir)
|
|
||||||
local aside = vector.add(pos, minetest.facedir_to_dir(dir))
|
|
||||||
if is_pane(aside) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local connects_to = minetest.registered_nodes[name].connects_to
|
|
||||||
if not connects_to then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
local list = minetest.find_nodes_in_area(aside, aside, connects_to)
|
|
||||||
|
|
||||||
if #list > 0 then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local function swap(pos, node, name, param2)
|
|
||||||
if node.name == name and node.param2 == param2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.swap_node(pos, {name = name, param2 = param2})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update_pane(pos)
|
|
||||||
if not is_pane(pos) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local name = node.name
|
|
||||||
if name:sub(-5) == "_flat" then
|
|
||||||
name = name:sub(1, -6)
|
|
||||||
end
|
|
||||||
|
|
||||||
local any = node.param2
|
|
||||||
local c = {}
|
|
||||||
local count = 0
|
|
||||||
for dir = 0, 3 do
|
|
||||||
c[dir] = connects_dir(pos, name, dir)
|
|
||||||
if c[dir] then
|
|
||||||
any = dir
|
|
||||||
count = count + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if count == 0 then
|
|
||||||
swap(pos, node, name .. "_flat", any)
|
|
||||||
elseif count == 1 then
|
|
||||||
swap(pos, node, name .. "_flat", (any + 1) % 4)
|
|
||||||
elseif count == 2 then
|
|
||||||
if (c[0] and c[2]) or (c[1] and c[3]) then
|
|
||||||
swap(pos, node, name .. "_flat", (any + 1) % 4)
|
|
||||||
else
|
|
||||||
swap(pos, node, name, 0)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
swap(pos, node, name, 0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_placenode(function(pos, node)
|
|
||||||
if minetest.get_item_group(node, "pane") then
|
|
||||||
update_pane(pos)
|
|
||||||
end
|
|
||||||
for i = 0, 3 do
|
|
||||||
local dir = minetest.facedir_to_dir(i)
|
|
||||||
update_pane(vector.add(pos, dir))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_dignode(function(pos)
|
|
||||||
for i = 0, 3 do
|
|
||||||
local dir = minetest.facedir_to_dir(i)
|
|
||||||
update_pane(vector.add(pos, dir))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
xpanes = {}
|
|
||||||
function xpanes.register_pane(name, def)
|
|
||||||
for i = 1, 15 do
|
|
||||||
minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat")
|
|
||||||
end
|
|
||||||
|
|
||||||
local flatgroups = table.copy(def.groups)
|
|
||||||
flatgroups.pane = 1
|
|
||||||
minetest.register_node(":xpanes:" .. name .. "_flat", {
|
|
||||||
description = def.description,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
paramtype = "light",
|
|
||||||
is_ground_content = false,
|
|
||||||
sunlight_propagates = true,
|
|
||||||
inventory_image = def.inventory_image,
|
|
||||||
wield_image = def.wield_image,
|
|
||||||
paramtype2 = "facedir",
|
|
||||||
tiles = {
|
|
||||||
def.textures[3],
|
|
||||||
def.textures[3],
|
|
||||||
def.textures[3],
|
|
||||||
def.textures[3],
|
|
||||||
def.textures[1],
|
|
||||||
def.textures[1]
|
|
||||||
},
|
|
||||||
groups = flatgroups,
|
|
||||||
drop = "xpanes:" .. name .. "_flat",
|
|
||||||
sounds = def.sounds,
|
|
||||||
use_texture_alpha = def.use_texture_alpha and "blend" or "clip",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}},
|
|
||||||
},
|
|
||||||
selection_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {{-1/2, -1/2, -1/32, 1/2, 1/2, 1/32}},
|
|
||||||
},
|
|
||||||
connect_sides = { "left", "right" },
|
|
||||||
})
|
|
||||||
|
|
||||||
local groups = table.copy(def.groups)
|
|
||||||
groups.pane = 1
|
|
||||||
groups.not_in_creative_inventory = 1
|
|
||||||
minetest.register_node(":xpanes:" .. name, {
|
|
||||||
drawtype = "nodebox",
|
|
||||||
paramtype = "light",
|
|
||||||
is_ground_content = false,
|
|
||||||
sunlight_propagates = true,
|
|
||||||
description = def.description,
|
|
||||||
tiles = {
|
|
||||||
def.textures[3],
|
|
||||||
def.textures[3],
|
|
||||||
def.textures[1]
|
|
||||||
},
|
|
||||||
groups = groups,
|
|
||||||
drop = "xpanes:" .. name .. "_flat",
|
|
||||||
sounds = def.sounds,
|
|
||||||
use_texture_alpha = def.use_texture_alpha and "blend" or "clip",
|
|
||||||
node_box = {
|
|
||||||
type = "connected",
|
|
||||||
fixed = {{-1/32, -1/2, -1/32, 1/32, 1/2, 1/32}},
|
|
||||||
connect_front = {{-1/32, -1/2, -1/2, 1/32, 1/2, -1/32}},
|
|
||||||
connect_left = {{-1/2, -1/2, -1/32, -1/32, 1/2, 1/32}},
|
|
||||||
connect_back = {{-1/32, -1/2, 1/32, 1/32, 1/2, 1/2}},
|
|
||||||
connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}},
|
|
||||||
},
|
|
||||||
connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"},
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "xpanes:" .. name .. "_flat 16",
|
|
||||||
recipe = def.recipe
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
xpanes.register_pane("pane", {
|
|
||||||
description = S("Glass Pane"),
|
|
||||||
textures = {"default_glass.png", "", "xpanes_edge.png"},
|
|
||||||
inventory_image = "default_glass.png",
|
|
||||||
wield_image = "default_glass.png",
|
|
||||||
sounds = default.node_sound_glass_defaults(),
|
|
||||||
groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3},
|
|
||||||
recipe = {
|
|
||||||
{"default:glass", "default:glass", "default:glass"},
|
|
||||||
{"default:glass", "default:glass", "default:glass"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
xpanes.register_pane("obsidian_pane", {
|
|
||||||
description = S("Obsidian Glass Pane"),
|
|
||||||
textures = {"default_obsidian_glass.png", "", "xpanes_edge_obsidian.png"},
|
|
||||||
inventory_image = "default_obsidian_glass.png",
|
|
||||||
wield_image = "default_obsidian_glass.png",
|
|
||||||
sounds = default.node_sound_glass_defaults(),
|
|
||||||
groups = {snappy=2, cracky=3},
|
|
||||||
recipe = {
|
|
||||||
{"default:obsidian_glass", "default:obsidian_glass", "default:obsidian_glass"},
|
|
||||||
{"default:obsidian_glass", "default:obsidian_glass", "default:obsidian_glass"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
xpanes.register_pane("bar", {
|
|
||||||
description = S("Steel Bars"),
|
|
||||||
textures = {"xpanes_bar.png", "", "xpanes_bar_top.png"},
|
|
||||||
inventory_image = "xpanes_bar.png",
|
|
||||||
wield_image = "xpanes_bar.png",
|
|
||||||
groups = {cracky=2},
|
|
||||||
sounds = default.node_sound_metal_defaults(),
|
|
||||||
recipe = {
|
|
||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
|
||||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "xpanes:gen2",
|
|
||||||
nodenames = {"group:pane"},
|
|
||||||
action = function(pos, node)
|
|
||||||
update_pane(pos)
|
|
||||||
for i = 0, 3 do
|
|
||||||
local dir = minetest.facedir_to_dir(i)
|
|
||||||
update_pane(vector.add(pos, dir))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Register steel bar doors and trapdoors
|
|
||||||
|
|
||||||
if minetest.get_modpath("doors") then
|
|
||||||
|
|
||||||
doors.register("xpanes:door_steel_bar", {
|
|
||||||
tiles = {{name = "xpanes_door_steel_bar.png", backface_culling = true}},
|
|
||||||
description = S("Steel Bar Door"),
|
|
||||||
inventory_image = "xpanes_item_steel_bar.png",
|
|
||||||
protected = true,
|
|
||||||
groups = {node = 1, cracky = 1, level = 2},
|
|
||||||
sounds = default.node_sound_metal_defaults(),
|
|
||||||
sound_open = "xpanes_steel_bar_door_open",
|
|
||||||
sound_close = "xpanes_steel_bar_door_close",
|
|
||||||
gain_open = 0.15,
|
|
||||||
gain_close = 0.13,
|
|
||||||
recipe = {
|
|
||||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
|
||||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
|
||||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
doors.register_trapdoor("xpanes:trapdoor_steel_bar", {
|
|
||||||
description = S("Steel Bar Trapdoor"),
|
|
||||||
inventory_image = "xpanes_trapdoor_steel_bar.png",
|
|
||||||
wield_image = "xpanes_trapdoor_steel_bar.png",
|
|
||||||
tile_front = "xpanes_trapdoor_steel_bar.png",
|
|
||||||
tile_side = "xpanes_trapdoor_steel_bar_side.png",
|
|
||||||
protected = true,
|
|
||||||
groups = {node = 1, cracky = 1, level = 2, door = 1},
|
|
||||||
sounds = default.node_sound_metal_defaults(),
|
|
||||||
sound_open = "xpanes_steel_bar_door_open",
|
|
||||||
sound_close = "xpanes_steel_bar_door_close",
|
|
||||||
gain_open = 0.15,
|
|
||||||
gain_close = 0.13,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "xpanes:trapdoor_steel_bar",
|
|
||||||
recipe = {
|
|
||||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
|
||||||
{"xpanes:bar_flat", "xpanes:bar_flat"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
License of source code
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
The MIT License (MIT)
|
|
||||||
Copyright (C) 2014-2016 xyz
|
|
||||||
Copyright (C) 2014-2016 BlockMen
|
|
||||||
Copyright (C) 2016 Auke Kok <sofar@foo-projects.org>
|
|
||||||
Copyright (C) 2014-2016 Various Minetest Game developers and contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
||||||
software and associated documentation files (the "Software"), to deal in the Software
|
|
||||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
||||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or
|
|
||||||
substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
||||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
For more details:
|
|
||||||
https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
|
|
||||||
Licenses of media (textures)
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
|
||||||
Copyright (C) 2014-2016 xyz
|
|
||||||
Copyright (C) 2013-2016 Gambit
|
|
||||||
Copyright (C) 2016 paramat
|
|
||||||
Copyright (C) 2019 TumeniNodes
|
|
||||||
|
|
||||||
You are free to:
|
|
||||||
Share — copy and redistribute the material in any medium or format.
|
|
||||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
|
||||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
|
||||||
|
|
||||||
Under the following terms:
|
|
||||||
|
|
||||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
|
||||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
|
||||||
that suggests the licensor endorses you or your use.
|
|
||||||
|
|
||||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
|
||||||
your contributions under the same license as the original.
|
|
||||||
|
|
||||||
No additional restrictions — You may not apply legal terms or technological measures that
|
|
||||||
legally restrict others from doing anything the license permits.
|
|
||||||
|
|
||||||
Notices:
|
|
||||||
|
|
||||||
You do not have to comply with the license for elements of the material in the public
|
|
||||||
domain or where your use is permitted by an applicable exception or limitation.
|
|
||||||
No warranties are given. The license may not give you all of the permissions necessary
|
|
||||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
|
||||||
rights may limit how you use the material.
|
|
||||||
|
|
||||||
For more details:
|
|
||||||
http://creativecommons.org/licenses/by-sa/3.0/
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=
|
|
||||||
Obsidian Glass Pane=
|
|
||||||
Steel Bars=
|
|
||||||
Steel Bar Door=
|
|
||||||
Steel Bar Trapdoor=
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Стъклен прозорец
|
|
||||||
Obsidian Glass Pane=Прозорец от обсидианово стъкло
|
|
||||||
Steel Bars=Стоманени решетки
|
|
||||||
Steel Bar Door=Стоманени решетки за врата
|
|
||||||
Steel Bar Trapdoor=Стоманени решетки за капак
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Glasscheibe
|
|
||||||
Obsidian Glass Pane=Obsidianglasscheibe
|
|
||||||
Steel Bars=Stahlgitter
|
|
||||||
Steel Bar Door=Stahlgittertür
|
|
||||||
Steel Bar Trapdoor=Stahlgitterfalltür
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Vitra vitraĵo
|
|
||||||
Obsidian Glass Pane=Obsidiana vitra vitraĵo
|
|
||||||
Steel Bars=Ŝtalaj baraĵoj
|
|
||||||
Steel Bar Door=Ŝtala baraĵa pordo
|
|
||||||
Steel Bar Trapdoor=Ŝtala baraĵa plankpordo
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Panel de vidrio
|
|
||||||
Obsidian Glass Pane=Panel de vidrio de obsidiana
|
|
||||||
Steel Bars=Barras de acero
|
|
||||||
Steel Bar Door=Puerta de barras de acero
|
|
||||||
Steel Bar Trapdoor=Trampilla de barras de acero
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Beirazko panela
|
|
||||||
Obsidian Glass Pane=Obsidiana-beirazko panela
|
|
||||||
Steel Bars=Altzairuzko barrak
|
|
||||||
Steel Bar Door=Altzairu-barrazko atea
|
|
||||||
Steel Bar Trapdoor=Altzairu-barrazko tranpola
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Panneau de verre
|
|
||||||
Obsidian Glass Pane=Panneau de verre d'obsidienne
|
|
||||||
Steel Bars=Barreaux d'acier
|
|
||||||
Steel Bar Door=Porte en barreaux d'acier
|
|
||||||
Steel Bar Trapdoor=Trappe en barreaux d'acier
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Panel Kaca
|
|
||||||
Obsidian Glass Pane=Panel Kaca Obsidian
|
|
||||||
Steel Bars=Batang Baja
|
|
||||||
Steel Bar Door=Pintu Batang Baja
|
|
||||||
Steel Bar Trapdoor=Pintu Kolong Batang Baja
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Pannello di vetro
|
|
||||||
Obsidian Glass Pane=Pannello di vetro d'ossidiana
|
|
||||||
Steel Bars=Sbarre d'acciaio
|
|
||||||
Steel Bar Door=Porta con sbarre d'acciaio
|
|
||||||
Steel Bar Trapdoor=Botola con sbarre d'acciaio
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=板ガラス
|
|
||||||
Obsidian Glass Pane=黒曜石の板ガラス
|
|
||||||
Steel Bars=鉄棒の柵
|
|
||||||
Steel Bar Door=鉄棒のドア
|
|
||||||
Steel Bar Trapdoor=鉄棒のトラップドア
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=lo blaci plita
|
|
||||||
Obsidian Glass Pane=lo je'erma'ablaci blaci plita
|
|
||||||
Steel Bars=lo gasta garna
|
|
||||||
Steel Bar Door=lo gasta garna vrogai
|
|
||||||
Steel Bar Trapdoor=lo gasta garna lolvrogai
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Stikla panelis
|
|
||||||
Obsidian Glass Pane=Obsidiāna stikla panelis
|
|
||||||
Steel Bars=Tērauda režģis
|
|
||||||
Steel Bar Door=Tērauda režģa durvis
|
|
||||||
Steel Bar Trapdoor=Tērauda režģa lūka
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Kaca Tingkap
|
|
||||||
Obsidian Glass Pane=Kaca Tingkap Obsidia
|
|
||||||
Steel Bars=Jeriji Keluli
|
|
||||||
Steel Bar Door=Pintu Jeriji Keluli
|
|
||||||
Steel Bar Trapdoor=Pintu Kolong Jeriji Keluli
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Szyba
|
|
||||||
Obsidian Glass Pane=Obsydianowa szyba
|
|
||||||
Steel Bars=Stalowe kraty
|
|
||||||
Steel Bar Door=Drzwi ze stalowych krat
|
|
||||||
Steel Bar Trapdoor=Właz ze stalowych krat
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Painel de Vidro
|
|
||||||
Obsidian Glass Pane=Painel de Vidro de Obsidiana
|
|
||||||
Steel Bars=Barras de Aço
|
|
||||||
Steel Bar Door=Porta de Barras de Aço
|
|
||||||
Steel Bar Trapdoor=Alçapão de Barras de Aço
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Стеклянная панель
|
|
||||||
Obsidian Glass Pane=Панель из обсидианового стекла
|
|
||||||
Steel Bars=Стальная решетка
|
|
||||||
Steel Bar Door=Стальная решётчатая дверь
|
|
||||||
Steel Bar Trapdoor=Стальной решётчатый люк
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Tabuľa skla
|
|
||||||
Obsidian Glass Pane=Tabuľa obsidiánového skla
|
|
||||||
Steel Bars=Oceľové mreže
|
|
||||||
Steel Bar Door=Dvere z oceľových mreží
|
|
||||||
Steel Bar Trapdoor=Padajúce dvere z oceľových mreží
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Glasruta
|
|
||||||
Obsidian Glass Pane=Obsidianglasruta
|
|
||||||
Steel Bars=Stålgaller
|
|
||||||
Steel Bar Door=Stålgallerdörr
|
|
||||||
Steel Bar Trapdoor=Stålgallerfallucka
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=Скляна панель
|
|
||||||
Obsidian Glass Pane=Панель з обсидіанового скла
|
|
||||||
Steel Bars=Ґрати
|
|
||||||
Steel Bar Door=Двері з ґратами
|
|
||||||
Steel Bar Trapdoor=Люк з ґратами
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=玻璃窗
|
|
||||||
Obsidian Glass Pane=黑曜石玻璃窗
|
|
||||||
Steel Bars=钢筋
|
|
||||||
Steel Bar Door=钢筋门
|
|
||||||
Steel Bar Trapdoor=钢筋活板门
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# textdomain: xpanes
|
|
||||||
Glass Pane=玻璃窗
|
|
||||||
Obsidian Glass Pane=黑曜石玻璃窗
|
|
||||||
Steel Bars=鋼筋
|
|
||||||
Steel Bar Door=鋼筋門
|
|
||||||
Steel Bar Trapdoor=鋼筋活板門
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
name = xpanes
|
|
||||||
description = Minetest Game mod: xpanes
|
|
||||||
depends = default
|
|
||||||
optional_depends = doors
|
|
||||||
|
Before Width: | Height: | Size: 155 B |
|
Before Width: | Height: | Size: 101 B |
|
Before Width: | Height: | Size: 552 B |
|
Before Width: | Height: | Size: 269 B |
|
Before Width: | Height: | Size: 98 B |
|
Before Width: | Height: | Size: 301 B |
|
Before Width: | Height: | Size: 208 B |
|
Before Width: | Height: | Size: 98 B |
BIN
screenshot.png
|
Before Width: | Height: | Size: 387 KiB |