fun_caves/init.lua
2016-07-16 05:26:12 -05:00

419 lines
11 KiB
Lua

fun_caves = {}
fun_caves.version = "1.0"
fun_caves.time_factor = 10 -- affects growth abms
fun_caves.light_max = 8 -- light intensity for mushroom growth
fun_caves.path = minetest.get_modpath(minetest.get_current_modname())
fun_caves.world = minetest.get_worldpath()
local armor_mod = minetest.get_modpath("3d_armor") and armor and armor.set_player_armor
fun_caves.elixir_armor = minetest.setting_getbool('fun_caves_use_armor_elixirs')
if fun_caves.elixir_armor == nil then
fun_caves.elixir_armor = true
end
fun_caves.expire_elixir_on_death = minetest.setting_getbool('fun_caves_expire_elixir_on_death')
if fun_caves.expire_elixir_on_death == nil then
fun_caves.expire_elixir_on_death = true
end
fun_caves.exploding_fungi = minetest.setting_getbool('fun_caves_exploding_fungi')
if fun_caves.exploding_fungi == nil then
fun_caves.exploding_fungi = true
end
fun_caves.breakable_wood = minetest.setting_getbool('fun_caves_breakable_wood')
if fun_caves.breakable_wood == nil then
fun_caves.breakable_wood = false
end
fun_caves.use_villages = minetest.setting_getbool('fun_caves_use_villages')
if fun_caves.use_villages == nil then
fun_caves.use_villages = true
end
fun_caves.DEBUG = false -- for maintenance only
local f_date = io.open(fun_caves.world .. '/date.txt', 'r')
if f_date then
local s = f_date:read('*a')
f_date:close()
for y, m, d in s:gmatch('(%d%d%d%d)(%d%d)(%d%d)') do
local yn, mn, dn = tonumber(y), tonumber(m), tonumber(d)
if yn and mn and dn then
fun_caves.date = {yn, mn, dn}
end
break
end
end
local inp = io.open(fun_caves.world..'/fun_caves_data.txt','r')
if inp then
local d = inp:read('*a')
fun_caves.db = minetest.deserialize(d)
inp:close()
end
if not fun_caves.db then
fun_caves.db = {}
end
for _, i in pairs({'teleport_data', 'hunger', 'status', 'translocators', 'elixir_formulae'}) do
if not fun_caves.db[i] then
fun_caves.db[i] = {}
end
end
-- whether to use biomes and heightmap
fun_caves.use_bi_hi = false
local mg_params = minetest.get_mapgen_params()
if mg_params and mg_params.mgname ~= "v6" and mg_params.mgname ~= "v5" then
fun_caves.use_bi_hi = true
end
minetest.register_on_mapgen_init(function(mgparams)
minetest.set_mapgen_params({flags="nocaves,nodungeons"})
end)
-- Check if the table contains an element.
function table.contains(table, element)
for key, value in pairs(table) do
if value == element then
if key then
return key
else
return true
end
end
end
return false
end
-- Modify a node to add a group
function minetest.add_group(node, groups)
local def = minetest.registered_items[node]
if not (node and def and groups and type(groups) == 'table') then
return false
end
local def_groups = def.groups or {}
for group, value in pairs(groups) do
if value ~= 0 then
def_groups[group] = value
else
def_groups[group] = nil
end
end
minetest.override_item(node, {groups = def_groups})
return true
end
function fun_caves.clone_node(name)
if not (name and type(name) == 'string') then
return
end
local node = minetest.registered_nodes[name]
local node2 = table.copy(node)
return node2
end
fun_caves.registered_status = {}
function fun_caves.register_status(def)
if not (def and fun_caves.registered_status and type(def) == 'table') then
return
end
fun_caves.registered_status[def.name] = {
remove = def.remove,
start = def.start,
during = def.during,
terminate = def.terminate,
}
end
function fun_caves.set_status(player_name, status, time, param)
if not (player_name and type(player_name) == 'string' and status and type(status) == 'string') and fun_caves.db and fun_caves.db.status and fun_caves.db.status[player_name] then
return
end
local player = minetest.get_player_by_name(player_name)
local def = fun_caves.registered_status[status]
if not (def and player) then
return
end
if not param then
param = {}
end
if time then
param.remove = (minetest.get_gametime() or 0) + time
end
fun_caves.db.status[player_name][status] = param
if def.start then
def.start(player)
end
end
function fun_caves.remove_status(player_name, status)
if not (player_name and type(player_name) == 'string' and status and type(status) == 'string') and fun_caves.db and fun_caves.db.status and fun_caves.db.status[player_name] then
return
end
local player = minetest.get_player_by_name(player_name)
local def = fun_caves.registered_status[status]
if player and def then
if def.terminate then
fun_caves.db.status[player_name][status] = def.terminate(player)
else
fun_caves.db.status[player_name][status] = nil
end
end
end
--dofile(fun_caves.path .. "/recipe_list.lua")
dofile(fun_caves.path .. "/abms.lua")
dofile(fun_caves.path .. "/nodes.lua")
dofile(fun_caves.path .. "/deco.lua")
dofile(fun_caves.path .. "/fungal_tree.lua")
dofile(fun_caves.path .. "/wallhammer.lua")
dofile(fun_caves.path .. "/mapgen.lua")
dofile(fun_caves.path .. "/wooden_buckets.lua")
dofile(fun_caves.path .. "/spec_bomb.lua")
dofile(fun_caves.path .. "/elixir.lua") -- must go after all items are registered
dofile(fun_caves.path .. "/chat.lua")
if minetest.get_modpath("mobs_redo") and mobs and mobs.mod == "redo" then
dofile(fun_caves.path .. "/mobs.lua")
end
--fun_caves.print_recipes()
-- Attempt to save data at shutdown (as well as periodically).
minetest.register_on_shutdown(function()
local out = io.open(fun_caves.world..'/fun_caves_data.txt','w')
if out then
print('Fun Caves: Saving database at shutdown')
out:write(minetest.serialize(fun_caves.db))
out:close()
end
end)
local hunger_mod = minetest.get_modpath("hunger")
fun_caves.hunger_id = {}
function fun_caves.hunger_change(player, change)
if not (player and change and type(change) == 'number') then
return
end
local player_name = player:get_player_name()
if hunger_mod then
if change < 0 and hunger and hunger.update_hunger and hunger.players then
hunger.update_hunger(player, hunger.players[player_name].lvl + change * 4)
end
return
end
if not (fun_caves.db.hunger and fun_caves.hunger_id) then
return
end
local hp = player:get_hp()
if not (hp and type(hp) == 'number') then
return
end
if change < 0 or hp >= 16 then
fun_caves.db.hunger[player_name] = math.min(20, math.max(0, fun_caves.db.hunger[player_name] + change))
player:hud_change(fun_caves.hunger_id[player_name], 'number', fun_caves.db.hunger[player_name])
if fun_caves.db.hunger[player_name] == 0 then
player:set_hp(hp - 1)
end
end
end
local hunger_hud
if not hunger_mod then
hunger_hud = function(player)
if not (player and fun_caves.db.hunger and fun_caves.hunger_id) then
return
end
local player_name = player:get_player_name()
if not fun_caves.db.hunger[player_name] then
fun_caves.db.hunger[player_name] = 20
end
local hunger_bar = {
hud_elem_type = 'statbar',
position = {x=0.52, y=1},
offset = {x = 0, y = -90},
name = "hunger",
text = "farming_bread.png",
number = fun_caves.db.hunger[player_name],
direction = 0,
size = { x=24, y=24 },
}
fun_caves.hunger_id[player_name] = player:hud_add(hunger_bar)
end
minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing)
if not (hp_change and type(hp_change) == 'number') then
return
end
if hp_change > 0 then
fun_caves.hunger_change(user, hp_change)
end
end)
end
minetest.register_on_dieplayer(function(player)
if fun_caves.db.status and not player then
return
end
local player_name = player:get_player_name()
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
if fun_caves.db.status[player_name] then
for status in pairs(fun_caves.db.status[player_name]) do
local def = fun_caves.registered_status[status]
if not def.remain_after_death then
fun_caves.remove_status(player_name, status)
end
end
end
if fun_caves.db.hunger and fun_caves.hunger_id and not hunger_mod then
fun_caves.db.hunger[player_name] = 20
player:hud_change(fun_caves.hunger_id[player_name], 'number', 20)
end
local pos = vector.round(player:getpos())
if pos then
minetest.chat_send_player(player_name, 'Your bones will lie at ('..pos.x..','..pos.y..','..pos.z..'), in ignominy, unless you collect them.')
end
end)
fun_caves.armor_id = {}
local armor_hud
if not armor_mod then
armor_hud = function(player)
if not (player and fun_caves.armor_id) then
return
end
local player_name = player:get_player_name()
if not player_name then
return
end
local armor_icon = {
hud_elem_type = 'image',
name = "armor_icon",
text = 'fun_caves_shield.png',
scale = {x=1,y=1},
position = {x=0.8, y=1},
offset = {x = -30, y = -80},
}
local armor_text = {
hud_elem_type = 'text',
name = "armor_text",
text = '0%',
number = 0xFFFFFF,
position = {x=0.8, y=1},
offset = {x = 0, y = -80},
}
fun_caves.armor_id[player_name] = {}
fun_caves.armor_id[player_name].icon = player:hud_add(armor_icon)
fun_caves.armor_id[player_name].text = player:hud_add(armor_text)
end
fun_caves.display_armor = function(player)
if not (player and fun_caves.armor_id) then
return
end
local player_name = player:get_player_name()
local armor = player:get_armor_groups()
if not (player_name and armor and armor.fleshy) then
return
end
player:hud_change(fun_caves.armor_id[player_name].text, 'text', (100 - armor.fleshy)..'%')
end
end
minetest.register_on_joinplayer(function(player)
if not (player and fun_caves.db.status) then
return
end
local player_name = player:get_player_name()
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
if not fun_caves.db.status[player_name] then
fun_caves.db.status[player_name] = {}
end
if armor_hud then
armor_hud(player)
end
if hunger_hud then
hunger_hud(player)
end
-- If there's an armor mod, we wait for it to load armor.
if fun_caves.load_armor_elixir and not armor_mod then
fun_caves.load_armor_elixir(player)
end
end)
-- support for 3d_armor
-- This may or may not work with all versions.
if armor_mod then
local old_set_player_armor = armor.set_player_armor
armor.set_player_armor = function(self, player)
old_set_player_armor(self, player)
if fun_caves.load_armor_elixir then
fun_caves.load_armor_elixir(player)
end
end
end
----------------------------------------------------------------------
-- Change old factor to current value.
if fun_caves.db.status then
for player_name, status in pairs(fun_caves.db.status) do
if status.armor_elixir and status.armor_elixir.factor then
status.armor_elixir.value = status.armor_elixir.factor * 100
status.armor_elixir.factor = nil
end
end
end
----------------------------------------------------------------------