]> git.lizzy.rs Git - xdecor.git/blob - enchanting.lua
70918260bbb2c91f62e7a04f55e60ed6fb6793c0
[xdecor.git] / enchanting.lua
1 local enchanting = {}
2 screwdriver = screwdriver or {}
3
4 function enchanting.formspec(pos, tooltype)
5         local xbg = default.gui_slots..default.get_hotbar_bg(0.5,4.5)
6         local meta = minetest.get_meta(pos)
7         local formspec = "size[9,9;]"..xbg..
8                 "bgcolor[#080808BB;true]background[0,0;9,9;ench_ui.png]list[context;tool;0.9,2.9;1,1;]list[context;mese;2,2.9;1,1;]image[2,2.9;1,1;mese_layout.png]list[current_player;main;0.5,4.5;8,4;]"
9         
10         if tooltype == "sword" then
11                 formspec = formspec.."image_button[3.9,2.95;4,0.9;bg_btn.png;sharp;Sharpness]"
12         elseif tooltype == "tool" then
13                 formspec = formspec.."image_button[3.9,0.9;4,0.9;bg_btn.png;fast;Efficiency]image_button[3.9,1.82;4,1.1;bg_btn.png;durable;Durability]"
14         elseif tooltype == "armor" then
15                 formspec = formspec.."image_button[3.9,0.9;4,0.9;bg_btn.png;strong;Strength]"
16         elseif tooltype == "boots" then
17                 formspec = formspec.."image_button[3.9,0.9;4,0.9;bg_btn.png;strong;Strength]image_button[3.9,1.82;4,1.1;bg_btn.png;speed;Speed]"
18         end
19
20         meta:set_string("formspec", formspec)
21         meta:set_string("infotext", "Enchantment Table")
22
23         local inv = meta:get_inventory()
24         inv:set_size("tool", 1)
25         inv:set_size("mese", 1)
26
27         return formspec
28 end
29
30 function enchanting.on_put(pos, listname, _, stack, _)
31         local stn = stack:get_name()
32         local meta = minetest.get_meta(pos)
33
34         if listname == "tool" then
35                 if stn:find("pick") or stn:find("axe") or stn:find("shovel") then
36                         meta:set_string("formspec", enchanting.formspec(pos, "tool"))
37                 elseif stn:find("sword") then
38                         meta:set_string("formspec", enchanting.formspec(pos, "sword"))
39                 elseif stn:find("chestplate") or stn:find("leggings") or stn:find("helmet") then
40                         meta:set_string("formspec", enchanting.formspec(pos, "armor"))
41                 elseif stn:find("boots") then
42                         meta:set_string("formspec", enchanting.formspec(pos, "boots"))
43                 end
44         end
45 end
46
47 function enchanting.fields(pos, _, fields, _)
48         local inv = minetest.get_meta(pos):get_inventory()
49         local toolstack = inv:get_stack("tool", 1)
50         local toolstack_name = toolstack:get_name()
51         local mesestack = inv:get_stack("mese", 1)
52         local modname, toolname = toolstack_name:match("([%w_]+):([%w_]+)")
53         local toolwear = toolstack:get_wear()
54         local mese = mesestack:get_count()
55         local ench = dump(fields):match("%w+")
56         if ench == "quit" then return end
57
58         if mese > 0 and fields[ench] then
59                 local enchanted_tool = modname..":enchanted_"..toolname.."_"..ench
60                 local tdef = minetest.registered_tools[enchanted_tool]
61
62                 if tdef then
63                         toolstack:replace(enchanted_tool)
64                         toolstack:add_wear(toolwear)
65                         mesestack:take_item()
66                         inv:set_stack("mese", 1, mesestack)
67                         inv:set_stack("tool", 1, toolstack)
68                 end
69         end
70 end
71
72 function enchanting.dig(pos, _)
73         local inv = minetest.get_meta(pos):get_inventory()
74         return inv:is_empty("tool") and inv:is_empty("mese")
75 end
76
77 function enchanting.put(_, listname, _, stack, _)
78         local toolstack = stack:get_name()
79         local count = stack:get_count()
80
81         if listname == "mese" and
82                 toolstack ~= "default:mese_crystal" then return 0
83         elseif listname == "tool" and not
84                 minetest.registered_tools[toolstack] then return 0
85         end
86         return count
87 end
88
89 xdecor.register("enchantment_table", {
90         description = "Enchantment Table",
91         tiles = {
92                 "xdecor_enchantment_top.png", "xdecor_enchantment_bottom.png",
93                 "xdecor_enchantment_side.png", "xdecor_enchantment_side.png",
94                 "xdecor_enchantment_side.png", "xdecor_enchantment_side.png"
95         },
96         groups = {cracky=1, oddly_breakable_by_hand=1, level=2},
97         sounds = default.node_sound_stone_defaults(),
98         on_rotate = screwdriver.rotate_simple,
99         can_dig = enchanting.dig,
100         on_construct = enchanting.formspec,
101         on_receive_fields = enchanting.fields,
102         on_metadata_inventory_put = enchanting.on_put,
103         allow_metadata_inventory_put = enchanting.put,
104         allow_metadata_inventory_move = function(...) return 0 end,
105         on_metadata_inventory_take = function(pos, listname, _, _, _)
106                 if listname == "tool" then enchanting.formspec(pos, nil) end
107         end
108 })
109
110 local function cap(str) return str:gsub("^%l", string.upper) end
111
112  -- Higher number = stronger enchant.
113 local use_factor = 1.2
114 local times_subtractor = 0.1
115 local damage_adder = 1
116 local strenght_factor = 1.2
117
118 local tools = {
119         --[[ Registration format :
120                 [Mod name] = {
121                         {materials},
122                         {tool name, tool group, {enchantments}}
123                  }
124         --]]
125         ["default"] = {
126                 {"steel", "bronze", "mese", "diamond"},
127                 {"axe", "choppy", {"durable", "fast"}}, 
128                 {"pick", "cracky", {"durable", "fast"}}, 
129                 {"shovel", "crumbly", {"durable", "fast"}},
130                 {"sword", "fleshy", {"sharp"}}
131         },
132         ["3d_armor"] = {
133                 {"steel", "bronze", "gold", "diamond"},
134                 {"boots", nil, {"strong", "speed"}},
135                 {"chestplate", nil, {"strong"}},
136                 {"helmet", nil, {"strong"}},
137                 {"leggings", nil, {"strong"}}
138         }
139 }
140
141 for mod, defs in pairs(tools) do
142 for _, mat in pairs(defs[1]) do
143 for _, tooldef in next, defs, 1 do
144 for _, ench in pairs(tooldef[3]) do
145         local tool, group, material, enchant = tooldef[1], tooldef[2], mat, ench
146         local original_tool = minetest.registered_tools[mod..":"..tool.."_"..material]
147
148         if original_tool then
149                 if mod == "default" then
150                         local original_damage_groups = original_tool.tool_capabilities.damage_groups
151                         local original_groupcaps = original_tool.tool_capabilities.groupcaps
152                         local groupcaps = table.copy(original_groupcaps)
153                         local fleshy = original_damage_groups.fleshy
154                         local full_punch_interval = original_tool.tool_capabilities.full_punch_interval
155                         local max_drop_level = original_tool.tool_capabilities.max_drop_level
156
157                         if enchant == "durable" then
158                                 groupcaps[group].uses = math.ceil(original_groupcaps[group].uses * use_factor)
159                         elseif enchant == "fast" then
160                                 for i = 1, 3 do
161                                         groupcaps[group].times[i] = original_groupcaps[group].times[i] - times_subtractor
162                                 end
163                         elseif enchant == "sharp" then
164                                 fleshy = fleshy + damage_adder
165                         end
166
167                         minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
168                                 description = string.format("Enchanted %s %s (%s)", cap(material), cap(tool), cap(enchant)),
169                                 inventory_image = original_tool.inventory_image.."^[colorize:violet:50",
170                                 wield_image = original_tool.wield_image,
171                                 groups = {not_in_creative_inventory=1},
172                                 tool_capabilities = {
173                                         groupcaps = groupcaps, damage_groups = {fleshy = fleshy},
174                                         full_punch_interval = full_punch_interval, max_drop_level = max_drop_level
175                                 }
176                         })
177                 end
178
179                 if mod == "3d_armor" then
180                         local original_armor_groups = original_tool.groups
181                         local armorcaps = table.copy(original_armor_groups)
182                         local armorcaps = {}
183                         armorcaps.not_in_creative_inventory=1
184
185                         for armor_group, value in pairs(original_armor_groups) do
186                                 if enchant == "strong" then
187                                         armorcaps[armor_group] = math.ceil(value * 1.2)
188                                 elseif enchant == "speed" then
189                                         armorcaps[armor_group] = value
190                                         armorcaps.physics_speed = 0.4
191                                         armorcaps.physics_jump = 0.2
192                                 end
193                         end
194
195                         minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
196                                 description = string.format("Enchanted %s %s (%s)", cap(material), cap(tool), cap(enchant)),
197                                 inventory_image = original_tool.inventory_image.."^[colorize:blue:20",
198                                 wield_image = original_tool.wield_image,
199                                 groups = armorcaps,
200                                 wear = 0
201                         })
202                 end
203         end
204         minetest.register_alias("xdecor:enchanted_"..tool.."_"..material.."_"..enchant, mod..":enchanted_"..tool.."_"..material.."_"..enchant)
205         minetest.register_alias(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, mod..":enchanted_"..tool.."_"..material.."_"..enchant)
206 end
207 end
208 end
209 end
210