TONS of changes again, closes a couple issues and makes hunger, beds, and achievements more stable

This commit is contained in:
KaadmY 2017-05-15 10:44:27 -07:00
parent fce9574528
commit d4103c3c15
8 changed files with 341 additions and 150 deletions

View File

@ -338,7 +338,7 @@ achievements.register_achievement(
}) })
achievements.register_achievement( achievements.register_achievement(
"rockin'", "rockin",
{ {
title = "Rockin'", title = "Rockin'",
description = "Mine 200 stone", description = "Mine 200 stone",

View File

@ -1,3 +1,4 @@
crafting
default default
player_effects player_effects
achievements achievements

View File

@ -1,10 +1,243 @@
-- --
-- Bed mod -- Bed mod
-- By PilzAdam, thefamilygrog66 -- By PilzAdam, thefamilygrog66
-- Tweaked by Kaadmy, for Pixture -- Tweaked by Kaadmy, for Pixture
-- --
local players_in_bed = {} bed = {}
-- Per-user data table
bed.userdata = {}
local bed_file = minetest.get_worldpath() .. "/bed.dat"
local saving = false
local timer = 0
local delay_daytime = false
local function is_bed_node(pos)
if pos == nil then
return false
end
local node = minetest.get_node(pos)
if node.name == "bed:bed_foot" then
return true
end
return false
end
local function put_player_in_bed(player)
if player == nil then
return
end
local name = player:get_player_name()
if bed.userdata[name].slept
and not is_bed_node(bed.userdata[name].node_pos) then
return
end
player:set_look_horizontal(bed.userdata[name].spawn_yaw)
player:setpos(bed.userdata[name].spawn_pos)
player_effects.apply_effect(player, "inbed")
player:set_eye_offset(vector.new(0, -13, 0), vector.new(0, -13, 0))
player:set_local_animation(
{x=162, y=166},
{x=162, y=166},
{x=162, y=166},
{x=162, y=168},
30)
default.player_set_animation(player, "lay", 30)
default.player_attached[name] = true
end
local function take_player_from_bed(player)
if player == nil then
return
end
local name = player:get_player_name()
player:setpos(bed.userdata[name].spawn_pos)
player_effects.remove_effect(player, "inbed")
player:set_eye_offset(vector.new(0, 0, 0), vector.new(0, 0, 0))
player:set_local_animation(
{x=0, y=79},
{x=168, y=187},
{x=189, y=198},
{x=200, y=219},
30)
default.player_set_animation(player, "stand", 30)
default.player_attached[name] = false
end
local function save_bed()
local f = io.open(bed_file, "w")
f:write(minetest.serialize(bed.userdata))
io.close(f)
saving = false
end
local function delayed_save()
if not saving then
saving = true
minetest.after(40, save_bed)
end
end
local function load_bed()
local f = io.open(bed_file, "r")
if f then
bed.userdata = minetest.deserialize(f:read("*all"))
io.close(f)
else
save_bed()
end
end
local function on_load()
load_bed()
end
local function on_shutdown()
save_bed()
end
local function on_joinplayer(player)
local name = player:get_player_name()
if not bed.userdata[name] then
bed.userdata[name] = {
in_bed = false,
spawn_yaw = 0,
spawn_pos = nil,
slept = false,
node_pos = nil,
}
delayed_save()
end
if bed.userdata[name].in_bed then
minetest.after(
0.1,
function()
put_player_in_bed(player)
end)
end
end
local function on_respawnplayer(player)
local name = player:get_player_name()
if bed.userdata[name] then
if not bed.userdata[name].slept then
if not is_bed_node(bed.userdata[name].node_pos) then
minetest.chat_send_player(
name,
minetest.colorize(
"#f00", "You don't have a bed"))
else
minetest.chat_send_player(
name,
minetest.colorize(
"#f00", "You haven't slept in a bed yet"))
end
return
end
bed.userdata[name].in_bed = false
take_player_from_bed(player)
return true
end
end
local function on_globalstep(dtime)
timer = timer + dtime
if timer < 2 then
return
end
timer = 0
local sleeping_players = 0
for _, data in pairs(bed.userdata) do
if data.in_bed then
sleeping_players = sleeping_players + 1
end
end
local players = #minetest.get_connected_players()
if players > 0 and (players / 2.0) < sleeping_players then
if minetest.get_timeofday() < 0.2 or minetest.get_timeofday() > 0.8 then
if not delay_daytime then
delay_daytime = true
minetest.after(
2,
function()
minetest.chat_send_all(
minetest.colorize(
"#0ff",
"*** " .. sleeping_players .. " of " .. players
.. " players slept, rise and shine!"))
minetest.set_timeofday(0.23)
delay_daytime = false
for _, player in ipairs(minetest.get_connected_players()) do
if bed.userdata[player:get_player_name()].in_bed then
bed.userdata[player:get_player_name()].slept = true
end
end
end)
delayed_save()
end
end
end
end
minetest.after(0, on_load)
minetest.register_on_shutdown(on_shutdown)
minetest.register_on_joinplayer(on_joinplayer)
minetest.register_on_respawnplayer(on_respawnplayer)
minetest.register_globalstep(on_globalstep)
minetest.register_node( minetest.register_node(
"bed:bed_foot", "bed:bed_foot",
@ -29,74 +262,75 @@ minetest.register_node(
}, },
after_place_node = function(pos) after_place_node = function(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2) local dir = minetest.facedir_to_dir(node.param2)
local head_pos = vector.add(pos, dir) local head_pos = vector.add(pos, dir)
node.name = "bed:bed_head" node.name = "bed:bed_head"
if minetest.registered_nodes[minetest.get_node(head_pos).name].buildable_to then if minetest.registered_nodes[minetest.get_node(head_pos).name].buildable_to then
minetest.set_node(head_pos, node) minetest.set_node(head_pos, node)
else else
minetest.remove_node(pos) minetest.remove_node(pos)
end end
end, end,
on_destruct = function(pos) on_destruct = function(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local dir = minetest.facedir_to_dir(node.param2) local dir = minetest.facedir_to_dir(node.param2)
local head_pos = vector.add(pos, dir) local head_pos = vector.add(pos, dir)
if minetest.get_node(head_pos).name == "bed:bed_head" then if minetest.get_node(head_pos).name == "bed:bed_head" then
minetest.remove_node(head_pos) minetest.remove_node(head_pos)
end end
end, end,
on_rightclick = function(pos, node, clicker) on_rightclick = function(pos, node, clicker)
if not clicker:is_player() or not minetest.setting_getbool("bed_enabled") then if not clicker:is_player() then
return return
end end
local name = clicker:get_player_name() local name = clicker:get_player_name()
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local put_pos = vector.add(pos, vector.divide(minetest.facedir_to_dir(node.param2), 2)) local put_pos = vector.add(pos, vector.divide(
minetest.facedir_to_dir(node.param2), 2))
if clicker:get_player_name() == meta:get_string("player") then if clicker:get_player_name() == meta:get_string("player") then
put_pos.y = put_pos.y - 0.5 put_pos.y = put_pos.y - 0.5
clicker:setpos(put_pos) bed.userdata[name].in_bed = false
player_effects.remove_effect(clicker, "inbed")
clicker:set_eye_offset(vector.new(0, 0, 0), vector.new(0, 0, 0))
clicker:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30)
default.player_set_animation(clicker, "stand", 30)
players_in_bed[name] = nil take_player_from_bed(clicker)
default.player_attached[name] = false
meta:set_string("player", "") meta:set_string("player", "")
elseif meta:get_string("player") == "" and not default.player_attached[name] and players_in_bed[name] == nil then elseif meta:get_string("player") == "" and not default.player_attached[name]
put_pos.y = put_pos.y + 0.6 and bed.userdata[name].in_bed == false then
if not minetest.setting_getbool("bed_enabled") then
return
end
clicker:setpos(put_pos) put_pos.y = put_pos.y + 0.6
player_effects.apply_effect(clicker, "inbed")
clicker:set_eye_offset(vector.new(0, -13, 0), vector.new(0, -13, 0))
clicker:set_local_animation({x=162, y=166}, {x=162, y=166}, {x=162, y=166}, {x=162, y=168}, 30)
default.player_set_animation(clicker, "lay", 30)
if node.param2 == 2 then local yaw = 0
clicker:set_look_yaw(0)
else
clicker:set_look_yaw(node.param2 / 2 * math.pi)
end
players_in_bed[name] = true if node.param2 ~= 2 then
default.player_attached[name] = true yaw = (node.param2 / 2.0) * math.pi
end
meta:set_string("player", name) bed.userdata[name].in_bed = true
end
end, bed.userdata[name].spawn_yaw = yaw
bed.userdata[name].spawn_pos = put_pos
bed.userdata[name].node_pos = pos
put_player_in_bed(clicker)
meta:set_string("player", name)
end
end,
can_dig = function(pos) can_dig = function(pos)
return minetest.get_meta(pos):get_string("player") == "" return minetest.get_meta(pos):get_string("player") == ""
end end
}) })
minetest.register_node( minetest.register_node(
"bed:bed_head", "bed:bed_head",
@ -112,68 +346,18 @@ minetest.register_node(
type = "fixed", type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 2/16, 0.5} fixed = {-0.5, -0.5, -0.5, 0.5, 2/16, 0.5}
} }
}) })
minetest.register_alias("bed:bed", "bed:bed_foot") minetest.register_alias("bed:bed", "bed:bed_foot")
minetest.register_craft( crafting.register_craft(
{ {
output = "bed:bed", output = "bed:bed",
recipe = { items = {
{"group:fuzzy", "group:fuzzy", "group:fuzzy"}, "group:fuzzy 3",
{"group:planks", "group:planks", "group:planks"} "group:planks 3",
} }
}) })
bed_player_spawns = {}
local file = io.open(minetest.get_worldpath().."/bed.dat", "r")
if file then
bed_player_spawns = minetest.deserialize(file:read("*all"))
file:close()
end
local timer = 0
local wait = false
minetest.register_globalstep(
function(dtime)
if timer < 2 then
timer = timer + dtime
return
end
timer = 0
local sleeping_players = 0
for _, i in pairs(players_in_bed) do
if i then
sleeping_players = sleeping_players + 1
end
end
local players = #minetest.get_connected_players()
if players > 0 and players * 0.5 < sleeping_players then
if minetest.get_timeofday() < 0.2 or minetest.get_timeofday() > 0.8 then
if not wait then
minetest.chat_send_all("[zzz] "..sleeping_players.." of "..players.." players slept, skipping to day.")
wait = true
minetest.after(2, function()
minetest.set_timeofday(0.23)
wait = false
end)
for _, player in ipairs(minetest.get_connected_players()) do
bed_player_spawns[player:get_player_name()] = player:getpos()
end
local file = io.open(minetest.get_worldpath().."/bed.dat", "w")
file:write(minetest.serialize(bed_player_spawns))
file:close()
end
end
end
end)
player_effects.register_effect( player_effects.register_effect(
"inbed", "inbed",
@ -186,20 +370,7 @@ player_effects.register_effect(
jump = 0, jump = 0,
gravity = 0, gravity = 0,
} }
}) })
minetest.register_on_respawnplayer(
function(player)
local name = player:get_player_name()
if bed_player_spawns[name] then
player:setpos(bed_player_spawns[name])
end
end)
minetest.register_on_leaveplayer(
function(player)
players_in_bed[player:get_player_name()] = nil
end)
-- Achievements -- Achievements
@ -210,6 +381,6 @@ achievements.register_achievement(
description = "Craft a bed", description = "Craft a bed",
times = 1, times = 1,
craftitem = "bed:bed_foot", craftitem = "bed:bed_foot",
}) })
default.log("mod:bed", "loaded") default.log("mod:bed", "loaded")

