forked from VoxeLibre/VoxeLibre
Update mobs mod
This commit is contained in:
parent
084c299a3c
commit
b25254e516
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
-- Mobs Api (4th July 2017)
|
-- Mobs Api (14th July 2017)
|
||||||
|
|
||||||
mobs = {}
|
mobs = {}
|
||||||
mobs.mod = "redo"
|
mobs.mod = "redo"
|
||||||
mobs.version = "20170704"
|
mobs.version = "20170714"
|
||||||
|
|
||||||
|
|
||||||
-- Intllib
|
-- Intllib
|
||||||
|
@ -48,7 +48,7 @@ local damage_enabled = minetest.setting_getbool("enable_damage")
|
||||||
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
|
local peaceful_only = minetest.setting_getbool("only_peaceful_mobs")
|
||||||
local disable_blood = minetest.setting_getbool("mobs_disable_blood")
|
local disable_blood = minetest.setting_getbool("mobs_disable_blood")
|
||||||
local creative = minetest.setting_getbool("creative_mode")
|
local creative = minetest.setting_getbool("creative_mode")
|
||||||
local spawn_protected = tonumber(minetest.setting_get("mobs_spawn_protected")) or 1
|
local spawn_protected = minetest.setting_getbool("mobs_spawn_protected") ~= false
|
||||||
local remove_far = minetest.setting_getbool("remove_far_mobs")
|
local remove_far = minetest.setting_getbool("remove_far_mobs")
|
||||||
local difficulty = tonumber(minetest.setting_get("mob_difficulty")) or 1.0
|
local difficulty = tonumber(minetest.setting_get("mob_difficulty")) or 1.0
|
||||||
local show_health = false
|
local show_health = false
|
||||||
|
@ -64,6 +64,13 @@ local enable_pathfinding = true
|
||||||
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
|
local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching
|
||||||
local stuck_path_timeout = 10 -- how long will mob follow path before giving up
|
local stuck_path_timeout = 10 -- how long will mob follow path before giving up
|
||||||
|
|
||||||
|
-- default nodes
|
||||||
|
local node_fire = "mcl_fire:fire"
|
||||||
|
local node_permanent_flame = "mcl_fire:eternal_fire"
|
||||||
|
local node_ice = "mcl_core:ice"
|
||||||
|
local node_snowblock = "mcl_core:snowblock"
|
||||||
|
local node_snow = "mcl_core:snow"
|
||||||
|
mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt"
|
||||||
|
|
||||||
-- play sound
|
-- play sound
|
||||||
local mob_sound = function(self, sound)
|
local mob_sound = function(self, sound)
|
||||||
|
@ -242,9 +249,10 @@ end
|
||||||
local flight_check = function(self, pos_w)
|
local flight_check = function(self, pos_w)
|
||||||
|
|
||||||
local nod = self.standing_in
|
local nod = self.standing_in
|
||||||
|
local def = minetest.registered_nodes[nod]
|
||||||
|
|
||||||
if type(self.fly_in) == "string"
|
if type(self.fly_in) == "string"
|
||||||
and (nod == self.fly_in or nod == self.fly_in:gsub("_source", "_flowing")) then
|
and (nod == self.fly_in or def.liquid_alternative_flowing ~= "") then
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
@ -252,7 +260,7 @@ local flight_check = function(self, pos_w)
|
||||||
|
|
||||||
for _,fly_in in pairs(self.fly_in) do
|
for _,fly_in in pairs(self.fly_in) do
|
||||||
|
|
||||||
if nod == fly_in or nod == fly_in:gsub("_source", "_flowing") then
|
if nod == fly_in or def.liquid_alternative_flowing ~= "" then
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -507,7 +515,7 @@ end
|
||||||
-- get node but use fallback for nil or unknown
|
-- get node but use fallback for nil or unknown
|
||||||
local node_ok = function(pos, fallback)
|
local node_ok = function(pos, fallback)
|
||||||
|
|
||||||
fallback = fallback or "mcl_core:dirt"
|
fallback = fallback or mobs.fallback_node
|
||||||
|
|
||||||
local node = minetest.get_node_or_nil(pos)
|
local node = minetest.get_node_or_nil(pos)
|
||||||
|
|
||||||
|
@ -598,8 +606,8 @@ local do_env_damage = function(self)
|
||||||
-- lava or fire
|
-- lava or fire
|
||||||
elseif self.lava_damage
|
elseif self.lava_damage
|
||||||
and (nodef.groups.lava
|
and (nodef.groups.lava
|
||||||
or self.standing_in == "mcl_fire:fire"
|
or self.standing_in == node_fire
|
||||||
or self.standing_in == "mcl_fire:eternal_fire") then
|
or self.standing_in == node_permanent_flame) then
|
||||||
|
|
||||||
if self.lava_damage ~= 0 then
|
if self.lava_damage ~= 0 then
|
||||||
|
|
||||||
|
@ -681,7 +689,7 @@ local do_jump = function(self)
|
||||||
})
|
})
|
||||||
|
|
||||||
-- thin blocks that do not need to be jumped
|
-- thin blocks that do not need to be jumped
|
||||||
if nod.name == "mcl_core:snow" then
|
if nod.name == node_snow then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1049,7 +1057,7 @@ local smart_mobs = function(self, s, p, dist, dtime)
|
||||||
|
|
||||||
if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then
|
if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then
|
||||||
|
|
||||||
minetest.set_node(s, {name = "mcl_core:dirt"})
|
minetest.set_node(s, {name = mobs.fallback_node})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1511,7 +1519,7 @@ local do_states = function(self, dtime)
|
||||||
and minetest.registered_nodes[self.standing_in].groups.water) then
|
and minetest.registered_nodes[self.standing_in].groups.water) then
|
||||||
|
|
||||||
lp = minetest.find_node_near(s, 5, {"group:soil", "group:stone",
|
lp = minetest.find_node_near(s, 5, {"group:soil", "group:stone",
|
||||||
"group:sand", "mcl_core:ice", "mcl_core:snowblock"})
|
"group:sand", node_ice, node_snowblock})
|
||||||
|
|
||||||
-- did we find land?
|
-- did we find land?
|
||||||
if lp then
|
if lp then
|
||||||
|
@ -1675,30 +1683,36 @@ local do_states = function(self, dtime)
|
||||||
|
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
local radius = self.explosion_radius or 1
|
local radius = self.explosion_radius or 1
|
||||||
|
local damage_radius = radius
|
||||||
|
|
||||||
-- dont damage anything if area protected or next to water
|
-- dont damage anything if area protected or next to water
|
||||||
if minetest.find_node_near(pos, 1, {"group:water"})
|
if minetest.find_node_near(pos, 1, {"group:water"})
|
||||||
or minetest.is_protected(pos, "") then
|
or minetest.is_protected(pos, "") then
|
||||||
|
|
||||||
mob_sound(self, self.sounds.explode)
|
damage_radius = 0
|
||||||
|
|
||||||
self.object:remove()
|
|
||||||
|
|
||||||
effect(pos, 15, "tnt_smoke.png")
|
|
||||||
|
|
||||||
-- hurt player/mobs caught in blast area
|
|
||||||
entity_physics(pos, radius)
|
|
||||||
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|
||||||
pos.y = pos.y - 1
|
|
||||||
|
|
||||||
mobs:explosion(pos, radius, 0, 1, self.sounds.explode)
|
|
||||||
|
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
|
|
||||||
entity_physics(pos, radius)
|
if minetest.get_modpath("tnt") and tnt and tnt.boom
|
||||||
|
and not minetest.is_protected(pos, "") then
|
||||||
|
|
||||||
|
tnt.boom(pos, {
|
||||||
|
radius = radius,
|
||||||
|
damage_radius = damage_radius,
|
||||||
|
sound = self.sounds.explode,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
|
||||||
|
minetest.sound_play(self.sounds.explode, {
|
||||||
|
pos = pos,
|
||||||
|
gain = 1.0,
|
||||||
|
max_hear_distance = self.sounds.distance or 32
|
||||||
|
})
|
||||||
|
|
||||||
|
entity_physics(pos, damage_radius)
|
||||||
|
effect(pos, 32, "tnt_smoke.png", radius * 3, radius * 5, radius, 1, 0)
|
||||||
|
end
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -2764,7 +2778,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
|
||||||
end
|
end
|
||||||
|
|
||||||
-- mobs cannot spawn in protected areas when enabled
|
-- mobs cannot spawn in protected areas when enabled
|
||||||
if spawn_protected == 1
|
if not spawn_protected
|
||||||
and minetest.is_protected(pos, "") then
|
and minetest.is_protected(pos, "") then
|
||||||
--print ("--- inside protected area", name)
|
--print ("--- inside protected area", name)
|
||||||
return
|
return
|
||||||
|
@ -2850,96 +2864,6 @@ function mobs:spawn(def)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- set content id's
|
|
||||||
local c_air = minetest.get_content_id("air")
|
|
||||||
local c_ignore = minetest.get_content_id("ignore")
|
|
||||||
local c_obsidian = minetest.get_content_id("mcl_core:obsidian")
|
|
||||||
local c_fire = minetest.get_content_id("mcl_fire:fire")
|
|
||||||
|
|
||||||
-- explosion (cannot break protected or unbreakable nodes)
|
|
||||||
function mobs:explosion(pos, radius, fire, smoke, sound)
|
|
||||||
|
|
||||||
radius = radius or 0
|
|
||||||
fire = fire or 0
|
|
||||||
smoke = smoke or 0
|
|
||||||
|
|
||||||
-- if area protected or near map limits then no blast damage
|
|
||||||
if minetest.is_protected(pos, "")
|
|
||||||
or not within_limits(pos, radius) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- explosion sound
|
|
||||||
if sound
|
|
||||||
and sound ~= "" then
|
|
||||||
|
|
||||||
minetest.sound_play(sound, {
|
|
||||||
pos = pos,
|
|
||||||
gain = 1.0,
|
|
||||||
max_hear_distance = 16
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
pos = vector.round(pos) -- voxelmanip doesn't work properly unless pos is rounded ?!?!
|
|
||||||
|
|
||||||
local vm = VoxelManip()
|
|
||||||
local minp, maxp = vm:read_from_map(vector.subtract(pos, radius), vector.add(pos, radius))
|
|
||||||
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
|
||||||
local data = vm:get_data()
|
|
||||||
local p = {}
|
|
||||||
local pr = PseudoRandom(os.time())
|
|
||||||
|
|
||||||
for z = -radius, radius do
|
|
||||||
for y = -radius, radius do
|
|
||||||
local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
|
|
||||||
for x = -radius, radius do
|
|
||||||
|
|
||||||
p.x = pos.x + x
|
|
||||||
p.y = pos.y + y
|
|
||||||
p.z = pos.z + z
|
|
||||||
|
|
||||||
if (x * x) + (y * y) + (z * z) <= (radius * radius) + pr:next(-radius, radius)
|
|
||||||
and data[vi] ~= c_air
|
|
||||||
and data[vi] ~= c_ignore
|
|
||||||
and data[vi] ~= c_obsidian
|
|
||||||
and data[vi] ~= c_fire then
|
|
||||||
|
|
||||||
local n = node_ok(p).name
|
|
||||||
local on_blast = minetest.registered_nodes[n].on_blast
|
|
||||||
|
|
||||||
if on_blast then
|
|
||||||
|
|
||||||
return on_blast(p)
|
|
||||||
|
|
||||||
elseif minetest.registered_nodes[n].groups.unbreakable == 1 then
|
|
||||||
|
|
||||||
-- do nothing
|
|
||||||
else
|
|
||||||
|
|
||||||
-- after effects
|
|
||||||
if fire > 0
|
|
||||||
and (minetest.registered_nodes[n].groups.flammable
|
|
||||||
or random(1, 100) <= 30) then
|
|
||||||
|
|
||||||
minetest.set_node(p, {name = "mcl_fire:fire"})
|
|
||||||
else
|
|
||||||
minetest.set_node(p, {name = "air"})
|
|
||||||
|
|
||||||
if smoke > 0 then
|
|
||||||
effect(p, 2, "tnt_smoke.png", 3*radius, 5*radius, radius, 0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vi = vi + 1
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- register arrow for shoot attack
|
-- register arrow for shoot attack
|
||||||
function mobs:register_arrow(name, def)
|
function mobs:register_arrow(name, def)
|
||||||
|
|
||||||
|
@ -3034,16 +2958,12 @@ function mobs:register_arrow(name, def)
|
||||||
end
|
end
|
||||||
|
|
||||||
local entity = player:get_luaentity()
|
local entity = player:get_luaentity()
|
||||||
and player:get_luaentity().name or ""
|
|
||||||
|
|
||||||
if self.hit_mob
|
if entity
|
||||||
|
and self.hit_mob
|
||||||
|
and entity._cmi_is_mob == true
|
||||||
and tostring(player) ~= self.owner_id
|
and tostring(player) ~= self.owner_id
|
||||||
and entity ~= self.object:get_luaentity().name
|
and entity.name ~= self.object:get_luaentity().name then
|
||||||
and entity ~= "__builtin:item"
|
|
||||||
and entity ~= "__builtin:falling_node"
|
|
||||||
and entity ~= "gauges:hp_bar"
|
|
||||||
and entity ~= "mcl_signs:text"
|
|
||||||
and entity ~= "itemframes:item" then
|
|
||||||
|
|
||||||
self.hit_mob(self, player)
|
self.hit_mob(self, player)
|
||||||
|
|
||||||
|
@ -3060,6 +2980,38 @@ function mobs:register_arrow(name, def)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- compatibility function
|
||||||
|
function mobs:explosion(pos, radius)
|
||||||
|
local self = {sounds = {}}
|
||||||
|
self.sounds.explode = "tnt_explode"
|
||||||
|
mobs:boom(self, pos, radius)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- make explosion with protection and tnt mod check
|
||||||
|
function mobs:boom(self, pos, radius)
|
||||||
|
|
||||||
|
if minetest.get_modpath("tnt") and tnt and tnt.boom
|
||||||
|
and not minetest.is_protected(pos, "") then
|
||||||
|
|
||||||
|
tnt.boom(pos, {
|
||||||
|
radius = radius,
|
||||||
|
damage_radius = radius,
|
||||||
|
sound = self.sounds.explode,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
minetest.sound_play(self.sounds.explode, {
|
||||||
|
pos = pos,
|
||||||
|
gain = 1.0,
|
||||||
|
max_hear_distance = self.sounds.distance or 32
|
||||||
|
})
|
||||||
|
|
||||||
|
entity_physics(pos, radius)
|
||||||
|
effect(pos, 32, "tnt_smoke.png", radius * 3, radius * 5, radius, 1, 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Register spawn eggs
|
-- Register spawn eggs
|
||||||
|
|
||||||
-- Note: This also introduces the “spawn_egg” group:
|
-- Note: This also introduces the “spawn_egg” group:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
MOB API (4th July 2017)
|
MOB API (13th July 2017)
|
||||||
|
|
||||||
The mob api is a function that can be called on by other mods to add new animals or monsters into minetest.
|
The mob api is a function that can be called on by other mods to add new animals or monsters into minetest.
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ The mob api is a function that can be called on by other mods to add new animals
|
||||||
'enable_damage' if true monsters will attack players (default is true)
|
'enable_damage' if true monsters will attack players (default is true)
|
||||||
'only_peaceful_mobs' if true only animals will spawn in game (default is false)
|
'only_peaceful_mobs' if true only animals will spawn in game (default is false)
|
||||||
'mobs_disable_blood' if false blood effects appear when mob is hit (default is false)
|
'mobs_disable_blood' if false blood effects appear when mob is hit (default is false)
|
||||||
'mobs_spawn_protected' if set to 1 then mobs will not spawn in protected areas (default is 0)
|
'mobs_spawn_protected' if set to false then mobs will not spawn in protected areas (default is true)
|
||||||
'remove_far_mobs' if true then mobs that are outside players visual range will be removed (default is false)
|
'remove_far_mobs' if true then mobs that are outside players visual range will be removed (default is false)
|
||||||
'mobname' can change specific mob chance rate (0 to disable) and spawn number e.g. mobs_animal:cow = 1000,5
|
'mobname' can change specific mob chance rate (0 to disable) and spawn number e.g. mobs_animal:cow = 1000,5
|
||||||
'mob_difficulty' sets difficulty level (health and hit damage multiplied by this number), defaults to 1.0.
|
'mob_difficulty' sets difficulty level (health and hit damage multiplied by this number), defaults to 1.0.
|
||||||
|
@ -229,15 +229,14 @@ This function registers a spawn egg which can be used by admin to properly spawn
|
||||||
'no_creative' when set to true this stops spawn egg appearing in creative mode for destructive mobs like Dungeon Masters
|
'no_creative' when set to true this stops spawn egg appearing in creative mode for destructive mobs like Dungeon Masters
|
||||||
|
|
||||||
|
|
||||||
mobs:explosion(pos, radius, fire, smoke)
|
mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead
|
||||||
|
|
||||||
This function generates an explosion which removes nodes in a specific radius and replace them with fire or air. Protection nodes, obsidian and locked chests will not be destroyed although a normal chest will drop it's contents.
|
mobs:boom(self, pos, radius)
|
||||||
|
This function generates an explosion which removes nodes in a specific radius and damages any entity caught inside the blast radius. Protection will limit node destruction but not entity damage.
|
||||||
|
|
||||||
|
'self' mob entity
|
||||||
'pos' centre position of explosion
|
'pos' centre position of explosion
|
||||||
'radius' radius of explosion (typically set to 3)
|
'radius' radius of explosion (typically set to 3)
|
||||||
'fire' should fire appear in explosion (1=yes, 0=no)
|
|
||||||
'smoke' should smoke appear in explosion (1=yes, 0=no)
|
|
||||||
'sound' sound played when mob explodes
|
|
||||||
|
|
||||||
|
|
||||||
mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
mcl_core
|
mcl_core
|
||||||
mcl_hunger
|
|
||||||
mcl_sounds
|
|
||||||
invisibility?
|
invisibility?
|
||||||
intllib?
|
intllib?
|
||||||
lucky_block?
|
lucky_block?
|
||||||
|
|
|
@ -12,7 +12,7 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false
|
||||||
|
|
||||||
local node_ok = function(pos, fallback)
|
local node_ok = function(pos, fallback)
|
||||||
|
|
||||||
fallback = fallback or "mcl_core:dirt"
|
fallback = fallback or mobs.fallback_node
|
||||||
|
|
||||||
local node = minetest.get_node_or_nil(pos)
|
local node = minetest.get_node_or_nil(pos)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue