2 arrow.initial_properties = {
4 collide_with_objects = false,
5 collisionbox = {-0.05, -0.05, -0.05, 0.05, 0.05, 0.05},
7 visual_size = {x = 1 , y = 1},
8 mesh = "basic_bow_arrow.b3d",
10 "basic_bow_arrow_uv.png"
14 --automatic_face_movement_dir = 0.0,
15 --automatic_face_movement_max_rotation_per_sec = 600,
17 arrow.on_activate = function(self, staticdata, dtime_s)
18 --self.object:set_animation({x=0,y=180}, 15, 0, true)
19 self.object:set_acceleration(vector.new(0,-9.81,0))
22 local radians_to_degrees = function(radians)
23 return(radians*180.0/math.pi)
29 arrow.on_step = function(self, dtime,moveresult)
30 local pos = self.object:get_pos()
31 local vel = self.object:get_velocity()
33 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do
34 if (object:is_player() and object:get_hp() > 0 and object:get_player_name() ~= self.thrower) or (object:get_luaentity() and object:get_luaentity().mob == true) then
35 if (object:is_player() and object:get_player_name() ~= self.owner) or (object:get_luaentity() and object:get_luaentity().mob == true) then
36 object:punch(self.object, 2,
38 full_punch_interval=1.5,
39 damage_groups = {damage=3},
48 if moveresult and moveresult.collides and self.stuck == false then
50 if moveresult.collisions[1].new_velocity.x == 0 and moveresult.collisions[1].old_velocity.x ~= 0 then
51 self.check_dir = vector.direction(vector.new(pos.x,0,0),vector.new(moveresult.collisions[1].node_pos.x,0,0))
52 elseif moveresult.collisions[1].new_velocity.y == 0 and moveresult.collisions[1].old_velocity.y ~= 0 then
53 self.check_dir = vector.direction(vector.new(0,pos.y,0),vector.new(0,moveresult.collisions[1].node_pos.y,0))
54 elseif moveresult.collisions[1].new_velocity.z == 0 and moveresult.collisions[1].old_velocity.z ~= 0 then
55 self.check_dir = vector.direction(vector.new(0,0,pos.z),vector.new(0,0,moveresult.collisions[1].node_pos.z))
58 minetest.sound_play("arrow_hit",{object=self.object,gain=1,pitch=math.random(80,100)/100,max_hear_distance=64})
60 self.object:set_velocity(vector.new(0,0,0))
61 self.object:set_acceleration(vector.new(0,0,0))
62 elseif self.stuck == true and self.check_dir then
63 local pos2 = vector.add(pos,vector.multiply(self.check_dir,0.2))
65 minetest.add_particle({
67 velocity = {x=0, y=0, z=0},
68 acceleration = {x=0, y=0, z=0},
74 local ray = minetest.raycast(pos, pos2, false, false)
75 local pointed_thing = ray:next()
77 if not pointed_thing then
79 self.object:set_acceleration(vector.new(0,-9.81,0))
83 if not self.stuck and pos and self.oldpos then
84 self.spin = self.spin + (dtime*10)
85 if self.spin > math.pi then
89 local dir = vector.normalize(vector.subtract(pos,self.oldpos))
90 local y = minetest.dir_to_yaw(dir)
91 local x = (minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(self.oldpos.x,0,self.oldpos.z)),0,pos.y-self.oldpos.y))+(math.pi/2))
92 self.object:set_rotation(vector.new(x,y,self.spin))
93 --local frame = self.get_animation_frame(dir)
94 --self.object:set_animation({x=frame, y=frame}, 0)
96 if self.stuck == false then
101 minetest.register_entity("bow:arrow", arrow)
104 minetest.register_craftitem("bow:bow_empty", {
106 inventory_image = "bow.png",
112 minetest.register_craftitem("bow:bow_"..i, {
114 inventory_image = "bow_"..i..".png",
116 groups = {bow=1,bow_loaded=i}
120 minetest.register_craftitem("bow:arrow", {
121 description = "Arrow",
122 inventory_image = "arrow_item.png",
125 minetest.register_globalstep(function(dtime)
126 --check if player has bow
127 for _,player in ipairs(minetest.get_connected_players()) do
128 local item = player:get_wielded_item():get_name()
129 if minetest.get_item_group(item, "bow") > 0 then
130 --begin to pull the bow back
131 if player:get_player_control().RMB == true then
132 local meta = player:get_meta()
133 local animation = meta:get_float("bow_loading_animation")
135 if animation <= 5 then
137 if animation == 0 then
139 player:set_wielded_item(ItemStack("bow:bow_1"))
141 animation = animation + (dtime*2)
145 meta:set_float("bow_loading_animation", animation)
147 local level = minetest.get_item_group(item, "bow_loaded")
150 local new_level = math.floor(animation + 0.5)
152 --print(new_level,level)
154 if new_level > level then
156 minetest.sound_play("bow_pull_back", {object=player, gain = 1.0, max_hear_distance = 60,pitch = 0.7+new_level*0.1})
158 player:set_wielded_item(ItemStack("bow:bow_"..new_level))
162 --player:set_wielded_item(ItemStack("main:glass"))
164 local power = minetest.get_item_group(item, "bow_loaded")
167 local dir = player:get_look_dir()
168 local vel = vector.multiply(dir,power*10)
169 local pos = player:get_pos()
170 pos.y = pos.y + 1.625
171 local object = minetest.add_entity(pos,"bow:arrow")
172 object:set_velocity(vel)
173 object:get_luaentity().owner = player:get_player_name()
174 minetest.sound_play("bow", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
177 player:set_wielded_item(ItemStack("bow:bow_empty"))
178 local meta = player:get_meta()
179 meta:set_float("bow_loading_animation", 0)