0
0
Fork 0

Update mobs mod

This commit is contained in:
Wuzzy 2017-07-25 04:30:23 +02:00
parent 084c299a3c
commit b25254e516
4 changed files with 84 additions and 135 deletions

View File

@ -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:

View File

@ -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)

View File

@ -1,6 +1,4 @@
mcl_core mcl_core
mcl_hunger
mcl_sounds
invisibility? invisibility?
intllib? intllib?
lucky_block? lucky_block?

View File

@ -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)