View File

@ -845,7 +845,6 @@ minetest.register_node(
"default:water_flowing", "default:water_flowing",
{ {
description = "Water (flowing)", description = "Water (flowing)",
inventory_image = minetest.inventorycube("default_water.png"),
drawtype = "flowingliquid", drawtype = "flowingliquid",
tiles ={"default_water.png"}, tiles ={"default_water.png"},
special_tiles = { special_tiles = {
@ -881,7 +880,6 @@ minetest.register_node(
"default:water_source", "default:water_source",
{ {
description = "Water", description = "Water",
inventory_image = minetest.inventorycube("default_water.png"),
drawtype = "liquid", drawtype = "liquid",
tiles ={"default_water.png"}, tiles ={"default_water.png"},
special_tiles = { special_tiles = {
@ -911,7 +909,6 @@ minetest.register_node(
"default:river_water_flowing", "default:river_water_flowing",
{ {
description = "River Water (flowing)", description = "River Water (flowing)",
inventory_image = minetest.inventorycube("default_water.png"),
drawtype = "flowingliquid", drawtype = "flowingliquid",
tiles ={"default_water.png"}, tiles ={"default_water.png"},
special_tiles = { special_tiles = {
@ -949,7 +946,6 @@ minetest.register_node(
"default:river_water_source", "default:river_water_source",
{ {
description = "River Water", description = "River Water",
inventory_image = minetest.inventorycube("default_water.png"),
drawtype = "liquid", drawtype = "liquid",
tiles ={"default_water.png"}, tiles ={"default_water.png"},
special_tiles = { special_tiles = {
@ -981,7 +977,6 @@ minetest.register_node(
"default:swamp_water_flowing", "default:swamp_water_flowing",
{ {
description = "Swamp Water (flowing)", description = "Swamp Water (flowing)",
inventory_image = minetest.inventorycube("default_swamp_water.png"),
drawtype = "flowingliquid", drawtype = "flowingliquid",
tiles ={"default_swamp_water.png"}, tiles ={"default_swamp_water.png"},
special_tiles = { special_tiles = {
@ -1019,7 +1014,6 @@ minetest.register_node(
"default:swamp_water_source", "default:swamp_water_source",
{ {
description = "Swamp Water", description = "Swamp Water",
inventory_image = minetest.inventorycube("default_swamp.png"),
drawtype = "liquid", drawtype = "liquid",
tiles ={"default_swamp_water.png"}, tiles ={"default_swamp_water.png"},
special_tiles = { special_tiles = {

View File

@ -38,7 +38,7 @@ local function delayed_save()
if not saving then if not saving then
saving = true saving = true
minetest.after(5, save_hunger) minetest.after(40, save_hunger)
end end
end end
@ -83,6 +83,10 @@ local function on_load()
load_hunger() load_hunger()
end end
local function on_shutdown()
save_hunger()
end
function hunger.update_bar(player) function hunger.update_bar(player)
if not player then if not player then
return return
@ -220,7 +224,7 @@ local function on_item_eat(hpdata, replace_with_item, itemstack,
player_effects.apply_effect(player, "hunger_eating") player_effects.apply_effect(player, "hunger_eating")
hunger.update_bar(player) hunger.update_bar(player)
hunger.save_hunger() delayed_save()
itemstack:take_item(1) itemstack:take_item(1)
@ -334,6 +338,10 @@ end
if minetest.setting_getbool("hunger_enable") then if minetest.setting_getbool("hunger_enable") then
minetest.after(0, on_load)
minetest.register_on_shutdown(on_shutdown)
minetest.register_on_dignode(on_dignode) minetest.register_on_dignode(on_dignode)
minetest.register_on_placenode(on_placenode) minetest.register_on_placenode(on_placenode)

View File

@ -248,13 +248,19 @@ player_effects.register_effect(
speed = 2, speed = 2,
} }
}) })
minetest.register_privilege("uberspeed", "Can use /uberspeed command") minetest.register_privilege(
"uberspeed",
{
description = "Can use /uberspeed command",
give_to_singleplayer = false
})
minetest.register_chatcommand( minetest.register_chatcommand(
"uberspeed", "uberspeed",
{ {
params = "[on|off|cinematic]", params = "[on|off|cinematic]",
description = "Set Uberspeed", description = "Set Uberspeed",
privs = {uberspeed = true}, privs = {uberspeed = true, give_to_singleplayer = false},
func = function(name, param) func = function(name, param)
local player=minetest.get_player_by_name(name) local player=minetest.get_player_by_name(name)

View File

@ -27,7 +27,7 @@ function util.fixlight(pos1, pos2)
local pos1, pos2 = util.sort_pos(pos1, pos2) local pos1, pos2 = util.sort_pos(pos1, pos2)
--make area stay loaded --make area stay loaded
local manip = minetest.get_voxel_manip() local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2) manip:read_from_map(pos1, pos2)
@ -41,8 +41,14 @@ function util.fixlight(pos1, pos2)
return #nodes return #nodes
end end
if minetest.setting_getbool("fixlight_command_enable") then if minetest.setting_getbool("fixlight_command_enable") then
minetest.register_privilege("fixlight", "Can use /fixlight command") minetest.register_privilege(
"fixlight",
{
description = "Can use /fixlight command",
give_to_singleplayer = false
})
minetest.register_chatcommand( minetest.register_chatcommand(
"fixlight", "fixlight",
@ -83,7 +89,7 @@ function util.nodefunc(pos1, pos2, name, func, nomanip)
local manip = minetest.get_voxel_manip() local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2) manip:read_from_map(pos1, pos2)
end end
local nodes = minetest.find_nodes_in_area(pos1, pos2, name) local nodes = minetest.find_nodes_in_area(pos1, pos2, name)
for _, pos in ipairs(nodes) do for _, pos in ipairs(nodes) do
func(pos) func(pos)
@ -97,7 +103,7 @@ function util.getvoxelmanip(pos1, pos2)
local manip = minetest.get_voxel_manip() local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2) manip:read_from_map(pos1, pos2)
return manip return manip
end end
@ -110,7 +116,7 @@ function util.remove_area(pos1, pos2, nomanip)
local manip = minetest.get_voxel_manip() local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2) manip:read_from_map(pos1, pos2)
end end
for i = pos1.x, pos2.x-1 do for i = pos1.x, pos2.x-1 do
for j = pos1.y, pos2.y-1 do for j = pos1.y, pos2.y-1 do
for k = pos1.z, pos2.z-1 do for k = pos1.z, pos2.z-1 do
@ -131,7 +137,7 @@ function util.areafunc(pos1, pos2, func, nomanip)
local manip = minetest.get_voxel_manip() local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2) manip:read_from_map(pos1, pos2)
end end
for i = pos1.x, pos2.x-1 do for i = pos1.x, pos2.x-1 do
for j = pos1.y, pos2.y-1 do for j = pos1.y, pos2.y-1 do
for k = pos1.z, pos2.z-1 do for k = pos1.z, pos2.z-1 do
@ -150,7 +156,7 @@ function util.reconstruct(pos1, pos2, nomanip)
local manip = minetest.get_voxel_manip() local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2) manip:read_from_map(pos1, pos2)
end end
-- fix chests -- fix chests
local nodes = minetest.find_nodes_in_area(pos1, pos2, "default:chest") local nodes = minetest.find_nodes_in_area(pos1, pos2, "default:chest")
local node = minetest.registered_nodes["default:chest"] local node = minetest.registered_nodes["default:chest"]
@ -161,14 +167,14 @@ function util.reconstruct(pos1, pos2, nomanip)
-- fix music players -- fix music players
nodes = minetest.find_nodes_in_area(pos1, pos2, "music:player") nodes = minetest.find_nodes_in_area(pos1, pos2, "music:player")
node = minetest.registered_nodes["music:player"] node = minetest.registered_nodes["music:player"]
for _, pos in ipairs(nodes) do for _, pos in ipairs(nodes) do
node.on_construct(pos) node.on_construct(pos)
end end
-- fix furnaces -- fix furnaces
nodes = minetest.find_nodes_in_area(pos1, pos2, "default:furnace") nodes = minetest.find_nodes_in_area(pos1, pos2, "default:furnace")
node = minetest.registered_nodes["default:furnace"] node = minetest.registered_nodes["default:furnace"]
for _, pos in ipairs(nodes) do for _, pos in ipairs(nodes) do
node.on_construct(pos) node.on_construct(pos)
end end
end end
@ -177,7 +183,7 @@ function util.choice(tab, pr)
-- return a random index of the given table -- return a random index of the given table
local choices = {} local choices = {}
for n, _ in pairs(tab) do for n, _ in pairs(tab) do
table.insert(choices, n) table.insert(choices, n)
end end
@ -195,7 +201,7 @@ function util.choice_element(tab, pr)
-- return a random element of the given table -- return a random element of the given table
local choices = {} local choices = {}
for _,n in pairs(tab) do for _,n in pairs(tab) do
table.insert(choices, n) table.insert(choices, n)
end end
@ -228,4 +234,4 @@ function util.split(str, tok)
table.insert(arr, string.sub(str, pos)) table.insert(arr, string.sub(str, pos))
return arr return arr
end end

View File

@ -155,14 +155,19 @@ minetest.register_globalstep(
end end
) )
minetest.register_privilege("weather", "Can use /weather command") minetest.register_privilege(
"weather",
{
description = "Can use /weather command",
give_to_singleplayer = false
})
minetest.register_chatcommand( minetest.register_chatcommand(
"weather", "weather",
{ {
params = "[storm|snowstorm|clear]", params = "[storm|snowstorm|clear]",
description = "Set the weather to either clear, storm, or snowstorm", description = "Set the weather to either clear, storm, or snowstorm",
privs = {weather= true}, privs = {weather = true, give_to_singleplayer = false},
func = function(name, param) func = function(name, param)
setweather_type(param) setweather_type(param)
end end