commit 7353195bb1047049226a13fffe3ba42f883b1f2d Author: tchncs Date: Tue Jul 26 15:23:03 2016 +0200 initial commit diff --git a/Readme.txt b/Readme.txt new file mode 100644 index 0000000..4403d56 --- /dev/null +++ b/Readme.txt @@ -0,0 +1,54 @@ +Licenses: code LGPL 2.1 media CC BY-SA 3.0 +Name: Bows +Created by: UjEdwin +Date: 2016-04-08 +Version: 3 + +A very easy bow api mod with arrows + +Load a bow: +place a arrow left of the bow + use it + +Bows / levels: +Wooded +Stone +Steel +Bronze +Osidian +Mese +Diamond +Rainbow +Admin: bows:bow_admin (unlimited + very high level) + +Arrows / level: +Wooded +Steel +Gold +Diamond +Dig: digs the block it hits. +Fire: spawning fire on the block or object it hits +Build: placing a block from the right stack of the bow. +Toxic: keep hurting after it hits. +Tetanus: makes you cant move (will not work with other arrows) +TNT: placing a burning tnt (depends) +Admin: bows:arrow_admin (always kill when hits) + + +The target gives a mesecon signal when an arrow hits it. + +Changes log: +V3: +Added: rainbow arrow +Added: on_step function for arrows +Fixed: tnt arrow + craft +Fixed: bug inside arrow damage system +Fixed: variable name conflict error (found by TenPlus1) +V2: +Added: craft gravel to flint +Fixed: crash with fire arrow +Changed: arrow crafts: toxic, fire, tetanus +Added: admin bow/arrow +Added: bows: osidian/rainbow +Added: tnt arrow +V1: +Mod created \ No newline at end of file diff --git a/arrow.lua b/arrow.lua new file mode 100644 index 0000000..86263c1 --- /dev/null +++ b/arrow.lua @@ -0,0 +1,135 @@ +bows.nothing=function(self,target,hp,user,lastpos) + return self +end + +bows.on_hit_object=function(self,target,hp,user,lastpos) + target:set_hp(target:get_hp()-hp) + target:punch(user,1, "default:sword_wood", nil) + if target:get_hp()>0 then + local pos=self.object:getpos() + local opos=target:getpos() + local dir = user:get_look_dir() + self.object:set_attach(target, "", {x=(opos.x-pos.x)*4,y=(pos.y-opos.y)*4,z=(pos.z-opos.z)*4},{x=0,y=-90,z=0}) + else + bows.arrow_remove(self) + end + return self +end + + +bows.on_hit_node=function(self,pos,user,lastpos) + if not minetest.registered_nodes[minetest.get_node(pos).name].node_box then + local mpos={x=(pos.x-lastpos.x),y=(pos.y-lastpos.y),z=(pos.z-lastpos.z)} + local npos={x=bows.rnd(pos.x),y=bows.rnd(pos.y),z=bows.rnd(pos.z)} + local m={x=-0.6,y=-0.6,z=-0.6} + local bigest={x=mpos.x,y=mpos.y,z=mpos.z} + if bigest.x<0 then bigest.x=bigest.x*-1 m.x=0.6 end + if bigest.y<0 then bigest.y=bigest.y*-1 m.y=0.6 end + if bigest.z<0 then bigest.z=bigest.z*-1 m.z=0.6 end + local b=math.max(bigest.x,bigest.y,bigest.z) + if b==bigest.x then + pos.x=npos.x+m.x + elseif b==bigest.y then + pos.y=npos.y+m.y + else + pos.z=npos.z+m.z + end + self.object:setpos(pos) + end + return self +end + +bows.rnd=function(r) + return math.floor(r+ 0.5) +end + +bows.arrow_remove=function(self) + if self.object:get_attach() then self.object:set_detach() end + if self.target then self.target:punch(self.object, {full_punch_interval=1,damage_groups={fleshy=4}}, "default:bronze_pick", nil) end + self.object:set_hp(0) + self.object:punch(self.object, {full_punch_interval=1.0,damage_groups={fleshy=4}}, "bows:bow_wood", nil) + return self +end + +minetest.register_entity("bows:arrow",{ + hp_max = 10, + visual="wielditem", + visual_size={x=.20,y=.20}, + collisionbox = {0,0,0,0,0,0}, + physical=false, + textures={"air"}, + on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir) + if not self.target then return self end + if not self.hp then self.hp=self.object:get_hp() end + local hp=self.object:get_hp() + local hurt=self.hp-self.object:get_hp() + self.hp=self.object:get_hp() + self.target:set_hp(self.target:get_hp()-hurt) + self.target:punch(self.object, hurt,{full_punch_interval=1.0,damage_groups={fleshy=4}}, "default:sword_wood", nil) + if hurt>100 or hp<=hurt then + self.target:set_detach() + self.target:setvelocity({x=0, y=4, z=0}) + self.target:setacceleration({x=0, y=-10, z=0}) + self.on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir) end + bows.arrow_remove(self) + end + return self + end, + on_activate = function(self, staticdata) + if bows.tmp and bows.tmp.arrow ~= nil then + self.arrow=bows.tmp.arrow + self.user=bows.tmp.user + self.name=bows.tmp.name + self.dmg=bows.registed_arrows[self.name].damage + bows.tmp=nil + self.object:set_properties({textures={self.arrow}}) + else + self.object:remove() + end + end, + stuck=false, + bow_arrow=true, + timer=20, + x=0, + y=0, + z=0, + on_step= function(self, dtime) + self.timer=self.timer-dtime + if self.stuck then + if self.target and self.target:get_hp()<=1 then self.timer=-1 end + if self.timer<0 then + bows.arrow_remove(self) + end + return self + end + local pos=self.object:getpos() + if (self.user==nil or self.timer<16 ) or minetest.get_node(pos) and minetest.registered_nodes[minetest.get_node(pos).name].walkable then + if bows.mesecons and minetest.get_node(pos).name=="bows:target" then + mesecon.receptor_on(pos) + minetest.env:get_node_timer(pos):start(2) + end + self.object:setvelocity({x=0, y=0, z=0}) + self.object:setacceleration({x=0, y=0, z=0}) + self.stuck=true + bows.registed_arrows[self.name].on_hit_node(self,pos,self.user,{x=self.x,y=self.y,z=self.z}) + minetest.sound_play(bows.registed_arrows[self.name].on_hit_sound, {pos=pos, gain = 1.0, max_hear_distance = 7}) + return self + end + bows.registed_arrows[self.name].on_step(self,dtime,self.user,pos,{x=self.x,y=self.y,z=self.z}) + self.x=pos.x + self.y=pos.y + self.z=pos.z + for i, ob in pairs(minetest.get_objects_inside_radius(pos, 1)) do + if ob and ((bows.pvp and ob:is_player() and ob:get_player_name()~=self.user:get_player_name()) or (ob:get_luaentity() and ob:get_luaentity().physical and ob:get_luaentity().bow_arrow==nil and ob:get_luaentity().name~="__builtin:item" )) then + self.object:setvelocity({x=0, y=0, z=0}) + self.object:setacceleration({x=0, y=0, z=0}) + self.stuck=true + bows.on_hit_object(self,ob,self.dmg,self.user,{x=self.x,y=self.y,z=self.z}) + bows.registed_arrows[self.name].on_hit_object(self,ob,self.dmg,self.user,{x=self.x,y=self.y,z=self.z}) + minetest.sound_play(bows.registed_arrows[self.name].on_hit_sound, {pos=pos, gain = 1.0, max_hear_distance = 7}) + return self + end + end + return self + end, +}) \ No newline at end of file diff --git a/craft.png b/craft.png new file mode 100644 index 0000000..ad28787 Binary files /dev/null and b/craft.png differ diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..ba9c2c9 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +tnt? \ No newline at end of file diff --git a/functions.txt b/functions.txt new file mode 100644 index 0000000..1ea76ed --- /dev/null +++ b/functions.txt @@ -0,0 +1,33 @@ +-- useful functions if you want to use this api.. all other functions are automatic used (no idea to use them in your code) + +bows.arrow_remove(self) -- remove the arrow +self.target= target --(punching its target when it self is punched) + +bows.register_bow("bow_test",{ + description="Test bow", + texture="bows_bow.png", + texture_loaded="bows_bow_loaded.png", + uses=50, + level=1,-- (19 is double speed) + craft={ + {"","group:stick","farming:cotton"}, + {"group:stick","","farming:cotton"}, + {"","group:stick","farming:cotton"} + }, +}) + +bows.register_arrow("arrow_test",{ + description="Test arrow", + texture="bows_arrow_wood.png", + damage=5, + craft_count=8,-- count of items from craft + craft={ + {"default:flint","group:stick","group:leaves"} + } + on_hit_node=function(self,pos,user,lastpos) + end, + on_hit_object=function(self,target,hp,user,lastpos) + end, + on_step=function(self,dtime,user,pos,lastpos) + end, +}) \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..71b4027 --- /dev/null +++ b/init.lua @@ -0,0 +1,130 @@ +-- Mode by UjEdwin + +bows={ + pvp=minetest.setting_getbool("enable_pvp"), + tnt=minetest.setting_getbool("enable_tnt") and minetest.get_modpath("tnt"), + creative=minetest.setting_getbool("creative_mode"), + mesecons=minetest.get_modpath("mesecons"), + registed_arrows={}, + registed_bows={}, +} + +minetest.register_craft({ + type = "fuel", + recipe = "group:bow", + burntime = 3, +}) + +bows.register_arrow=function(name,def) + if name==nil or name=="" then return false end + + def.damage = def.damage or 0 + def.name = "bows:".. name + def.level = def.level or 1 + def.on_hit_object = def.on_hit_object or bows.nothing + def.on_hit_node = def.on_hit_node or bows.on_hit_node + def.on_hit_sound= def.on_hit_sound or "default_dig_dig_immediate" + def.on_step = def.on_step or bows.nothing + + bows.registed_arrows[def.name]=def + + minetest.register_craftitem("bows:".. name, { + description = def.description or name, + inventory_image = def.texture or "bows_arrow_wooden.png", + groups = {arrow=1} + }) + if def.craft then + def.craft_count= def.craft_count or 4 + minetest.register_craft({ + output = def.name .." " .. def.craft_count, + recipe = def.craft + }) + end +end + +bows.register_bow=function(name,def) + if name==nil or name=="" then return false end + + def.replace = "bows:" .. name .."_loaded" + def.name = "bows:".. name + def.uses = def.uses-1 or 49 + + bows.registed_bows[def.replace]=def + + minetest.register_tool(def.name, { + description = def.description or name, + inventory_image = def.texture or "bows_bow.png", + on_use =bows.load, + groups = {bow=1,stick=1}, + }) + minetest.register_tool(def.replace, { + description = def.description or name, + inventory_image = def.texture_loaded or "bows_bow_loaded.png", + on_use =bows.shoot, + groups = {bow=1,stick=1,not_in_creative_inventory=1}, + }) + if def.craft then + minetest.register_craft({output = def.name,recipe = def.craft}) + end +end + +bows.load=function(itemstack, user, pointed_thing) + local inv=user:get_inventory() + local index=user:get_wield_index()-1 + local arrow=inv:get_stack("main", index) + if minetest.get_item_group(arrow:get_name(), "arrow")==0 then return itemstack end + local item=itemstack:to_table() + local meta=minetest.deserialize(item.metadata) + meta={arrow=arrow:get_name()} + item.metadata=minetest.serialize(meta) + item.name=item.name .. "_loaded" + itemstack:replace(item) + + if bows.creative==false then + inv:set_stack("main",index,ItemStack(arrow:get_name() .. " " .. (arrow:get_count()-1))) + end + + return itemstack +end + +bows.shoot=function(itemstack, user, pointed_thing) + local item=itemstack:to_table() + local meta=minetest.deserialize(item.metadata) + + if (not (meta and meta.arrow)) or (not bows.registed_arrows[meta.arrow]) then + return itemstack + end + local name=itemstack:get_name() + local replace=bows.registed_bows[name].name + local ar=bows.registed_bows[name].uses + local wear=bows.registed_bows[name].uses + local level=19 + bows.registed_bows[name].level + + bows.tmp = {} + bows.tmp.arrow = meta.arrow + bows.tmp.user = user + bows.tmp.name=meta.arrow + + item.arrow="" + item.metadata=minetest.serialize(meta) + item.name=replace + itemstack:replace(item) + + local pos = user:getpos() + local dir = user:get_look_dir() + local e = minetest.env:add_entity({x=pos.x,y=pos.y+1.5,z=pos.z}, "bows:arrow") + e:setvelocity({x=dir.x*level, y=dir.y*level, z=dir.z*level}) + e:setacceleration({x=dir.x*-3, y=-10, z=dir.z*-3}) + e:setyaw(user:get_look_yaw()+math.pi) + + if bows.creative==false then + itemstack:add_wear(65535/wear) + end + + minetest.sound_play("bows_shoot", {pos=pos}) + return itemstack +end + +dofile(minetest.get_modpath("bows") .. "/arrow.lua") +dofile(minetest.get_modpath("bows") .. "/items_functions.lua") +dofile(minetest.get_modpath("bows") .. "/items.lua") \ No newline at end of file diff --git a/items.lua b/items.lua new file mode 100644 index 0000000..df2a3a0 --- /dev/null +++ b/items.lua @@ -0,0 +1,304 @@ + +minetest.register_node("bows:target", { + description = "Target", + tiles = {"default_wood.png","default_wood.png","default_wood.png","default_wood.png","default_wood.png","default_wood.png^bows_target.png","default_wood.png"}, + groups = {choppy = 2, oddly_breakable_by_hand = 2,mesecon = 2}, + drawtype="nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.1875, 0.375, 0.5, 0.1875, 0.5}, + {-0.4375, -0.25, 0.375, 0.4375, 0.25, 0.5}, + {-0.375, -0.375, 0.375, 0.375, 0.375, 0.5}, + {-0.25, -0.4375, 0.375, 0.25, 0.4375, 0.5}, + {-0.125, -0.5, 0.375, 0.125, 0.5, 0.5}, + } + }, + paramtype2="facedir", + paramtype = "light", + sunlight_propagates = true, + mesecons = {receptor = {state = "off"}}, + on_timer = function (pos, elapsed) + mesecon.receptor_off(pos) + return false + end, +}) +minetest.register_craft({ + output = "bows:target", + recipe = { + {"","group:wood",""}, + {"group:wood","group:wood","group:wood"}, + {"","group:wood",""} + } +}) +minetest.register_craft({output = "default:flint",recipe = {{"default:gravel"},}}) +minetest.register_craft({output = "farming:cotton 4",recipe = {{"group:wool"},}}) + +bows.register_bow("bow_wood",{ + description="Wooden bow", + texture="bows_bow.png", + texture_loaded="bows_bow_loaded.png", + uses=50, + level=1, + craft={ + {"","group:stick","farming:cotton"}, + {"group:stick","","farming:cotton"}, + {"","group:stick","farming:cotton"} + }, +}) + +bows.register_bow("bow_stone",{ + description="Stone bow", + texture="bows_bow_stone.png", + texture_loaded="bows_bow_loaded_stone.png", + uses=70, + level=4, + craft={ + {"","group:stone","farming:cotton"}, + {"group:stone","","farming:cotton"}, + {"","group:stone","farming:cotton"} + }, +}) + +bows.register_bow("bow_steel",{ + description="Steel bow", + texture="bows_bow_steel.png", + texture_loaded="bows_bow_loaded_steel.png", + uses=140, + level=8, + craft={ + {"","default:steel_ingot","farming:cotton"}, + {"default:steel_ingot","","farming:cotton"}, + {"","default:steel_ingot","farming:cotton"} + }, +}) + +bows.register_bow("bow_bronze",{ + description="Bronze bow", + texture="bows_bow_bronze.png", + texture_loaded="bows_bow_loaded_bronze.png", + uses=280, + level=10, + craft={ + {"","default:bronze_ingot","farming:cotton"}, + {"default:bronze_ingot","","farming:cotton"}, + {"","default:bronze_ingot","farming:cotton"} + }, +}) + +bows.register_bow("bow_obsidian",{ + description="Obsidian bow", + texture="bows_bow_ob.png", + texture_loaded="bows_bow_loaded_ob.png", + uses=400, + level=11, + craft={ + {"","default:obsidian","farming:cotton"}, + {"default:obsidian","","farming:cotton"}, + {"","default:obsidian","farming:cotton"} + }, +}) + +bows.register_bow("bow_mese",{ + description="Mese bow", + texture="bows_bow_mese.png", + texture_loaded="bows_bow_loaded_mese.png", + uses=500, + level=13, + craft={ + {"","default:mese_crystal","farming:cotton"}, + {"default:mese_crystal","","farming:cotton"}, + {"","default:mese_crystal","farming:cotton"} + }, +}) + +bows.register_bow("bow_diamond",{ + description="Diamond bow", + texture="bows_bow_diamond.png", + texture_loaded="bows_bow_loaded_diamond.png", + uses=800, + level=19, + craft={ + {"","default:diamond","farming:cotton"}, + {"default:diamond","","farming:cotton"}, + {"","default:diamond","farming:cotton"} + }, +}) + +bows.register_bow("bow_rainbow",{ + description="Rainbow bow", + texture="bows_bow_rain.png", + texture_loaded="bows_bow_loaded_rain.png", + uses=1100, + level=19, + craft={ + {"","default:nyancat_rainbow","farming:cotton"}, + {"default:nyancat_rainbow","","farming:cotton"}, + {"","default:nyancat_rainbow","farming:cotton"} + }, +}) + +bows.register_bow("bow_admin",{ + description="Admin bow (admin arrows = bows:arrow_admin)", + texture="bows_bow_admin.png", + texture_loaded="bows_bow_loaded_admin.png", + level=39, + uses=0, +}) + + +bows.register_arrow("arrow",{ + description="Arrow", + texture="bows_arrow_wood.png", + damage=5, + craft_count=8, + craft={{"default:flint","group:stick","group:leaves"},} +}) + +bows.register_arrow("arrow_admin",{ + description="Admin arrow", + texture="bows_arrow_wood.png^[colorize:#ea00cccc", + damage=9000, + on_hit_object=bows.arrow_admin_object, + on_hit_node=bows.arrow_remove, +}) +minetest.override_item("bows:arrow_admin", {groups = {arrow=1,not_in_creative_inventory=1}}) + + +bows.register_arrow("arrow_steel",{ + description="Steel arrow", + texture="bows_arrow_wood.png^[colorize:#FFFFFFcc", + damage=8, + craft_count=8, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:steel_ingot","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"}, + } +}) + +bows.register_arrow("arrow_gold",{ + description="Gold arrow", + texture="bows_arrow_wood.png^[colorize:#d7c633cc", + damage=10, + craft_count=8, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:gold_ingot","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"}, + } +}) + +bows.register_arrow("arrow_mese",{ + description="Mese arrow", + texture="bows_arrow_wood.png^[colorize:#e3ff00cc", + damage=12, + craft_count=8, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:mese_crystal","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"}, + } +}) + +bows.register_arrow("arrow_diamond",{ + description="Diamond arrow", + texture="bows_arrow_wood.png^[colorize:#15d7c2cc", + damage=15, + craft_count=8, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:diamond","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"}, + } +}) + + +bows.register_arrow("arrow_fire",{ + description="Fire arrow", + texture="bows_arrow_wood.png^[colorize:#ffb400cc", + damage=10, + craft_count=1, + on_hit_node=bows.arrow_fire, + on_hit_object=bows.arrow_fire_object, + craft={ + {"group:arrow","default:torch"}, + } +}) + +bows.register_arrow("arrow_build",{ + description="Build arrow", + texture="bows_arrow_wood.png^[colorize:#33336677", + on_hit_node=bows.arrow_build, + craft_count=8, + damage=8, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:obsidian_shard","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"} + } +}) + +bows.register_arrow("arrow_dig",{ + description="Dig arrow", + texture="bows_arrow_wood.png^[colorize:#333333aa", + on_hit_node=bows.arrow_dig, + craft_count=16, + damage=8, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:pick_steel","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"} + } +}) + +bows.register_arrow("arrow_toxic",{ + description="Toxic arrow", + texture="bows_arrow_wood.png^[colorize:#66aa11aa", + on_hit_object=bows.arrow_toxic, + craft_count=1, + damage=0, + craft={ + {"group:arrow","default:papyrus"}, + } +}) + +bows.register_arrow("arrow_Tetanus",{ + description="Tetanus arrow", + texture="bows_arrow_wood.png^[colorize:#aa5500aa", + on_hit_object=bows.arrow_tetanus, + craft_count=4, + damage=2, + craft={ + {"","group:arrow",""}, + {"group:arrow","bucket:bucket_water","group:arrow"}, + {"","group:arrow",""} + } +}) + + +if bows.tnt then +bows.register_arrow("arrow_tnt",{ + description="TNT arrow", + texture="bows_arrow_wood.png^[colorize:#aa0000aa", + on_hit_object=bows.arrow_tnt_object, + on_hit_node=bows.arrow_tnt_node, + craft_count=1, + damage=25, + craft={{"tnt:tnt","group:arrow"}} +}) +end + +bows.register_arrow("arrow_rainbow",{ + description="Rainbow arrow", + texture="bows_arrow_wood.png^bows_rainbow.png", + craft_count=8, + damage=11, + craft={ + {"group:arrow","group:arrow","group:arrow"}, + {"group:arrow","default:nyancat_rainbow","group:arrow"}, + {"group:arrow","group:arrow","group:arrow"} + }, + on_step=bows.arrow_rainbow_step, + on_hit_object=bows.arrow_rainbow_object +}) \ No newline at end of file diff --git a/items_functions.lua b/items_functions.lua new file mode 100644 index 0000000..d035a30 --- /dev/null +++ b/items_functions.lua @@ -0,0 +1,179 @@ + +bows.arrow_dig=function(self,pos,user,lastpos) + minetest.node_dig(pos, minetest.get_node(pos), user) + bows.arrow_remove(self) + return self +end + + +bows.arrow_fire_object=function(self,target,hp,user,lastpos) + bows.arrow_fire(self,lastpos,user,target:getpos()) + return self +end + +bows.arrow_fire=function(self,pos,user,lastpos) + local name=user:get_player_name() + local node=minetest.get_node(lastpos).name + if minetest.is_protected(lastpos, name) then + minetest.chat_send_player(name, minetest.pos_to_string(lastpos) .." is protected") + elseif minetest.registered_nodes[node].buildable_to then + minetest.set_node(lastpos,{name="fire:basic_flame"}) + end + bows.arrow_remove(self) + return self +end + +bows.arrow_build=function(self,pos,user,lastpos) + local name=user:get_player_name() + local node=minetest.get_node(lastpos).name + local index=user:get_wield_index()+1 + local inv=user:get_inventory() + local stack=inv:get_stack("main", index) + if minetest.is_protected(lastpos, name) then + minetest.chat_send_player(name, minetest.pos_to_string(lastpos) .." is protected") + elseif minetest.registered_nodes[node].buildable_to + and minetest.registered_nodes[stack:get_name()] then + minetest.set_node(lastpos,{name=stack:get_name()}) + if bows.creative==false then + inv:set_stack("main",index,ItemStack(stack:get_name() .. " " .. (stack:get_count()-1))) + end + end + bows.arrow_remove(self) + return self +end + +bows.arrow_toxic=function(self,target,hp,user,lastpos) + if self.object==nil or user==nil or target==nil or target:get_properties()==nil then + bows.arrow_remove(self) + return self + end + target:punch(user, 3,{full_punch_interval=1.0,damage_groups={fleshy=4}}, "default:sword_wood", nil) + local rnd=math.random(1,10) + if rnd~=4 and target:get_hp()>0 then + minetest.after(math.random(0.5,2), function(self,target,hp,user,lastpos) + bows.arrow_toxic(self,target,hp,user,lastpos) + end, self,target,hp,user,lastpos) + else + bows.arrow_remove(self) + end +end + +bows.arrow_tetanus=function(self,target,hp,user,lastpos) + if self.object==nil or user==nil or target==nil or target:get_properties()==nil then + bows.arrow_remove(self) + return self + end + if target:get_attach()==nil then + self.object:set_detach() + local col=target:get_properties().collisionbox + self.object:set_properties({ + collisionbox=col, + physical=true, + visual_size={x=1,y=1}, + visual="sprite", + textures={"bows_hidden.png"} + }) + self.object:setpos(target:getpos()) + target:set_attach(self.object, "", {x=0,y=0,z=0},{x=0,y=0,z=0}) + self.target=target + self.hp=self.object:get_hp() + self.object:setvelocity({x=0, y=-3, z=0}) + self.object:setacceleration({x=0, y=-3, z=0}) + return self + end + + local rnd=math.random(1,10) + if rnd~=4 and target:get_hp()>0 then + minetest.after(math.random(4), function(self,target,hp,user,lastpos) + bows.arrow_tetanus(self,target,hp,user,lastpos) + end, self,target,hp,user,lastpos) + else + target:set_detach() + target:setvelocity({x=0, y=4, z=0}) + target:setacceleration({x=0, y=-10, z=0}) + bows.arrow_remove(self) + end +end + +bows.arrow_admin_object=function(self,target,hp,user,lastpos) + target:set_hp(0) + target:punch(self.object, {full_punch_interval=1.0,damage_groups={fleshy=4}}, "default:sword_wood", nil) + bows.arrow_remove(self) + return self +end + +bows.arrow_admin_node=function(self,pos,user,lastpos) + bows.arrow_remove(self) + return self +end + +bows.arrow_tnt_object=function(self,target,hp,user,lastpos) + local name=user:get_player_name() + local node=minetest.get_node(lastpos).name + if minetest.is_protected(lastpos, name) then + minetest.chat_send_player(name, minetest.pos_to_string(lastpos) .." is protected") + elseif minetest.registered_nodes[node].buildable_to then + tnt.boom(lastpos, {damage_radius=5,radius=3,ignore_protection=false}) + end + bows.arrow_remove(self) + return self +end + +bows.arrow_tnt_node=function(self,pos,user,lastpos) + local name=user:get_player_name() + local node=minetest.get_node(lastpos).name + if minetest.is_protected(lastpos, name) then + minetest.chat_send_player(name, minetest.pos_to_string(lastpos) .." is protected") + elseif minetest.registered_nodes[node].buildable_to then + tnt.boom(pos, {damage_radius=5,radius=3,ignore_protection=false}) + end + bows.arrow_remove(self) + return self +end + +bows.arrow_rainbow_step=function(self,dtime,user,pos,lastpos) +minetest.add_particlespawner({ + amount = 90, + time =0.5, + minpos = pos, + maxpos =pos, + minvel = {x=-1, y=-1, z=-1}, + maxvel = {x=1, y=-0.5, z=1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1.0, + maxexptime = 1.5, + minsize = 2.6, + maxsize = 1.2, + texture = "bows_rainbow.png", +}) +end + +bows.arrow_rainbow_object=function(self,target,hp,user,lastpos) + local pos=target:getpos() + minetest.add_particle({ + pos = pos, + velocity = vector.new(), + acceleration = vector.new(), + expirationtime = 0.4, + size = 20, + collisiondetection = false, + vertical = false, + texture = "bows_rainbow.png", + }) + minetest.add_particlespawner({ + amount = 100, + time = 0.5, + minpos = vector.subtract(pos, 3), + maxpos = vector.add(pos, 3), + minvel = {x = -10, y = -10, z = -10}, + maxvel = {x = 10, y = 10, z = 10}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 1, + maxexptime = 2.5, + minsize = 3, + maxsize = 9, + texture = "bows_rainbow.png", + }) +end \ No newline at end of file diff --git a/sounds/bows_shoot.ogg b/sounds/bows_shoot.ogg new file mode 100644 index 0000000..f4f2ff9 Binary files /dev/null and b/sounds/bows_shoot.ogg differ diff --git a/textures/bows_arrow_wood.png b/textures/bows_arrow_wood.png new file mode 100644 index 0000000..fe40cfc Binary files /dev/null and b/textures/bows_arrow_wood.png differ diff --git a/textures/bows_bow.png b/textures/bows_bow.png new file mode 100644 index 0000000..7698470 Binary files /dev/null and b/textures/bows_bow.png differ diff --git a/textures/bows_bow_admin.png b/textures/bows_bow_admin.png new file mode 100644 index 0000000..bd0b932 Binary files /dev/null and b/textures/bows_bow_admin.png differ diff --git a/textures/bows_bow_bronze.png b/textures/bows_bow_bronze.png new file mode 100644 index 0000000..94cf54b Binary files /dev/null and b/textures/bows_bow_bronze.png differ diff --git a/textures/bows_bow_diamond.png b/textures/bows_bow_diamond.png new file mode 100644 index 0000000..9baa9c4 Binary files /dev/null and b/textures/bows_bow_diamond.png differ diff --git a/textures/bows_bow_loaded.png b/textures/bows_bow_loaded.png new file mode 100644 index 0000000..f468a92 Binary files /dev/null and b/textures/bows_bow_loaded.png differ diff --git a/textures/bows_bow_loaded_admin.png b/textures/bows_bow_loaded_admin.png new file mode 100644 index 0000000..05e290c Binary files /dev/null and b/textures/bows_bow_loaded_admin.png differ diff --git a/textures/bows_bow_loaded_bronze.png b/textures/bows_bow_loaded_bronze.png new file mode 100644 index 0000000..a662635 Binary files /dev/null and b/textures/bows_bow_loaded_bronze.png differ diff --git a/textures/bows_bow_loaded_diamond.png b/textures/bows_bow_loaded_diamond.png new file mode 100644 index 0000000..9880a5e Binary files /dev/null and b/textures/bows_bow_loaded_diamond.png differ diff --git a/textures/bows_bow_loaded_mese.png b/textures/bows_bow_loaded_mese.png new file mode 100644 index 0000000..48ef2ff Binary files /dev/null and b/textures/bows_bow_loaded_mese.png differ diff --git a/textures/bows_bow_loaded_ob.png b/textures/bows_bow_loaded_ob.png new file mode 100644 index 0000000..2538009 Binary files /dev/null and b/textures/bows_bow_loaded_ob.png differ diff --git a/textures/bows_bow_loaded_rain.png b/textures/bows_bow_loaded_rain.png new file mode 100644 index 0000000..344221c Binary files /dev/null and b/textures/bows_bow_loaded_rain.png differ diff --git a/textures/bows_bow_loaded_steel.png b/textures/bows_bow_loaded_steel.png new file mode 100644 index 0000000..f9860d0 Binary files /dev/null and b/textures/bows_bow_loaded_steel.png differ diff --git a/textures/bows_bow_loaded_stone.png b/textures/bows_bow_loaded_stone.png new file mode 100644 index 0000000..12e274f Binary files /dev/null and b/textures/bows_bow_loaded_stone.png differ diff --git a/textures/bows_bow_mese.png b/textures/bows_bow_mese.png new file mode 100644 index 0000000..6ac7cec Binary files /dev/null and b/textures/bows_bow_mese.png differ diff --git a/textures/bows_bow_ob.png b/textures/bows_bow_ob.png new file mode 100644 index 0000000..089c75c Binary files /dev/null and b/textures/bows_bow_ob.png differ diff --git a/textures/bows_bow_rain.png b/textures/bows_bow_rain.png new file mode 100644 index 0000000..da804b4 Binary files /dev/null and b/textures/bows_bow_rain.png differ diff --git a/textures/bows_bow_steel.png b/textures/bows_bow_steel.png new file mode 100644 index 0000000..3bd30da Binary files /dev/null and b/textures/bows_bow_steel.png differ diff --git a/textures/bows_bow_stone.png b/textures/bows_bow_stone.png new file mode 100644 index 0000000..4b22ad8 Binary files /dev/null and b/textures/bows_bow_stone.png differ diff --git a/textures/bows_hidden.png b/textures/bows_hidden.png new file mode 100644 index 0000000..b26ccf3 Binary files /dev/null and b/textures/bows_hidden.png differ diff --git a/textures/bows_rainbow.png b/textures/bows_rainbow.png new file mode 100644 index 0000000..b3d1b9d Binary files /dev/null and b/textures/bows_rainbow.png differ diff --git a/textures/bows_target.png b/textures/bows_target.png new file mode 100644 index 0000000..be4dc7f Binary files /dev/null and b/textures/bows_target.png differ