diff --git a/elixir.lua b/elixir.lua index be4cdeb..f4a2a25 100644 --- a/elixir.lua +++ b/elixir.lua @@ -1,4 +1,5 @@ local elixir_duration = 3600 +local armor_mod = minetest.get_modpath("3d_armor") and armor and armor.set_player_armor local elixir_ingredients = { @@ -133,7 +134,6 @@ if count > 15 then 'mobs_slimes:green_slimeball', 'group:elixir_ingredient', 'group:elixir_ingredient', - 'group:elixir_ingredient', "vessels:glass_bottle", }, }) @@ -230,67 +230,14 @@ if fun_caves.register_status and fun_caves.set_status then end local player_name = player:get_player_name() + if not (player_name and type(player_name) == 'string' and player_name ~= '') then + return + end + minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'You feel weaker...')) - fun_caves.db.status[player_name].damage_elixir = nil end, }) - - fun_caves.register_status({ - name = 'armor_elixir', - terminate = function(player) - if not (player and fun_caves.db.status and fun_caves.display_armor) 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 - - local armor_elixir = fun_caves.db.status[player_name].armor_elixir - local factor = armor_elixir.factor - local armor = player:get_armor_groups() - if not (armor and armor.fleshy) then - return - end - - armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / factor))) - player:set_armor_groups(armor) - minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'Your skin feels softer...')) - fun_caves.db.status[player_name].armor_elixir = nil - fun_caves.display_armor(player) - end, - }) - - - if fun_caves.expire_elixir_on_death then - minetest.register_on_dieplayer(function(player) - if not (player and fun_caves.db.status and fun_caves.display_armor) 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] and fun_caves.db.status[player_name].armor_elixir then - local factor = fun_caves.db.status[player_name].armor_elixir.factor - local armor = player:get_armor_groups() - if not (armor and armor.fleshy) then - return - end - - armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / factor))) - player:set_armor_groups(armor) - fun_caves.db.status[player_name].armor_elixir = nil - fun_caves.display_armor(player) - end - end) - end - - local function increase_damage(user, bonus) if not (user and fun_caves.set_status) then return @@ -305,94 +252,6 @@ if fun_caves.register_status and fun_caves.set_status then fun_caves.set_status(player_name, 'damage_elixir', elixir_duration, {bonus = bonus}) end - - local function armor(user, factor) - if not (user and fun_caves.db.status and fun_caves.display_armor and fun_caves.set_status) then - return - end - - local player_name = user:get_player_name() - if not (player_name and type(player_name) == 'string' and player_name ~= '') then - return - end - - local armor = user:get_armor_groups() - if not (armor and armor.fleshy) then - return - end - - if fun_caves.db.status[player_name].armor_elixir then - local old_factor = fun_caves.db.status[player_name].armor_elixir.factor - armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / old_factor))) - end - - armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy * factor))) - user:set_armor_groups(armor) - minetest.chat_send_player(player_name, 'Your skin feels harder...') - fun_caves.set_status(player_name, 'armor_elixir', elixir_duration, {factor = factor}) - fun_caves.display_armor(user) - end - - local descs = { - {'wood', 0.95, 'group:wood'}, - {'stone', 0.9, 'group:stone'}, - {'steel', 0.8, 'default:steel_ingot'}, - {'copper', 0.85, 'default:copper_ingot'}, - {'bronze', 0.7, 'default:bronze_ingot'}, - {'gold', 0.6, 'default:gold_ingot'}, - {'diamond', 0.5, 'default:diamond'}, - {'silver', 0.4, 'fun_caves:silver_ingot'}, - {'mese', 0.3, 'default:mese_crystal'}, - --{'', 0.2, ''}, - --{'adamant', 0.1, 'fun_caves:adamant'}, - } - - if fun_caves.elixir_armor then - for _, desc in pairs(descs) do - local name = desc[1] - local value = desc[2] - local cap = name:gsub('^%l', string.upper) - minetest.register_craftitem("fun_caves:liquid_"..name, { - description = 'Dr Robertson\'s Patented Liquid '..cap..' Elixir', - drawtype = "plantlike", - paramtype = "light", - tiles = {'fun_caves_liquid_'..name..'.png'}, - inventory_image = 'fun_caves_liquid_'..name..'.png', - groups = {dig_immediate = 3, vessel = 1}, - sounds = default.node_sound_glass_defaults(), - on_use = function(itemstack, user, pointed_thing) - if not (itemstack and user) then - return - end - - armor(user, value) - itemstack:take_item() - return itemstack - end, - }) - - minetest.register_craft({ - type = "shapeless", - output = 'fun_caves:liquid_'..name, - recipe = { - 'mobs_slimes:green_slimeball', - desc[3], - "vessels:glass_bottle", - }, - }) - - minetest.register_craft({ - type = "shapeless", - output = 'fun_caves:liquid_'..name, - recipe = { - 'fun_caves:syrup', - desc[3], - }, - }) - end - end - - local descs = { {'boar', 2, 'fun_caves:meteorite'}, {'lion', 4, 'fun_caves:eternal_ice_crystal'}, @@ -446,4 +305,173 @@ if fun_caves.register_status and fun_caves.set_status then }) end end + + + fun_caves.reconcile_armor = function(elixir_armor, worn_armor) + if elixir_armor < worn_armor then + return elixir_armor + end + + return worn_armor + end + + -- set_armor assumes any armor mods have already set the normal armor values. + local function set_armor(player, value, delay) + if not (player and fun_caves.reconcile_armor) then + return + end + + local armor = player:get_armor_groups() + if not (armor and armor.fleshy and armor.fleshy ~= value) then + return + end + + if armor_mod then + armor.fleshy = fun_caves.reconcile_armor(value, armor.fleshy) + else + armor.fleshy = value + end + + player:set_armor_groups(armor) + + if fun_caves.display_armor then + if delay then + -- Delay display, in case of lag. + minetest.after(delay, function() + fun_caves.display_armor(player) + end) + else + fun_caves.display_armor(player) + end + end + + return true + end + + -- called only by armor elixirs + local function ingest_armor_elixir(player, value) + if not (player and fun_caves.set_status) then + return + end + + -- support for 3d_armor + -- This may or may not work with all versions. + if armor_mod then + armor:set_player_armor(player) + end + + if not set_armor(player, value) 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 + + minetest.chat_send_player(player_name, 'Your skin feels harder...') + fun_caves.set_status(player_name, 'armor_elixir', elixir_duration, {value = value}) + end + + -- called on joinplayer and every time an armor mod updates + fun_caves.load_armor_elixir = 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 fun_caves.db.status[player_name] and fun_caves.db.status[player_name].armor_elixir then + local value = fun_caves.db.status[player_name].armor_elixir.value + set_armor(player, value, 3) + end + end + + fun_caves.register_status({ + name = 'armor_elixir', + terminate = function(player) + if not player then + return + end + + player:set_armor_groups({fleshy = 100}) + + -- support for 3d_armor + -- This may or may not work with all versions. + if armor_mod then + minetest.after(1, function() + armor:set_player_armor(player) + end) + end + + local player_name = player:get_player_name() + if not (player_name and type(player_name) == 'string' and player_name ~= '') then + return + end + + minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'Your skin feels softer...')) + end, + }) + + local descs = { + {'wood', 95, 'group:wood'}, + {'stone', 90, 'group:stone'}, + {'steel', 80, 'default:steel_ingot'}, + {'copper', 85, 'default:copper_ingot'}, + {'bronze', 70, 'default:bronze_ingot'}, + {'gold', 60, 'default:gold_ingot'}, + {'diamond', 50, 'default:diamond'}, + {'silver', 40, 'fun_caves:silver_ingot'}, + {'mese', 30, 'default:mese_crystal'}, + --{'', 20, ''}, + --{'adamant', 10, 'fun_caves:adamant'}, + } + + if fun_caves.elixir_armor then + for _, desc in pairs(descs) do + local name = desc[1] + local value = desc[2] + local cap = name:gsub('^%l', string.upper) + minetest.register_craftitem("fun_caves:liquid_"..name, { + description = 'Dr Robertson\'s Patented Liquid '..cap..' Elixir', + drawtype = "plantlike", + paramtype = "light", + tiles = {'fun_caves_liquid_'..name..'.png'}, + inventory_image = 'fun_caves_liquid_'..name..'.png', + groups = {dig_immediate = 3, vessel = 1}, + sounds = default.node_sound_glass_defaults(), + on_use = function(itemstack, user, pointed_thing) + if not (itemstack and user) then + return + end + + ingest_armor_elixir(user, value) + itemstack:take_item() + return itemstack + end, + }) + + minetest.register_craft({ + type = "shapeless", + output = 'fun_caves:liquid_'..name, + recipe = { + 'mobs_slimes:green_slimeball', + desc[3], + "vessels:glass_bottle", + }, + }) + + minetest.register_craft({ + type = "shapeless", + output = 'fun_caves:liquid_'..name, + recipe = { + 'fun_caves:syrup', + desc[3], + }, + }) + end + end end diff --git a/init.lua b/init.lua index ff1bcbe..2d9c823 100644 --- a/init.lua +++ b/init.lua @@ -5,6 +5,8 @@ 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 @@ -188,7 +190,7 @@ 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 mobs and mobs.mod == "redo" then +if minetest.get_modpath("mobs_redo") and mobs and mobs.mod == "redo" then dofile(fun_caves.path .. "/mobs.lua") end @@ -276,35 +278,41 @@ if not hunger_mod then fun_caves.hunger_change(user, hp_change) end end) - - minetest.register_on_dieplayer(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() - local pos = vector.round(player:getpos()) - - if not (player_name and pos) then - return - end - - if not hunger_mod then - fun_caves.db.hunger[player_name] = 20 - player:hud_change(fun_caves.hunger_id[player_name], 'number', 20) - end - - 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 -local armor_mod = minetest.get_modpath("3d_armor") +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 armor_mod then - fun_caves.display_armor = function() - end -else +if not armor_mod then armor_hud = function(player) if not (player and fun_caves.armor_id) then return @@ -361,7 +369,7 @@ minetest.register_on_joinplayer(function(player) local player_name = player:get_player_name() - if not player_name then + if not (player_name and type(player_name) == 'string' and player_name ~= '') then return end @@ -377,15 +385,35 @@ minetest.register_on_joinplayer(function(player) hunger_hud(player) end - if fun_caves.db.status[player_name] and fun_caves.db.status[player_name].armor_elixir then - local factor = fun_caves.db.status[player_name].armor_elixir.factor - local armor = player:get_armor_groups() - armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy * factor))) - player:set_armor_groups(armor) - if fun_caves.display_armor then - minetest.after(3, function() - fun_caves.display_armor(player) - end) - 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 +---------------------------------------------------------------------- + diff --git a/nodes.lua b/nodes.lua index 744632a..3794e03 100644 --- a/nodes.lua +++ b/nodes.lua @@ -275,7 +275,7 @@ minetest.register_craftitem("fun_caves:apple_pie_uncooked", { inventory_image = "fun_caves_apple_pie_uncooked.png", }) -if mobs and mobs.mod == "redo" then +if minetest.get_modpath("mobs_redo") and mobs and mobs.mod == "redo" then minetest.register_craft({ output = 'fun_caves:apple_pie_uncooked', type = 'shapeless', diff --git a/village.lua b/village.lua index 2be07fe..35a924c 100644 --- a/village.lua +++ b/village.lua @@ -5,7 +5,7 @@ minetest.register_node("fun_caves:hut_floor", newnode) local farming = minetest.get_modpath('farming') -if mobs and mobs.mod == "redo" then +if minetest.get_modpath("mobs_redo") and mobs and mobs.mod == "redo" then local drops = { {name = "default:axe_stone", chance = 3, min = 1, max = 1}, {name = "default:hoe_stone", chance = 3, min = 1, max = 1},