livetools/init.lua

395 lines
12 KiB
Lua

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:set_velocity({x=dir.x*2, y=dir.y*2, z=dir.z*2})
e:set_acceleration({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:set_velocity({x = dir.x*3,y = self.object:get_velocity().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):set_velocity({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:get_velocity()
self.object:set_velocity({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:set_acceleration({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:get_velocity()
self.object:set_velocity({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:set_velocity({x = x*4,y = self.object:get_velocity().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