Add campfires, mobs avoid nodes (e.g. fire, water, lava)
This commit is contained in:
parent
591e26d500
commit
a0501747f0
1
mods/campfire/depends.txt
Executable file
1
mods/campfire/depends.txt
Executable file
@ -0,0 +1 @@
|
||||
default
|
262
mods/campfire/init.lua
Executable file
262
mods/campfire/init.lua
Executable file
@ -0,0 +1,262 @@
|
||||
local function get_campfire_active_formspec(pos, percent)
|
||||
local formspec =
|
||||
"size[8,9]"..
|
||||
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
|
||||
(100-percent)..":default_furnace_fire_fg.png]"..
|
||||
"list[current_name;fuel;2,3;1,1;]"..
|
||||
"list[current_name;src;2,1;1,1;]"..
|
||||
"list[current_name;dst;5,1;2,2;]"..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
return formspec
|
||||
end
|
||||
|
||||
|
||||
local campfire_inactive_formspec =
|
||||
"size[8,9]"..
|
||||
"image[2,2;1,1;default_furnace_fire_bg.png]"..
|
||||
"list[current_name;fuel;2,3;1,1;]"..
|
||||
"list[current_name;src;2,1;1,1;]"..
|
||||
"list[current_name;dst;5,1;2,2;]"..
|
||||
"list[current_player;main;0,5;8,4;]"
|
||||
|
||||
minetest.register_node("campfire:campfire", {
|
||||
description = "Campfire",
|
||||
tiles = {"campfire_campfire.png"},
|
||||
use_texture_alpha=true,
|
||||
drawtype = "firelike",
|
||||
paramtype="light",
|
||||
paramtype2="facedir",
|
||||
sunlight_propagates = true,
|
||||
groups = {dig_immediate=2,flammable=1},
|
||||
is_ground_content = false,
|
||||
inventory_image = "campfire_campfire.png",
|
||||
drop = "",
|
||||
walkable=false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, 0.15, 0.5},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", campfire_inactive_formspec)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", 4)
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local meta = minetest:get_meta(pos)
|
||||
meta:from_table(oldmetadata)
|
||||
local inv = meta:get_inventory()
|
||||
default.dump_inv(pos,"fuel",inv)
|
||||
default.dump_inv(pos,"dst",inv)
|
||||
default.dump_inv(pos,"src",inv)
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if listname == "fuel" then
|
||||
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
|
||||
return stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif listname == "src" then
|
||||
print(player:get_player_name().." put item into campfire")
|
||||
meta:set_string("owner",player:get_player_name())
|
||||
return stack:get_count()
|
||||
elseif listname == "dst" then
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local stack = inv:get_stack(from_list, from_index)
|
||||
if to_list == "fuel" then
|
||||
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
|
||||
return count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif to_list == "src" then
|
||||
return count
|
||||
elseif to_list == "dst" then
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("campfire:campfire_burning", {
|
||||
description = "Campfire Burning",
|
||||
drawtype = "firelike",
|
||||
tiles = {{
|
||||
name="campfire_active.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
|
||||
}},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
light_source = 16,
|
||||
drop = "",
|
||||
groups = {igniter=2,hot=3},
|
||||
is_ground_content = false,
|
||||
damage_per_second = 2,
|
||||
walkable=false,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", campfire_inactive_formspec)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("fuel", 1)
|
||||
inv:set_size("src", 1)
|
||||
inv:set_size("dst", 4)
|
||||
end,
|
||||
can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
if not inv:is_empty("fuel") then
|
||||
return false
|
||||
elseif not inv:is_empty("dst") then
|
||||
return false
|
||||
elseif not inv:is_empty("src") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
if listname == "fuel" then
|
||||
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
|
||||
return stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif listname == "src" then
|
||||
print(player:get_player_name().." put item into campfire")
|
||||
meta:set_string("owner",player:get_player_name())
|
||||
return stack:get_count()
|
||||
elseif listname == "dst" then
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local stack = inv:get_stack(from_list, from_index)
|
||||
if to_list == "fuel" then
|
||||
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
|
||||
return count
|
||||
else
|
||||
return 0
|
||||
end
|
||||
elseif to_list == "src" then
|
||||
return count
|
||||
elseif to_list == "dst" then
|
||||
return 0
|
||||
end
|
||||
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
return stack:get_count()
|
||||
end
|
||||
})
|
||||
|
||||
local function swap_node(pos,name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos,node)
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"campfire:campfire","campfire:campfire_burning"},
|
||||
interval = 1.0,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
for i, name in ipairs({
|
||||
"fuel_totaltime",
|
||||
"fuel_time",
|
||||
"src_totaltime",
|
||||
"src_time"
|
||||
}) do
|
||||
if meta:get_string(name) == "" then
|
||||
meta:set_float(name, 0.0)
|
||||
end
|
||||
end
|
||||
|
||||
local owner = meta:get_string("owner")
|
||||
local inv = meta:get_inventory()
|
||||
|
||||
local srclist = inv:get_list("src")
|
||||
local cooked = nil
|
||||
local aftercooked
|
||||
|
||||
if srclist then
|
||||
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
|
||||
end
|
||||
|
||||
local was_active = false
|
||||
|
||||
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
||||
was_active = true
|
||||
meta:set_float("fuel_time", meta:get_float("fuel_time") + 0.25)
|
||||
meta:set_float("src_time", meta:get_float("src_time") + 0.25)
|
||||
if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
|
||||
if inv:room_for_item("dst",cooked.item) then
|
||||
-- Put result in "dst" list
|
||||
inv:add_item("dst", cooked.item)
|
||||
-- take stuff from "src" list
|
||||
inv:set_stack("src", 1, aftercooked.items[1])
|
||||
end
|
||||
meta:set_string("src_time", 0)
|
||||
end
|
||||
end
|
||||
|
||||
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
||||
local percent = math.floor(meta:get_float("fuel_time") /
|
||||
meta:get_float("fuel_totaltime") * 100)
|
||||
swap_node(pos,"campfire:campfire_burning")
|
||||
meta:set_string("formspec",get_campfire_active_formspec(pos, percent))
|
||||
if meta:get_int("sound_played") == nil or ( os.time() - meta:get_int("sound_played") ) >= 4 then
|
||||
minetest.sound_play("default_furnace",{pos=pos})
|
||||
meta:set_string("sound_played",os.time())
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local fuel = nil
|
||||
local afterfuel
|
||||
local cooked = nil
|
||||
local fuellist = inv:get_list("fuel")
|
||||
local srclist = inv:get_list("src")
|
||||
|
||||
if srclist then
|
||||
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
|
||||
end
|
||||
if fuellist then
|
||||
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
|
||||
end
|
||||
|
||||
if not fuel or fuel.time <= 0 then
|
||||
swap_node(pos,"campfire:campfire")
|
||||
meta:set_string("formspec", campfire_inactive_formspec)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
meta:set_string("fuel_totaltime", fuel.time)
|
||||
meta:set_string("fuel_time", 0)
|
||||
|
||||
inv:set_stack("fuel", 1, afterfuel.items[1])
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type="shapeless",
|
||||
output = "campfire:campfire",
|
||||
recipe = {"group:stick","group:stick","group:stick","group:tree"}
|
||||
})
|
BIN
mods/campfire/textures/campfire_active.png
Executable file
BIN
mods/campfire/textures/campfire_active.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
mods/campfire/textures/campfire_campfire.png
Executable file
BIN
mods/campfire/textures/campfire_campfire.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 622 B |
@ -1,68 +1,124 @@
|
||||
-- minetest/fire/init.lua
|
||||
|
||||
-- Global namespace for functions
|
||||
|
||||
fire = {}
|
||||
|
||||
|
||||
-- Register flame nodes
|
||||
|
||||
minetest.register_node("fire:basic_flame", {
|
||||
description = "Fire",
|
||||
drawtype = "plantlike",
|
||||
tiles = {{
|
||||
name="fire_basic_flame_animated.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
|
||||
}},
|
||||
description = "Basic Flame",
|
||||
drawtype = "firelike",
|
||||
tiles = {
|
||||
{
|
||||
name = "fire_basic_flame_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1
|
||||
},
|
||||
},
|
||||
},
|
||||
inventory_image = "fire_basic_flame.png",
|
||||
paramtype = "light",
|
||||
light_source = 14,
|
||||
groups = {igniter=2,dig_immediate=3,hot=3},
|
||||
drop = '',
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
sunlight_propagates = true,
|
||||
damage_per_second = 4,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
fire.on_flame_add_at(pos)
|
||||
groups = {igniter = 2, dig_immediate = 3},
|
||||
drop = "",
|
||||
|
||||
on_construct = function(pos)
|
||||
minetest.after(0, fire.on_flame_add_at, pos)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
fire.on_flame_remove_at(pos)
|
||||
|
||||
on_destruct = function(pos)
|
||||
minetest.after(0, fire.on_flame_remove_at, pos)
|
||||
end,
|
||||
|
||||
on_blast = function()
|
||||
end, -- unaffected by explosions
|
||||
})
|
||||
|
||||
minetest.register_node("fire:permanent_flame", {
|
||||
description = "Permanent Flame",
|
||||
drawtype = "firelike",
|
||||
tiles = {
|
||||
{
|
||||
name = "fire_basic_flame_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1
|
||||
},
|
||||
},
|
||||
},
|
||||
inventory_image = "fire_basic_flame.png",
|
||||
paramtype = "light",
|
||||
light_source = 14,
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
sunlight_propagates = true,
|
||||
damage_per_second = 4,
|
||||
groups = {igniter = 2, dig_immediate = 3},
|
||||
drop = "",
|
||||
|
||||
on_blast = function()
|
||||
end,
|
||||
})
|
||||
|
||||
fire = {}
|
||||
fire.D = 6
|
||||
-- key: position hash of low corner of area
|
||||
-- value: {handle=sound handle, name=sound name}
|
||||
fire.sounds = {}
|
||||
|
||||
-- Get sound area of position
|
||||
|
||||
fire.D = 6 -- size of sound areas
|
||||
|
||||
function fire.get_area_p0p1(pos)
|
||||
local p0 = {
|
||||
x=math.floor(pos.x/fire.D)*fire.D,
|
||||
y=math.floor(pos.y/fire.D)*fire.D,
|
||||
z=math.floor(pos.z/fire.D)*fire.D,
|
||||
x = math.floor(pos.x / fire.D) * fire.D,
|
||||
y = math.floor(pos.y / fire.D) * fire.D,
|
||||
z = math.floor(pos.z / fire.D) * fire.D,
|
||||
}
|
||||
local p1 = {
|
||||
x=p0.x+fire.D-1,
|
||||
y=p0.y+fire.D-1,
|
||||
z=p0.z+fire.D-1
|
||||
x = p0.x + fire.D - 1,
|
||||
y = p0.y + fire.D - 1,
|
||||
z = p0.z + fire.D - 1
|
||||
}
|
||||
return p0, p1
|
||||
end
|
||||
|
||||
|
||||
-- Fire sounds table
|
||||
-- key: position hash of low corner of area
|
||||
-- value: {handle=sound handle, name=sound name}
|
||||
fire.sounds = {}
|
||||
|
||||
|
||||
-- Update fire sounds in sound area of position
|
||||
|
||||
function fire.update_sounds_around(pos)
|
||||
local p0, p1 = fire.get_area_p0p1(pos)
|
||||
local cp = {x=(p0.x+p1.x)/2, y=(p0.y+p1.y)/2, z=(p0.z+p1.z)/2}
|
||||
local cp = {x = (p0.x + p1.x) / 2, y = (p0.y + p1.y) / 2, z = (p0.z + p1.z) / 2}
|
||||
local flames_p = minetest.find_nodes_in_area(p0, p1, {"fire:basic_flame"})
|
||||
--print("number of flames at "..minetest.pos_to_string(p0).."/"
|
||||
-- ..minetest.pos_to_string(p1)..": "..#flames_p)
|
||||
local should_have_sound = (#flames_p > 0)
|
||||
local wanted_sound = nil
|
||||
if #flames_p >= 9 then
|
||||
wanted_sound = {name="fire_large", gain=1.5}
|
||||
wanted_sound = {name = "fire_large", gain = 0.7}
|
||||
elseif #flames_p > 0 then
|
||||
wanted_sound = {name="fire_small", gain=1.5}
|
||||
wanted_sound = {name = "fire_small", gain = 0.9}
|
||||
end
|
||||
local p0_hash = minetest.hash_node_position(p0)
|
||||
local sound = fire.sounds[p0_hash]
|
||||
if not sound then
|
||||
if should_have_sound then
|
||||
fire.sounds[p0_hash] = {
|
||||
handle = minetest.sound_play(wanted_sound, {pos=cp, loop=true}),
|
||||
handle = minetest.sound_play(wanted_sound,
|
||||
{pos = cp, max_hear_distance = 16, loop = true}),
|
||||
name = wanted_sound.name,
|
||||
}
|
||||
end
|
||||
@ -73,64 +129,132 @@ function fire.update_sounds_around(pos)
|
||||
elseif sound.name ~= wanted_sound.name then
|
||||
minetest.sound_stop(sound.handle)
|
||||
fire.sounds[p0_hash] = {
|
||||
handle = minetest.sound_play(wanted_sound, {pos=cp, loop=true}),
|
||||
handle = minetest.sound_play(wanted_sound,
|
||||
{pos = cp, max_hear_distance = 16, loop = true}),
|
||||
name = wanted_sound.name,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Update fire sounds on flame node construct or destruct
|
||||
|
||||
function fire.on_flame_add_at(pos)
|
||||
--print("flame added at "..minetest.pos_to_string(pos))
|
||||
fire.update_sounds_around(pos)
|
||||
end
|
||||
|
||||
|
||||
function fire.on_flame_remove_at(pos)
|
||||
--print("flame removed at "..minetest.pos_to_string(pos))
|
||||
fire.update_sounds_around(pos)
|
||||
end
|
||||
|
||||
|
||||
-- Return positions for flames around a burning node
|
||||
|
||||
function fire.find_pos_for_flame_around(pos)
|
||||
return minetest.find_node_near(pos, 1, {"air"})
|
||||
end
|
||||
|
||||
|
||||
-- Detect nearby extinguishing nodes
|
||||
|
||||
function fire.flame_should_extinguish(pos)
|
||||
if minetest.setting_getbool("disable_fire") then return true end
|
||||
--return minetest.find_node_near(pos, 1, {"group:puts_out_fire"})
|
||||
local p0 = {x=pos.x-2, y=pos.y, z=pos.z-2}
|
||||
local p1 = {x=pos.x+2, y=pos.y, z=pos.z+2}
|
||||
local ps = minetest.find_nodes_in_area(p0, p1, {"group:puts_out_fire"})
|
||||
return (#ps ~= 0)
|
||||
return minetest.find_node_near(pos, 1, {"group:puts_out_fire"})
|
||||
end
|
||||
|
||||
-- Ignite neighboring nodes
|
||||
|
||||
-- Extinguish all flames quickly with water, snow, ice
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:flammable"},
|
||||
neighbors = {"group:igniter"},
|
||||
interval = 1,
|
||||
nodenames = {"fire:basic_flame", "fire:permanent_flame"},
|
||||
neighbors = {"group:puts_out_fire"},
|
||||
interval = 3,
|
||||
chance = 2,
|
||||
catch_up = false,
|
||||
action = function(p0, node, _, _)
|
||||
if abm_limiter() then return end
|
||||
-- If there is water or stuff like that around flame, don't ignite
|
||||
if fire.flame_should_extinguish(p0) then
|
||||
return
|
||||
end
|
||||
local p = fire.find_pos_for_flame_around(p0)
|
||||
if p then
|
||||
minetest.set_node(p, {name="fire:basic_flame"})
|
||||
fire.on_flame_add_at(p)
|
||||
end
|
||||
minetest.remove_node(p0)
|
||||
minetest.sound_play("fire_extinguish_flame",
|
||||
{pos = p0, max_hear_distance = 16, gain = 0.25})
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- Enable the following ABMs according to 'disable fire' setting
|
||||
|
||||
if minetest.setting_getbool("disable_fire") then
|
||||
|
||||
-- Remove basic flames only
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fire:basic_flame"},
|
||||
interval = 7,
|
||||
chance = 2,
|
||||
catch_up = false,
|
||||
action = function(p0, node, _, _)
|
||||
minetest.remove_node(p0)
|
||||
end,
|
||||
})
|
||||
|
||||
else
|
||||
|
||||
-- Ignite neighboring nodes, add basic flames
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:flammable"},
|
||||
neighbors = {"group:igniter"},
|
||||
interval = 7,
|
||||
chance = 16,
|
||||
catch_up = false,
|
||||
action = function(p0, node, _, _)
|
||||
-- If there is water or stuff like that around node, don't ignite
|
||||
if fire.flame_should_extinguish(p0) then
|
||||
return
|
||||
end
|
||||
local p = fire.find_pos_for_flame_around(p0)
|
||||
if p then
|
||||
minetest.set_node(p, {name = "fire:basic_flame"})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Remove basic flames and flammable nodes
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fire:basic_flame"},
|
||||
interval = 5,
|
||||
chance = 16,
|
||||
catch_up = false,
|
||||
action = function(p0, node, _, _)
|
||||
-- If there are no flammable nodes around flame, remove flame
|
||||
if not minetest.find_node_near(p0, 1, {"group:flammable"}) then
|
||||
minetest.remove_node(p0)
|
||||
return
|
||||
end
|
||||
if math.random(1, 4) == 1 then
|
||||
-- remove flammable nodes around flame
|
||||
local p = minetest.find_node_near(p0, 1, {"group:flammable"})
|
||||
if p then
|
||||
minetest.remove_node(p)
|
||||
nodeupdate(p)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Rarely ignite things from far
|
||||
|
||||
--[[ Currently disabled to reduce the chance of uncontrollable spreading
|
||||
fires that disrupt servers. Also for less lua processing load.
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:igniter"},
|
||||
neighbors = {"air"},
|
||||
interval = 4,
|
||||
chance = 40,
|
||||
interval = 5,
|
||||
chance = 10,
|
||||
action = function(p0, node, _, _)
|
||||
if abm_limiter() then return end
|
||||
local reg = minetest.registered_nodes[node.name]
|
||||
if not reg or not reg.groups.igniter or reg.groups.igniter < 2 then
|
||||
return
|
||||
@ -144,52 +268,9 @@ minetest.register_abm({
|
||||
end
|
||||
local p2 = fire.find_pos_for_flame_around(p)
|
||||
if p2 then
|
||||
minetest.set_node(p2, {name="fire:basic_flame"})
|
||||
fire.on_flame_add_at(p2)
|
||||
minetest.set_node(p2, {name = "fire:basic_flame"})
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Remove flammable nodes and flame
|
||||
minetest.register_abm({
|
||||
nodenames = {"fire:basic_flame"},
|
||||
interval = 1,
|
||||
chance = 2,
|
||||
action = function(p0, node, _, _)
|
||||
if abm_limiter() then return end
|
||||
-- If there is water or stuff like that around flame, remove flame
|
||||
if fire.flame_should_extinguish(p0) then
|
||||
minetest.remove_node(p0)
|
||||
fire.on_flame_remove_at(p0)
|
||||
return
|
||||
end
|
||||
-- Make the following things rarer
|
||||
if math.random(1,3) == 1 then
|
||||
return
|
||||
end
|
||||
-- If there are no flammable nodes around flame, remove flame
|
||||
if not minetest.find_node_near(p0, 1, {"group:flammable"}) then
|
||||
minetest.remove_node(p0)
|
||||
fire.on_flame_remove_at(p0)
|
||||
return
|
||||
end
|
||||
if math.random(1,4) == 1 then
|
||||
-- remove a flammable node around flame
|
||||
local p = minetest.find_node_near(p0, 1, {"group:flammable"})
|
||||
if p then
|
||||
-- If there is water or stuff like that around flame, don't remove
|
||||
if fire.flame_should_extinguish(p0) then
|
||||
return
|
||||
end
|
||||
minetest.remove_node(p)
|
||||
nodeupdate(p)
|
||||
end
|
||||
else
|
||||
-- remove flame
|
||||
minetest.remove_node(p0)
|
||||
fire.on_flame_remove_at(p0)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--]]
|
@ -35,6 +35,8 @@ mobs:register_mob("mobs:rabbit", {
|
||||
passive = true,
|
||||
blood_amount = 5,
|
||||
blood_offset = 0,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:rabbit_brown", {
|
||||
@ -74,6 +76,8 @@ mobs:register_mob("mobs:rabbit_brown", {
|
||||
passive = true,
|
||||
blood_amount = 5,
|
||||
blood_offset = 0,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:rabbit_grey", {
|
||||
@ -113,6 +117,8 @@ mobs:register_mob("mobs:rabbit_grey", {
|
||||
passive = true,
|
||||
blood_amount = 5,
|
||||
blood_offset = 0,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
|
||||
|
||||
|
@ -26,6 +26,8 @@ mobs:register_mob("mobs:rat", {
|
||||
passive = true,
|
||||
blood_amount = 5,
|
||||
blood_offset = 0,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
mobs:register_spawn("mobs:rat", {"default:dirt_with_grass", "default:stone"}, 20, -1, 10000, 1, 31000)
|
||||
|
||||
|
@ -74,6 +74,8 @@ mobs:register_mob("mobs:sheep", {
|
||||
passive = true,
|
||||
blood_offset = 0.25,
|
||||
blood_amount = 20,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
mobs:register_spawn("mobs:sheep", {"default:dirt_with_grass"}, 20, 8, 9000, 2, 31000)
|
||||
|
||||
|
@ -62,6 +62,8 @@ function mobs:register_mob(name, def)
|
||||
rewards = def.rewards or nil,
|
||||
stationary = def.stationary or false,
|
||||
activity_level = def.activity_level or 10,
|
||||
avoid_nodes = def.avoid_nodes or nil,
|
||||
avoid_range = def.avoid_range or nil,
|
||||
|
||||
stimer = 0,
|
||||
timer = 0,
|
||||
@ -142,6 +144,31 @@ function mobs:register_mob(name, def)
|
||||
end
|
||||
end,
|
||||
|
||||
do_avoidance = function(self)
|
||||
if self.avoid_nodes ~= nil then
|
||||
local avoid_range = self.avoid_range
|
||||
local avoid_nodes = self.avoid_nodes
|
||||
|
||||
local pos = self.object:getpos()
|
||||
|
||||
local minx = pos.x - math.ceil( avoid_range / 2 )
|
||||
local maxx = pos.x + math.ceil( avoid_range / 2 )
|
||||
|
||||
local minz = pos.z - math.ceil( avoid_range / 2 )
|
||||
local maxz = pos.z + math.ceil( avoid_range / 2 )
|
||||
|
||||
local npos = minetest.find_nodes_in_area({x=minx,y=(pos.y-1),z=minz},{x=maxx,y=(pos.y+1),z=maxz}, avoid_nodes)
|
||||
|
||||
if #npos > 0 then
|
||||
local fpos = { x=(npos[1].x * -1),y=npos[1].y,z=(npos[1].z*-1) }
|
||||
mobs:face_pos(self,fpos)
|
||||
self.state="walk"
|
||||
self:set_animation("walk")
|
||||
self:set_velocity(4)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
set_velocity = function(self, v)
|
||||
local yaw = self.object:getyaw()
|
||||
if self.drawtype == "side" then
|
||||
|
@ -43,6 +43,8 @@ mobs:register_mob("mobs:dirt_monster", {
|
||||
blood_amount=30,
|
||||
blood_offset=.25,
|
||||
blood_texture = "default_dirt.png",
|
||||
avoid_nodes = {"default:water_source","default:water_flowing"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:dirt_monster2", {
|
||||
@ -95,6 +97,8 @@ mobs:register_mob("mobs:dirt_monster2", {
|
||||
blood_amount=30,
|
||||
blood_offset=.25,
|
||||
blood_texture = "default_dirt.png",
|
||||
avoid_nodes = {"default:water_source","default:water_flowing"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
|
||||
mobs:register_spawn("mobs:dirt_monster", {"default:dirt_with_grass"}, 3, -1, 5000, 3, 31000)
|
||||
|
@ -51,6 +51,8 @@ mobs:register_mob("mobs:jungle_spider",{
|
||||
step = 1,
|
||||
blood_amount = 14,
|
||||
blood_offset = 0.1,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
attack_function = function(self, target)
|
||||
self.attack.player:punch(self.object, 1.0, {
|
||||
full_punch_interval=1.0,
|
||||
|
@ -41,6 +41,8 @@ mobs:register_mob("mobs:sand_monster", {
|
||||
death = "mob_death2",
|
||||
},
|
||||
step = 0.5,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
mobs:register_spawn("mobs:sand_monster", {"default:sand"}, 20, -1, 8000, 4, 31000)
|
||||
mobs:register_spawn("mobs:sand_monster", {"default:desert_sand"}, 20, -1, 4000, 4, 31000)
|
||||
|
@ -45,6 +45,8 @@ mobs:register_mob("mobs:spider",{
|
||||
step = 1,
|
||||
blood_amount = 22,
|
||||
blood_offset = 0.1,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 14,
|
||||
})
|
||||
mobs:register_spawn("mobs:spider", {"default:leaves", "mg:savannaleaves"}, 22, -1, 7000, 4, 31000)
|
||||
mobs:register_spawn("mobs:spider", {"default:leaves", "mg:savannaleaves"}, 7, -1, 3000, 6, 31000)
|
@ -55,5 +55,7 @@ mobs:register_mob("mobs:tree_monster", {
|
||||
death = "mob_death1",
|
||||
},
|
||||
step = 0.5,
|
||||
avoid_nodes = {"campfire:campfire_burning","fire:basic_flame","fire:permanent_flame","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
mobs:register_spawn("mobs:tree_monster", {"default:leaves", "default:jungleleaves"}, 5, -1, 5000, 3, 31000)
|
@ -41,5 +41,7 @@ mobs:register_mob("mobs:snow_monster", {
|
||||
attack = "mobs_slash_attack",
|
||||
},
|
||||
step = 0.5,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","campfire:campfire_burning","fire:basic_flame","fire:permanent_flame"},
|
||||
avoid_range = 15,
|
||||
})
|
||||
mobs:register_spawn("mobs:snow_monster", {"default:snow","default:snow_with_grass","default:snowblock"}, 10, -1, 7000, 2, 31000)
|
||||
|
@ -59,7 +59,8 @@ mobs:register_mob("mobs:blacksmith",{
|
||||
blood_offset = 0.25,
|
||||
activity_level = 1,
|
||||
lifetimer = false,
|
||||
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
||||
-- list of active blacksmiths... I'm not sure how this is going to work when an entity is unloaded
|
||||
|
@ -60,4 +60,6 @@ mobs:register_mob("mobs:explorer",{
|
||||
},
|
||||
lifetimer = false,
|
||||
activity_level = 2,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
@ -57,6 +57,8 @@ mobs:register_mob("mobs:male1_npc",{
|
||||
},
|
||||
walk_chance = 5,
|
||||
lifetimer = false,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:male2_npc",{
|
||||
@ -118,6 +120,8 @@ mobs:register_mob("mobs:male2_npc",{
|
||||
},
|
||||
walk_chance = 5,
|
||||
lifetimer = false,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:male3_npc",{
|
||||
@ -179,4 +183,6 @@ mobs:register_mob("mobs:male3_npc",{
|
||||
},
|
||||
walk_chance = 2,
|
||||
lifetimer = false,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
@ -53,6 +53,8 @@ type = "npc",
|
||||
{chance=60, item="potions:magic_replenish1"},
|
||||
},
|
||||
lifetimer = false,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:female2_npc", {
|
||||
@ -111,6 +113,8 @@ type = "npc",
|
||||
},
|
||||
walk_chance = 3,
|
||||
lifetimer = false,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
||||
mobs:register_mob("mobs:female3_npc", {
|
||||
@ -170,4 +174,6 @@ type = "npc",
|
||||
},
|
||||
walk_chance = 4,
|
||||
lifetimer = false,
|
||||
avoid_nodes = {"default:water_source","default:water_flowing","default:lava_source","default:lava_flowing"},
|
||||
avoid_range = 4,
|
||||
})
|
||||
|
@ -114,6 +114,8 @@ function mobs.on_step(self,dtime)
|
||||
do_env_damage(self)
|
||||
end
|
||||
|
||||
self:do_avoidance()
|
||||
|
||||
-- if they are attacking that should take priority over everything else so move it up here
|
||||
if self.state == "attack" and self.attack_type == "dogfight" then
|
||||
if not self.attack.player or not self.attack.player:getpos() then
|
||||
|
Loading…
x
Reference in New Issue
Block a user