Compare commits
8 Commits
1c7d727286
...
aafd806e89
Author | SHA1 | Date |
---|---|---|
teknomunk | aafd806e89 | |
teknomunk | 352ebb3b32 | |
teknomunk | cc5c3dda83 | |
teknomunk | 2df62db430 | |
teknomunk | bdd44a62ee | |
teknomunk | 6ec3770b6e | |
teknomunk | ba4d09a4c6 | |
teknomunk | bc3e2ebd72 |
|
@ -731,3 +731,22 @@ function mcl_util.get_entity_id(entity)
|
|||
return id
|
||||
end
|
||||
end
|
||||
function mcl_util.get_entity_from_id(id)
|
||||
local player = minetest.get_player_by_name(id)
|
||||
if player then return player end
|
||||
|
||||
for i,le in pairs(minetest.luaentities) do
|
||||
if le._uuid == id then return le.object end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
function mcl_util.remove_entity(luaentity)
|
||||
if luaentity._removed then return end
|
||||
luaentity._removed = true
|
||||
|
||||
local hook = luaentity._on_remove
|
||||
if hook then hook(luaentity) end
|
||||
|
||||
luaentity.object:remove()
|
||||
end
|
||||
|
|
|
@ -434,14 +434,12 @@ function mcl_mobs.register_arrow(name, def)
|
|||
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
|
||||
end
|
||||
|
||||
self._removed = true
|
||||
self.object:remove();
|
||||
mcl_util.remove_entity(self)
|
||||
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()
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -451,13 +449,11 @@ function mcl_mobs.register_arrow(name, def)
|
|||
|
||||
if self.hit_mob and entity.is_mob == true then
|
||||
self.hit_mob(self, object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
elseif self.hit_object then
|
||||
self.hit_object(self, object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -481,8 +477,7 @@ function mcl_mobs.register_arrow(name, def)
|
|||
|
||||
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();
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -201,8 +201,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
|
|||
self._death_timer = self._death_timer + self.health - self._health_old
|
||||
if self.health == self._health_old then self._death_timer = self._death_timer + dtime end
|
||||
if self._death_timer > 100 then
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
return false
|
||||
end
|
||||
self._health_old = self.health
|
||||
|
|
|
@ -138,8 +138,9 @@ local arrow_entity = {
|
|||
|
||||
-- Because arrows are flagged to survive collisions to allow sticking into blocks, manually remove it now that it
|
||||
-- has collided with an entity
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
if not is_player then
|
||||
mcl_util.remove_entity(self)
|
||||
end
|
||||
end
|
||||
},
|
||||
|
||||
|
@ -186,8 +187,7 @@ local arrow_entity = {
|
|||
end
|
||||
|
||||
if data.stuckin_player then
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ minetest.register_on_respawnplayer(function(player)
|
|||
for _, obj in pairs(player:get_children()) do
|
||||
local ent = obj:get_luaentity()
|
||||
if ent and ent.name and string.find(ent.name, "mcl_bows:arrow_entity") then
|
||||
obj:remove()
|
||||
mcl_util.remove_entity(ent)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -241,7 +241,7 @@ minetest.register_craftitem("mcl_bows:rocket", {
|
|||
local eploded_particle = particle_explosion(pos)
|
||||
damage_explosion(self, eploded_particle * 17, pos)
|
||||
mcl_burning.extinguish(self.object)
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -268,7 +268,7 @@ rocket_entity.on_step = function(self, dtime)
|
|||
local eploded_particle = particle_explosion(self)
|
||||
damage_explosion(self, eploded_particle * 17)
|
||||
mcl_burning.extinguish(self.object)
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -331,8 +331,7 @@ vl_projectile.register("mcl_fishing:flying_bobber_entity", {
|
|||
on_collide_with_solid = function(self, pos, node)
|
||||
local player = self._owner
|
||||
|
||||
self._remove = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
|
||||
-- Make sure the player field is valid for when we create the floating bobber
|
||||
if not player then return end
|
||||
|
|
|
@ -151,9 +151,12 @@ function mcl_potions.register_lingering(name, descr, color, def)
|
|||
local dir = placer:get_look_dir();
|
||||
local pos = placer:getpos();
|
||||
minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
|
||||
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
|
||||
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
|
||||
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
|
||||
local obj = vl_projectile.create(id.."_flying",{
|
||||
pos = vector.offset(pos, dir.x, dir.y + 1.64, dir.z),
|
||||
owner = placer,
|
||||
dir = dir,
|
||||
velocity = velocity,
|
||||
})
|
||||
local ent = obj:get_luaentity()
|
||||
ent._thrower = placer:get_player_name()
|
||||
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
|
||||
|
@ -212,6 +215,7 @@ function mcl_potions.register_lingering(name, descr, color, def)
|
|||
vl_projectile.collides_with_entities,
|
||||
vl_projectile.collides_with_solids,
|
||||
},
|
||||
grace_distance = 3.34, -- 1.5 active region + 1.64 height offset + 0.1 safety
|
||||
on_collide_with_entity = on_collide,
|
||||
on_collide_with_solid = function(self, pos, node)
|
||||
if mod_target and node.name == "mcl_target:target_off" then
|
||||
|
|
|
@ -46,9 +46,12 @@ function mcl_potions.register_splash(name, descr, color, def)
|
|||
local dir = placer:get_look_dir();
|
||||
local pos = placer:get_pos();
|
||||
minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
|
||||
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
|
||||
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
|
||||
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
|
||||
local obj = vl_projectile.create(id.."_flying",{
|
||||
pos = vector.offset(pos, dir.x, dir.y + 1.64, dir.z),
|
||||
owner = placer,
|
||||
dir = dir,
|
||||
velocity = velocity,
|
||||
})
|
||||
local ent = obj:get_luaentity()
|
||||
ent._thrower = placer:get_player_name()
|
||||
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
|
||||
|
@ -180,6 +183,7 @@ function mcl_potions.register_splash(name, descr, color, def)
|
|||
vl_projectile.collides_with_entities,
|
||||
vl_projectile.collides_with_solids,
|
||||
},
|
||||
grace_distance = 3.34, -- 1.5 active region + 1.64 height offset + 0.1 safety
|
||||
on_collide_with_solid = function(self, pos, node)
|
||||
splash_effects(self, pos, def, 4)
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ function mcl_potions.register_arrow(name, desc, color, def)
|
|||
mcl_bows.arrow_entity.on_activate(self, staticdata, dtime_s)
|
||||
self._arrow_item = arrow_item
|
||||
end
|
||||
minetest.register_entity("mcl_potions:"..name.."_arrow_entity", arrow_entity)
|
||||
vl_projectile.register("mcl_potions:"..name.."_arrow_entity", arrow_entity)
|
||||
|
||||
if minetest.get_modpath("mcl_bows") then
|
||||
minetest.register_craft({
|
||||
|
|
|
@ -53,14 +53,16 @@ function mod.projectile_physics(obj, entity_def, v, a)
|
|||
|
||||
-- Update projectile yaw to match velocity direction
|
||||
if v and le and not le._stuck then
|
||||
local yaw = minetest.dir_to_yaw(v) + YAW_OFFSET
|
||||
local pitch = math.asin(vector.normalize(v).y)
|
||||
local yaw = minetest.dir_to_yaw(v) + YAW_OFFSET + (entity_def._vl_projectile.yaw_offset or 0)
|
||||
local pitch = math.asin(vector.normalize(v).y) + (entity_def._vl_projectile.pitch_offset or 0)
|
||||
obj:set_rotation(vector.new(0,yaw,pitch))
|
||||
end
|
||||
end
|
||||
|
||||
function mod.update_projectile(self, dtime)
|
||||
if self._removed then return end
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
-- Workaround for randomly occurring velocity change between projectile creation
|
||||
-- and the first time step
|
||||
|
@ -82,15 +84,14 @@ function mod.update_projectile(self, dtime)
|
|||
self.timer = (self.timer or 0) + dtime
|
||||
local maximum_flight_time = entity_vl_projectile.maximum_time or 300
|
||||
if (self.timer or 0) > maximum_flight_time then
|
||||
self.removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
end
|
||||
|
||||
-- Run behaviors
|
||||
local behaviors = entity_vl_projectile.behaviors or {}
|
||||
for i=1,#behaviors do
|
||||
if behaviors[i](self, dtime, entity_def, entity_vl_projectile) then
|
||||
if behaviors[i](self, dtime, entity_def, entity_vl_projectile) or self._removed then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -98,6 +99,9 @@ function mod.update_projectile(self, dtime)
|
|||
if not self._stuck then
|
||||
mod.projectile_physics(self.object, entity_def)
|
||||
end
|
||||
|
||||
-- Update last position
|
||||
self._last_pos = pos
|
||||
end
|
||||
|
||||
local function damage_particles(pos, is_critical)
|
||||
|
@ -155,10 +159,7 @@ local function handle_player_sticking(self, entity_def, projectile_def, entity)
|
|||
if self._in_player or self._blocked then return end
|
||||
if not projectile_def.sticks_in_players then return end
|
||||
|
||||
minetest.after(150, function()
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
end)
|
||||
minetest.after(150, function() mcl_util.remove_entity(self) end)
|
||||
|
||||
-- Handle blocking projectiles
|
||||
if mcl_shields.is_blocking(entity) then
|
||||
|
@ -256,15 +257,14 @@ function mod.replace_with_item_drop(self, pos, projectile_def)
|
|||
item = projectile_def.item
|
||||
end
|
||||
|
||||
if self._collectable and not minetest.is_creative_enabled("") then
|
||||
if item and self._collectable and not minetest.is_creative_enabled("") then
|
||||
local item = minetest.add_item(pos, item)
|
||||
item:set_velocity(vector.zero())
|
||||
item:set_yaw(self.object:get_yaw())
|
||||
end
|
||||
|
||||
mcl_burning.extinguish(self.object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
end
|
||||
|
||||
local function stuck_on_step(self, dtime, entity_def, projectile_def)
|
||||
|
@ -275,8 +275,7 @@ local function stuck_on_step(self, dtime, entity_def, projectile_def)
|
|||
self._stucktimer = (self._stucktimer or 0) + dtime
|
||||
if self._stucktimer > STUCK_TIMEOUT then
|
||||
mcl_burning.extinguish(self.object)
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -295,15 +294,22 @@ local function stuck_on_step(self, dtime, entity_def, projectile_def)
|
|||
end
|
||||
end
|
||||
|
||||
-- Don't allow players to pick up arrows stuck in them or other players
|
||||
if self._in_player then return true end
|
||||
|
||||
-- Pickup arrow if player is nearby (not in Creative Mode)
|
||||
if not self._collectable or self._removed then return end
|
||||
|
||||
local objects = minetest.get_objects_inside_radius(pos, 1)
|
||||
for i = 1,#objects do
|
||||
obj = objects[i]
|
||||
local obj = objects[i]
|
||||
if obj:is_player() then
|
||||
if self._collectable and not minetest.is_creative_enabled(obj:get_player_name()) then
|
||||
local arrow_item = self._arrow_item
|
||||
local player_name = obj:get_player_name()
|
||||
if not minetest.is_creative_enabled(player_name) then
|
||||
local arrow_item = self._itemstring or self._arrow_item
|
||||
if arrow_item and minetest.registered_items[arrow_item] and obj:get_inventory():room_for_item("main", arrow_item) then
|
||||
obj:get_inventory():add_item("main", arrow_item)
|
||||
self._picked_up = true
|
||||
|
||||
minetest.sound_play("item_drop_pickup", {
|
||||
pos = pos,
|
||||
|
@ -311,13 +317,12 @@ local function stuck_on_step(self, dtime, entity_def, projectile_def)
|
|||
gain = 1.0,
|
||||
}, true)
|
||||
end
|
||||
end
|
||||
mcl_burning.extinguish(self.object)
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
||||
return true
|
||||
mcl_burning.extinguish(self.object)
|
||||
mcl_util.remove_entity(self)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -334,13 +339,9 @@ end
|
|||
|
||||
function mod.collides_with_solids(self, dtime, entity_def, projectile_def)
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
-- Don't try to do anything on first update
|
||||
if not self._last_pos then
|
||||
self._last_pos = pos
|
||||
return
|
||||
end
|
||||
if not self._last_pos then return end
|
||||
|
||||
-- Check if the object can collide with this node
|
||||
local node = minetest.get_node(pos)
|
||||
|
@ -440,8 +441,7 @@ function mod.collides_with_solids(self, dtime, entity_def, projectile_def)
|
|||
survive_collision = survive_collision(self, entity_def, projectile_def, "node", node, node_def)
|
||||
end
|
||||
if not survive_collision then
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
end
|
||||
|
||||
-- Done with behaviors
|
||||
|
@ -458,21 +458,13 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
|
|||
allow_punching = allow_punching(self, entity_def, projectile_def, object)
|
||||
end
|
||||
|
||||
if DEBUG then
|
||||
minetest.log("handle_entity_collision("..dump({
|
||||
self = self,
|
||||
allow_punching = allow_punching,
|
||||
entity_def = entity_def,
|
||||
object = object,
|
||||
object_id = mcl_util.get_entity_id(object),
|
||||
luaentity = object:get_luaentity(),
|
||||
})..")")
|
||||
end
|
||||
|
||||
if not allow_punching then return end
|
||||
|
||||
local object_lua = object:get_luaentity()
|
||||
|
||||
-- Normally objects should be removed on collision with entities
|
||||
local survive_collision = projectile_def.survive_collision
|
||||
|
||||
-- Apply damage
|
||||
-- Note: Damage blocking for shields is handled in mcl_shields with an mcl_damage modifier
|
||||
local do_damage = false
|
||||
|
@ -480,6 +472,7 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
|
|||
do_damage = true
|
||||
|
||||
handle_player_sticking(self, entity_def, projectile_def, object)
|
||||
survive_collision = true
|
||||
elseif object_lua and (object_lua.is_mob or object_lua._hittable_by_projectile) then
|
||||
do_damage = true
|
||||
end
|
||||
|
@ -491,7 +484,7 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
|
|||
dmg = dmg(self, entity_def, projectile_def, object)
|
||||
end
|
||||
|
||||
object:punch(self.object, 1.0, projectile_def.tool or { full_punch_interval = 1.0, damage_groups = dmg }, dir )
|
||||
mcl_util.deal_damage(object, dmg.fleshy, {type = projectile_def.damage_type or "arrow", source = mcl_util.get_entity_from_id(self._owner), direct = self.object})
|
||||
|
||||
-- Guard against crashes when projectiles get destroyed in response to what it punched
|
||||
if not self.object:get_pos() then return true end
|
||||
|
@ -525,14 +518,12 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
|
|||
minetest.sound_play(sound[1], arg2, sound[3])
|
||||
end
|
||||
|
||||
-- Normally objects should be removed on collision with entities
|
||||
local survive_collision = projectile_def.survive_collision
|
||||
-- Remove the projectile if it didn't survive
|
||||
if type(survive_collision) == "function" then
|
||||
survive_collision = survive_collision(self, entity_def, projectile_def, "entity", object)
|
||||
end
|
||||
if not survive_collision then
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
mcl_util.remove_entity(self)
|
||||
end
|
||||
|
||||
return true
|
||||
|
|
Loading…
Reference in New Issue