mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-12-11 12:13:15 +01:00
Fix player-mcl_throwing collisions, fix chick spawning on egg collisions, luacheck fixes
This commit is contained in:
parent
c465c469c3
commit
8f7a020a0d
@ -17,6 +17,24 @@ minetest.register_craftitem("mcl_throwing:egg", {
|
|||||||
groups = { craftitem = 1 },
|
groups = { craftitem = 1 },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function egg_spawn_chicks(pos)
|
||||||
|
-- 1/8 chance to spawn a chick
|
||||||
|
if math.random(1,8) ~= 1 then return end
|
||||||
|
|
||||||
|
pos.y = math.ceil(pos.y)
|
||||||
|
|
||||||
|
if not mcl_mobs.spawn_child(pos, "mobs_mc:chicken") then
|
||||||
|
minetest.log("unable to spawn chick at "..vector.to_string(pos))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- BONUS ROUND: 1/32 chance to spawn 3 additional chicks
|
||||||
|
if math.random(1,32) ~= 1 then return end
|
||||||
|
|
||||||
|
mcl_mobs.spawn_child(vector.offset(pos, 0.7, 0, 0 ), "mobs_mc:chicken")
|
||||||
|
mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0, -0.7), "mobs_mc:chicken")
|
||||||
|
mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0, 0.7), "mobs_mc:chicken")
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_entity("mcl_throwing:egg_entity",{
|
minetest.register_entity("mcl_throwing:egg_entity",{
|
||||||
physical = false,
|
physical = false,
|
||||||
timer=0,
|
timer=0,
|
||||||
@ -34,24 +52,22 @@ minetest.register_entity("mcl_throwing:egg_entity",{
|
|||||||
_vl_projectile = {
|
_vl_projectile = {
|
||||||
behaviors = {
|
behaviors = {
|
||||||
vl_projectile.collides_with_solids,
|
vl_projectile.collides_with_solids,
|
||||||
|
vl_projectile.collides_with_entities,
|
||||||
},
|
},
|
||||||
|
allow_punching = function(self, _, _, object)
|
||||||
|
if self._owner == object:get_player_name() then
|
||||||
|
return self.timer > 1
|
||||||
|
end
|
||||||
|
end,
|
||||||
on_collide_with_solid = function(self, pos, node)
|
on_collide_with_solid = function(self, pos, node)
|
||||||
if mod_target and node.name == "mcl_target:target_off" then
|
if mod_target and node.name == "mcl_target:target_off" then
|
||||||
mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
|
mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 1/8 chance to spawn a chick
|
egg_spawn_chicks(pos)
|
||||||
-- FIXME: Chicks have a quite good chance to spawn in walls
|
end,
|
||||||
if math.random(1,8) ~= 1 then return end
|
on_collide_with_entity = function(self, pos, obj)
|
||||||
|
egg_spawn_chicks(pos)
|
||||||
mcl_mobs.spawn_child(pos, "mobs_mc:chicken")
|
|
||||||
|
|
||||||
-- BONUS ROUND: 1/32 chance to spawn 3 additional chicks
|
|
||||||
if math.random(1,32) ~= 1 then return end
|
|
||||||
|
|
||||||
mcl_mobs.spawn_child(vector.offset(pos, 0.7, 0, 0 ), "mobs_mc:chicken")
|
|
||||||
mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0, -0.7), "mobs_mc:chicken")
|
|
||||||
mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0, 0.7), "mobs_mc:chicken")
|
|
||||||
end,
|
end,
|
||||||
sounds = {
|
sounds = {
|
||||||
on_collision = {"mcl_throwing_egg_impact", {max_hear_distance=10, gain=0.5}, true}
|
on_collision = {"mcl_throwing_egg_impact", {max_hear_distance=10, gain=0.5}, true}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
local modname = minetest.get_current_modname()
|
local modname = minetest.get_current_modname()
|
||||||
local modpath = minetest.get_modpath(modname)
|
|
||||||
local S = minetest.get_translator(modname)
|
local S = minetest.get_translator(modname)
|
||||||
|
|
||||||
local math = math
|
local math = math
|
||||||
@ -21,6 +20,85 @@ minetest.register_craftitem("mcl_throwing:ender_pearl", {
|
|||||||
groups = { transport = 1 },
|
groups = { transport = 1 },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function on_collide(self, pos, node)
|
||||||
|
if mod_target and node.name == "mcl_target:target_off" then
|
||||||
|
mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
|
||||||
|
end
|
||||||
|
|
||||||
|
if node.name == "ignore" then
|
||||||
|
-- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Make sure we have a reference to the player
|
||||||
|
local player = self._thrower and minetest.get_player_by_name(self._thrower)
|
||||||
|
if not player then return end
|
||||||
|
|
||||||
|
-- Teleport and hurt player
|
||||||
|
|
||||||
|
-- First determine good teleport position
|
||||||
|
local dir = vector.zero()
|
||||||
|
|
||||||
|
local v = self.object:get_velocity()
|
||||||
|
local node_def = minetest.registered_nodes[node.name]
|
||||||
|
if node_def and node_def.walkable then
|
||||||
|
local vc = vector.normalize(v) -- vector for calculating
|
||||||
|
-- Node is walkable, we have to find a place somewhere outside of that node
|
||||||
|
|
||||||
|
-- Zero-out the two axes with a lower absolute value than the axis with the strongest force
|
||||||
|
local lv, ld = math.abs(vc.y), "y"
|
||||||
|
if math.abs(vc.x) > lv then
|
||||||
|
lv, ld = math.abs(vc.x), "x"
|
||||||
|
end
|
||||||
|
if math.abs(vc.z) > lv then
|
||||||
|
ld = "z" --math.abs(vc.z)
|
||||||
|
end
|
||||||
|
if ld ~= "x" then vc.x = 0 end
|
||||||
|
if ld ~= "y" then vc.y = 0 end
|
||||||
|
if ld ~= "z" then vc.z = 0 end
|
||||||
|
|
||||||
|
-- Final tweaks to the teleporting pos, based on direction
|
||||||
|
-- Impact from the side
|
||||||
|
dir.x = vc.x * -1
|
||||||
|
dir.z = vc.z * -1
|
||||||
|
|
||||||
|
-- Special case: top or bottom of node
|
||||||
|
if vc.y > 0 then
|
||||||
|
-- We need more space when impact is from below
|
||||||
|
dir.y = -2.3
|
||||||
|
elseif vc.y < 0 then
|
||||||
|
-- Standing on top
|
||||||
|
dir.y = 0.5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- If node was not walkable, no modification to pos is made.
|
||||||
|
|
||||||
|
-- Final teleportation position
|
||||||
|
local telepos = vector.add(pos, dir)
|
||||||
|
local telenode = minetest.get_node(telepos)
|
||||||
|
|
||||||
|
--[[ It may be possible that telepos is walkable due to the algorithm.
|
||||||
|
Especially when the ender pearl is faster horizontally than vertical.
|
||||||
|
This applies final fixing, just to be sure we're not in a walkable node ]]
|
||||||
|
if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then
|
||||||
|
if v.y < 0 then
|
||||||
|
telepos.y = telepos.y + 0.5
|
||||||
|
else
|
||||||
|
telepos.y = telepos.y - 2.3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local oldpos = player:get_pos()
|
||||||
|
-- Teleport and hurt player
|
||||||
|
player:set_pos(telepos)
|
||||||
|
player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" })
|
||||||
|
|
||||||
|
-- 5% chance to spawn endermite at the player's origin
|
||||||
|
if math.random(1,20) == 1 then
|
||||||
|
minetest.add_entity(oldpos, "mobs_mc:endermite")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Ender pearl entity
|
-- Ender pearl entity
|
||||||
vl_projectile.register("mcl_throwing:ender_pearl_entity",{
|
vl_projectile.register("mcl_throwing:ender_pearl_entity",{
|
||||||
physical = false,
|
physical = false,
|
||||||
@ -39,90 +117,22 @@ vl_projectile.register("mcl_throwing:ender_pearl_entity",{
|
|||||||
_vl_projectile = {
|
_vl_projectile = {
|
||||||
behaviors = {
|
behaviors = {
|
||||||
vl_projectile.collides_with_solids,
|
vl_projectile.collides_with_solids,
|
||||||
|
vl_projectile.collides_with_entities,
|
||||||
},
|
},
|
||||||
collides_with = {
|
collides_with = {
|
||||||
"mcl_core:vine", "mcl_core:deadbush",
|
"mcl_core:vine", "mcl_core:deadbush",
|
||||||
"group:flower", "group:sapling",
|
"group:flower", "group:sapling",
|
||||||
"group:plant", "group:mushroom",
|
"group:plant", "group:mushroom",
|
||||||
},
|
},
|
||||||
on_collide_with_solid = function(self, pos, node)
|
allow_punching = function(self, _, _, object)
|
||||||
if mod_target and node.name == "mcl_target:target_off" then
|
if self._owner == object:get_player_name() then
|
||||||
mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
|
return self.timer > 1
|
||||||
end
|
end
|
||||||
|
end,
|
||||||
if node.name == "ignore" then
|
on_collide_with_entity = function(self, pos, entity)
|
||||||
-- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas
|
on_collide(self, pos, minetest.get_node(pos))
|
||||||
return
|
end,
|
||||||
end
|
on_collide_with_solid = on_collide,
|
||||||
|
|
||||||
-- Make sure we have a reference to the player
|
|
||||||
local player = self._thrower and minetest.get_player_by_name(self._thrower)
|
|
||||||
if not player then return end
|
|
||||||
|
|
||||||
-- Teleport and hurt player
|
|
||||||
|
|
||||||
-- First determine good teleport position
|
|
||||||
local dir = vector.zero()
|
|
||||||
|
|
||||||
local v = self.object:get_velocity()
|
|
||||||
local node_def = minetest.registered_nodes[node.name]
|
|
||||||
if node_def and node_def.walkable then
|
|
||||||
local vc = vector.normalize(v) -- vector for calculating
|
|
||||||
-- Node is walkable, we have to find a place somewhere outside of that node
|
|
||||||
|
|
||||||
-- Zero-out the two axes with a lower absolute value than the axis with the strongest force
|
|
||||||
local lv, ld = math.abs(vc.y), "y"
|
|
||||||
if math.abs(vc.x) > lv then
|
|
||||||
lv, ld = math.abs(vc.x), "x"
|
|
||||||
end
|
|
||||||
if math.abs(vc.z) > lv then
|
|
||||||
ld = "z" --math.abs(vc.z)
|
|
||||||
end
|
|
||||||
if ld ~= "x" then vc.x = 0 end
|
|
||||||
if ld ~= "y" then vc.y = 0 end
|
|
||||||
if ld ~= "z" then vc.z = 0 end
|
|
||||||
|
|
||||||
-- Final tweaks to the teleporting pos, based on direction
|
|
||||||
-- Impact from the side
|
|
||||||
dir.x = vc.x * -1
|
|
||||||
dir.z = vc.z * -1
|
|
||||||
|
|
||||||
-- Special case: top or bottom of node
|
|
||||||
if vc.y > 0 then
|
|
||||||
-- We need more space when impact is from below
|
|
||||||
dir.y = -2.3
|
|
||||||
elseif vc.y < 0 then
|
|
||||||
-- Standing on top
|
|
||||||
dir.y = 0.5
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- If node was not walkable, no modification to pos is made.
|
|
||||||
|
|
||||||
-- Final teleportation position
|
|
||||||
local telepos = vector.add(pos, dir)
|
|
||||||
local telenode = minetest.get_node(telepos)
|
|
||||||
|
|
||||||
--[[ It may be possible that telepos is walkable due to the algorithm.
|
|
||||||
Especially when the ender pearl is faster horizontally than vertical.
|
|
||||||
This applies final fixing, just to be sure we're not in a walkable node ]]
|
|
||||||
if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then
|
|
||||||
if v.y < 0 then
|
|
||||||
telepos.y = telepos.y + 0.5
|
|
||||||
else
|
|
||||||
telepos.y = telepos.y - 2.3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local oldpos = player:get_pos()
|
|
||||||
-- Teleport and hurt player
|
|
||||||
player:set_pos(telepos)
|
|
||||||
player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" })
|
|
||||||
|
|
||||||
-- 5% chance to spawn endermite at the player's origin
|
|
||||||
if math.random(1,20) == 1 then
|
|
||||||
minetest.add_entity(oldpos, "mobs_mc:endermite")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22)
|
mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
local modname = minetest.get_current_modname()
|
local modname = minetest.get_current_modname()
|
||||||
local S = minetest.get_translator(modname)
|
local S = minetest.get_translator(modname)
|
||||||
|
|
||||||
|
local mod_target = minetest.get_modpath("mcl_target")
|
||||||
local how_to_throw = S("Use the punch key to throw.")
|
local how_to_throw = S("Use the punch key to throw.")
|
||||||
|
|
||||||
-- Snowball
|
-- Snowball
|
||||||
@ -54,8 +55,11 @@ vl_projectile.register("mcl_throwing:snowball_entity", {
|
|||||||
vl_projectile.collides_with_entities,
|
vl_projectile.collides_with_entities,
|
||||||
},
|
},
|
||||||
allow_punching = function(self, _, _, object)
|
allow_punching = function(self, _, _, object)
|
||||||
return object.is_mob or object._hittable_by_projectile or
|
if self._owner == object:get_player_name() then
|
||||||
not object:is_player() or self._owner ~= object:get_player_name()
|
return self.timer > 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return object.is_mob or object._hittable_by_projectile or object:is_player()
|
||||||
end,
|
end,
|
||||||
on_collide_with_solid = function(self, pos, node)
|
on_collide_with_solid = function(self, pos, node)
|
||||||
if mod_target and node.name == "mcl_target:target_off" then
|
if mod_target and node.name == "mcl_target:target_off" then
|
||||||
|
Loading…
Reference in New Issue
Block a user