forked from mtcontrib/mobs_redo
tweaked line of sight, mob drops
This commit is contained in:
parent
e64df178f8
commit
607e596c05
149
api.lua
149
api.lua
@ -1,32 +1,20 @@
|
|||||||
|
|
||||||
-- Mobs Api
|
-- Intllib and CMI support check
|
||||||
|
|
||||||
mobs = {}
|
|
||||||
mobs.mod = "redo"
|
|
||||||
mobs.version = "20180831"
|
|
||||||
|
|
||||||
|
|
||||||
-- Intllib
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
local S, NS = dofile(MP .. "/intllib.lua")
|
local S, NS = dofile(MP .. "/intllib.lua")
|
||||||
mobs.intllib = S
|
|
||||||
|
|
||||||
|
|
||||||
-- CMI support check
|
|
||||||
local use_cmi = minetest.global_exists("cmi")
|
local use_cmi = minetest.global_exists("cmi")
|
||||||
|
|
||||||
|
mobs = {
|
||||||
-- Invisibility mod check
|
mod = "redo",
|
||||||
mobs.invis = {}
|
version = "20180904",
|
||||||
if minetest.global_exists("invisibility") then
|
intllib = S,
|
||||||
mobs.invis = invisibility
|
invis = minetest.global_exists("invisibility") and invisibility or {},
|
||||||
end
|
}
|
||||||
|
|
||||||
|
|
||||||
-- creative check
|
-- creative check
|
||||||
local creative_mode_cache = minetest.settings:get_bool("creative_mode")
|
local creative_cache = minetest.settings:get_bool("creative_mode")
|
||||||
function mobs.is_creative(name)
|
function mobs.is_creative(name)
|
||||||
return creative_mode_cache or minetest.check_player_privs(name, {creative = true})
|
return creative_cache or minetest.check_player_privs(name, {creative = true})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -123,7 +111,7 @@ end
|
|||||||
-- move mob in facing direction
|
-- move mob in facing direction
|
||||||
local set_velocity = function(self, v)
|
local set_velocity = function(self, v)
|
||||||
|
|
||||||
-- do not move if mob has been ordered to stay
|
-- halt mob if it has been ordered to stay
|
||||||
if self.order == "stand" then
|
if self.order == "stand" then
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
self.object:set_velocity({x = 0, y = 0, z = 0})
|
||||||
return
|
return
|
||||||
@ -220,7 +208,6 @@ local set_animation = function(self, anim)
|
|||||||
0, self.animation[anim .. "_loop"] ~= false)
|
0, self.animation[anim .. "_loop"] ~= false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- above function exported for mount.lua
|
-- above function exported for mount.lua
|
||||||
function mobs:set_animation(self, anim)
|
function mobs:set_animation(self, anim)
|
||||||
set_animation(self, anim)
|
set_animation(self, anim)
|
||||||
@ -264,8 +251,8 @@ local line_of_sight = function(self, pos1, pos2, stepsize)
|
|||||||
-- It continues to advance in the line of sight in search of a real
|
-- It continues to advance in the line of sight in search of a real
|
||||||
-- obstruction which counts as 'normal' nodebox.
|
-- obstruction which counts as 'normal' nodebox.
|
||||||
while minetest.registered_nodes[nn]
|
while minetest.registered_nodes[nn]
|
||||||
and (minetest.registered_nodes[nn].walkable == false
|
and (minetest.registered_nodes[nn].walkable == false) do
|
||||||
or minetest.registered_nodes[nn].drawtype == "nodebox") do
|
-- or minetest.registered_nodes[nn].drawtype == "nodebox") do
|
||||||
|
|
||||||
npos1 = vector.add(npos1, stepv)
|
npos1 = vector.add(npos1, stepv)
|
||||||
|
|
||||||
@ -379,7 +366,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- drop items
|
-- drop items
|
||||||
local item_drop = function(self, cooked)
|
local item_drop = function(self)
|
||||||
|
|
||||||
-- check for nil or no drops
|
-- check for nil or no drops
|
||||||
if not self.drops or #self.drops == 0 then
|
if not self.drops or #self.drops == 0 then
|
||||||
@ -392,6 +379,10 @@ local item_drop = function(self, cooked)
|
|||||||
-- no drops for child mobs
|
-- no drops for child mobs
|
||||||
if self.child then return end
|
if self.child then return end
|
||||||
|
|
||||||
|
-- was mob killed by player?
|
||||||
|
local death_by_player = self.cause_of_death and self.cause_of_death.puncher
|
||||||
|
and self.cause_of_death.puncher:is_player() or nil
|
||||||
|
|
||||||
local obj, item, num
|
local obj, item, num
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
@ -402,8 +393,8 @@ local item_drop = function(self, cooked)
|
|||||||
num = random(self.drops[n].min or 0, self.drops[n].max or 1)
|
num = random(self.drops[n].min or 0, self.drops[n].max or 1)
|
||||||
item = self.drops[n].name
|
item = self.drops[n].name
|
||||||
|
|
||||||
-- cook items when true
|
-- cook items on a hot death
|
||||||
if cooked then
|
if self.cause_of_death.hot then
|
||||||
|
|
||||||
local output = minetest.get_craft_result({
|
local output = minetest.get_craft_result({
|
||||||
method = "cooking", width = 1, items = {item}})
|
method = "cooking", width = 1, items = {item}})
|
||||||
@ -413,8 +404,13 @@ local item_drop = function(self, cooked)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add item if it exists
|
-- only drop rare items (drops.min=0) if killed by player
|
||||||
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
|
if death_by_player then
|
||||||
|
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
|
||||||
|
|
||||||
|
elseif self.drops[n].min ~= 0 then
|
||||||
|
obj = minetest.add_item(pos, ItemStack(item .. " " .. num))
|
||||||
|
end
|
||||||
|
|
||||||
if obj and obj:get_luaentity() then
|
if obj and obj:get_luaentity() then
|
||||||
|
|
||||||
@ -423,6 +419,7 @@ local item_drop = function(self, cooked)
|
|||||||
y = 6,
|
y = 6,
|
||||||
z = random(-10, 10) / 9,
|
z = random(-10, 10) / 9,
|
||||||
})
|
})
|
||||||
|
|
||||||
elseif obj then
|
elseif obj then
|
||||||
obj:remove() -- item does not exist
|
obj:remove() -- item does not exist
|
||||||
end
|
end
|
||||||
@ -470,12 +467,10 @@ local check_for_death = function(self, cause, cmi_cause)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- dropped cooked item if mob died in lava
|
self.cause_of_death = cmi_cause
|
||||||
if cause == "lava" then
|
|
||||||
item_drop(self, true)
|
-- drop items
|
||||||
else
|
item_drop(self)
|
||||||
item_drop(self, nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
mob_sound(self, self.sounds.death)
|
mob_sound(self, self.sounds.death)
|
||||||
|
|
||||||
@ -536,22 +531,6 @@ local check_for_death = function(self, cause, cmi_cause)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- check if within physical map limits (-30911 to 30927)
|
|
||||||
local within_limits = function(pos, radius)
|
|
||||||
|
|
||||||
if (pos.x - radius) > -30913
|
|
||||||
and (pos.x + radius) < 30928
|
|
||||||
and (pos.y - radius) > -30913
|
|
||||||
and (pos.y + radius) < 30928
|
|
||||||
and (pos.z - radius) > -30913
|
|
||||||
and (pos.z + radius) < 30928 then
|
|
||||||
return true -- within limits
|
|
||||||
end
|
|
||||||
|
|
||||||
return false -- beyond limits
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- is mob facing a cliff
|
-- is mob facing a cliff
|
||||||
local is_at_cliff = function(self)
|
local is_at_cliff = function(self)
|
||||||
|
|
||||||
@ -613,13 +592,13 @@ local do_env_damage = function(self)
|
|||||||
|
|
||||||
self.time_of_day = minetest.get_timeofday()
|
self.time_of_day = minetest.get_timeofday()
|
||||||
|
|
||||||
-- remove mob if beyond map limits
|
-- remove mob if standing inside ignore node
|
||||||
if not within_limits(pos, 0) then
|
if self.standing_in == "ignore" then
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- bright light harms mob
|
-- is mob light sensative :)
|
||||||
if self.light_damage ~= 0
|
if self.light_damage ~= 0
|
||||||
-- and pos.y > 0
|
-- and pos.y > 0
|
||||||
-- and self.time_of_day > 0.2
|
-- and self.time_of_day > 0.2
|
||||||
@ -644,10 +623,6 @@ local do_env_damage = function(self)
|
|||||||
self.standing_in = node_ok(pos, "air").name
|
self.standing_in = node_ok(pos, "air").name
|
||||||
-- print ("standing in " .. self.standing_in)
|
-- print ("standing in " .. self.standing_in)
|
||||||
]]
|
]]
|
||||||
-- don't fall when on ignore, just stand still
|
|
||||||
if self.standing_in == "ignore" then
|
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
|
||||||
end
|
|
||||||
|
|
||||||
local nodef = minetest.registered_nodes[self.standing_in]
|
local nodef = minetest.registered_nodes[self.standing_in]
|
||||||
|
|
||||||
@ -680,7 +655,7 @@ local do_env_damage = function(self)
|
|||||||
effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
|
effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
|
||||||
|
|
||||||
if check_for_death(self, "lava", {type = "environment",
|
if check_for_death(self, "lava", {type = "environment",
|
||||||
pos = pos, node = self.standing_in}) then return end
|
pos = pos, node = self.standing_in, hot = true}) then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- damage_per_second node check
|
-- damage_per_second node check
|
||||||
@ -1744,28 +1719,16 @@ local do_states = function(self, dtime)
|
|||||||
set_velocity(self, 0)
|
set_velocity(self, 0)
|
||||||
set_animation(self, "stand")
|
set_animation(self, "stand")
|
||||||
|
|
||||||
-- npc's ordered to stand stay standing
|
-- mobs ordered to stand stay standing
|
||||||
-- if self.type ~= "npc"
|
if self.order ~= "stand"
|
||||||
if self.order ~= "stand" then
|
and self.walk_chance ~= 0
|
||||||
|
and self.facing_fence ~= true
|
||||||
|
and random(1, 100) <= self.walk_chance
|
||||||
|
and is_at_cliff(self) == false then
|
||||||
|
|
||||||
if self.walk_chance ~= 0
|
set_velocity(self, self.walk_velocity)
|
||||||
and self.facing_fence ~= true
|
self.state = "walk"
|
||||||
and random(1, 100) <= self.walk_chance
|
set_animation(self, "walk")
|
||||||
and is_at_cliff(self) == false then
|
|
||||||
|
|
||||||
set_velocity(self, self.walk_velocity)
|
|
||||||
self.state = "walk"
|
|
||||||
set_animation(self, "walk")
|
|
||||||
|
|
||||||
--[[ fly up/down randomly for flying mobs
|
|
||||||
if self.fly and random(1, 100) <= self.walk_chance then
|
|
||||||
|
|
||||||
local v = self.object:get_velocity()
|
|
||||||
local ud = random(-1, 2) / 9
|
|
||||||
|
|
||||||
self.object:set_velocity({x = v.x, y = ud, z = v.z})
|
|
||||||
end--]]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif self.state == "walk" then
|
elseif self.state == "walk" then
|
||||||
@ -1871,7 +1834,8 @@ local do_states = function(self, dtime)
|
|||||||
|
|
||||||
-- stop after 5 seconds or when at cliff
|
-- stop after 5 seconds or when at cliff
|
||||||
if self.runaway_timer > 5
|
if self.runaway_timer > 5
|
||||||
or is_at_cliff(self) then
|
or is_at_cliff(self)
|
||||||
|
or self.order == "stand" then
|
||||||
self.runaway_timer = 0
|
self.runaway_timer = 0
|
||||||
set_velocity(self, 0)
|
set_velocity(self, 0)
|
||||||
self.state = "stand"
|
self.state = "stand"
|
||||||
@ -2493,8 +2457,8 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
|
|||||||
|
|
||||||
-- exit here if dead, special item check
|
-- exit here if dead, special item check
|
||||||
if weapon:get_name() == "mobs:pick_lava" then
|
if weapon:get_name() == "mobs:pick_lava" then
|
||||||
if check_for_death(self, "lava", {type = "punch",
|
if check_for_death(self, "hit", {type = "punch",
|
||||||
puncher = hitter}) then
|
puncher = hitter, hot = true}) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -3321,7 +3285,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- compatibility with older mob registration
|
-- compatibility with older mob registration
|
||||||
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
|
function mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
||||||
|
active_object_count, max_height, day_toggle)
|
||||||
|
|
||||||
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
|
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
|
||||||
chance, active_object_count, -31000, max_height, day_toggle)
|
chance, active_object_count, -31000, max_height, day_toggle)
|
||||||
@ -3381,8 +3346,7 @@ function mobs:register_arrow(name, def)
|
|||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
if self.switch == 0
|
if self.switch == 0
|
||||||
or self.timer > 150
|
or self.timer > 150 then
|
||||||
or not within_limits(pos, 0) then
|
|
||||||
|
|
||||||
self.object:remove() ; -- print ("removed arrow")
|
self.object:remove() ; -- print ("removed arrow")
|
||||||
|
|
||||||
@ -3548,7 +3512,6 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if pos
|
if pos
|
||||||
and within_limits(pos, 0)
|
|
||||||
and not minetest.is_protected(pos, placer:get_player_name()) then
|
and not minetest.is_protected(pos, placer:get_player_name()) then
|
||||||
|
|
||||||
if not minetest.registered_entities[mob] then
|
if not minetest.registered_entities[mob] then
|
||||||
@ -3595,7 +3558,6 @@ function mobs:register_egg(mob, desc, background, addegg, no_creative)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if pos
|
if pos
|
||||||
and within_limits(pos, 0)
|
|
||||||
and not minetest.is_protected(pos, placer:get_player_name()) then
|
and not minetest.is_protected(pos, placer:get_player_name()) then
|
||||||
|
|
||||||
if not minetest.registered_entities[mob] then
|
if not minetest.registered_entities[mob] then
|
||||||
@ -3628,7 +3590,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
-- capture critter (thanks to blert2112 for idea)
|
-- capture critter (thanks to blert2112 for idea)
|
||||||
function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
|
||||||
|
force_take, replacewith)
|
||||||
|
|
||||||
if self.child
|
if self.child
|
||||||
or not clicker:is_player()
|
or not clicker:is_player()
|
||||||
@ -3890,8 +3853,10 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
|||||||
minetest.show_formspec(name, "mobs_nametag", "size[8,4]"
|
minetest.show_formspec(name, "mobs_nametag", "size[8,4]"
|
||||||
.. default.gui_bg
|
.. default.gui_bg
|
||||||
.. default.gui_bg_img
|
.. default.gui_bg_img
|
||||||
.. "field[0.5,1;7.5,0;name;" .. minetest.formspec_escape(S("Enter name:")) .. ";" .. tag .. "]"
|
.. "field[0.5,1;7.5,0;name;"
|
||||||
.. "button_exit[2.5,3.5;3,1;mob_rename;" .. minetest.formspec_escape(S("Rename")) .. "]")
|
.. minetest.formspec_escape(S("Enter name:")) .. ";" .. tag .. "]"
|
||||||
|
.. "button_exit[2.5,3.5;3,1;mob_rename;"
|
||||||
|
.. minetest.formspec_escape(S("Rename")) .. "]")
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -23,6 +23,7 @@ Lucky Blocks: 9
|
|||||||
|
|
||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
|
- 1.46- Mobs only drop rare items when killed by player (drops.min = 0 makes them rare), code tweak, pathfinding no longer sees through walkable nodes
|
||||||
- 1.45- Added Fence Top to add on top of any fence to stop mobs escaping, new line_of_sight tweaked by Astrobe
|
- 1.45- Added Fence Top to add on top of any fence to stop mobs escaping, new line_of_sight tweaked by Astrobe
|
||||||
- 1.44- Added ToolRanks support for swords when attacking mobs
|
- 1.44- Added ToolRanks support for swords when attacking mobs
|
||||||
- 1.43- Better 0.4.16 compatibility, added general attack function and settings
|
- 1.43- Better 0.4.16 compatibility, added general attack function and settings
|
||||||
|
Loading…
Reference in New Issue
Block a user