commit 96dfc925834ebaccd16574a91be5ef734f98a22c Author: ermprost Date: Mon Aug 19 08:30:40 2024 +0300 Загрузить файлы в «/» diff --git a/api.lua b/api.lua new file mode 100644 index 0000000..78d7a42 --- /dev/null +++ b/api.lua @@ -0,0 +1,91 @@ +local S, modname = ... + +-- Function to register the potions +brewing.register_potion = function(sname, name, fname, def) + local tps = {"add", "sub"} + for t=1, #tps do + for i=1, #def.types do + local sdata = def.types[i] + local tps_sign + if tps[t] == "add" then + tps_sign= "+" + else + tps_sign= "-" + end + local item_def = { + description = S("@1 Potion", name) .. " ("..S("lvl")..":".." "..tps_sign..sdata.type..")", + inventory_image = "potions_bottle.png^potions_"..(def.texture or sname)..".png^potions_"..tps[t]..sdata.type..".png", + drawtype = "plantlike", + paramtype = "light", + walkable = false, + groups = {dig_immediate=3,attached_node=1}, + --sounds = default.node_sound_glass_defaults(), + } + item_def.tiles = {item_def.inventory_image} + local flags = { + inv = false, + type = tps[t], + } + if t == 2 then + flags.inv = true + end + for key, val in pairs(brewing.effects[def.effect](sname, name, fname, sdata, flags)) do + item_def[key] = val + end + for key, val in pairs(sdata.set) do + item_def[key] = val + end + item_def["time"] = sdata.time + for key, val in pairs(sdata.effects) do + item_def.potions[key] = val + end + minetest.register_node(fname.."_"..tps[t]..sdata.type, item_def) + end + end +end + +-- Function to register the potion crafts + +brewing.register_potion_craft = function(def) + brewing.craft_list[#brewing.craft_list+1] = {["effect"] = def.effect, ["description"] = def.description, ["type"] = def.type, ["level"] = def.level, ["recipe"] = def.recipe} +end + +brewing.get_craft_result = function(ingredients) + --recipes are 2x3 + local output + local match + --To get the output of the first potion: minetest.chat_send_player("singleplayer", brewing.craftlist[1][1]) + --To get the first ingredient of the first potion: minetest.chat_send_player("singleplayer", brewing.craftlist[1][2][1][1]) + --for key, potion_craft in pairs(brewing.craftlist) do + for index, potion_craft in ipairs(brewing.craft_list) do + --To get the output of the potion: minetest.chat_send_player("singleplayer", potion_craft[1]) + --To get the first ingredient of the 1st row of the potion: minetest.chat_send_player("singleplayer", potion_craft[2][1][1]) + --To get the first ingredient of the 2nd row of the potion: minetest.chat_send_player("singleplayer", potion_craft[2][2][1]) + --To get the second ingredient of the 2nd row of the potion: minetest.chat_send_player("singleplayer", potion_craft[2][2][2]) + --check recipe concordance + --firstly in the 2 rows + for i= 1, 3, 1 do + match = false + if (potion_craft["recipe"][i] == ingredients[i]) or (potion_craft["recipe"][i] == '') then + match = true + end + if not match then --if an ingredient does not match + break + end + end + if match then --if coincidence with a potion_craft + output = modname ..":" .. potion_craft["effect"] .. "_".. potion_craft["type"] .. math.abs(potion_craft["level"]) + break + end + end + local item + if match == true then + item = ItemStack(output) + --minetest.chat_send_player("singleplayer", "match") + else + item = nil + --minetest.chat_send_player("singleplayer", "unmatched") + end + return item +end + diff --git a/armor.conf.example b/armor.conf.example new file mode 100644 index 0000000..ee63812 --- /dev/null +++ b/armor.conf.example @@ -0,0 +1,62 @@ +-- DEPRECATED, will not be supported in future versions + +-- See README.txt for new configuration options. + +-- Armor Configuration (defaults) + +-- You can remove any unwanted armor materials from this table. +-- Note that existing armor that is removed will show up as an unknown item. +ARMOR_MATERIALS = { + wood = "group:wood", + cactus = "default:cactus", + steel = "default:steel_ingot", + bronze = "default:bronze_ingot", + diamond = "default:diamond", + gold = "default:gold_ingot", + mithril = "moreores:mithril_ingot", + crystal = "ethereal:crystal_ingot", + nether = "nether:nether_ingot", +} + +-- Enable fire protection (defaults true if using ethereal mod) +ARMOR_FIRE_PROTECT = false + +-- Fire protection nodes, (name, protection level, damage) +ARMOR_FIRE_NODES = { + {"default:lava_source", 5, 4}, + {"default:lava_flowing", 5, 4}, + {"fire:basic_flame", 3, 4}, + {"fire:permanent_flame", 3, 4}, + {"ethereal:crystal_spike", 2, 1}, + {"ethereal:fire_flower", 2, 1}, + {"default:torch", 1, 1}, +} + +-- Increase this if you get initialization glitches when a player first joins. +ARMOR_INIT_DELAY = 1 + +-- Increase this if armor is not getting into bones due to server lag. +ARMOR_BONES_DELAY = 1 + +-- How often player armor/wield items are updated. +ARMOR_UPDATE_TIME = 1 + +-- Drop armor when a player dies. +-- Uses bones mod if present, otherwise items are dropped around the player. +ARMOR_DROP = true + +-- Pulverise armor when a player dies, overrides ARMOR_DROP. +ARMOR_DESTROY = false + +-- You can use this to increase or decrease overall armor effectiveness, +-- eg: ARMOR_LEVEL_MULTIPLIER = 0.5 will reduce armor level by half. +ARMOR_LEVEL_MULTIPLIER = 1 + +-- You can use this to increase or decrease overall armor healing, +-- eg: ARMOR_HEAL_MULTIPLIER = 0 will disable healing altogether. +ARMOR_HEAL_MULTIPLIER = 1 + +-- You can use this to increase or decrease overall armor radiation protection, +-- eg: ARMOR_RADIATION_MULTIPLIER = 0 will completely disable radiation protection. +-- Note: patched technic mod is required +ARMOR_RADIATION_MULTIPLIER = 1 diff --git a/armor.lua b/armor.lua new file mode 100644 index 0000000..ecf0f17 --- /dev/null +++ b/armor.lua @@ -0,0 +1,158 @@ +if minetest.get_modpath("3d_armor") then + + --- Magic Helmet + armor:register_armor("brewing:helmet_magic", { + description = ("Магический Шлем"), + inventory_image = "brewing_inv_helmet_magic.png", + groups = {radiation=100, armor_head=1, armor_heal=12, armor_use=600, armor_fire=1}, + armor_groups = {fleshy=15}, + damage_groups = {cracky=2, snappy=1, level=3}, + }) + + --- Magic Chestplate + armor:register_armor("brewing:chestplate_magic", { + description = ("Магический Нагрудник"), + inventory_image = "brewing_inv_chestplate_magic.png", + groups = {radiation=100, armor_torso=1, armor_heal=12, armor_use=600, armor_fire=1}, + armor_groups = {fleshy=20}, + damage_groups = {cracky=2, snappy=1, level=3}, + }) + + --- Magic Leggings + armor:register_armor("brewing:leggings_magic", { + description = ("Магические Поножи"), + inventory_image = "brewing_inv_leggings_magic.png", + groups = {radiation=100, armor_legs=1, armor_heal=12, armor_use=600, armor_fire=1}, + armor_groups = {fleshy=20}, + damage_groups = {cracky=2, snappy=1, level=3}, + }) + + --- Magic Boots + armor:register_armor("brewing:boots_magic", { + description = ("Магические Ботинки"), + inventory_image = "brewing_inv_boots_magic.png", + groups = {radiation=100, armor_feet=1, armor_heal=12, armor_use=600, physics_speed=2, + physics_jump=0.75, armor_fire=1}, + armor_groups = {fleshy=15}, + damage_groups = {cracky=2, snappy=1, level=3}, + }) +end + + --- Craft + +if minetest.get_modpath("3d_armor") or minetest.get_modpath("mcl_armor") then + + --- Magic Helmet + minetest.register_craft({ + output = "brewing:helmet_magic", + recipe = { + {"brewing:magic_gem", "brewing:magic_gem", "brewing:magic_gem"}, + {"brewing:magic_gem", "", "brewing:magic_gem"}, + {"", "", ""} + } + }) + + --- Magic Chestplate + minetest.register_craft({ + output = "brewing:chestplate_magic", + recipe = { + {"brewing:magic_gem", "", "brewing:magic_gem"}, + {"brewing:magic_gem", "brewing:magic_gem", "brewing:magic_gem"}, + {"brewing:magic_gem", "brewing:magic_gem", "brewing:magic_gem"} + } + }) + + --- Magic Leggings + minetest.register_craft({ + output = "brewing:leggings_magic", + recipe = { + {"brewing:magic_gem", "brewing:magic_gem", "brewing:magic_gem"}, + {"brewing:magic_gem", "", "brewing:magic_gem"}, + {"brewing:magic_gem", "", "brewing:magic_gem"} + } + }) + + --- Magic Boots + minetest.register_craft({ + output = "brewing:boots_magic", + recipe = { + {"", "", ""}, + {"brewing:magic_gem", "", "brewing:magic_gem"}, + {"brewing:magic_gem", "", "brewing:magic_gem"} + } + }) +end + + +-- Armor/Tool Player Damage + +if allow_tool_damage or (allow_armor_damage and minetest.get_modpath("3d_armor")) then + + local function has_item(player_name, item_name) + local inventory = minetest.get_inventory({type="player", name=player_name}) + local main_list = inventory:get_list("main") + for _, stack in ipairs(main_list) do + if stack:get_name() == item_name then + return true + end + end + return false + end + + local function alter_health(player, change) + if player == nil then return end + local hp_max = player:get_properties().hp_max + local current_health = player:get_hp() + local new_health = current_health + change + + if new_health > hp_max then new_health = hp_max end + if new_health < 0 then new_health = 0 end + + player:set_hp(new_health) + end + + local function has_radioactive_tool(player) + local wield = player:get_wielded_item() + if wield then + local tool_cap = wield:get_tool_capabilities() + if tool_cap and tool_cap.damage_groups and tool_cap.damage_groups.radioactive then + return true + end + end + return false + end + + local function pattern_count(base, pattern) + return select(2, string.gsub(base, pattern, "")) + end + + local function get_radioactive_armor_count(player) + local inv_3d = player:get_meta():get_string("3d_armor_inventory") + if not inv_3d then return 0 end + return pattern_count(inv_3d, "uraniumstuff:") + end + + local function damage_players() + local players = minetest.get_connected_players() + for _, player in ipairs(players) do + local damage = 0 + if allow_armor_damage then + damage = damage + get_radioactive_armor_count(player) + end + if allow_tool_damage and has_radioactive_tool(player) then + damage = damage + 1 + end + if damage > 0 then + local player_name = player:get_player_name() + local has_gem = has_item(player_name, "uraniumstuff:uranium_protection_gem") + if not has_gem then + alter_health(player, damage*-1) + end + end + end + minetest.after(5, damage_players) + end + damage_players() + +end + diff --git a/brewing.conf b/brewing.conf new file mode 100644 index 0000000..d0f4f39 --- /dev/null +++ b/brewing.conf @@ -0,0 +1,9 @@ +#Change the name of the ignitor +ignitor_name = brewing:magic_dust +ignitor_image = brewing_ignitor_dust_gray.png + +flask_name = vessels:glass_bottle +#How much flask to be filled by each water bucket +filled_flasks = 5 + +liquid = bucket:bucket_water, bucket:bucket_river_water diff --git a/cauldron.lua b/cauldron.lua new file mode 100644 index 0000000..d88e231 --- /dev/null +++ b/cauldron.lua @@ -0,0 +1,361 @@ +local S = ... + +local function uppercase(str) + return (str:gsub("^%l", string.upper)) +end + +-- Cauldron Form + +local formspec = + "size[8,9;]".. + "image_button[1,0;1,1;default_book_written.png;btn_recipe_book;]".. + "tooltip[btn_recipe_book;"..S("Recipe Book").."]".. + "label[0,1;"..S("Recipe").."]".. + "list[context;ing1;1,1;1,1;]".. + "list[context;ing2;2,1;1,1;]".. + "list[context;ing3;3,1;1,1;]".. + "image[3,2;1,1;brewing_arrow_ing_gray.png]".. + "image[0,4;1,1;"..brewing.settings.ignitor_image.."]".. + "list[context;ignitor;1,4;1,1;]".. + "image[2,4;1,1;brewing_arrow_gray.png]".. + "image[3,4;1,1;brewing_bucket_water_gray.png]".. + "list[context;water;4,4;1,1;]".. + "image[4,3;1,1;brewing_arrow_gray.png^[transformR90]]".. + "image[4,2;1,1;brewing_cauldron_form.png]".. + "image[5,0;1,1;brewing_vessels_glass_bottle_gray.png]".. + "list[current_name;flask;5,1;1,1;]".. + "image[5,2;1,1;brewing_arrow_gray.png]".. + "label[6,1;".. brewing.settings.filled_flasks .."x]".. + "list[current_name;dst;6,2;1,1;]".. + "list[current_player;main;0,5;8,4;]" + +--Recipe Book Form + +local function create_recipe_book_form() + local recipe_book_formspec = + "size[8,8;]".. + "real_coordinates[true]".. + "button_exit[3.5,6.6;1,1;btn_exit;"..S("Close").."]" + --Create the cells + local cells = "" + local potion_names = {} + local potion_idxs = "" + local ing1_idxs = "" + local ing2_idxs = "" + local ing3_idxs = "" + for index, potion_craft in ipairs(brewing.craft_list) do + local potion_texture + if potion_craft["effect"] == "jump" then + potion_texture = "potions_jump.png" + else + potion_texture = "potions_"..potion_craft["effect"]..".png" + end + local potion_exists + for idx, value in ipairs(potion_names) do + if value == potion_texture then + potion_exists = idx + else + potion_exists = nil + end + end + local potion_idx + if potion_exists then + potion_idx = potion_exists + else + local next_idx = #potion_names+1 + potion_names[next_idx]= potion_texture + potion_idx = next_idx + end + local ing_idxs = {} + for i = 1, 3, 1 do + local ingredient_image + if potion_craft["recipe"][i] == "" then + ingredient_image = "brewing_blank_ingredient.png" + else + ingredient_image = minetest.registered_items[potion_craft["recipe"][i]].inventory_image + if not ingredient_image then + ingredient_image = "brewing_blank_ingredient.png" + end + end + ing_idxs[i] = tostring(index).."="..ingredient_image + end + if index > 1 then + cells = cells .."," + end + local effect_type + if potion_craft["type"] == "add" then + effect_type = "+" + else + effect_type = "-" + end + local potion_name = "brewing:"..potion_craft["effect"].."_"..potion_craft["type"]..math.abs(potion_craft["level"]) + --minetest.chat_send_all(potion_name) + local potion_time= minetest.registered_items[potion_name].time + if potion_time == nil then + potion_time = "-" + else + potion_time = potion_time.."s" + end + local potion_craft_description + if potion_craft["description"] then + potion_craft_description = S(potion_craft["description"]) + else + potion_craft_description = S(uppercase(potion_craft["effect"])) + end + cells = cells .. potion_idx .. ",".. potion_craft_description.. ",".. S("lvl").. " ".. effect_type .. potion_craft["level"]..','..index..','..index..','..index..','..potion_time + if index > 1 then + ing1_idxs = ing1_idxs .. ',' + ing2_idxs = ing2_idxs .. ',' + ing3_idxs = ing3_idxs .. ',' + end + ing1_idxs = ing1_idxs .. ing_idxs[1] + ing2_idxs = ing2_idxs .. ing_idxs[2] + ing3_idxs = ing3_idxs .. ing_idxs[3] + end + for idx, value in ipairs(potion_names) do + if idx > 1 then + potion_idxs = potion_idxs.."," + end + potion_idxs = potion_idxs .. tostring(idx).."="..value + end + --minetest.chat_send_all(potion_idxs) + --local def = minetest.registered_items[potion_name] + recipe_book_formspec = + recipe_book_formspec .. + "tablecolumns[image,"..potion_idxs..";text;text;image,"..ing1_idxs..";image,"..ing2_idxs..";image,"..ing3_idxs..";text]".. + "table[0.375,0.375;7.2,6;table_potions;"..cells..";0]" + return recipe_book_formspec +end + +-- +-- Node callback functions +-- + +local function can_dig(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty("water") and inv:is_empty("dst") and inv:is_empty("flask") +end + +local function is_valid_water(liquid_to_check) + local isvalid = false + for key, value in pairs(brewing.settings.liquid) do + if value == liquid_to_check then + isvalid = true + break + end + end + return isvalid +end + +--when an item is put into the inventory +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + if listname == "water" then + local water_name= stack:get_name() + --check if is a valid water liquid + if is_valid_water(water_name) == true then + return stack:get_count() + else + return 0 + end + elseif listname == "ignitor" then + local iswater= stack:get_name() + if iswater == brewing.settings.ignitor_name then + return stack:get_count() + else + return 0 + end + elseif listname == "flask" then + local iswater= stack:get_name() + if iswater == brewing.settings.flask_name then + return stack:get_count() + else + return 0 + end + elseif listname == "dst" then + return 0 + else + return stack:get_count() + end +end + +--when an item is moved inside the inventory +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function decrease_stacks(pos, ing_listname, ing_stack, howmuch) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local count = ing_stack:get_count() + if count > 0 then + count = count - howmuch + if count < 0 then + count = 0 + end + ing_stack:set_count(count) + end + inv:set_stack(ing_listname, 1, ing_stack) +end + +local function try_to_make_potion(pos, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local ing1, ing2, ing3, ignitor, water, flask + local ing1_name, ing2_name, ing3_name, ignitor_name, water_name, flask_name + local flask_count + local brewed + local infotext + local update = true + while update do + update = false + ing1= inv:get_stack("ing1", 1) + ing1_name = ing1:get_name() + ing2= inv:get_stack("ing2", 1) + ing2_name = ing2:get_name() + ing3= inv:get_stack("ing3", 1) + ing3_name = ing3:get_name() + ignitor= inv:get_stack("ignitor", 1) + ignitor_name = ignitor:get_name() + water= inv:get_stack("water", 1) + water_name = water:get_name() + flask= inv:get_stack("flask", 1) + flask_name = flask:get_name() + flask_count = flask:get_count() + + --The list: {ingredient_list_name, ingredient_stack, ingredient_name, how_much_decrements_when_crafted} + local ing_list = {{"ing1", ing1, ing1_name, 1}, {"ing2", ing2, ing2_name, 1}, {"ing3", ing3, ing3_name, 1}, {"ignitor", ignitor, ignitor_name, 1}, {"flask", flask, flask_name, brewing.settings.filled_flasks}} + + local valid_water= is_valid_water(water_name) + + --minetest.chat_send_player("singleplayer", brewing.settings.ignitor_name) + + if ignitor_name== brewing.settings.ignitor_name and valid_water and flask_name== brewing.settings.flask_name and flask_count >= brewing.settings.filled_flasks then + --brewed, afterbrewed = minetest.get_craft_result({method = "normal", width =3, items = {ingplus1, ingplus2, ingplus3, ingminus1, ingminus2, ingminus3, ignitor, water, flask}}) + brewed = brewing.get_craft_result({ing1_name, ing2_name, ing3_name}) + if brewed ~= nil then + if inv:room_for_item("dst", brewed) then + brewed:set_count(brewing.settings.filled_flasks) --How much flask will be filled + inv:add_item("dst", brewed) --Make the potion/s!!! + --Decrease stacks of the ingredients + local ing_stack + local ing_list_name + for key, ing in pairs(ing_list) do + ing_list_name= ing[1] + ing_stack = ing[2] + local howmuch = ing[4] + decrease_stacks(pos, ing_list_name, ing_stack, howmuch) + end + --replace the water bucket--> + inv:set_stack("water", 1, ItemStack("bucket:bucket_empty 1")) + brewing.make_sound("player", player, "brewing_magic_realization") + --Message to player + --minetest.chat_send_player("singleplayer", S("Potion created!)") + end + end + end + infotext = "" + end + -- + -- Set meta values + -- + meta:set_string("formspec", formspec) + meta:set_string("infotext", infotext) + +end + +--Register Cauldron Node + +minetest.register_node("brewing:magic_cauldron", { + description = S("Magic Cauldron"), + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.375, -0.5, 0.5, -0.3125, 0.5}, -- NodeBox1 + {-0.5, -0.3125, -0.5, 0.5, 0.5, -0.375}, -- NodeBox2 + {-0.5, -0.3125, 0.375, 0.5, 0.5, 0.5}, -- NodeBox3 + {-0.5, -0.3125, -0.375, -0.375, 0.5, 0.375}, -- NodeBox4 + {0.375, -0.3125, -0.375, 0.5, 0.5, 0.375}, -- NodeBox5 + {0.375, -0.5, -0.5, 0.5, -0.375, -0.375}, -- NodeBox6 + {0.375, -0.5, 0.375, 0.5, -0.375, 0.5}, -- NodeBox7 + {-0.5, -0.5, -0.5, -0.375, -0.375, -0.375}, -- NodeBox8 + {-0.5, -0.5, 0.375, -0.375, -0.375, 0.5}, -- NodeBox9 + {-0.375, 0.3125, -0.375, 0.375, 0.375, 0.375}, -- NodeBox10 + }, + }, + tiles = { + "brewing_cauldron_top.png", "brewing_cauldron_side.png", + "brewing_cauldron_side.png", "brewing_cauldron_side.png", + "brewing_cauldron_side.png", "brewing_cauldron_side.png" + }, + use_texture_alpha = true, + paramtype2 = "facedir", + groups = {cracky=2}, + legacy_facedir_simple = true, + is_ground_content = false, + can_dig = can_dig, + sounds = default.node_sound_stone_defaults(), + drop = "brewing:magic_cauldron", + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", formspec) + local inv = meta:get_inventory() + inv:set_size('ing1', 1) + inv:set_size('ing2', 1) + inv:set_size('ing3', 1) + inv:set_size('ignitor', 1) + inv:set_size('water', 1) + inv:set_size('flask', 1) + inv:set_size('dst', 1) + end, + + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "ing1", drops) + default.get_inventory_drops(pos, "ing2", drops) + default.get_inventory_drops(pos, "ing3", drops) + default.get_inventory_drops(pos, "ignitor", drops) + default.get_inventory_drops(pos, "water", drops) + default.get_inventory_drops(pos, "flask", drops) + default.get_inventory_drops(pos, "dst", drops) + drops[#drops+1] = "brewing:magic_cauldron" + minetest.remove_node(pos) + return drops + end, + + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + try_to_make_potion(pos, player) + end, + + on_metadata_inventory_put = function(pos, listname, index, stack, player) + try_to_make_potion(pos, player) + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if fields.btn_recipe_book then + minetest.show_formspec(player_name, "brewing:recipe_book", create_recipe_book_form()) + end + end, +}) + +