-- -- Init -- dofile(minetest.get_modpath("obsidianmese").."/api.lua") dofile(minetest.get_modpath("obsidianmese").."/obsidianmese_chest.lua") -- -- Tools -- -- sword - mese minetest.register_tool("obsidianmese:sword", { description = "Obsidian Mese Sword", inventory_image = "obsidianmese_sword.png", tool_capabilities = { full_punch_interval = 0.45, max_drop_level=1, groupcaps={ fleshy={times={[1]=2.00, [2]=0.65, [3]=0.25}, uses=400, maxlevel=3}, snappy={times={[1]=1.90, [2]=0.70, [3]=0.25}, uses=350, maxlevel=3}, choppy={times={[3]=0.65}, uses=300, maxlevel=0} }, damage_groups = {fleshy=8}, sound = {breaks = "default_tool_breaks"}, } }) -- sword - balrog boss -- minetest.register_tool("obsidianmese:sword_balrog_boss", { -- description = "Balrog Boss Sword", -- inventory_image = "obsidianmese_sword_balrog_boss.png", -- tool_capabilities = { -- full_punch_interval = 3, -- max_drop_level=1, -- groupcaps={ -- snappy={times={[1]=3.80, [2]=1.80, [3]=0.60}, uses=20, maxlevel=3}, -- }, -- -- wield_scale = {x=2.5, y=3, z=2}, -- damage_groups = {fleshy=200}, -- sound = {breaks = "default_tool_breaks"}, -- } -- }) -- sword - engraved -- check if within physical map limits (-30911 to 30927) local fired_table = {} local within_limits = function(pos, radius) if (pos.x - radius) > -30913 and (pos.x + radius) < 30928 and (pos.y - radius) > -30913 and (pos.y + radius) < 30928 and (pos.z - radius) > -30913 and (pos.z + radius) < 30928 then return true -- within limits end return false -- beyond limits end local sync_table = function(owner) if fired_table[owner] ~= nil then fired_table[owner] = fired_table[owner] - 1 print(minetest.serialize(fired_table)) end end minetest.register_entity("obsidianmese:sword_bullet", { physical = false, visual = "sprite", visual_size = { x = 1, y = 1 }, textures = { "obsidianmese_shard.png" }, collisionbox = {0.25, 0.25, 0.25, -0.25, -0.25, -0.25}, timer = 0, speed = 8, owner = "", twowillremove = 0, on_activate = function(self, staticdata, dtime_s) self.object:set_armor_groups({ immortal = 1 }) end, get_staticdata = function(self) self.twowillremove = self.twowillremove + 1 print("self.twowillremove: "..self.twowillremove) if self.twowillremove >= 2 then self.object:remove() sync_table(self.owner) return "object was removed" end return "object is alive" end, on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir) if time_from_last_punch < 0.5 then return end local name = puncher:get_player_name() local pos = self.object:getpos() local v = math.random(1, 8) local velocity = dir velocity.x = velocity.x * v velocity.y = velocity.y * v velocity.z = velocity.z * v self.object:setvelocity(velocity) end, on_step = function(self, dtime) local pos = self.object:getpos() local node = minetest.get_node_or_nil(pos) self.timer = self.timer + 1 print(self.owner.." : "..self.timer) if self.timer > 50 or not within_limits(pos, 0) or self.owner == "" then sync_table(self.owner) self.object:remove() return end -- hit node if node and minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].walkable then sync_table(self.owner) self.object:remove() return end -- hit player or mob for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do if player:is_player() then player:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 8}, }, nil) sync_table(self.owner) self.object:remove() return end local entity = player:get_luaentity() if entity and entity._cmi_is_mob == true and entity.name ~= self.object:get_luaentity().name then player:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 8}, }, nil) sync_table(self.owner) self.object:remove() return end end self.lastpos = pos end }) function fire_sword(itemstack, user, pointed_thing) local speed = 8 local pos = user:getpos() local v = user:get_look_dir() local player_name = user:get_player_name() if fired_table[player_name] ~= nil then if fired_table[player_name] >= 1 then minetest.chat_send_player(player_name, "You can shoot 1 shot at the same time!") return else fired_table[player_name] = fired_table[player_name] + 1 end else fired_table[player_name] = 1 end print(minetest.serialize(fired_table)) pos.x = pos.x + v.x pos.z = pos.z + v.z if v.y > 0.4 or v.y < -0.4 then pos.y = pos.y + v.y else pos.y = pos.y + 1 end -- play shoot attack sound minetest.sound_play("throwing_sound", { pos = pos, gain = 1.0, -- default max_hear_distance = 32, -- default, uses an euclidean metric }) local obj = minetest.add_entity(pos, "obsidianmese:sword_bullet") local ent = obj:get_luaentity() if ent then ent.owner = player_name or "" v.x = v.x * speed v.y = v.y * speed v.z = v.z * speed obj:setvelocity(v) end -- wear tool local wdef = itemstack:get_definition() itemstack:add_wear(65535 / (150 - 1)) -- Tool break sound if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then minetest.sound_play(wdef.sound.breaks, {pos = pointed_thing.above, gain = 0.5}) end return itemstack end minetest.register_tool("obsidianmese:sword_engraved", { description = "Obsidian Mese Sword Engraved - right click shoot 1 shot", inventory_image = "obsidianmese_sword_diamond_engraved.png", tool_capabilities = { full_punch_interval = 0.6, max_drop_level=1, groupcaps={ snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=300, maxlevel=3}, }, damage_groups = {fleshy=8}, sound = {breaks = "default_tool_breaks"}, }, on_secondary_use = function(itemstack, user, pointed_thing) if user:get_player_control().RMB then return fire_sword(itemstack, user, pointed_thing) end end }) -- pick axe minetest.register_tool("obsidianmese:pick", { description = "Obsidian Mese Pickaxe", inventory_image = "obsidianmese_pick.png", tool_capabilities = { full_punch_interval = 0.9, max_drop_level=3, groupcaps={ cracky={times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=250, maxlevel=3}, crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=350, maxlevel=3}, snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=300, maxlevel=3} }, damage_groups = {fleshy=5}, sound = {breaks = "default_tool_breaks"}, }, }) -- pick axe engraved -- prevent pick axe engraved of placing item when clicken on one of the items from this list pick_engraved_place_blacklist = { ["xdecor:itemframe"] = true } function pick_engraved_place_add_wear(itemstack) -- wear tool local wdef = itemstack:get_definition() itemstack:add_wear(65535 / (400 - 1)) -- Tool break sound if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then minetest.sound_play(wdef.sound.breaks, {pos = pointed_thing.above, gain = 0.5}) end return itemstack end function pick_engraved_place(itemstack, placer, pointed_thing) local idx = placer:get_wield_index() + 1 -- item to right of wielded tool local inv = placer:get_inventory() local stack = inv:get_stack("main", idx) -- stack to right of tool local stack_name = stack:get_name() local under = pointed_thing.under local above = pointed_thing.above local node_under = minetest.get_node(under) local udef = {} local temp_stack = "" -- handle objects/lua entitties if pointed_thing.type == "object" then local obj = pointed_thing.ref local name = obj:get_luaentity().name -- print("object_name: "..name) -- do something here end -- handle nodes if pointed_thing.type == "node" then local pos = minetest.get_pointed_thing_position(pointed_thing) local pointed_node = minetest.get_node_or_nil(pos) -- check if have to use default on_place first if pick_engraved_place_blacklist[pointed_node.name] ~= nil then -- print("minetest.item_place") return minetest.item_place(itemstack, placer, pointed_thing) end if pointed_node ~= nil and stack_name ~= "" then local stack_def = minetest.registered_nodes[stack_name] local stack_name_split = string.split(stack_name, ":") local stack_mod = stack_name_split[1] -- print("pointed_thing: "..pointed_node.name) -- print("stack_name: "..stack_name) -- print("stack_mod: "..stack_mod) udef = minetest.registered_nodes[stack_name] -- not for farming - that should be part of a hoe if stack_mod ~= "farming" or stack_mod ~= "farming_addons" then if udef and udef.on_place then temp_stack = udef.on_place(stack, placer, pointed_thing) or stack inv:set_stack("main", idx, temp_stack) -- itemstack = pick_engraved_place_add_wear(itemstack) return itemstack elseif udef and udef.on_use then temp_stack = udef.on_use(stack, placer, pointed_thing) or stack inv:set_stack("main", idx, temp_stack) -- itemstack = pick_engraved_place_add_wear(itemstack) return itemstack end end -- handle farming and farming_addons placement -- if stack_mod == "farming" or stack_mod == "farming_addons" then -- print("farming.place_seed") -- udef = minetest.registered_nodes[stack_name] -- if udef and udef.on_place then -- temp_stack = udef.on_place(stack, placer, pointed_thing) or stack -- elseif udef and udef.on_use then -- temp_stack = udef.on_use(stack, placer, pointed_thing) or stack -- end -- inv:set_stack("main", idx, temp_stack) -- itemstack = pick_engraved_place_add_wear(itemstack) -- return itemstack -- end -- handle default stairs placement -- if stack_mod == "stairs" then -- print("place stairs") -- udef = minetest.registered_nodes[stack_name] -- if udef and udef.on_place then -- temp_stack = udef.on_place(stack, placer, pointed_thing) or stack -- end -- inv:set_stack("main", idx, temp_stack) -- itemstack = pick_engraved_place_add_wear(itemstack) -- return itemstack -- end -- handle default torch placement if stack_name == "default:torch" then local wdir = minetest.dir_to_wallmounted(vector.subtract(under, above)) local fakestack = stack if wdir == 0 then fakestack:set_name("default:torch_ceiling") elseif wdir == 1 then fakestack:set_name("default:torch") else fakestack:set_name("default:torch_wall") end temp_stack = minetest.item_place(fakestack, placer, pointed_thing, wdir) temp_stack:set_name("default:torch") inv:set_stack("main", idx, temp_stack) -- itemstack = pick_engraved_place_add_wear(itemstack) return itemstack end end -- if everything else fails use default on_place stack = minetest.item_place(stack, placer, pointed_thing) inv:set_stack("main", idx, stack) return itemstack end end minetest.register_tool("obsidianmese:pick_engraved", { description = "Obsidian Mese Pickaxe Engraved - right click to place item next to the pickaxe in your inventory slot", inventory_image = "obsidianmese_pick_engraved.png", tool_capabilities = { full_punch_interval = 0.9, max_drop_level=3, groupcaps={ cracky={times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=200, maxlevel=3} }, damage_groups = {fleshy=5}, sound = {breaks = "default_tool_breaks"}, }, on_place = pick_engraved_place }) -- -- ObsiadianMese Shovel -- minetest.register_tool("obsidianmese:shovel", { description = "ObsidianMese Shovel", inventory_image = "obsidianmese_shovel.png", wield_image = "obsidianmese_shovel.png^[transformR90", wield_scale = {x=1.5, y=1.5, z=1.5}, tool_capabilities = { full_punch_interval = 0.9, max_drop_level=1, groupcaps={ crumbly = {times={[1]=1.10, [2]=0.50, [3]=0.30}, uses=50, maxlevel=3}, }, damage_groups = {fleshy=4}, }, sound = {breaks = "default_tool_breaks"}, on_place = function(itemstack, placer, pointed_thing) local pt = pointed_thing -- check if pointing at a node if not pt then return end if pt.type ~= "node" then return end local under = minetest.get_node(pt.under) local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z} local above = minetest.get_node(p) -- return if any of the nodes is not registered if not minetest.registered_nodes[under.name] then return end if not minetest.registered_nodes[above.name] then return end -- check if the node above the pointed thing is air if above.name ~= "air" then return end if minetest.is_protected(pt.under, placer:get_player_name()) then minetest.record_protection_violation(pt.under, placer:get_player_name()) return end -- check on what we are pointing -- dirt path if under.name == "default:dirt" and under.name ~= "obsidianmese:dirt_path" then -- print("set_node DIRT path") minetest.set_node(pt.under, {name = "obsidianmese:path_dirt"}) -- grass path elseif (under.name == "default:dirt" or under.name == "default:dirt_with_grass" or under.name == "default:dirt_with_grass_footsteps" or under.name == "default:dirt_with_dry_grass" or under.name == "default:dirt_with_snow" or under.name == "default:dirt_with_rainforest_litter") and under.name ~= "obsidianmese:grass_path" then -- print("set_node GRASS path") minetest.set_node(pt.under, {name = "obsidianmese:path_grass"}) -- sand path elseif (under.name == "default:sand" or under.name == "default:desert_sand" or under.name == "default:silver_sand") and under.name ~= "obsidianmese:sand_path" then -- print("set_node SAND path") minetest.set_node(pt.under, {name = "obsidianmese:path_sand"}) else return end -- play sound minetest.sound_play("default_dig_crumbly", { pos = pt.under, gain = 0.5 }) -- add wear itemstack = pick_engraved_place_add_wear(itemstack) return itemstack end }) -- dirt path node minetest.register_node("obsidianmese:path_dirt", { description = "Dirt Path", drawtype = "nodebox", tiles = {"obsidianmese_dirt_path_top.png", "obsidianmese_dirt_path_top.png", "obsidianmese_dirt_path_side.png"}, node_box = { type = "fixed", fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2}, }, drop = "default:dirt", is_ground_content = false, groups = {crumbly = 3, not_in_creative_inventory = 1}, sounds = default.node_sound_dirt_defaults(), }) -- grass path node minetest.register_node("obsidianmese:path_grass", { description = "Grass Path", drawtype = "nodebox", tiles = {"obsidianmese_grass_path_top.png", "obsidianmese_dirt_path_top.png", "obsidianmese_dirt_path_side.png"}, node_box = { type = "fixed", fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2}, }, drop = "default:dirt", is_ground_content = false, groups = {crumbly = 3, not_in_creative_inventory = 1}, sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_grass_footstep", gain = 0.25}, }), }) -- sand path node minetest.register_node("obsidianmese:path_sand", { description = "Sand Path", drawtype = "nodebox", tiles = {"obsidianmese_sand_path_top.png", "obsidianmese_sand_path_top.png", "obsidianmese_sand_path_side.png"}, node_box = { type = "fixed", fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2}, }, drop = "default:desert_sand", groups = {crumbly = 3, falling_node = 1, not_in_creative_inventory = 1}, sounds = default.node_sound_sand_defaults(), }) -- -- Items -- -- apple minetest.register_craftitem("obsidianmese:mese_apple", { description = "Mese apple [restores full health]", inventory_image = "obsidianmese_apple.png", on_use = function(itemstack, user, pointed_thing) minetest.sound_play("apple_eat", { pos = user:getpos(), max_hear_distance = 32, gain = 0.5, }) user:set_hp(20) itemstack:take_item() return itemstack end }) -- -- Crafting -- minetest.register_craft({ output = "obsidianmese:sword", recipe = { {"", "default:mese_crystal", ""}, {"default:obsidian_shard", "default:mese_crystal", "default:obsidian_shard"}, {"", "default:obsidian_shard", ""}, } }) minetest.register_craft({ output = "obsidianmese:pick", recipe = { {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}, {"", "default:obsidian_shard", ""}, {"", "default:obsidian_shard", ""}, } }) minetest.register_craft({ output = "obsidianmese:shovel", recipe = { {"default:mese_crystal"}, {"default:obsidian_shard"}, {"default:obsidian_shard"}, } }) minetest.register_craft({ output = "obsidianmese:pick_engraved", recipe = { {"default:diamond", "default:diamond", "default:diamond"}, {"", "default:obsidian_shard", ""}, {"", "default:obsidian_shard", ""}, } }) minetest.register_craft({ output = "obsidianmese:mese_apple 4", recipe = { {"", "default:apple", ""}, {"default:apple","default:mese", "default:apple"}, {"", "default:apple", ""}, } }) print("[Mod] ObsidianMese Loaded.")