Enchanting table formspec redo

This commit is contained in:
AFCMS 2022-09-10 13:44:12 +02:00
parent 37176976b6
commit 842363464d
Signed by untrusted user: AFCMS
GPG Key ID: 8720389A25B652E3
1 changed files with 105 additions and 53 deletions

View File

@ -2,7 +2,8 @@ local S = minetest.get_translator(minetest.get_current_modname())
local F = minetest.formspec_escape local F = minetest.formspec_escape
function mcl_enchanting.is_book(itemname) function mcl_enchanting.is_book(itemname)
return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or itemname == "mcl_books:book_enchanted" return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or
itemname == "mcl_books:book_enchanted"
end end
function mcl_enchanting.get_enchantments(itemstack) function mcl_enchanting.get_enchantments(itemstack)
@ -54,11 +55,13 @@ end
function mcl_enchanting.get_enchantment_description(enchantment, level) function mcl_enchanting.get_enchantment_description(enchantment, level)
local enchantment_def = mcl_enchanting.enchantments[enchantment] local enchantment_def = mcl_enchanting.enchantments[enchantment]
return enchantment_def.name .. (enchantment_def.max_level == 1 and "" or " " .. mcl_enchanting.roman_numerals.toRoman(level)) return enchantment_def.name ..
(enchantment_def.max_level == 1 and "" or " " .. mcl_enchanting.roman_numerals.toRoman(level))
end end
function mcl_enchanting.get_colorized_enchantment_description(enchantment, level) function mcl_enchanting.get_colorized_enchantment_description(enchantment, level)
return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY, mcl_enchanting.get_enchantment_description(enchantment, level)) return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY,
mcl_enchanting.get_enchantment_description(enchantment, level))
end end
function mcl_enchanting.get_enchanted_itemstring(itemname) function mcl_enchanting.get_enchanted_itemstring(itemname)
@ -169,7 +172,9 @@ function mcl_enchanting.combine(itemstack, combine_with)
local itemname = itemstack:get_name() local itemname = itemstack:get_name()
local combine_name = combine_with:get_name() local combine_name = combine_with:get_name()
local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname) local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname)
if not enchanted_itemname or enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and not mcl_enchanting.is_book(combine_name) then if not enchanted_itemname or
enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and
not mcl_enchanting.is_book(combine_name) then
return false return false
end end
local enchantments = mcl_enchanting.get_enchantments(itemstack) local enchantments = mcl_enchanting.get_enchantments(itemstack)
@ -267,7 +272,7 @@ function mcl_enchanting.initialize()
for itemname, itemdef in pairs(minetest.registered_items) do for itemname, itemdef in pairs(minetest.registered_items) do
if mcl_enchanting.can_enchant_freshly(itemname) and not mcl_enchanting.is_book(itemname) then if mcl_enchanting.can_enchant_freshly(itemname) and not mcl_enchanting.is_book(itemname) then
local new_name = itemname .. "_enchanted" local new_name = itemname .. "_enchanted"
minetest.override_item(itemname, {_mcl_enchanting_enchanted_tool = new_name}) minetest.override_item(itemname, { _mcl_enchanting_enchanted_tool = new_name })
local new_def = table.copy(itemdef) local new_def = table.copy(itemdef)
new_def.inventory_image = itemdef.inventory_image .. mcl_enchanting.overlay new_def.inventory_image = itemdef.inventory_image .. mcl_enchanting.overlay
if new_def.wield_image then if new_def.wield_image then
@ -303,7 +308,7 @@ end
function mcl_enchanting.random(pr, ...) function mcl_enchanting.random(pr, ...)
local r = pr and pr:next(...) or math.random(...) local r = pr and pr:next(...) or math.random(...)
if pr and not ({...})[1] then if pr and not ({ ... })[1] then
r = r / 32767 r = r / 32767
end end
@ -328,20 +333,24 @@ function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, ex
return #possible > 0 and possible[mcl_enchanting.random(pr, 1, #possible)] return #possible > 0 and possible[mcl_enchanting.random(pr, 1, #possible)]
end end
function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance,
ignore_already_enchanted, pr)
local itemname = itemstack:get_name() local itemname = itemstack:get_name()
if (not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then if (not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted) or
mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then
return return
end end
itemstack = ItemStack(itemstack) itemstack = ItemStack(itemstack)
local enchantability = minetest.get_item_group(itemname, "enchantability") local enchantability = minetest.get_item_group(itemname, "enchantability")
enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) +
mcl_enchanting.random(pr, 0, math.floor(enchantability / 4))
enchantment_level = enchantment_level + enchantability enchantment_level = enchantment_level + enchantability
enchantment_level = enchantment_level + enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15 enchantment_level = enchantment_level +
enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15
enchantment_level = math.max(math.floor(enchantment_level + 0.5), 1) enchantment_level = math.max(math.floor(enchantment_level + 0.5), 1)
local enchantments = {} local enchantments = {}
@ -393,18 +402,22 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve
return enchantments, description return enchantments, description
end end
function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure,
no_reduced_bonus_chance, ignore_already_enchanted, pr)
local enchantments local enchantments
repeat repeat
enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure,
no_reduced_bonus_chance, ignore_already_enchanted, pr)
until enchantments until enchantments
return enchantments return enchantments
end end
function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance,
local enchantments = mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) ignore_already_enchanted, pr)
local enchantments = mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure,
no_reduced_bonus_chance, ignore_already_enchanted, pr)
mcl_enchanting.set_enchanted_itemstring(itemstack) mcl_enchanting.set_enchanted_itemstring(itemstack)
mcl_enchanting.set_enchantments(itemstack, enchantments) mcl_enchanting.set_enchantments(itemstack, enchantments)
@ -416,7 +429,8 @@ function mcl_enchanting.enchant_uniform_randomly(stack, exclude, pr)
local enchantment = mcl_enchanting.get_random_enchantment(stack, true, false, exclude, pr) local enchantment = mcl_enchanting.get_random_enchantment(stack, true, false, exclude, pr)
if enchantment then if enchantment then
mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) mcl_enchanting.enchant(stack, enchantment,
mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level))
end end
return stack return stack
@ -426,7 +440,8 @@ function mcl_enchanting.get_random_glyph_row()
local glyphs = "" local glyphs = ""
local x = 1.3 local x = 1.3
for i = 1, 9 do for i = 1, 9 do
glyphs = glyphs .. "image[".. x .. ",0.1;0.5,0.5;mcl_enchanting_glyph_" .. math.random(18) .. ".png^[colorize:#675D49:255]" glyphs = glyphs ..
"image[" .. x .. ",0.1;0.5,0.5;mcl_enchanting_glyph_" .. math.random(18) .. ".png^[colorize:#675D49:255]"
x = x + 0.6 x = x + 0.6
end end
return glyphs return glyphs
@ -459,7 +474,7 @@ end
function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves)
local itemname = itemstack:get_name() local itemname = itemstack:get_name()
if (not mcl_enchanting.can_enchant_freshly(itemname)) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then if (not mcl_enchanting.can_enchant_freshly(itemname)) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then
return {false, false, false} return { false, false, false }
end end
local meta = player:get_meta() local meta = player:get_meta()
local player_slots = minetest.deserialize(meta:get_string("mcl_enchanting:slots")) or {} local player_slots = minetest.deserialize(meta:get_string("mcl_enchanting:slots")) or {}
@ -475,7 +490,7 @@ function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves)
meta:set_string("mcl_enchanting:slots", minetest.serialize(player_slots)) meta:set_string("mcl_enchanting:slots", minetest.serialize(player_slots))
return player_bookshelves_item_slots return player_bookshelves_item_slots
else else
return {false, false, false} return { false, false, false }
end end
end end
end end
@ -491,28 +506,37 @@ function mcl_enchanting.show_enchanting_formspec(player)
local inv = player:get_inventory() local inv = player:get_inventory()
local num_bookshelves = meta:get_int("mcl_enchanting:num_bookshelves") local num_bookshelves = meta:get_int("mcl_enchanting:num_bookshelves")
local table_name = meta:get_string("mcl_enchanting:table_name") local table_name = meta:get_string("mcl_enchanting:table_name")
local formspec = ""
.. "size[9.07,8.6;]" local formspec = table.concat({
.. "formspec_version[3]" "formspec_version[4]",
.. "label[0,0;" .. C("#313131") .. F(table_name) .. "]" "size[11.75,10.425]",
.. mcl_formspec.get_itemslot_bg(0.2, 2.4, 1, 1)
.. "list[current_player;enchanting_item;0.2,2.4;1,1]" "label[0.375,0.375;" .. F(C(mcl_formspec.label_color) .. table_name) .. "]",
.. mcl_formspec.get_itemslot_bg(1.1, 2.4, 1, 1)
.. "image[1.1,2.4;1,1;mcl_enchanting_lapis_background.png]" mcl_formspec.get_itemslot_bg_v4(1, 3.25, 1, 1),
.. "list[current_player;enchanting_lapis;1.1,2.4;1,1]" "list[current_player;enchanting_item;1,3.25;1,1]",
.. "label[0,4;" .. C("#313131") .. F(S("Inventory")).."]" mcl_formspec.get_itemslot_bg_v4(2.25, 3.25, 1, 1),
.. mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) "list[current_player;enchanting_lapis;2.25,3.25;1,1]",
.. mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) "image[2.25,2.4;1,1;mcl_enchanting_lapis_background.png]",
.. "list[current_player;main;0,4.5;9,3;9]"
.. "listring[current_player;enchanting_item]" "image[4.125,0.375;7.25,4.1;mcl_enchanting_button_background.png]",
.. "listring[current_player;main]"
.. "listring[current_player;enchanting]" "label[0.375,4.7;" .. F(C(mcl_formspec.label_color) .. S("Inventory")) .. "]",
.. "listring[current_player;main]"
.. "listring[current_player;enchanting_lapis]" mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3),
.. "listring[current_player;main]" "list[current_player;main;0.375,5.1;9,3;9]",
.. "list[current_player;main;0,7.74;9,1;]"
.. "real_coordinates[true]" mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1),
.. "image[3.15,0.6;7.6,4.1;mcl_enchanting_button_background.png]" "list[current_player;main;0.375,9.05;9,1;]",
"listring[current_player;enchanting_item]",
"listring[current_player;main]",
"listring[current_player;enchanting]",
"listring[current_player;main]",
"listring[current_player;enchanting_lapis]",
"listring[current_player;main]",
})
local itemstack = inv:get_stack("enchanting_item", 1) local itemstack = inv:get_stack("enchanting_item", 1)
local player_levels = mcl_experience.get_level(player) local player_levels = mcl_experience.get_level(player)
local y = 0.65 local y = 0.65
@ -526,18 +550,43 @@ function mcl_enchanting.show_enchanting_formspec(player)
local ending = (can_enchant and "" or "_off") local ending = (can_enchant and "" or "_off")
local hover_ending = (can_enchant and "_hovered" or "_off") local hover_ending = (can_enchant and "_hovered" or "_off")
formspec = formspec formspec = formspec
.. "container[3.2," .. y .. "]" .. "container[4.125," .. y .. "]"
.. (slot and "tooltip[button_" .. i .. ";" .. C("#818181") .. ((slot.description and F(slot.description)) or "") .. " " .. C("#FFFFFF") .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and "#818181" or "#FC5454") .. F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") ..
.. "style[button_" .. i .. ";bgimg=mcl_enchanting_button" .. ending .. ".png;bgimg_hovered=mcl_enchanting_button" .. hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]" (
slot and
"tooltip[button_" ..
i ..
";" ..
C("#818181") ..
((slot.description and F(slot.description)) or "") ..
" " ..
C("#FFFFFF") ..
" . . . ?\n\n" ..
(
enough_levels and
C(enough_lapis and "#818181" or "#FC5454") ..
F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or
C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "")
..
"style[button_" ..
i ..
";bgimg=mcl_enchanting_button" ..
ending ..
".png;bgimg_hovered=mcl_enchanting_button" ..
hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]"
.. "button[0,0;7.5,1.3;button_" .. i .. ";]" .. "button[0,0;7.5,1.3;button_" .. i .. ";]"
.. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "") .. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "")
.. (slot and "label[7.2,1.1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "") .. (slot and "label[6.8,1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "")
.. (slot and slot.glyphs or "") .. (slot and slot.glyphs or "")
.. "container_end[]" .. "container_end[]"
y = y + 1.35 y = y + 1.3
end end
formspec = formspec formspec = formspec
.. "image[" .. (any_enchantment and 0.58 or 1.15) .. ",1.2;" .. (any_enchantment and 2 or 0.87) .. ",1.43;mcl_enchanting_book_" .. (any_enchantment and "open" or "closed") .. ".png]" ..
"image[" ..
(any_enchantment and 1.1 or 1.67) ..
",1.2;" ..
(any_enchantment and 2 or 0.87) .. ",1.43;mcl_enchanting_book_" .. (any_enchantment and "open" or "closed") .. ".png]"
minetest.show_formspec(name, "mcl_enchanting:table", formspec) minetest.show_formspec(name, "mcl_enchanting:table", formspec)
end end
@ -573,7 +622,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields)
mcl_enchanting.set_enchanted_itemstring(itemstack) mcl_enchanting.set_enchanted_itemstring(itemstack)
mcl_enchanting.set_enchantments(itemstack, slot.enchantments) mcl_enchanting.set_enchantments(itemstack, slot.enchantments)
inv:set_stack("enchanting_item", 1, itemstack) inv:set_stack("enchanting_item", 1, itemstack)
minetest.sound_play("mcl_enchanting_enchant", {to_player = name, gain = 5.0}) minetest.sound_play("mcl_enchanting_enchant", { to_player = name, gain = 5.0 })
mcl_enchanting.reset_table_slots(player) mcl_enchanting.reset_table_slots(player)
mcl_enchanting.show_enchanting_formspec(player) mcl_enchanting.show_enchanting_formspec(player)
awards.unlock(player:get_player_name(), "mcl:enchanter") awards.unlock(player:get_player_name(), "mcl:enchanter")
@ -645,13 +694,16 @@ function mcl_enchanting.on_inventory_action(player, action, inventory, inventory
end end
function mcl_enchanting.schedule_book_animation(self, anim) function mcl_enchanting.schedule_book_animation(self, anim)
self.scheduled_anim = {timer = self.anim_length, anim = anim} self.scheduled_anim = { timer = self.anim_length, anim = anim }
end end
function mcl_enchanting.set_book_animation(self, anim) function mcl_enchanting.set_book_animation(self, anim)
local anim_index = mcl_enchanting.book_animations[anim] local anim_index = mcl_enchanting.book_animations[anim]
local start, stop = mcl_enchanting.book_animation_steps[anim_index], mcl_enchanting.book_animation_steps[anim_index + 1] local start, stop = mcl_enchanting.book_animation_steps[anim_index],
self.object:set_animation({x = start, y = stop}, mcl_enchanting.book_animation_speed, 0, mcl_enchanting.book_animation_loop[anim] or false) mcl_enchanting.book_animation_steps[anim_index + 1
]
self.object:set_animation({ x = start, y = stop }, mcl_enchanting.book_animation_speed, 0,
mcl_enchanting.book_animation_loop[anim] or false)
self.scheduled_anim = nil self.scheduled_anim = nil
self.anim_length = (stop - start) / 40 self.anim_length = (stop - start) / 40
end end
@ -669,7 +721,7 @@ end
function mcl_enchanting.look_at(self, pos2) function mcl_enchanting.look_at(self, pos2)
local pos1 = self.object:get_pos() local pos1 = self.object:get_pos()
local vec = vector.subtract(pos1, pos2) local vec = vector.subtract(pos1, pos2)
local yaw = math.atan(vec.z / vec.x) - math.pi/2 local yaw = math.atan(vec.z / vec.x) - math.pi / 2
yaw = yaw + (pos1.x >= pos2.x and math.pi or 0) yaw = yaw + (pos1.x >= pos2.x and math.pi or 0)
self.object:set_yaw(yaw + math.pi) self.object:set_yaw(yaw + math.pi)
end end