forked from VoxeLibre/VoxeLibre
Convert mcl_mobs.register_arrow() to use vl_projectile, tested only with shulker bullet so far
This commit is contained in:
parent
74d97132c1
commit
2a2d082046
|
@ -1236,13 +1236,14 @@ function mob_class:do_states_attack (dtime)
|
|||
minetest.after(1, function()
|
||||
self.firing = false
|
||||
end)
|
||||
arrow = minetest.add_entity(p, self.arrow)
|
||||
|
||||
arrow = vl_projectile.create(self.arrow, {
|
||||
pos = p,
|
||||
owner = self,
|
||||
})
|
||||
ent = arrow:get_luaentity()
|
||||
if ent.velocity then
|
||||
v = ent.velocity
|
||||
end
|
||||
ent.switch = 1
|
||||
ent.owner_id = tostring(self.object) -- add unique owner id to arrow
|
||||
v = ent.velocity or 1
|
||||
|
||||
-- important for mcl_shields
|
||||
ent._shooter = self.object
|
||||
|
@ -1252,12 +1253,10 @@ function mob_class:do_states_attack (dtime)
|
|||
end
|
||||
end
|
||||
|
||||
local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5
|
||||
-- offset makes shoot aim accurate
|
||||
vec.y = vec.y + self.shoot_offset
|
||||
vec.x = vec.x * (v / amount)
|
||||
vec.y = vec.y * (v / amount)
|
||||
vec.z = vec.z * (v / amount)
|
||||
local amount = vector.length(vec)
|
||||
vec = vector.multiply(vec, v / vector.length(vec))
|
||||
|
||||
if self.shoot_arrow then
|
||||
vec = vector.normalize(vec)
|
||||
self:shoot_arrow(p, vec)
|
||||
|
|
|
@ -386,8 +386,15 @@ function mcl_mobs.register_arrow(name, def)
|
|||
|
||||
if not name or not def then return end -- errorcheck
|
||||
|
||||
minetest.register_entity(name, {
|
||||
local behaviors = {}
|
||||
if def.hit_node then
|
||||
table.insert(behaviors, vl_projectile.collides_with_solids)
|
||||
end
|
||||
if def.hit_player or def.hit_mob or def.hit_object then
|
||||
table.insert(behaviors, vl_projectile.collides_with_entities)
|
||||
end
|
||||
|
||||
vl_projectile.register(name, {
|
||||
physical = false,
|
||||
visual = def.visual,
|
||||
visual_size = def.visual_size,
|
||||
|
@ -405,6 +412,53 @@ function mcl_mobs.register_arrow(name, def)
|
|||
_lifetime = def._lifetime or 7,
|
||||
owner_id = def.owner_id,
|
||||
rotate = def.rotate,
|
||||
_vl_projectile = {
|
||||
behaviors = behaviors,
|
||||
ignore_gravity = true,
|
||||
damages_players = true,
|
||||
allow_punching = function(self, entity_def, projectile_def, object)
|
||||
if self._owner and object == self._owner.object then return false end
|
||||
return true
|
||||
end,
|
||||
on_collide_with_solid = function(self, pos, node, nodedef)
|
||||
if nodedef or not nodedef.walkable then return end
|
||||
|
||||
self.hit_node(self, pos, node)
|
||||
if self.drop == true then
|
||||
pos.y = pos.y + 1
|
||||
self.lastpos = self.lastpos or pos
|
||||
|
||||
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
|
||||
end
|
||||
|
||||
self._removed = true
|
||||
self.object:remove();
|
||||
end,
|
||||
on_collide_with_entity = function(self, pos, object)
|
||||
if self.hit_player and object:is_player() then
|
||||
self.hit_player(self, object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
||||
local entity = object:get_luaentity()
|
||||
if not entity or entity.name == self.object:get_luaentity().name then return end
|
||||
if self.timer <= 2 then return end
|
||||
|
||||
if self.hit_mob and entity.is_mob == true then
|
||||
self.hit_mob(self, object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
return
|
||||
elseif self.hit_object then
|
||||
self.hit_object(self, object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
end
|
||||
},
|
||||
on_punch = def.on_punch or function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
|
||||
local vel = self.object:get_velocity():length()
|
||||
self.object:set_velocity(dir * vel)
|
||||
|
@ -417,25 +471,21 @@ function mcl_mobs.register_arrow(name, def)
|
|||
on_activate = def.on_activate,
|
||||
|
||||
on_step = def.on_step or function(self, dtime)
|
||||
|
||||
self.timer = self.timer + dtime
|
||||
-- Projectile behavior processing
|
||||
vl_projectile.update_projectile(self, dtime)
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
if self.switch == 0
|
||||
or self.timer > self._lifetime
|
||||
or not within_limits(pos, 0) then
|
||||
if self.switch == 0 or self.timer > self._lifetime or not within_limits(pos, 0) then
|
||||
mcl_burning.extinguish(self.object)
|
||||
self._removed = true
|
||||
self.object:remove();
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- does arrow have a tail (fireball)
|
||||
if def.tail
|
||||
and def.tail == 1
|
||||
and def.tail_texture then
|
||||
|
||||
if def.tail and def.tail == 1 and def.tail_texture then
|
||||
minetest.add_particle({
|
||||
pos = pos,
|
||||
velocity = {x = 0, y = 0, z = 0},
|
||||
|
@ -448,29 +498,6 @@ function mcl_mobs.register_arrow(name, def)
|
|||
})
|
||||
end
|
||||
|
||||
if self.hit_node then
|
||||
|
||||
local node = node_ok(pos).name
|
||||
|
||||
if minetest.registered_nodes[node].walkable then
|
||||
|
||||
self.hit_node(self, pos, node)
|
||||
|
||||
if self.drop == true then
|
||||
|
||||
pos.y = pos.y + 1
|
||||
|
||||
self.lastpos = (self.lastpos or pos)
|
||||
|
||||
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
|
||||
end
|
||||
|
||||
self.object:remove();
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if self.homing and self._target then
|
||||
local p = self._target:get_pos()
|
||||
if p then
|
||||
|
@ -482,42 +509,6 @@ function mcl_mobs.register_arrow(name, def)
|
|||
end
|
||||
end
|
||||
|
||||
if self.hit_player or self.hit_mob or self.hit_object then
|
||||
|
||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do
|
||||
|
||||
if self.hit_player
|
||||
and object:is_player() then
|
||||
|
||||
self.hit_player(self, object)
|
||||
self.object:remove();
|
||||
return
|
||||
end
|
||||
|
||||
local entity = object:get_luaentity()
|
||||
|
||||
if entity
|
||||
and self.hit_mob
|
||||
and entity.is_mob == true
|
||||
and (tostring(object) ~= self.owner_id or self.timer > 2)
|
||||
and entity.name ~= self.object:get_luaentity().name then
|
||||
self.hit_mob(self, object)
|
||||
self.object:remove();
|
||||
return
|
||||
end
|
||||
|
||||
if entity
|
||||
and self.hit_object
|
||||
and (not entity.is_mob)
|
||||
and (tostring(object) ~= self.owner_id or self.timer > 2)
|
||||
and entity.name ~= self.object:get_luaentity().name then
|
||||
self.hit_object(self, object)
|
||||
self.object:remove();
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.lastpos = pos
|
||||
end
|
||||
})
|
||||
|
|
|
@ -386,10 +386,11 @@ function mod.create(entity_id, options)
|
|||
end
|
||||
|
||||
function mod.register(name, def)
|
||||
assert(def._vl_projectile)
|
||||
assert(def._vl_projectile, "vl_projectile.register() requires definition to define _vl_projectile")
|
||||
assert(def._vl_projectile.behaviors, "vl_projectile.register() requires definition to define _vl_projectile.behaviors")
|
||||
local behaviors = def._vl_projectile.behaviors
|
||||
for i = 1,#behaviors do
|
||||
assert(behaviors[i])
|
||||
assert(behaviors[i] and type(behaviors[i]) == "function", "def._vl_projectile.behaviors["..i.." is malformed")
|
||||
end
|
||||
|
||||
if not def.on_step then
|
||||
|
|
Loading…
Reference in New Issue