diff --git a/mods/CORE/mcl_enchanting/api.lua b/mods/CORE/mcl_enchanting/api.lua index 907fb63dd..158122562 100644 --- a/mods/CORE/mcl_enchanting/api.lua +++ b/mods/CORE/mcl_enchanting/api.lua @@ -5,16 +5,21 @@ end function mcl_enchanting.set_enchantments(itemstack, enchantments) itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments)) local itemdef = itemstack:get_definition() - for enchantment, level in pairs(enchantments) do - local enchantment_def = mcl_enchanting.enchantments[enchantment] - if enchantment_def.on_enchant then - enchantment_def.on_enchant(itemstack, level, itemdef) + if itemstack:get_name() ~= "mcl_enchanting:book_enchanted" then + for enchantment, level in pairs(enchantments) do + local enchantment_def = mcl_enchanting.enchantments[enchantment] + if enchantment_def.on_enchant then + enchantment_def.on_enchant(itemstack, level, itemdef) + end end end tt.reload_itemstack_description(itemstack) end function mcl_enchanting.get_enchantment(itemstack, enchantment) + if itemstack:get_name() == "mcl_enchanting:book_enchanted" then + return 0 + end return mcl_enchanting.get_enchantments(itemstack)[enchantment] or 0 end @@ -45,6 +50,9 @@ function mcl_enchanting.is_enchanted(itemstack) end function mcl_enchanting.item_supports_enchantment(itemname, enchantment, early) + if itemname == "mcl_enchanting:book_enchanted" then + return true, true + end if not early and not mcl_enchanting.get_enchanted_itemstring(itemname) then return false end @@ -58,9 +66,14 @@ function mcl_enchanting.item_supports_enchantment(itemname, enchantment, early) return false end end - for group in pairs(enchantment_def.all) do + for group in pairs(enchantment_def.primary) do if minetest.get_item_group(itemname, group) > 0 then - return true + return true, true + end + end + for group in pairs(enchantment_def.secondary) do + if minetest.get_item_group(itemname, group) > 0 then + return true, false end end return false @@ -71,7 +84,8 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) if not enchantment_def then return false, "enchantment invalid" end - if itemstack:get_name() == "" then + local itemname = itemstack:get_name() + if itemname == "" then return false, "item missing" end if not mcl_enchanting.item_supports_enchantment(itemstack:get_name(), enchantment) then @@ -90,10 +104,12 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) if enchantment_level then return false, "incompatible", mcl_enchanting.get_enchantment_description(enchantment, enchantment_level) end - for incompatible in pairs(enchantment_def.incompatible) do - local incompatible_level = item_enchantments[incompatible] - if incompatible_level then - return false, "incompatible", mcl_enchanting.get_enchantment_description(incompatible, incompatible_level) + if itemname ~= "mcl_enchanting:book_enchanted" then + for incompatible in pairs(enchantment_def.incompatible) do + local incompatible_level = item_enchantments[incompatible] + if incompatible_level then + return false, "incompatible", mcl_enchanting.get_enchantment_description(incompatible, incompatible_level) + end end end return true @@ -109,17 +125,20 @@ end function mcl_enchanting.combine(itemstack, combine_with) local itemname = itemstack:get_name() + local combine_name = combine_with:get_name() local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname) - if enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_with:get_name()) then + if enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and combine_name ~= "mcl_enchanting:book_enchanted" then return false end local enchantments = mcl_enchanting.get_enchantments(itemstack) for enchantment, combine_level in pairs(mcl_enchanting.get_enchantments(combine_with)) do local enchantment_def = mcl_enchanting.enchantments[enchantment] - local enchantment_level = enchantments[combine_enchantment] + local enchantment_level = enchantments[enchantment] if enchantment_level then if enchantment_level == combine_level then enchantment_level = math.min(enchantment_level + 1, enchantment_def.max_level) + else + enchantment_level = math.max(enchantment_level, combine_level) end elseif mcl_enchanting.item_supports_enchantment(itemname, enchantment) then local supported = true @@ -133,7 +152,9 @@ function mcl_enchanting.combine(itemstack, combine_with) enchantment_level = combine_level end end - enchantments[enchantment] = enchantment_level + if enchantment_level and enchantment_level > 0 then + enchantments[enchantment] = enchantment_level + end end local any_enchantment = false for enchantment, enchantment_level in pairs(enchantments) do @@ -150,28 +171,24 @@ function mcl_enchanting.combine(itemstack, combine_with) end function mcl_enchanting.initialize() - local tool_list = {} - local item_list = {} + local all_groups = {} for enchantment, enchantment_def in pairs(mcl_enchanting.enchantments) do - local all_item_groups = {} for primary in pairs(enchantment_def.primary) do - all_item_groups[primary] = true - mcl_enchanting.all_item_groups[primary] = true + all_groups[primary] = true end for secondary in pairs(enchantment_def.secondary) do - all_item_groups[secondary] = true - mcl_enchanting.all_item_groups[secondary] = true + all_groups[secondary] = true end - enchantment_def.all = all_item_groups - mcl_enchanting.total_weight = mcl_enchanting.total_weight + enchantment_def.weight end + local register_tool_list = {} + local register_item_list = {} for itemname, itemdef in pairs(minetest.registered_items) do if itemdef.groups.enchanted then break end local quick_test = false for group, groupv in pairs(itemdef.groups) do - if groupv > 0 and mcl_enchanting.all_item_groups[group] then + if groupv > 0 and all_groups[group] then quick_test = true break end @@ -196,48 +213,26 @@ function mcl_enchanting.initialize() minetest.override_item(itemname, {_mcl_enchanting_enchanted_tool = new_name}) local new_def = table.copy(itemdef) new_def.inventory_image = itemdef.inventory_image .. "^[colorize:purple:50" + if new_def.wield_image then + new_def.wield_image = new_def.wield_image .. "^[colorize:purple:50" + end new_def.groups.not_in_creative_inventory = 1 new_def.groups.enchanted = 1 new_def.texture = itemdef.texture or itemname:gsub("%:", "_") new_def._mcl_enchanting_enchanted_tool = new_name - local register_list = item_list + local register_list = register_item_list if itemdef.type == "tool" then - register_list = tool_list + register_list = register_tool_list end register_list[":" .. new_name] = new_def end end end - for new_name, new_def in pairs(item_list) do + for new_name, new_def in pairs(register_item_list) do minetest.register_craftitem(new_name, new_def) end - for new_name, new_def in pairs(tool_list) do + for new_name, new_def in pairs(register_tool_list) do minetest.register_tool(new_name, new_def) end end ---[[ -minetest.register_on_mods_loaded(function() - for toolname, tooldef in pairs(minetest.registered_tools) do - for _, material in pairs(tooldef.materials) do - local full_name = toolname .. ((material == "") and "" or "_" .. material) - local old_def = minetest.registered_tools[full_name] - if not old_def then break end - mcl_enchanting.all_tools[full_name] = toolname - for _, enchantment in pairs(tooldef.enchantments) do - local enchantment_def = mcl_enchanting.enchantments[enchantment] - for lvl = 1, enchantment_def.max_level do - local new_def = table.copy(old_def) - new_def.description = minetest.colorize("#54FCFC", old_def.description) .. "\n" .. mcl_enchanting.get_enchantment_description(enchantment, lvl) - new_def.inventory_image = old_def.inventory_image .. "^[colorize:violet:50" - new_def.groups.not_in_creative_inventory = 1 - new_def.texture = old_def.texture or full_name:gsub("%:", "_") - new_def._original_tool = full_name - enchantment_def.create_itemdef(new_def, lvl) - minetest.register_tool(":" .. full_name .. "_enchanted_" .. enchantment .. "_" .. lvl, new_def) - end - end - end - end -end) ---]] diff --git a/mods/CORE/mcl_enchanting/book.lua b/mods/CORE/mcl_enchanting/book.lua index 132fb880b..7b0ee5080 100644 --- a/mods/CORE/mcl_enchanting/book.lua +++ b/mods/CORE/mcl_enchanting/book.lua @@ -1,87 +1,9 @@ -local book_animations = {["close"] = 1, ["opening"] = 2, ["open"] = 3, ["closing"] = 4} -local book_animation_steps = {0, 640, 680, 700, 740} -local book_animation_speed = 40 - -function mcl_enchanting.schedule_book_animation(self, anim) - self.scheduled_anim = {timer = self.anim_length, anim = anim} -end - -function mcl_enchanting.set_book_animation(self, anim) - local anim_index = book_animations[anim] - local start, stop = book_animation_steps[anim_index], book_animation_steps[anim_index + 1] - self.object:set_animation({x = start, y = stop}, book_animation_speed) - self.scheduled_anim = nil - self.anim_length = (stop - start) / 40 -end - -function mcl_enchanting.check_animation_schedule(self, dtime) - local schedanim = self.scheduled_anim - if schedanim then - schedanim.timer = schedanim.timer - dtime - if schedanim.timer <= 0 then - mcl_enchanting.set_book_animation(self, schedanim.anim)local pos1=self.object:get_pos() - end - end -end - -function mcl_enchanting.look_at(self, pos2) - local pos1 = self.object:get_pos() - local vec = vector.subtract(pos1, pos2) - local yaw = math.atan(vec.z / vec.x) - math.pi/2 - yaw = yaw + (pos1.x >= pos2.x and math.pi or 0) - self.object:set_yaw(yaw + math.pi) -end - -function mcl_enchanting.check_book(pos) - local obj_pos = vector.add(pos, mcl_enchanting.book_offset) - for _, obj in pairs(minetest.get_objects_inside_radius(obj_pos, 0.1)) do - local luaentity = obj:get_luaentity() - if luaentity and luaentity.name == "mcl_enchanting:book" then - if minetest.get_node(pos).name ~= "mcl_enchanting:table" then - obj:remove() - end - return - end - end - minetest.add_entity(obj_pos, "mcl_enchanting:book") -end - -minetest.register_entity("mcl_enchanting:book", { - initial_properties = { - visual = "mesh", - mesh = "mcl_enchanting_book.b3d", - visual_size = {x = 12.5, y = 12.5}, - collisionbox = {0, 0, 0}, - physical = false, - textures = {"mcl_enchanting_book_entity.png"}, - }, - player_near = false, - on_activate = function(self) - self.object:set_armor_groups({immortal = 1}) - mcl_enchanting.set_book_animation(self, "close") - mcl_enchanting.check_book(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset)) - end, - on_step = function(self, dtime) - local old_player_near = self.player_near - local player_near = false - local player - for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 2.5)) do - if obj:is_player() then - player_near = true - player = obj - end - end - if player_near and not old_player_near then - mcl_enchanting.set_book_animation(self, "opening") - mcl_enchanting.schedule_book_animation(self, "open") - elseif old_player_near and not player_near then - mcl_enchanting.set_book_animation(self, "closing") - mcl_enchanting.schedule_book_animation(self, "close") - end - if player then - mcl_enchanting.look_at(self, player:get_pos()) - end - self.player_near = player_near - mcl_enchanting.check_animation_schedule(self, dtime) - end, +minetest.register_craftitem("mcl_enchanting:book_enchanted", { + description = "Enchanted Book", + inventory_image = "mcl_enchanting_book_enchanted.png^[colorize:purple:50", + groups = {enchanted = 1, not_in_creative_inventory = 1}, + _mcl_enchanting_enchanted_tool = "mcl_enchanting:book_enchanted", + stack_max = 1, }) + +minetest.registered_items["mcl_books:book"]._mcl_enchanting_enchanted_tool = "mcl_enchanting:book_enchanted" diff --git a/mods/CORE/mcl_enchanting/enchantments.lua b/mods/CORE/mcl_enchanting/enchantments.lua index ee007b91d..b5452f96e 100644 --- a/mods/CORE/mcl_enchanting/enchantments.lua +++ b/mods/CORE/mcl_enchanting/enchantments.lua @@ -1,7 +1,7 @@ -- Taken from https://minecraft.gamepedia.com/Enchanting --- unimplemented -mcl_enchanting.enchantments.aqua_affinity = { +-- requires engine change +--[[mcl_enchanting.enchantments.aqua_affinity = { name = "Aqua Affinity", max_level = 1, primary = {armor_head = true}, @@ -13,7 +13,7 @@ mcl_enchanting.enchantments.aqua_affinity = { curse = false, on_enchant = function() end, requires_tool = false, -} +}]]-- -- unimplemented mcl_enchanting.enchantments.bane_of_anthropods = { @@ -45,7 +45,7 @@ mcl_enchanting.enchantments.blast_protection = { requires_tool = false, } --- unimplemented +-- implemented in mcl_armor mcl_enchanting.enchantments.curse_of_binding = { name = "Curse of Binding", max_level = 1, diff --git a/mods/CORE/mcl_enchanting/init.lua b/mods/CORE/mcl_enchanting/init.lua index 5921d77d3..1611557ce 100644 --- a/mods/CORE/mcl_enchanting/init.lua +++ b/mods/CORE/mcl_enchanting/init.lua @@ -5,8 +5,6 @@ mcl_enchanting = { book_offset = vector.new(0, 0.75, 0), roman_numerals = dofile(modpath .. "/roman_numerals.lua"), -- https://exercism.io/tracks/lua/exercises/roman-numerals/solutions/73c2fb7521e347209312d115f872fa49 enchantments = {}, - total_weight = 0, - all_item_groups = {}, debug = true, } @@ -14,6 +12,7 @@ dofile(modpath .. "/api.lua") dofile(modpath .. "/enchantments.lua") dofile(modpath .. "/command.lua") dofile(modpath .. "/tt.lua") +dofile(modpath .. "/book.lua") -- dofile(modpath .. "/ui.lua") -- dofile(modpath .. "/fx.lua") -- dofile(modpath .. "/book.lua") diff --git a/mods/CORE/mcl_enchanting/mod.conf b/mods/CORE/mcl_enchanting/mod.conf index 8dfe4e94f..3680b4fa9 100644 --- a/mods/CORE/mcl_enchanting/mod.conf +++ b/mods/CORE/mcl_enchanting/mod.conf @@ -1,5 +1,5 @@ name = mcl_enchanting description = The rewrite of the Enchanting mod for MineClone2 -depends = mcl_formspec, tt +depends = mcl_formspec, tt, mcl_books optional_depends = screwdriver author = Fleckenstein diff --git a/mods/CORE/mcl_enchanting/table_book.lua b/mods/CORE/mcl_enchanting/table_book.lua new file mode 100644 index 000000000..132fb880b --- /dev/null +++ b/mods/CORE/mcl_enchanting/table_book.lua @@ -0,0 +1,87 @@ +local book_animations = {["close"] = 1, ["opening"] = 2, ["open"] = 3, ["closing"] = 4} +local book_animation_steps = {0, 640, 680, 700, 740} +local book_animation_speed = 40 + +function mcl_enchanting.schedule_book_animation(self, anim) + self.scheduled_anim = {timer = self.anim_length, anim = anim} +end + +function mcl_enchanting.set_book_animation(self, anim) + local anim_index = book_animations[anim] + local start, stop = book_animation_steps[anim_index], book_animation_steps[anim_index + 1] + self.object:set_animation({x = start, y = stop}, book_animation_speed) + self.scheduled_anim = nil + self.anim_length = (stop - start) / 40 +end + +function mcl_enchanting.check_animation_schedule(self, dtime) + local schedanim = self.scheduled_anim + if schedanim then + schedanim.timer = schedanim.timer - dtime + if schedanim.timer <= 0 then + mcl_enchanting.set_book_animation(self, schedanim.anim)local pos1=self.object:get_pos() + end + end +end + +function mcl_enchanting.look_at(self, pos2) + local pos1 = self.object:get_pos() + local vec = vector.subtract(pos1, pos2) + local yaw = math.atan(vec.z / vec.x) - math.pi/2 + yaw = yaw + (pos1.x >= pos2.x and math.pi or 0) + self.object:set_yaw(yaw + math.pi) +end + +function mcl_enchanting.check_book(pos) + local obj_pos = vector.add(pos, mcl_enchanting.book_offset) + for _, obj in pairs(minetest.get_objects_inside_radius(obj_pos, 0.1)) do + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_enchanting:book" then + if minetest.get_node(pos).name ~= "mcl_enchanting:table" then + obj:remove() + end + return + end + end + minetest.add_entity(obj_pos, "mcl_enchanting:book") +end + +minetest.register_entity("mcl_enchanting:book", { + initial_properties = { + visual = "mesh", + mesh = "mcl_enchanting_book.b3d", + visual_size = {x = 12.5, y = 12.5}, + collisionbox = {0, 0, 0}, + physical = false, + textures = {"mcl_enchanting_book_entity.png"}, + }, + player_near = false, + on_activate = function(self) + self.object:set_armor_groups({immortal = 1}) + mcl_enchanting.set_book_animation(self, "close") + mcl_enchanting.check_book(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset)) + end, + on_step = function(self, dtime) + local old_player_near = self.player_near + local player_near = false + local player + for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 2.5)) do + if obj:is_player() then + player_near = true + player = obj + end + end + if player_near and not old_player_near then + mcl_enchanting.set_book_animation(self, "opening") + mcl_enchanting.schedule_book_animation(self, "open") + elseif old_player_near and not player_near then + mcl_enchanting.set_book_animation(self, "closing") + mcl_enchanting.schedule_book_animation(self, "close") + end + if player then + mcl_enchanting.look_at(self, player:get_pos()) + end + self.player_near = player_near + mcl_enchanting.check_animation_schedule(self, dtime) + end, +}) diff --git a/mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png b/mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png new file mode 100644 index 000000000..5cd46d8b6 Binary files /dev/null and b/mods/CORE/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png differ diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index 326aad6ef..b9aa1b271 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -418,6 +418,9 @@ minetest.register_on_joinplayer(function(player) end end, allow_take = function(inv, listname, index, stack, player) + if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.settings:get_bool("creative") then + return 0 + end return stack:get_count() end, allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 53776df3b..cf7efb623 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -333,13 +333,7 @@ end minetest.register_craft({ type = "fuel", - recipe = "mcl_bows:bow", - burntime = 15, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "mcl_bows:bow_enchanted", + recipe = "group:bow", burntime = 15, }) diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 5b3747350..833dded52 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -177,7 +177,7 @@ local bobber_on_step = function(self, dtime) if self._tick % 5 == 0 and self.player ~= nil and player ~= nil then --Destroy bobber if item not wielded. local wield = player:get_wielded_item() - if ((not wield) or (wield:get_name() ~= "mcl_fishing:fishing_rod")) then + if ((not wield) or (minetest.get_item_groups(wield:get_name(), "fishing_rod") <= 0)) then self.object:remove() return end @@ -343,7 +343,7 @@ minetest.register_craft({ }) minetest.register_craft({ type = "fuel", - recipe = "mcl_fishing:fishing_rod", + recipe = "group:fishing_rod", burntime = 15, })