diff --git a/craft.JPG b/craft.JPG new file mode 100644 index 0000000..133d4c0 Binary files /dev/null and b/craft.JPG differ diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..6b84a10 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +Chakram: weapon & tool at same time \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..7df457a --- /dev/null +++ b/init.lua @@ -0,0 +1,72 @@ +dofile(minetest.get_modpath("chakram") .. "/wood.lua") +dofile(minetest.get_modpath("chakram") .. "/steel.lua") +dofile(minetest.get_modpath("chakram") .. "/mese.lua") +pvp=minetest.setting_getbool("enable_pvp") +chakramshot_user="" +chakramshot_user_name="" +chakram_shot_chakram={} +chakram_max_number=10 + +function chakram_max(add) + local c=0 + for i in pairs(chakram_shot_chakram) do + c=c+1 + if chakram_shot_chakram[i]:get_pos()==nil then + table.remove(chakram_shot_chakram,c) + c=c-1 + end + end + if c+1>chakram_max_number then return false end + if add then + table.insert(chakram_shot_chakram,add) + return true + end + return true +end + +function chakram_def(pos,def) + local n=minetest.registered_nodes[minetest.get_node(pos).name] + return n and n[def] +end + +minetest.register_craft({ + output = "chakram:chakram", + recipe = { + {"default:steel_ingot","","default:steel_ingot"}, + {"","default:steelblock",""}, + {"default:steel_ingot","","default:steel_ingot"}, + } +}) + +minetest.register_craft({ + output = "chakram:chakram_mese", + recipe = { + {"default:mese_crystal","","default:mese_crystal"}, + {"","default:mese",""}, + {"default:mese_crystal","","default:mese_crystal"}, + } +}) + +minetest.register_craft({ + output = "chakram:chakram_wood", + recipe = { + {"default:stick","","default:stick"}, + {"","group:wood",""}, + {"default:stick","","default:stick"}, + } +}) +function chakram_drops(name) + local d=minetest.registered_nodes[name].drop + if d=="" or d==nil then return name end + if d.items then + if d.items[1].items and d.items[2] and d.items[2].items then + return d.items[math.random(1,2)].items[1] + end + if d.items[1].items then + return d.items[1].items[1] + end + return name + end + return d +end + diff --git a/mese.lua b/mese.lua new file mode 100644 index 0000000..2d98727 --- /dev/null +++ b/mese.lua @@ -0,0 +1,185 @@ +minetest.register_tool("chakram:chakram_mese", { + description = "Chakram Mese", + range = 1, + inventory_image = "chakram_chakram_m.png", +on_use=function(itemstack, user, pointed_thing) + if chakram_max()==false or type(user)=="table" then + minetest.chat_send_player(user:get_player_name(), "Too many chakrams: (max " .. chakram_max_number .. ")") + return itemstack + end + local pos=user:get_pos() + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 5)) do + if ob:get_luaentity() and ob:get_luaentity().name=="chakram:chakr_m" then + return itemstack + end + end + chakramshot_user=user + chakramshot_user_name=user:get_player_name() + local dir = user:get_look_dir() + local veloc=15 + pos.y=pos.y+1.5 + local m=minetest.add_entity(pos, "chakram:chakr_m") + chakram_max(m) + m:setvelocity({x=dir.x*veloc, y=dir.y*veloc, z=dir.z*veloc}) + m:setyaw(user:get_look_yaw()+math.pi) + itemstack:take_item() + minetest.sound_play("chakram_throw", {pos=pos, gain = 1.0, max_hear_distance = 5,}) + return itemstack +end, +}) + +minetest.register_entity("chakram:chakr_m",{ + hp_max = 999, + physical = false, + weight = 0, + visual="cube", + visual_size = {x=1, y=0.04}, + textures = {"chakram_chakram_m.png","chakram_chakram_m.png","chakram_light.png","chakram_chakram_m.png","chakram_chakram_m.png","chakram_chakram_m.png"}, + colors = {}, + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=1, y=1}, + is_visible = true, + makes_footstep_sound = false, + automatic_rotate = math.pi* 4, + timer = 0, + timer2 = 0, + timer3 = 0, + stuck = 0, + user={}, + user_name="", + opos={x=0,y=0,z=0}, + chakram_m=1, + on_activate=function(self, staticdata) + if chakramshot_user_name=="" then + minetest.add_item(self.object:get_pos(), "chakram:chakram_mese") + self.object:remove() + return false + end + self.user=chakramshot_user + self.user_name=chakramshot_user_name + chakramshot_user_name="" + chakramshot_user="" + end, + on_step = function(self, dtime) + self.timer=self.timer+dtime + if self.timer<0.05 then return self end + self.timer3=self.timer3+self.timer + + if self.user==nil then + self.timer3=10 + self.stuck=1 + end + + if self.timer3>=2 then + if self.stuck==1 then + minetest.add_item(self.object:get_pos(), "chakram:chakram_mese") + if self.ob then self.ob:set_detach() self.ob:setacceleration({x=0,y=-8,z=0}) end + self.object:remove() + return + else + self.timer3=-4 + self.stuck=1 + end + end + self.timer=0 + self.timer2=self.timer2+dtime + self.object:set_hp(999) + local pos=self.object:get_pos() + local name=minetest.get_node(pos).name + if name~="air" and (minetest.get_node_group(name, "snappy")>0 or minetest.get_node_group(name, "dig_immediate")>0 or minetest.get_node_group(name, "oddly_breakable_by_hand")>0 or minetest.get_node_group(name, "cracky")>0 ) and minetest.is_protected(pos,self.user:get_player_name())==false then + local meta=minetest.get_meta(pos) + if meta and meta:get_string("infotext")~="" then return self end + minetest.add_item(pos, chakram_drops(name)) + minetest.set_node(pos, {name="air"}) + + if name=="air" or minetest.get_node(self.opos).name=="air" then + minetest.set_node(pos, {name="chakram:light"}) + minetest.get_node_timer(pos):start(0.2) + end + + elseif chakram_def(pos,"walkable") then + self.timer3=-4 + self.stuck=1 + end + + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if ob:get_hp()<10 and (not ob:get_attach()) and ob:get_luaentity() and (not ob:get_luaentity().chakram_m) then + self.stuck=1 + self.ob=ob + ob:set_attach(self.object, "", {x=0,y=0,z=0}, {x=0,y=0,z=0}) + self.timer3=-4 + break + end + + if (not ob:get_attach()) and ((ob:get_luaentity() and (not ob:get_luaentity().itemstring) and (not ob:get_luaentity().chakram_m)) or ((not ob:get_luaentity()) and ob:get_player_name()~=self.user_name and pvp)) then + ob:set_hp(ob:get_hp()-10) + ob:punch(self.user,10,{full_punch_interval=1,damage_groups={fleshy=4}}) + minetest.sound_play("chakram_hard_punch", {pos=ob:get_pos(), gain = 1.0, max_hear_distance = 5,}) + end + end + if self.stuck==1 then + if self.user==nil or self.user:get_pos()==nil then + self.timer3=10 + self.stuck=1 + return + end + local ta=self.user:get_pos() + ta.y=ta.y+1 + local vec = {x = pos.x - ta.x, y = pos.y - ta.y, z = pos.z - ta.z} + local amount = (vec.x ^ 2 + vec.y ^ 2 + vec.z ^ 2) ^ 0.5 + local v = -15 + vec.x = vec.x * v / amount + vec.y = vec.y * v / amount + vec.z = vec.z * v / amount + self.object:setvelocity(vec) + + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if (not ob:get_luaentity()) and ob:get_player_name()==self.user_name then + if self.object==nil or self.user==nil or self.user:get_pos()==nil then + self.timer3=10 + self.stuck=1 + return + end + if self.ob and self.ob:get_attach() and self.ob:get_hp()~=nil and self.ob:get_hp()>0 then + self.ob:set_detach() + self.ob:set_hp(0) + self.ob:punch(self.user,1000,{full_punch_interval=1,damage_groups={fleshy=1000}}) + end + if self.object:get_attach() then self.object:set_detach() return false end + if self.ob and self.ob==nil then return false end + self.user:get_inventory():add_item("main", ItemStack("chakram:chakram_mese")) + self.object:set_hp(0) + self.object:punch(self.object,10,{full_punch_interval=1,damage_groups={fleshy=4}}) + break + end + end + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 3)) do + if ob:get_luaentity() and (not ob:get_attach()) and ob:get_luaentity().itemstring and ob:get_luaentity().itemstring~="chakram:chakram_mese" then + ob:punch(self.user,10,{full_punch_interval=1,damage_groups={fleshy=4}}) + end + end + end + self.opos=self.object:get_pos() + end, +}) + +minetest.register_node("chakram:light", { + description = "Light", + tiles = {"chakram_light.png",}, + drop="", + light_source = 10, + paramtype = "light", + alpha = 50, + walkable=false, + drawtype = "airlike", + sunlight_propagates = false, + pointable = false, + buildable_to = true, + groups = {not_in_creative_inventory=1}, + can_dig = function(pos, player) + return false + end, + on_timer=function (pos, elapsed) + minetest.remove_node(pos) + end, +}) diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..e3ab7b5 --- /dev/null +++ b/readme.txt @@ -0,0 +1,29 @@ +License: CC0 + +Version: 4.2 + +The tool is a weapon at same time +Throw it and it will always return as long there still is velocity/power left +It can pick up stuff that is breakable by hand (like no use by tools) and mobs/drops that have 10hp or less. +Players (or mobs that have more then 10 hp) will be hurted. + +Craft: Wood: +S = Stick +w = Wood +[S] [ ] [S] +[ ] [w] [ ] +[S] [ ] [S] + +Craft: Steel: +S = Steel ingot +B = Steel block +[S] [ ] [S] +[ ] [B] [ ] +[S] [ ] [S] + +Craft: Mese: +C = Mese crystal +B = Mese block +[C] [ ] [C] +[ ] [B] [ ] +[C] [ ] [C] \ No newline at end of file diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..f1f2022 Binary files /dev/null and b/screenshot.png differ diff --git a/sounds/chakram_hard_punch.ogg b/sounds/chakram_hard_punch.ogg new file mode 100644 index 0000000..b6740df Binary files /dev/null and b/sounds/chakram_hard_punch.ogg differ diff --git a/sounds/chakram_throw.ogg b/sounds/chakram_throw.ogg new file mode 100644 index 0000000..6f58f80 Binary files /dev/null and b/sounds/chakram_throw.ogg differ diff --git a/steel.lua b/steel.lua new file mode 100644 index 0000000..fece3b1 --- /dev/null +++ b/steel.lua @@ -0,0 +1,174 @@ +minetest.register_tool("chakram:chakram", { + description = "Chakram", + range = 1, + inventory_image = "chakram_chakram.png", +on_use=function(itemstack, user, pointed_thing) + if chakram_max()==false or type(user)=="table" then + minetest.chat_send_player(user:get_player_name(), "Too many chakrams: (max " .. chakram_max_number .. ")") + return itemstack + end + local pos=user:get_pos() + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 5)) do + if ob:get_luaentity() and ob:get_luaentity().name=="chakram:chakr" then + return itemstack + end + end + chakramshot_user=user + chakramshot_user_name=user:get_player_name() + local dir = user:get_look_dir() + local veloc=15 + pos.y=pos.y+1.5 + local m=minetest.add_entity(pos, "chakram:chakr") + chakram_max(m) + m:setvelocity({x=dir.x*veloc, y=dir.y*veloc, z=dir.z*veloc}) + m:setyaw(user:get_look_yaw()+math.pi) + itemstack:take_item() + minetest.sound_play("chakram_throw", {pos=pos, gain = 1.0, max_hear_distance = 5,}) + return itemstack +end, +}) + +minetest.register_entity("chakram:chakr",{ + hp_max = 999, + physical = false, + weight = 0, + visual="cube", + visual_size = {x=1, y=0.04}, + textures = {"chakram_chakram.png","chakram_chakram.png","chakram_light.png","chakram_light.png","chakram_light.png","chakram_light.png"}, + colors = {}, + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=1, y=1}, + is_visible = true, + makes_footstep_sound = false, + automatic_rotate = math.pi * 4, + timer = 0, + timer2 = 0, + timer3 = 0, + stuck = 0, + user={}, + user_name="", + chakram_s=1, +on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir) + if puncher:get_luaentity() or (puncher:get_player_name()~=self.user_name) then + self.timer3=-2 + self.stuck=1 + end + end, + on_activate=function(self, staticdata) + if chakramshot_user=="" then + minetest.add_item(self.object:get_pos(), "chakram:chakram") + self.object:remove() + return false + end + self.user=chakramshot_user + self.user_name=chakramshot_user_name + chakramshot_user_name="" + chakramshot_user="" + end, + on_step = function(self, dtime) + self.timer=self.timer+dtime + if self.timer<0.05 then return self end + self.timer3=self.timer3+self.timer + + if self.user==nil then + self.timer3=10 + self.stuck=1 + end + + + if self.timer3>=2 then + if self.stuck==1 then + minetest.add_item(self.object:get_pos(), "chakram:chakram") + if self.ob then self.ob:set_detach() self.ob:setacceleration({x=0,y=-8,z=0}) end + self.object:set_hp(0) + self.object:punch(self.object,10,{full_punch_interval=1,damage_groups={fleshy=4}}) + return + else + self.timer3=-2 + self.stuck=1 + end + end + self.timer=0 + self.timer2=self.timer2+dtime + self.object:set_hp(999) + local pos=self.object:get_pos() + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if ob:get_hp()<10 and (not ob:get_attach()) and ob:get_luaentity() and (not ob:get_luaentity().chakram_s) then + self.stuck=1 + self.ob=ob + ob:set_attach(self.object, "", {x=0,y=0,z=0}, {x=0,y=0,z=0}) + self.timer3=-2 + break + end + if self.stuck==0 then + if (ob:get_luaentity() and (not ob:get_luaentity().chakram_s) and (not ob:get_luaentity().itemstring) ) or ((not ob:get_luaentity()) and ob:get_player_name()~=self.user_name and pvp) then + ob:punch(self.user,5,{full_punch_interval=1,damage_groups={fleshy=4}}) + minetest.sound_play("chakram_hard_punch", {pos=ob:get_pos(), gain = 1.0, max_hear_distance = 5,}) + end + end + end + + if self.stuck==0 then + local name=minetest.get_node(pos).name + if name~="air" and (minetest.get_node_group(name, "snappy")>0 or minetest.get_node_group(name, "dig_immediate")>0 or minetest.get_node_group(name, "oddly_breakable_by_hand")>0) and minetest.is_protected(pos,self.user:get_player_name())==false then + + local meta=minetest.get_meta(pos) + if meta and meta:get_string("infotext")~="" then return self end + minetest.add_item(pos, chakram_drops(name)) + minetest.set_node(pos, {name="air"}) + elseif chakram_def(pos,"walkable") then + self.timer3=-2 + self.stuck=1 + end + + else + + if self.user==nil or self.user:get_pos()==nil then + self.timer3=10 + self.stuck=1 + return + end + + + local ta=self.user:get_pos() + ta.y=ta.y+1 + local vec = {x = pos.x - ta.x, y = pos.y - ta.y, z = pos.z - ta.z} + local amount = (vec.x ^ 2 + vec.y ^ 2 + vec.z ^ 2) ^ 0.5 + local v = -15 + vec.x = vec.x * v / amount + vec.y = vec.y * v / amount + vec.z = vec.z * v / amount + self.object:setvelocity(vec) + + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if (not ob:get_attach()) and ((ob:get_luaentity() and (not ob:get_luaentity().itemstring) and (not ob:get_luaentity().chakram_s)) or ((not ob:get_luaentity()) and ob:get_player_name()~=self.user_name and pvp)) then + ob:punch(self.user,15,{full_punch_interval=1,damage_groups={fleshy=4}}) + minetest.sound_play("chakram_hard_punch", {pos=ob:get_pos(), gain = 1.0, max_hear_distance = 5,}) + end + + if (not ob:get_luaentity()) and ob:get_player_name()==self.user_name then + + if self.user==nil or self.user:get_pos()==nil then + self.timer3=10 + self.stuck=1 + return + end + + if self.ob and self.ob:get_attach() and self.ob:get_hp()>0 then + self.ob:set_detach() + self.ob:set_hp(0) + self.ob:punch(self.user,1000,{full_punch_interval=1,damage_groups={fleshy=4}}) + end + if self.object:get_attach() then self.object:set_detach() return false end + self.user:get_inventory():add_item("main", ItemStack("chakram:chakram")) + self.object:remove() + end + end + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 3)) do + if ob:get_luaentity() and (not ob:get_attach()) and ob:get_luaentity().itemstring and ob:get_luaentity().itemstring~="chakram:chakram" then + ob:punch(self.user,5,{full_punch_interval=1,damage_groups={fleshy=4}}) + end + end + end + end, +}) \ No newline at end of file diff --git a/textures/chakram_chakram.png b/textures/chakram_chakram.png new file mode 100644 index 0000000..6e21f69 Binary files /dev/null and b/textures/chakram_chakram.png differ diff --git a/textures/chakram_chakram_m.png b/textures/chakram_chakram_m.png new file mode 100644 index 0000000..295e7e4 Binary files /dev/null and b/textures/chakram_chakram_m.png differ diff --git a/textures/chakram_chakram_w.png b/textures/chakram_chakram_w.png new file mode 100644 index 0000000..f2ec07c Binary files /dev/null and b/textures/chakram_chakram_w.png differ diff --git a/textures/chakram_light.png b/textures/chakram_light.png new file mode 100644 index 0000000..f93999f Binary files /dev/null and b/textures/chakram_light.png differ diff --git a/wood.lua b/wood.lua new file mode 100644 index 0000000..33d686f --- /dev/null +++ b/wood.lua @@ -0,0 +1,145 @@ +minetest.register_tool("chakram:chakram_wood", { + description = "Wooden Chakram", + range = 1, + inventory_image = "chakram_chakram_w.png", +on_use=function(itemstack, user, pointed_thing) + if chakram_max()==false or type(user)=="table" then + minetest.chat_send_player(user:get_player_name(), "Too many chakrams: (max " .. chakram_max_number .. ")") + return itemstack + end + local pos=user:get_pos() + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 5)) do + if ob:get_luaentity() and ob:get_luaentity().name=="chakram:chakramr_w" then + return itemstack + end + end + + chakramshot_user=user + chakramshot_user_name=user:get_player_name() + local dir = user:get_look_dir() + local veloc=15 + pos.y=pos.y+1.5 + local m=minetest.add_entity(pos, "chakram:chakr_w") + chakram_max(m) + m:setvelocity({x=dir.x*veloc, y=dir.y*veloc, z=dir.z*veloc}) + m:setyaw(user:get_look_yaw()+math.pi) + itemstack:take_item() + minetest.sound_play("chakram_throw", {pos=pos, gain = 1.0, max_hear_distance = 5,}) + return itemstack +end, +}) + +minetest.register_entity("chakram:chakr_w",{ + hp_max = 999, + physical = false, + weight = 0, + visual="cube", + visual_size = {x=1, y=0.04}, + textures = {"chakram_chakram_w.png","chakram_chakram_w.png","chakram_light.png","chakram_light.png","chakram_light.png","chakram_light.png"}, + colors = {}, + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=1, y=1}, + is_visible = true, + makes_footstep_sound = false, + automatic_rotate = math.pi * 4, + timer = 0, + timer2 = 0, + timer3 = 0, + stuck = 0, + user={}, + user_name="", + opos={x=0,z=0,y=0}, + chakram_w=1, +on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir) + if puncher:get_luaentity() or (puncher:get_player_name()~=self.user_name) then + minetest.add_item(self.object:get_pos(), "chakram:chakram_wood") + self.object:remove() + end + end, + on_activate=function(self, staticdata) + if chakramshot_user_name=="" then + minetest.add_item(self.object:get_pos(), "chakram:chakram_wood") + self.object:remove() + return false + end + self.user=chakramshot_user + self.user_name=chakramshot_user_name + chakramshot_user_name="" + chakramshot_user="" + end, + on_step = function(self, dtime) + self.timer=self.timer+dtime + if self.timer<0.05 then return self end + self.timer3=self.timer3+self.timer + + if self.user==nil then + self.timer3=10 + self.stuck=1 + end + + + if self.timer3>=2 then + if self.stuck==1 then + minetest.add_item(self.object:get_pos(), "chakram:chakram_wood") + self.object:remove() + return + else + self.timer3=-2 + self.stuck=1 + end + end + self.timer=0 + self.timer2=self.timer2+dtime + self.object:set_hp(999) + local pos=self.object:get_pos() + local name=minetest.get_node(pos).name + if name~="air" and (minetest.get_node_group(name, "snappy")>0 or minetest.get_node_group(name, "dig_immediate")>0) and minetest.is_protected(pos,self.user:get_player_name())==false then + local meta=minetest.get_meta(pos) + if meta and meta:get_string("infotext")~="" then return self end + + minetest.add_item(pos, chakram_drops(name)) + minetest.set_node(pos, {name="air"}) + elseif chakram_def(pos,"walkable") then + minetest.add_item(self.opos, "chakram:chakram_wood") + self.object:remove() + return false + end + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if (not ob:get_attach()) and (ob:get_luaentity() and (not ob:get_luaentity().chakram_w) and (not ob:get_luaentity().itemstring)) or ((not ob:get_luaentity()) and ob:get_player_name()~=self.user_name and pvp) then + ob:punch(self.user,2,{full_punch_interval=1,damage_groups={fleshy=4}}) + minetest.sound_play("chakram_hard_punch", {pos=ob:get_pos(), gain = 1.0, max_hear_distance = 5,}) + end + end + if self.stuck==0 then + else + if self.user==nil or self.user:get_pos()==nil then + self.timer3=10 + self.stuck=1 + return + end + local ta=self.user:get_pos() + ta.y=ta.y+1 + local vec = {x = pos.x - ta.x, y = pos.y - ta.y, z = pos.z - ta.z} + local amount = (vec.x ^ 2 + vec.y ^ 2 + vec.z ^ 2) ^ 0.5 + local v = -15 + vec.x = vec.x * v / amount + vec.y = vec.y * v / amount + vec.z = vec.z * v / amount + self.object:setvelocity(vec) + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if (not ob:get_luaentity()) and ob:get_player_name()==self.user_name then + if self.object==nil or self.user==nil or self.user:get_pos()==nil then + self.timer3=10 + self.stuck=1 + return + end + + if self.object:get_attach() then self.object:set_detach() return false end + self.user:get_inventory():add_item("main", ItemStack("chakram:chakram_wood")) + self.object:remove() + end + end + end + self.opos=pos + end, +}) \ No newline at end of file