Deal damage to players who venture too far

master
Wuzzy 2021-09-25 17:54:44 +02:00
parent 9aa4f98268
commit 9d6fbe645f
4 changed files with 133 additions and 0 deletions

130
mods/hades_bounds/init.lua Normal file
View File

@ -0,0 +1,130 @@
local S = minetest.get_translator("hades_bounds")
local players_out_of_bounds = {}
local players_out_of_bounds_blinding = {}
local has_death_messages_mod = minetest.get_modpath("hades_death_messages") ~= nil
-- Minetest world boundaries, as of 5.4.1
local END_MAX = 30927
local END_MIN = -30912
-- Where the player starts to take damage
local BOUNDARY_DIFF = 500.5
-- Where the textual out-of-bounds warning appears
local BOUNDARY_WARNING_DIFF = BOUNDARY_DIFF + 50
-- Where the out-of-bounds "green radiation warning screen" appears
local BOUNDARY_WARNING_DIFF_2 = BOUNDARY_DIFF + 20
-- At which time interval (in seconds) the player takes radiation damage
local BOUNDARY_TIME_CHECK = 1
-- Every how many blocks the radiation damage increases
local BOUNDARY_DAMAGE_INCREASE = 50
-- Maximum boundary damage to deal
local BOUNDARY_MAX_DAMAGE = 4
local timer = 0
local function out_of_bounds(pos, diff)
local boundary_min = END_MIN + diff
local boundary_max = END_MAX - diff
return pos.x > boundary_max or pos.x < boundary_min or pos.z > boundary_max or pos.z < boundary_min or pos.y > boundary_max
end
local function out_of_bounds_farthest(pos, diff)
local boundary_min = END_MIN + diff
local boundary_max = END_MAX - diff
local dists = {
pos.x - boundary_max,
pos.x - boundary_min,
pos.z - boundary_max,
pos.z - boundary_min,
pos.y - boundary_max,
}
local far = -1
for d=1, #dists do
if math.abs(dists[d]) > far then
far = dists[d]
end
end
return far
end
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < BOUNDARY_TIME_CHECK then
return
end
timer = 0
local players = minetest.get_connected_players()
for p=1, #players do
local player = players[p]
local name = player:get_player_name()
local pos = player:get_pos()
local creative = minetest.is_creative_enabled(name)
if not creative and out_of_bounds(pos, BOUNDARY_WARNING_DIFF) then
local oob = out_of_bounds(pos, BOUNDARY_DIFF)
local text, img
if oob then
text = S("WARNING: Critically high radiation!")
img = "hades_bounds_screen_radiation_full.png"
else
text = S("WARNING: High radiation!")
if out_of_bounds(pos, BOUNDARY_WARNING_DIFF_2) then
img = "hades_bounds_screen_radiation_warn.png"
end
end
if not players_out_of_bounds[name] then
local hudid = player:hud_add({
hud_elem_type = "text",
text = text,
position = { x = 0.5, y = 0.2 },
number = 0xFFFF00,
z_index = 100,
scale = { x = 100, y = 100 },
size = { x = 2, y = 2 },
})
players_out_of_bounds[name] = hudid
else
player:hud_change(players_out_of_bounds[name], "text", text)
end
if img and not players_out_of_bounds_blinding[name] then
local hudid = player:hud_add({
hud_elem_type = "image",
text = img,
position = { x = 0.5, y = 0.5 },
number = 0xFFFF00,
z_index = -400,
scale = { x = -100, y = -100 },
})
players_out_of_bounds_blinding[name] = hudid
elseif img then
player:hud_change(players_out_of_bounds_blinding[name], "text", img)
end
local hp = player:get_hp()
if oob and hp > 0 then
local how_deep_in = out_of_bounds_farthest(pos, BOUNDARY_DIFF)
local dmg = math.min(BOUNDARY_MAX_DAMAGE, math.max(1, math.floor(how_deep_in / BOUNDARY_DAMAGE_INCREASE)))
if has_death_messages_mod then
hades_death_messages.player_damage(player, S("Radiation poisoning"))
end
player:set_hp(hp - dmg)
end
else
if players_out_of_bounds[name] then
player:hud_remove(players_out_of_bounds[name])
players_out_of_bounds[name] = nil
end
end
if creative or not out_of_bounds(pos, BOUNDARY_WARNING_DIFF_2) then
if players_out_of_bounds_blinding[name] then
player:hud_remove(players_out_of_bounds_blinding[name])
players_out_of_bounds_blinding[name] = nil
end
end
end
end)
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
players_out_of_bounds[name] = nil
players_out_of_bounds_blinding[name] = nil
end)

View File

@ -0,0 +1,3 @@
name = hades_bounds
description = Deals radiation damage to players who ventured too far
optional_depends = hades_death_messages

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B