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") 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 ----------------------------------------------------------------------