diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..d4fccc4 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +Craft living tools! \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..70decbd --- /dev/null +++ b/init.lua @@ -0,0 +1,394 @@ +livetools={tmp={},pvp=minetest.settings:get("enable_pvp")} + + +print(dump(livetools.pvp)) + +minetest.register_craftitem("livetools:obsidian_mix", {description = "Obsidian mix",inventory_image = "default_coal_lump.png^[colorize:#45770099",}) +minetest.register_craftitem("livetools:liveobsidian", {description = "Living obsidian crystal",inventory_image = "default_coal_lump.png^[colorize:#458833ff",}) + +minetest.register_craft({ + output = "livetools:hand", + recipe = { + {"default:stick", "livetools:liveobsidian", "default:stick"}, + {"", "default:stick", ""}, + {"", "", ""}, + } +}) + +minetest.register_craft({ + output = "livetools:sword", + recipe = { + {"", "livetools:liveobsidian", ""}, + {"", "livetools:liveobsidian", ""}, + {"", "default:stick", ""}, + } +}) + +minetest.register_craft({ + output = "livetools:pick", + recipe = { + {"livetools:liveobsidian", "livetools:liveobsidian", "livetools:liveobsidian"}, + {"", "default:stick", ""}, + {"", "default:stick", ""}, + } +}) + + +minetest.register_craft({ + output = "livetools:obsidian_mix", + recipe = { + {"default:mese_crystal_fragment", "default:obsidian", "default:mese_crystal_fragment"}, + {"default:obsidian", "default:diamond", "default:obsidian"}, + {"default:mese_crystal_fragment", "default:obsidian", "default:mese_crystal_fragment"}, + } +}) + +minetest.register_craft({ + type = "cooking", + output = "livetools:liveobsidian", + recipe = "livetools:obsidian_mix", +}) + + +livetools.def=function(pos,def) + local n=minetest.registered_nodes[minetest.get_node(pos).name] + return n and n[def] +end + +livetools.set_target=function(user,pointed_thing) + local p=user:get_pos() + p={x=p.x,y=p.y+1.5,z=p.z} + local dir = user:get_look_dir() + local tar=1 + local pos + local opos + if pointed_thing.type=="nothing" then + for i=1,15,1 do + opos=pos + pos={x=p.x+(dir.x*i), y=p.y+(dir.y*i), z=p.z+(dir.z*i)} + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if not (ob:is_player() and ob:get_player_name()==user:get_player_name()) then + if livetools.pvp==false and ob:is_player() then return true end + livetools.tmp.target=ob + livetools.tmp.type="attack" + tar=nil + break + end + end + if minetest.get_node(pos).name~="air" and livetools.def(pos,"drop") and minetest.registered_nodes[minetest.get_node(pos).name].drop~="" then + if livetools.tmp.type=="attack" then return true end + if livetools.tmp.type=="dig"then + livetools.tmp.target=pos + tar=nil + break + end + + if livetools.tmp.type=="place" then + if opos and livetools.def(pos,walkable) and livetools.def(pos,"buildable_to") + and minetest.is_protected(opos,user:get_player_name())==false then + livetools.tmp.target=opos + tar=nil + break + end + end + end + end + if tar then return true end + end + local e = minetest.add_entity({x=p.x+(dir.x*0.5),y=p.y+(dir.y*0.5)-0.5,z=p.z+(dir.z*0.5)},"livetools:tool") + e:setvelocity({x=dir.x*2, y=dir.y*2, z=dir.z*2}) + e:setacceleration({x=0, y=-5, z=0}) + return false +end + +minetest.register_tool("livetools:sword", { + description = "Liveing Sword", + range = 13, + inventory_image = "default_tool_diamondsword.png^[colorize:#8aff0055", + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type~="nothing" and pointed_thing.type~="object" then return itemstack end + if livetools.pvp==false and pointed_thing.type=="object" and pointed_thing.ref:is_player() then return itemstack end + livetools.tmp.target=pointed_thing.ref + livetools.tmp.item="livetools:sword" + livetools.tmp.user=user + livetools.tmp.type="attack" + livetools.tmp.dmg=4 + livetools.tmp.hp=20 + if livetools.set_target(user,pointed_thing) then return itemstack end + itemstack:take_item() + return itemstack + end +}) + +minetest.register_tool("livetools:hand", { + description = "Liveing Hand", + range = 13, + inventory_image = "wieldhand.png^[colorize:#458833ff", + on_use = function(itemstack, user, pointed_thing) + if livetools.pvp==false and pointed_thing.type=="object" and pointed_thing.ref:is_player() then return itemstack end + livetools.tmp.item="livetools:hand" + livetools.tmp.user=user + if pointed_thing.type=="object" then + livetools.tmp.type="attack" + livetools.tmp.target=pointed_thing.ref + else + local index=user:get_wield_index()-1 + local inv=user:get_inventory() + local stack=inv:get_stack("main", index) + if minetest.is_protected(pointed_thing.above,user:get_player_name()) or (not minetest.registered_nodes[stack:get_name()]) then return itemstack end + livetools.tmp.type="place" + livetools.tmp.target=pointed_thing.above + if livetools.def(pointed_thing.under,"buildable_to") and minetest.is_protected(pointed_thing.under,user:get_player_name())==false then + livetools.tmp.target=pointed_thing.under + elseif livetools.def(pointed_thing.above,"buildable_to ") and minetest.is_protected(pointed_thing.above,user:get_player_name())==false then + livetools.tmp.target=pointed_thing.above + end + end + + livetools.tmp.dmg=1 + livetools.tmp.hp=5 + if livetools.set_target(user,pointed_thing) then return itemstack end + itemstack:take_item() + return itemstack + end +}) + +minetest.register_tool("livetools:pick", { + description = "Liveing Pick", + range = 13, + inventory_image = "default_tool_diamondpick.png^[colorize:#8aff0055", + on_use = function(itemstack, user, pointed_thing) + if livetools.pvp==false and pointed_thing.type=="object" and pointed_thing.ref:is_player() then return itemstack end + + livetools.tmp.item="livetools:pick" + livetools.tmp.user=user + livetools.tmp.dmg=2 + livetools.tmp.hp=10 + + if pointed_thing.type=="object" then + livetools.tmp.type="attack" + livetools.tmp.target=pointed_thing.ref + else + livetools.tmp.type="dig" + livetools.tmp.target=pointed_thing.under + end + + if livetools.set_target(user,pointed_thing) then return itemstack end + itemstack:take_item() + return itemstack + end +}) + +minetest.register_entity("livetools:tool",{ + hp_max = 20, + visual="wielditem", + visual_size={x=.50,y=.50}, + collisionbox = {-0.2,-0.4,-0.2,0.2,0.4,0.2}, + physical=true, + textures={"air"}, + makes_footstep_sound=true, + on_activate = function(self, staticdata) + if livetools.tmp.item ~= nil then + self.item=livetools.tmp.item + self.user=livetools.tmp.user + self.type=livetools.tmp.type + self.dmg=livetools.tmp.dmg + self.target=livetools.tmp.target + self.hp_max=livetools.tmp.hp + self.new=1 + livetools.tmp={} + self.object:set_properties({textures={self.item}}) + else + if staticdata~="" then + minetest.add_item(self.object:get_pos(), staticdata) + + end + self.object:remove() + end + end, + get_staticdata = function(self) + return self.item + end, + on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir) + if self.destry then return self end + if dir~=nil then self.object:setvelocity({x = dir.x*3,y = self.object:getvelocity().y,z = dir.z*3}) end + local inv=(self.user and self.user:get_inventory()) + + if puncher:is_player() and self.user and self.user:is_player() and puncher:get_player_name()==self.user:get_player_name() then + livetools.punch(self,self.object,1000) + self.destry=true + return self + else + if self.returnback then self.returnback=false end + self.target=puncher + end + + if self.object:get_hp()<=0 and self.item and inv then + self.destry=true + self.user:get_inventory():add_item("main", self.item) + return self + end + if self.object:get_hp()<=0 and self.item and inv==false then + self.destry=true + minetest.add_item(self.object:get_pos(), self.item):setvelocity({x = math.random(-1, 1),y=5,z = math.random(-1, 1)}) + return self + end + end, +on_step=function(self, dtime) + self.time=self.time+dtime + if self.time<0.5 then return self end + self.time=0 + local inv=(self.user and self.user:get_inventory()) + + if not (self.user and self.user:get_pos()) then + minetest.add_item(self.object:get_pos(), self.item) + self.object:remove() + return self + end + local ud=livetools.get_distance(self,self.user:get_pos()) + if self.target==nil and inv==false or self.user:get_hp()<=0 or (ud and ud>25) then + livetools.punch(self,self.object,1000) + return self + end + + local target=self.target + if self.type=="attack" then target=self.target:get_pos() end + + local d=livetools.get_distance(self,target) + if not d or (self.type=="attack" and self.target:get_hp()<=0) then + self.target=self.user + self.returnback=true + self.type="attack" + d=livetools.get_distance(self,self.target:get_pos()) + + if not d then + livetools.punch(self,self.object,1000) + return self + end + + end + local see=livetools.get_visiable(self.object:get_pos(),target) + if see then + self.able_to_see=true + end + if inv and ((d>15 or see==false) or (d<1.5 and self.returnback)) then + if self.returnback and (d<1.5 or self.able_to_see==false) then + livetools.punch(self,self.object,1000) + return self + elseif self.able_to_see and d<15 then + local v=self.object:getvelocity() + self.object:setvelocity({x = v.x,y = 5,z =v.z}) + self.able_to_see=false + return self + else + self.target=self.user + self.returnback=true + self.able_to_see=true + self.type="attack" + end + end + local pos=self.object:get_pos() + if self.type=="attack" and d<2 and (not self.returnback) then + livetools.punch(self,self.target,self.dmg) + end + if self.type=="dig" and d<2 and (not self.returnback) then + minetest.node_dig(target, minetest.get_node(target), self.user) + self.target=self.user + self.returnback=true + end + if self.type=="place" and d<2 and (not self.returnback) then + local index=self.user:get_wield_index()-1 + local inv=self.user:get_inventory() + local stack=inv:get_stack("main", index) + if minetest.registered_nodes[stack:get_name()] then + minetest.set_node(target,{name=stack:get_name()}) + inv:set_stack("main",index,ItemStack(stack:get_name() .. " " .. (stack:get_count()-1))) + end + self.target=self.user + self.returnback=true + end + livetools.set_lookat(self,target) + livetools.set_walk(self) + self.object:setacceleration({x=0, y=-8, z=0}) + if (livetools.def({x=pos.x+self.mx,y=pos.y,z=pos.z+self.mz},"walkable") + and livetools.def({x=pos.x+self.mx,y=pos.y+1,z=pos.z+self.mz},"walkable")==false) + or (livetools.def({x=pos.x+self.mx,y=pos.y-1,z=pos.z+self.mz},"walkable")==false + and livetools.def({x=pos.x,y=pos.y-1,z=pos.z},"walkable")) then + local v=self.object:getvelocity() + self.object:setvelocity({x = v.x,y = 5,z =v.z}) + end + +end, +destry=false, +time=0, +mx=0, +mz=0, +able_to_see=true, +type="npc", +dmg=4, +}) + +livetools.get_distance=function(self,pos) + if pos==nil or pos.x==nil then return nil end + local p=self.object:get_pos() + return math.sqrt((p.x-pos.x)*(p.x-pos.x) + (p.y-pos.y)*(p.y-pos.y)+(p.z-pos.z)*(p.z-pos.z)) +end + +livetools.get_visiable=function(pos,ta) + if not (ta and ta.x and ta.y and ta.z) then + return nil + end + local v = {x = pos.x - ta.x, y = pos.y - ta.y-1, z = pos.z - ta.z} + v.y=v.y-1 + local amount = (v.x ^ 2 + v.y ^ 2 + v.z ^ 2) ^ 0.5 + local d=math.sqrt((pos.x-ta.x)*(pos.x-ta.x) + (pos.y-ta.y)*(pos.y-ta.y)+(pos.z-ta.z)*(pos.z-ta.z)) + v.x = (v.x / amount)*-1 + v.y = (v.y / amount)*-1 + v.z = (v.z / amount)*-1 + for i=1,d,1 do + if livetools.def({x=pos.x+(v.x*i),y=pos.y+(v.y*i),z=pos.z+(v.z*i)},"walkable") then + return false + end + end + return true +end + +livetools.punch=function(self,ob,hp) + if hp>=999 then + if self and self.object then + self.object:set_hp(0) + self.object:punch(self.object, hp,{full_punch_interval=1.0,damage_groups={fleshy=4}}) + end + elseif self.user and self.user:is_player() then + ob:punch(self.user, hp,{full_punch_interval=1.0,damage_groups={fleshy=4}}) + else + ob:punch(self.object, hp,{full_punch_interval=1.0,damage_groups={fleshy=4}}) + end + return self +end + +livetools.set_walk=function(self) + local pos=self.object:get_pos() + local yaw=self.object:getyaw() + if yaw ~= yaw then + return false + end + local x =math.sin(yaw) * -1 + local z =math.cos(yaw) * 1 + self.mx=x + self.mz=z + self.object:setvelocity({x = x*4,y = self.object:getvelocity().y,z = z*4}) + return self +end + +livetools.set_lookat=function(self,goto) + if not (goto and goto.x and goto.y and goto.z) then + return self + end + local pos=self.object:get_pos() + local vec = {x=pos.x-goto.x, y=pos.y-goto.y, z=pos.z-goto.z} + local yaw = math.atan(vec.z/vec.x)-math.pi/2 + if pos.x > goto.x then yaw = yaw+math.pi end + self.object:setyaw(yaw) + return self +end \ No newline at end of file diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..8ab652e Binary files /dev/null and b/screenshot.png differ