diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index d7c76f1991..f971d0f35d 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -152,6 +152,11 @@ minetest.register_globalstep(function(dtime) end end + elseif not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mcl_experience:orb" then + local entity = object:get_luaentity() + entity.collector = player:get_player_name() + entity.collected = true + end end @@ -221,6 +226,12 @@ function minetest.handle_node_drops(pos, drops, digger) local dug_node = minetest.get_node(pos) local toolcaps if digger ~= nil then + if mcl_experience.throw_experience then + local experience_amount = minetest.get_item_group(dug_node.name,"experience") + if experience_amount > 0 then + mcl_experience.throw_experience(pos, experience_amount) + end + end local tool = digger:get_wielded_item() toolcaps = tool:get_tool_capabilities() diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index ab2480f9d4..a4e87341f5 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -640,6 +640,10 @@ local check_for_death = function(self, cause, cmi_cause) local pos = self.object:get_pos() + if mcl_experience.throw_experience and self.hp_min and self.hp_max then + mcl_experience.throw_experience(pos, math.ceil( math.random(self.hp_min,self.hp_max+5) / 5) ) + end + -- execute custom death function if self.on_die then diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index 6ddd4a03bf..44c8266567 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -46,6 +46,11 @@ end -- Load default settings dofile(minetest.get_modpath("hudbars").."/default_settings.lua") +if minetest.get_modpath("mcl_experience") then + -- reserve some space for experience bar: + hb.settings.start_offset_left.y = hb.settings.start_offset_left.y - 20 + hb.settings.start_offset_right.y = hb.settings.start_offset_right.y - 20 +end local function player_exists(player) return player ~= nil and player:is_player() diff --git a/mods/HUD/mcl_experience/README.md b/mods/HUD/mcl_experience/README.md new file mode 100644 index 0000000000..f59eab20f6 --- /dev/null +++ b/mods/HUD/mcl_experience/README.md @@ -0,0 +1,6 @@ +-- eXPerience mod +-- This mod has adopted from oil_boi's Crafter-minetest +-- ( https://www.patreon.com/oil_boi ) by kay27@bk.ru +-- for MineClone 2 under GNU General Public License v3.0. +-- Copyright (c) Oil_boi, Wuzzy, kay27, +-- experience_orb texture by github.com/Gerold55 diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua new file mode 100644 index 0000000000..bb62acbec2 --- /dev/null +++ b/mods/HUD/mcl_experience/init.lua @@ -0,0 +1,539 @@ +local S = minetest.get_translator("mcl_experience") +mcl_experience = {} +local pool = {} +local registered_nodes + +local gravity = {x = 0, y = -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), z = 0} +local size_min, size_max = 20, 59 -- percents +local delta_size = size_max - size_min +local size_to_xp = { + {-32768, 2}, -- 1 + { 3, 6}, -- 2 + { 7, 16}, -- 3 + { 17, 36}, -- 4 + { 37, 72}, -- 5 + { 73, 148}, -- 6 + { 149, 306}, -- 7 + { 307, 616}, -- 8 + { 617, 1236}, -- 9 + { 1237, 2476}, --10 + { 2477, 32767} --11 +} + +local function xp_to_size(xp) + local i, l = 1, #size_to_xp + while (xp > size_to_xp[i][1]) and (i < l) do + i = i + 1 + end + return ((i-1) / (l-1) * delta_size + size_min)/100 +end + +minetest.register_on_mods_loaded(function() + registered_nodes = minetest.registered_nodes +end) + +local load_data = function(player) + local name = player:get_player_name() + pool[name] = {} + local temp_pool = pool[name] + local meta = player:get_meta() + temp_pool.xp = meta:get_int("xp") or 0 + temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) + temp_pool.bar, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) + temp_pool.last_time= minetest.get_us_time()/1000000 +end + +-- saves data to be utilized on next login +local save_data = function(player) + name = player:get_player_name() + local temp_pool = pool[name] + local meta = player:get_meta() + meta:set_int("xp", temp_pool.xp) + pool[name] = nil +end + +local player_huds = {} -- the list of players hud lists (3d array) +hud_manager = {} -- hud manager class + +-- terminate the player's list on leave +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + player_huds[name] = nil +end) + +-- create instance of new hud +hud_manager.add_hud = function(player,hud_name,def) + local name = player:get_player_name() + local local_hud = player:hud_add({ + hud_elem_type = def.hud_elem_type, + position = def.position, + text = def.text, + number = def.number, + direction = def.direction, + size = def.size, + offset = def.offset, + }) + -- create new 3d array here + -- depends.txt is not needed + -- with it here + if not player_huds[name] then + player_huds[name] = {} + end + + player_huds[name][hud_name] = local_hud +end + +-- delete instance of hud +hud_manager.remove_hud = function(player,hud_name) + local name = player:get_player_name() + if player_huds[name] and player_huds[name][hud_name] then + player:hud_remove(player_huds[name][hud_name]) + player_huds[name][hud_name] = nil + end +end + +-- change element of hud +hud_manager.change_hud = function(data) + local name = data.player:get_player_name() + if player_huds[name] and player_huds[name][data.hud_name] then + data.player:hud_change(player_huds[name][data.hud_name], data.element, data.data) + end +end + +-- gets if hud exists +hud_manager.hud_exists = function(player,hud_name) + local name = player:get_player_name() + if player_huds[name] and player_huds[name][hud_name] then + return(true) + else + return(false) + end +end +------------------- + +-- saves specific users data for when they relog +minetest.register_on_leaveplayer(function(player) + save_data(player) +end) + +-- is used for shutdowns to save all data +local save_all = function() + for name,_ in pairs(pool) do + local player = minetest.get_player_by_name(name) + if player then + save_data(player) + end + end +end + +-- save all data to mod storage on shutdown +minetest.register_on_shutdown(function() + save_all() +end) + + +local name +function mcl_experience.get_player_xp_level(player) + name = player:get_player_name() + return(pool[name].level) +end + +local name +local temp_pool +function mcl_experience.set_player_xp_level(player,level) + name = player:get_player_name() + pool[name].level = level + pool[name].xp = mcl_experience.level_to_xp(level) +--todo: update bar + hud_manager.change_hud({ + player = player, + hud_name = "xp_level_fg", + element = "text", + data = tostring(level) + }) + hud_manager.change_hud({ + player = player, + hud_name = "xp_level_bg", + element = "text", + data = tostring(level) + }) +end + +local name +local temp_pool +minetest.register_on_joinplayer(function(player) + + load_data(player) + + name = player:get_player_name() + temp_pool = pool[name] + + hud_manager.add_hud(player, "experience_bar_background", + { + hud_elem_type = "statbar", position = {x=0.5, y=1}, + name = "experience bar background", text = "experience_bar_background.png", + number = 36, direction = 0, + offset = {x = (-8 * 28) - 29, y = -(48 + 24 + 16)}, + size = { x=28, y=28 }, z_index = 3, + }) + + hud_manager.add_hud(player,"experience_bar", + { + hud_elem_type = "statbar", position = {x=0.5, y=1}, + name = "experience bar", text = "experience_bar.png", + number = temp_pool.bar, direction = 0, + offset = {x = (-8 * 28) - 29, y = -(48 + 24 + 16)}, + size = { x=28, y=28 }, z_index = 4, + }) + + hud_manager.add_hud(player,"xp_level_bg", + { + hud_elem_type = "text", position = {x=0.5, y=1}, + name = "xp_level_bg", text = tostring(temp_pool.level), + number = 0x000000, + offset = {x = 0, y = -(48 + 24 + 24)}, + z_index = 5, + }) + + hud_manager.add_hud(player,"xp_level_fg", + { + hud_elem_type = "text", position = {x=0.5, y=1}, + name = "xp_level_fg", text = tostring(temp_pool.level), + number = 0xFFFFFF, + offset = {x = -1, y = -(48 + 24 + 25)}, + z_index = 6, + }) +end) + +function mcl_experience.xp_to_level(xp) + local xp = xp or 0 + local a, b, c, D + if xp > 1507 then + a, b, c = 4.5, -162.5, 2220-xp + elseif xp > 352 then + a, b, c = 2.5, -40.5, 360-xp + else + a, b, c = 1, 6, -xp + end + D = b*b-4*a*c + if D == 0 then + return math.floor(-b/2/a) + elseif D > 0 then + local v1, v2 = -b/2/a, math.sqrt(D)/2/a + return math.floor((math.max(v1-v2, v1+v2))) + end + return 0 +end + +function mcl_experience.level_to_xp(level) + if (level >= 1 and level <= 16) then + return math.floor(math.pow(level, 2) + 6 * level) + elseif (level >= 17 and level <= 31) then + return math.floor(2.5 * math.pow(level, 2) - 40.5 * level + 360) + elseif level >= 32 then + return math.floor(4.5 * math.pow(level, 2) - 162.5 * level + 2220); + end + return 0 +end + +function mcl_experience.xp_to_bar(xp, level) + local level = level or mcl_experience.xp_to_level(xp) + local xp_this_level = mcl_experience.level_to_xp(level) + local xp_next_level = mcl_experience.level_to_xp(level+1) + local bar = math.floor((xp-xp_this_level)/(xp_next_level-xp_this_level)*35) + return bar, xp_next_level +end + +function mcl_experience.add_experience(player, experience) + local name = player:get_player_name() + local temp_pool = pool[name] + + local old_bar, old_xp, old_level = temp_pool.bar, temp_pool.xp, temp_pool.level + temp_pool.xp = math.max(temp_pool.xp + experience, 0) + temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) + temp_pool.bar, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) + if old_level ~= temp_pool.level then + if minetest.get_us_time()/1000000 - temp_pool.last_time > 0.04 then + minetest.sound_play("level_up",{gain=0.2,to_player = name}) + temp_pool.last_time = minetest.get_us_time()/1000000 + end + hud_manager.change_hud({player = player, hud_name = "xp_level_fg", element = "text", data = tostring(temp_pool.level)}) + hud_manager.change_hud({player = player, hud_name = "xp_level_bg", element = "text", data = tostring(temp_pool.level)}) + elseif minetest.get_us_time()/1000000 - temp_pool.last_time > 0.01 then + temp_pool.last_time = minetest.get_us_time()/1000000 + minetest.sound_play("experience",{gain=0.1,to_player = name,pitch=math.random(75,99)/100}) + end + + if old_bar ~= temp_pool.bar then + hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "number", data = temp_pool.bar}) + end +end + +--reset player level +local name +local temp_pool +local xp_amount +minetest.register_on_dieplayer(function(player) + if minetest.settings:get_bool("mcl_keepInventory", false) then + return + end + + name = player:get_player_name() + temp_pool = pool[name] + xp_amount = temp_pool.xp + + temp_pool.bar = 0 + temp_pool.level = 0 + temp_pool.xp = 0 + + hud_manager.change_hud({player = player, hud_name = "xp_level_fg", element = "text", data = tostring(temp_pool.level)}) + hud_manager.change_hud({player = player, hud_name = "xp_level_bg", element = "text", data = tostring(temp_pool.level)}) + hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "number", data = temp_pool.bar}) + + mcl_experience.throw_experience(player:get_pos(), xp_amount) +end) + + +local name +local collector, pos, pos2 +local direction, distance, player_velocity, goal +local currentvel, acceleration, multiplier, velocity +local node, vel, def +local is_moving, is_slippery, slippery, slip_factor +local size, data +local function xp_step(self, dtime) + --if item set to be collected then only execute go to player + if self.collected == true then + if not self.collector then + self.collected = false + return + end + collector = minetest.get_player_by_name(self.collector) + if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 5 then + self.object:set_acceleration(vector.new(0,0,0)) + self.disable_physics(self) + --get the variables + pos = self.object:get_pos() + pos2 = collector:get_pos() + + player_velocity = collector:get_player_velocity() + + pos2.y = pos2.y + 0.8 + + direction = vector.direction(pos,pos2) + distance = vector.distance(pos2,pos) + multiplier = distance + if multiplier < 1 then + multiplier = 1 + end + goal = vector.multiply(direction,multiplier) + currentvel = self.object:get_velocity() + + if distance > 1 then + multiplier = 20 - distance + velocity = vector.multiply(direction,multiplier) + goal = velocity + acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z) + self.object:add_velocity(vector.add(acceleration,player_velocity)) + elseif distance < 0.4 then + mcl_experience.add_experience(collector, self._xp) + self.object:remove() + end + return + else + self.collector = nil + self.enable_physics(self) + end + end + + + self.age = self.age + dtime + if self.age > 300 then + self.object:remove() + return + end + + pos = self.object:get_pos() + + if pos then + node = minetest.get_node_or_nil({ + x = pos.x, + y = pos.y -0.25, + z = pos.z + }) + else + return + end + + -- Remove nodes in 'ignore' + if node and node.name == "ignore" then + self.object:remove() + return + end + + if not self.physical_state then + return -- Don't do anything + end + + -- Slide on slippery nodes + vel = self.object:get_velocity() + def = node and registered_nodes[node.name] + is_moving = (def and not def.walkable) or + vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0 + is_slippery = false + + if def and def.walkable then + slippery = minetest.get_item_group(node.name, "slippery") + is_slippery = slippery ~= 0 + if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then + -- Horizontal deceleration + slip_factor = 4.0 / (slippery + 4) + self.object:set_acceleration({ + x = -vel.x * slip_factor, + y = 0, + z = -vel.z * slip_factor + }) + elseif vel.y == 0 then + is_moving = false + end + end + + if self.moving_state == is_moving and self.slippery_state == is_slippery then + -- Do not update anything until the moving state changes + return + end + + self.moving_state = is_moving + self.slippery_state = is_slippery + + if is_moving then + self.object:set_acceleration(gravity) + else + self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_velocity({x = 0, y = 0, z = 0}) + end +end + +minetest.register_entity("mcl_experience:orb", { + initial_properties = { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, + visual = "sprite", + visual_size = {x = 0.4, y = 0.4}, + textures = {name="experience_orb.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}, + spritediv = {x = 1, y = 14}, + initial_sprite_basepos = {x = 0, y = 0}, + is_visible = true, + pointable = false, + static_save = false, + }, + moving_state = true, + slippery_state = false, + physical_state = true, + -- Item expiry + age = 0, + -- Pushing item out of solid nodes + force_out = nil, + force_out_start = nil, + --Collection Variables + collectable = false, + try_timer = 0, + collected = false, + delete_timer = 0, + radius = 4, + + + on_activate = function(self, staticdata, dtime_s) + self.object:set_velocity(vector.new( + math.random(-2,2)*math.random(), + math.random(2,5), + math.random(-2,2)*math.random() + )) + self.object:set_armor_groups({immortal = 1}) + self.object:set_velocity({x = 0, y = 2, z = 0}) + self.object:set_acceleration(gravity) + local xp = tonumber(staticdata) + self._xp = xp + size = xp_to_size(xp) + self.object:set_properties({ + visual_size = {x = size, y = size}, + glow = 14, + }) + self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false) + end, + + enable_physics = function(self) + if not self.physical_state then + self.physical_state = true + self.object:set_properties({physical = true}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration(gravity) + end + end, + + disable_physics = function(self) + if self.physical_state then + self.physical_state = false + self.object:set_properties({physical = false}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=0, z=0}) + end + end, + on_step = function(self, dtime) + xp_step(self, dtime) + end, +}) + +minetest.register_chatcommand("xp", { + params = S("[] []"), + description = S("Gives [[player ] ] XP"), + privs = {server=true}, + func = function(name, params) + local player, xp = nil, 1000 + local P, i = {}, 0 + for str in string.gmatch(params, "([^ ]+)") do + i = i + 1 + P[i] = str + end + if i > 2 then + return false, S("Error: Too many parameters!") + end + if i > 0 then + xp = tonumber(P[i]) + end + if i < 2 then + player = minetest.get_player_by_name(name) + end + if i == 2 then + player = minetest.get_player_by_name(P[1]) + end + if not xp then + return false, S("Error: Incorrect value of XP") + end + if not player then + return false, S("Error: Player not found") + end + mcl_experience.add_experience(player, xp) + end, +}) + +function mcl_experience.throw_experience(pos, amount) + local i, j = 0, 0 + local obj, xp + while i < amount and j < 100 do + xp = math.min(math.random(1, math.min(32767, amount-math.floor(i/2))), amount-i) + obj = minetest.add_entity(pos, "mcl_experience:orb", tostring(xp)) + if not obj then + return false + end + obj:set_velocity({ + x=math.random(-2,2)*math.random(), + y=math.random(2,5), + z=math.random(-2,2)*math.random() + }) + i = i + xp + j = j + 1 + end +end diff --git a/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr b/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr new file mode 100644 index 0000000000..1d2195e8d3 --- /dev/null +++ b/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr @@ -0,0 +1,5 @@ +[] []=[<игрок>] [] +Gives [[player ] ] XP=Даёт [[игроку <игрок> []] единиц опыта XP +Error: Too many parameters!=Ошибка: слишком много параметров! +Error: Incorrect value of XP=Ошибка: Недопустимое значение XP +Error: Player not found=Ошибка: Игрок не найден diff --git a/mods/HUD/mcl_experience/locale/template.txt b/mods/HUD/mcl_experience/locale/template.txt new file mode 100644 index 0000000000..963d9dffae --- /dev/null +++ b/mods/HUD/mcl_experience/locale/template.txt @@ -0,0 +1,5 @@ +[] []= +Gives [[player ] ] XP= +Error: Too many parameters!= +Error: Incorrect value of XP= +Error: Player not found= diff --git a/mods/HUD/mcl_experience/sounds/attributes.txt b/mods/HUD/mcl_experience/sounds/attributes.txt new file mode 100644 index 0000000000..26200b934d --- /dev/null +++ b/mods/HUD/mcl_experience/sounds/attributes.txt @@ -0,0 +1,2 @@ + +experience/level_up - https://freesound.org/people/geraldfiebig/sounds/323123/ diff --git a/mods/HUD/mcl_experience/sounds/experience.ogg b/mods/HUD/mcl_experience/sounds/experience.ogg new file mode 100644 index 0000000000..ed050d739f Binary files /dev/null and b/mods/HUD/mcl_experience/sounds/experience.ogg differ diff --git a/mods/HUD/mcl_experience/sounds/level_up.ogg b/mods/HUD/mcl_experience/sounds/level_up.ogg new file mode 100644 index 0000000000..9f0a9754bf Binary files /dev/null and b/mods/HUD/mcl_experience/sounds/level_up.ogg differ diff --git a/mods/HUD/mcl_experience/textures/attributes.txt b/mods/HUD/mcl_experience/textures/attributes.txt new file mode 100644 index 0000000000..892455baa4 --- /dev/null +++ b/mods/HUD/mcl_experience/textures/attributes.txt @@ -0,0 +1 @@ +experience_orb - https://github.com/Gerold55/Experience-Mod/blob/master/textures/orb.png \ No newline at end of file diff --git a/mods/HUD/mcl_experience/textures/experience_bar.png b/mods/HUD/mcl_experience/textures/experience_bar.png new file mode 100644 index 0000000000..d43a03d641 Binary files /dev/null and b/mods/HUD/mcl_experience/textures/experience_bar.png differ diff --git a/mods/HUD/mcl_experience/textures/experience_bar_background.png b/mods/HUD/mcl_experience/textures/experience_bar_background.png new file mode 100644 index 0000000000..0e6b597631 Binary files /dev/null and b/mods/HUD/mcl_experience/textures/experience_bar_background.png differ diff --git a/mods/HUD/mcl_experience/textures/experience_orb.png b/mods/HUD/mcl_experience/textures/experience_orb.png new file mode 100644 index 0000000000..4d553833ce Binary files /dev/null and b/mods/HUD/mcl_experience/textures/experience_orb.png differ diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 0bf91342eb..0728cb39e5 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -31,7 +31,7 @@ minetest.register_node("mcl_core:stone_with_coal", { tiles = {"mcl_core_coal_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=1, building_block=1, material_stone=1}, + groups = {pickaxey=1, building_block=1, material_stone=1, experience=1}, drop = 'mcl_core:coal_lump', sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, @@ -77,7 +77,7 @@ minetest.register_node("mcl_core:stone_with_redstone", { tiles = {"mcl_core_redstone_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1}, + groups = {pickaxey=4, building_block=1, material_stone=1, experience=7}, drop = { items = { max_items = 1, @@ -110,7 +110,7 @@ minetest.register_node("mcl_core:stone_with_redstone_lit", { light_source = 9, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, not_in_creative_inventory=1, material_stone=1}, + groups = {pickaxey=4, not_in_creative_inventory=1, material_stone=1, experience=7}, drop = { items = { max_items = 1, @@ -141,7 +141,7 @@ minetest.register_node("mcl_core:stone_with_lapis", { tiles = {"mcl_core_lapis_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=3, building_block=1, material_stone=1}, + groups = {pickaxey=3, building_block=1, material_stone=1, experience=6}, drop = { max_items = 1, items = { @@ -163,7 +163,7 @@ minetest.register_node("mcl_core:stone_with_emerald", { tiles = {"mcl_core_emerald_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1}, + groups = {pickaxey=4, building_block=1, material_stone=1, experience=6}, drop = "mcl_core:emerald", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, @@ -176,7 +176,7 @@ minetest.register_node("mcl_core:stone_with_diamond", { tiles = {"mcl_core_diamond_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1}, + groups = {pickaxey=4, building_block=1, material_stone=1, experience=4}, drop = "mcl_core:diamond", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index d019289d03..45af4e45ca 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -39,6 +39,9 @@ local fish = function(itemstack, player) if ent then if ent.player and ent.objtype=="fishing" then if (player:get_player_name() == ent.player) then + if mcl_experience.throw_experience then + mcl_experience.throw_experience(pos, math.random(1,6)) + end noent = false if ent._dive == true then local itemname diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index 39103f18f1..5bd2d0cfcb 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -344,6 +344,11 @@ local function furnace_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 + + if mcl_experience.throw_experience then + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + mcl_experience.throw_experience(vector.add(pos, dir), 1) + end end end diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 22d295d5b8..ee92de0285 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -35,7 +35,7 @@ minetest.register_node("mcl_nether:quartz_ore", { stack_max = 64, tiles = {"mcl_nether_quartz_ore.png"}, is_ground_content = true, - groups = {pickaxey=1, building_block=1, material_stone=1}, + groups = {pickaxey=1, building_block=1, material_stone=1, experience=3}, drop = 'mcl_nether:quartz', sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, diff --git a/mods/ITEMS/mcl_tools/enchanting.lua b/mods/ITEMS/mcl_tools/enchanting.lua new file mode 100644 index 0000000000..be01c18577 --- /dev/null +++ b/mods/ITEMS/mcl_tools/enchanting.lua @@ -0,0 +1,102 @@ +--[[ +swiftness - how fast you mine +hardness - allows the tool to go way above it's level +durable - makes the tool last longer +slippery - you drop the tool randomly +careful - "not silk touch" +fortune - drops extra items and experience +autorepair - tool will repair itself randomly +spiky - the tool will randomly hurt you when used +sharpness - the tool does more damage +]]-- +local S = minetest.get_translator("mcl_tools") + +local enchantment_list = {"swiftness", "durable", "careful", "fortune", "autorepair", "sharpness"} + +local hexer = {"a","b","c","d","e","f","1","2","3","4","5","6","7","8","9","0"} +minetest.register_node("mcl_tools:enchantingtable", { + description = S("Enchanting Table"), + tiles = {"mcl_core_bedrock.png"}, + groups = {wood = 1, pathable = 1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + minetest.after(0,function(clicker) + local stack = clicker:get_wielded_item() + + local meta = stack:get_meta() + + if meta:get_string("enchanted") == "true" then return end + + if not minetest.registered_tools[itemstack:get_name()] then return end + + local tool_caps = itemstack:get_tool_capabilities() + local groupcaps = tool_caps.groupcaps + + if not groupcaps then return end + + local able_enchantments = table.copy(enchantment_list) + + + local player_level = mcl_experience.get_player_xp_level(clicker) + + local enchants_available = math.floor(player_level/5) + local max_enchant_level = math.floor(player_level/5) + if enchants_available <= 0 then return end + if enchants_available > 3 then enchants_available = 3 end + local stock_name = minetest.registered_tools[stack:get_name()].name + local description = minetest.registered_tools[stack:get_name()].description + for i = 1,enchants_available do + local new_enchant = enchantment_list[math.random(1,table.getn(enchantment_list))] + local level = math.random(1,max_enchant_level) + if meta:get_int(new_enchant) == 0 then + player_level = player_level - 5 + meta:set_int(new_enchant, level) + description = description.."\n"..new_enchant:gsub("^%l", string.upper)..": "..tostring(level) + if new_enchant == "swiftness" then + for index,table in pairs(groupcaps) do + for index2,time in pairs(table.times) do + tool_caps["groupcaps"][index]["times"][index2] = time/(level+1) + end + end + end + if new_enchant == "durable" then + for index,table in pairs(groupcaps) do + tool_caps["groupcaps"][index]["uses"] = table.uses*(level+1) + end + end + + if new_enchant == "sharpness" then + for index,data in pairs(tool_caps.damage_groups) do + tool_caps.damage_groups[index] = data*(level+1) + end + end + end + end + + meta:set_string("description", S("Enchanted @1", description)) + meta:set_string("enchanted", "true") + meta:set_tool_capabilities(tool_caps) + + mcl_experience.set_player_xp_level(clicker,player_level) + + + --create truly random hex + local colorstring = "#" + for i = 1,6 do + colorstring = colorstring..hexer[math.random(1,16)] + end + stack = minetest.itemstring_with_color(stack, colorstring) + clicker:set_wielded_item(stack) + end,clicker) + end +}) + +minetest.register_craft({ + output = "mcl_tools:enchantingtable", + recipe = { + {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, + {"mcl_core:obsidian", "mcl_core:diamond", "mcl_core:obsidian"}, + {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, + }, +}) diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index f88ea8fa18..f0cea989a8 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -592,3 +592,4 @@ minetest.register_tool("mcl_tools:shears", { dofile(minetest.get_modpath("mcl_tools").."/crafting.lua") dofile(minetest.get_modpath("mcl_tools").."/aliases.lua") +dofile(minetest.get_modpath("mcl_tools").."/enchanting.lua") diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.de.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.de.tr index 6c061dd00f..96bf565f72 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.de.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.de.tr @@ -30,3 +30,5 @@ Iron Sword=Eisenschwert Golden Sword=Goldschwert Diamond Sword=Diamantschwert Shears=Schere +Enchanted @1= +Enchanting Table= diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.es.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.es.tr index 40b1d709bc..da16cbd29d 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.es.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.es.tr @@ -30,3 +30,5 @@ Iron Sword=Espada de hierro Golden Sword=Espada de oro Diamond Sword=Espada de diamante Shears=Tijeras +Enchanted @1= +Enchanting Table= diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr index 02cd7f2bd6..f5fb7a9482 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr @@ -30,3 +30,5 @@ Iron Sword=Épée en Fer Golden Sword=Épée en Or Diamond Sword=Épée en Diamant Shears=Cisailles +Enchanted @1= +Enchanting Table= diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr index e82fa15ef0..4eb721d6c2 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr @@ -30,3 +30,5 @@ Iron Sword=Железный меч Golden Sword=Золотой меч Diamond Sword=Алмазный меч Shears=Ножницы +Enchanted @1=@1 зачарованный(ая) +Enchanting Table=Волшебный стол diff --git a/mods/ITEMS/mcl_tools/locale/template.txt b/mods/ITEMS/mcl_tools/locale/template.txt index ecb94105f3..e083813243 100644 --- a/mods/ITEMS/mcl_tools/locale/template.txt +++ b/mods/ITEMS/mcl_tools/locale/template.txt @@ -30,3 +30,5 @@ Iron Sword= Golden Sword= Diamond Sword= Shears= +Enchanted @1= +Enchanting Table=