forked from VoxeLibre/VoxeLibre
Compare commits
4 Commits
master
...
limit-fire
Author | SHA1 | Date |
---|---|---|
teknomunk | 09ab93a24d | |
teknomunk | 34b5c1705b | |
teknomunk | 5907415762 | |
teknomunk | caeebcec60 |
|
@ -388,7 +388,7 @@ end
|
|||
|
||||
|
||||
|
||||
local function on_step_work(self, dtime, moveresult)
|
||||
local function on_step_work (self, dtime)
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
|
@ -402,7 +402,7 @@ local function on_step_work(self, dtime, moveresult)
|
|||
-- Do we abandon out of here now?
|
||||
end
|
||||
|
||||
if self:falling(pos, moveresult) then return end
|
||||
if self:falling(pos) then return end
|
||||
if self:step_damage (dtime, pos) then return end
|
||||
|
||||
if self.state == "die" then return end
|
||||
|
@ -502,11 +502,11 @@ end
|
|||
|
||||
|
||||
-- main mob function
|
||||
function mob_class:on_step(dtime, moveresult)
|
||||
function mob_class:on_step(dtime)
|
||||
if not DEVELOPMENT then
|
||||
-- Removed as bundled Lua (5.1 doesn't support xpcall)
|
||||
--local status, retVal = xpcall(on_step_work, on_step_error_handler, self, dtime)
|
||||
local status, retVal = pcall(on_step_work, self, dtime, moveresult)
|
||||
local status, retVal = pcall(on_step_work, self, dtime)
|
||||
if status then
|
||||
return retVal
|
||||
else
|
||||
|
@ -521,7 +521,7 @@ function mob_class:on_step(dtime, moveresult)
|
|||
log_error (dump(retVal), dump(pos), dump(self))
|
||||
end
|
||||
else
|
||||
return on_step_work (self, dtime, moveresult)
|
||||
return on_step_work (self, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ end
|
|||
|
||||
-- Spawn a child
|
||||
function mcl_mobs.spawn_child(pos, mob_type)
|
||||
local child = minetest.add_entity(pos, mob_type)
|
||||
local child = mcl_mobs.spawn(pos, mob_type)
|
||||
if not child then
|
||||
return
|
||||
end
|
||||
|
|
|
@ -615,7 +615,7 @@ function mcl_mobs.register_egg(mob_id, desc, background_color, overlay_color, ad
|
|||
|
||||
pos.y = pos.y - 1
|
||||
local mob = mcl_mobs.spawn(pos, mob_name)
|
||||
if not mob then
|
||||
if not object then
|
||||
pos.y = pos.y + 1
|
||||
mob = mcl_mobs.spawn(pos, mob_name)
|
||||
if not mob then return end
|
||||
|
|
|
@ -927,7 +927,8 @@ end
|
|||
|
||||
-- falling and fall damage
|
||||
-- returns true if mob died
|
||||
function mob_class:falling(pos, moveresult)
|
||||
function mob_class:falling(pos)
|
||||
|
||||
if self.fly and self.state ~= "die" then
|
||||
return
|
||||
end
|
||||
|
@ -950,13 +951,7 @@ function mob_class:falling(pos, moveresult)
|
|||
new_acceleration = vector.new(0, DEFAULT_FALL_SPEED, 0)
|
||||
elseif v.y <= 0 and v.y > self.fall_speed then
|
||||
-- fall downwards at set speed
|
||||
if moveresult and moveresult.touching_ground then
|
||||
-- when touching ground, retain a minimal gravity to keep the touching_ground flag
|
||||
-- but also to not get upwards acceleration with large dtime when on bouncy ground
|
||||
new_acceleration = vector.new(0, self.fall_speed * 0.01, 0)
|
||||
else
|
||||
new_acceleration = vector.new(0, self.fall_speed, 0)
|
||||
end
|
||||
new_acceleration = vector.new(0, self.fall_speed, 0)
|
||||
else
|
||||
-- stop accelerating once max fall speed hit
|
||||
new_acceleration =vector.zero()
|
||||
|
|
|
@ -72,24 +72,18 @@ local axolotl = {
|
|||
fly = true,
|
||||
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
|
||||
breathes_in_water = true,
|
||||
jump = false, -- would get them out of the water too often
|
||||
jump = true,
|
||||
damage = 2,
|
||||
reach = 2,
|
||||
attack_type = "dogfight",
|
||||
attack_animals = true,
|
||||
specific_attack = {
|
||||
"mobs_mc:cod",
|
||||
"mobs_mc:glow_squid",
|
||||
"mobs_mc:salmon",
|
||||
"mobs_mc:tropical_fish",
|
||||
"mobs_mc:squid",
|
||||
"mobs_mc:zombie", -- todo: only drowned?
|
||||
"mobs_mc:baby_zombie",
|
||||
"mobs_mc:husk",
|
||||
"mobs_mc:baby_husk",
|
||||
"mobs_mc:guardian_elder",
|
||||
"mobs_mc:guardian",
|
||||
},
|
||||
"extra_mobs_cod",
|
||||
"extra_mobs_glow_squid",
|
||||
"extra_mobs_salmon",
|
||||
"extra_mobs_tropical_fish",
|
||||
"mobs_mc_squid"
|
||||
},
|
||||
runaway = true,
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,6 @@ function mcl_weather.rain.clear()
|
|||
mcl_weather.rain.remove_sound(player)
|
||||
mcl_weather.rain.remove_player(player)
|
||||
mcl_weather.remove_spawners_player(player)
|
||||
player:set_clouds({color="#FFF0EF"})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
local NIGHT_VISION_RATIO = 0.45
|
||||
local DEBUG = false
|
||||
|
||||
-- Settings
|
||||
local minimum_update_interval = { 250e3 }
|
||||
|
@ -191,8 +190,8 @@ end
|
|||
|
||||
function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
|
||||
-- Clamp current_val to valid range
|
||||
current_val = math.max(minval, current_val)
|
||||
current_val = math.min(maxval, current_val)
|
||||
current_val = math.min(minval, current_val)
|
||||
current_val = math.max(maxval, current_val)
|
||||
|
||||
-- Rescale current_val from a number between minval and maxval to a number between 1 and #colors
|
||||
local scaled_value = (current_val - minval) / (maxval - minval) * (#colors - 1) + 1.0
|
||||
|
@ -200,7 +199,7 @@ function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
|
|||
-- Get the first color's values
|
||||
local index1 = math.floor(scaled_value)
|
||||
local color1 = colors[index1]
|
||||
local frac1 = 1.0 - (scaled_value - index1)
|
||||
local frac1 = scaled_value - index1
|
||||
|
||||
-- Get the second color's values
|
||||
local index2 = math.min(index1 + 1, #colors) -- clamp to maximum color index (will occur if index1 == #colors)
|
||||
|
@ -208,32 +207,11 @@ function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
|
|||
local color2 = colors[index2]
|
||||
|
||||
-- Interpolate between color1 and color2
|
||||
local res = {
|
||||
return {
|
||||
r = math.floor(frac1 * color1.r + frac2 * color2.r),
|
||||
g = math.floor(frac1 * color1.g + frac2 * color2.g),
|
||||
b = math.floor(frac1 * color1.b + frac2 * color2.b),
|
||||
}
|
||||
|
||||
if DEBUG then
|
||||
minetest.log(dump({
|
||||
minval = minval,
|
||||
maxval = maxval,
|
||||
current_val = current_val,
|
||||
colors = colors,
|
||||
res = res,
|
||||
scaled_value = scaled_value,
|
||||
|
||||
frac1 = frac1,
|
||||
index1 = index1,
|
||||
color1 = color1,
|
||||
|
||||
frac2 = frac2,
|
||||
index2 = index2,
|
||||
color2 = color2,
|
||||
}))
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- Simple getter. Either returns user given players list or get all connected players if none provided
|
||||
|
|
|
@ -40,21 +40,18 @@ function dimension_handlers.overworld(player, sky_data)
|
|||
end
|
||||
|
||||
-- Use overworld defaults
|
||||
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
|
||||
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15)
|
||||
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27)
|
||||
local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1)
|
||||
sky_data.sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky = day_color or "#7BA4FF",
|
||||
day_horizon = day_color or "#C0D8FF",
|
||||
dawn_sky = dawn_color or "7BA4FF",
|
||||
dawn_horizon = dawn_color or "#C0D8FF",
|
||||
night_sky = night_color or "000000",
|
||||
night_horizon = night_color or "4A6790",
|
||||
fog_sun_tint = "#ff5f33",
|
||||
fog_moon_tint = nil,
|
||||
fog_tint_type = "custom",
|
||||
day_sky = day_color,
|
||||
day_horizon = day_color,
|
||||
dawn_sky = dawn_color,
|
||||
dawn_horizon = dawn_color,
|
||||
night_sky = night_color,
|
||||
night_horizon = night_color,
|
||||
},
|
||||
clouds = true,
|
||||
}
|
||||
|
@ -78,15 +75,18 @@ function dimension_handlers.overworld(player, sky_data)
|
|||
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
|
||||
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75)
|
||||
local night_color = mcl_weather.skycolor.get_sky_layer_color(0)
|
||||
table.update(sky_data.sky.sky_color,{
|
||||
day_sky = day_color or "#7BA4FF",
|
||||
day_horizon = day_color or "#C0D8FF",
|
||||
dawn_sky = dawn_color or "7BA4FF",
|
||||
dawn_horizon = dawn_color or "#C0D8FF",
|
||||
night_sky = night_color or "000000",
|
||||
night_horizon = night_color or "4A6790",
|
||||
fog_tint_type = "default",
|
||||
})
|
||||
sky_data.sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky = day_color,
|
||||
day_horizon = day_color,
|
||||
dawn_sky = dawn_color,
|
||||
dawn_horizon = dawn_color,
|
||||
night_sky = night_color,
|
||||
night_horizon = night_color,
|
||||
},
|
||||
clouds = true,
|
||||
}
|
||||
sky_data.sun = {visible = false, sunrise_visible = false}
|
||||
sky_data.moon = {visible = false}
|
||||
sky_data.stars = {visible = false}
|
||||
|
@ -164,8 +164,7 @@ function dimension_handlers.nether(player, sky_data)
|
|||
end
|
||||
|
||||
function dimension_handlers.void(player, sky_data)
|
||||
sky_data.sky = {
|
||||
type = "plain",
|
||||
sky_data.sky = { type = "plain",
|
||||
base_color = "#000000",
|
||||
clouds = false,
|
||||
}
|
||||
|
|
|
@ -75,15 +75,13 @@ function mcl_weather.has_snow(pos)
|
|||
end
|
||||
|
||||
function mcl_weather.snow.set_sky_box()
|
||||
if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-snow-sky" then
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-snow-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=85, g=86, b=86},
|
||||
{r=135, g=135, b=135},
|
||||
{r=85, g=86, b=86},
|
||||
{r=0, g=0, b=0}})
|
||||
end
|
||||
mcl_weather.skycolor.add_layer(
|
||||
"weather-pack-snow-sky",
|
||||
{{r=0, g=0, b=0},
|
||||
{r=85, g=86, b=86},
|
||||
{r=135, g=135, b=135},
|
||||
{r=85, g=86, b=86},
|
||||
{r=0, g=0, b=0}})
|
||||
mcl_weather.skycolor.active = true
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
player:set_clouds({color="#ADADADE8"})
|
||||
|
|
|
@ -23,15 +23,13 @@ minetest.register_globalstep(function(dtime)
|
|||
mcl_weather.rain.make_weather()
|
||||
|
||||
if mcl_weather.thunder.init_done == false then
|
||||
if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-thunder-sky" then
|
||||
mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", {
|
||||
{r=0, g=0, b=0},
|
||||
{r=40, g=40, b=40},
|
||||
{r=85, g=86, b=86},
|
||||
{r=40, g=40, b=40},
|
||||
{r=0, g=0, b=0},
|
||||
})
|
||||
end
|
||||
mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", {
|
||||
{r=0, g=0, b=0},
|
||||
{r=40, g=40, b=40},
|
||||
{r=85, g=86, b=86},
|
||||
{r=40, g=40, b=40},
|
||||
{r=0, g=0, b=0},
|
||||
})
|
||||
mcl_weather.skycolor.active = true
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
player:set_clouds({color="#3D3D3FE8"})
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
--- Copyright (C) 2022 - 2023, Michieal. See License.txt
|
||||
|
||||
-- CONSTS
|
||||
local DOUBLE_DROP_CHANCE = 8
|
||||
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
|
||||
-- "BAMBOO" goes here.
|
||||
local BAMBOO = "mcl_bamboo:bamboo"
|
||||
local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap"
|
||||
local BAMBOO_PLANK = BAMBOO .. "_plank"
|
||||
|
@ -13,7 +16,7 @@ local BAMBOO_PLANK = BAMBOO .. "_plank"
|
|||
local modname = minetest.get_current_modname()
|
||||
local S = minetest.get_translator(modname)
|
||||
local node_sound = mcl_sounds.node_sound_wood_defaults()
|
||||
local pr = PseudoRandom((os.time() + 15766) * 12)
|
||||
local pr = PseudoRandom((os.time() + 15766) * 12) -- switched from math.random() to PseudoRandom because the random wasn't very random.
|
||||
|
||||
local on_rotate
|
||||
if minetest.get_modpath("screwdriver") then
|
||||
|
@ -28,7 +31,33 @@ local bamboo_def = {
|
|||
paramtype = "light",
|
||||
groups = {handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3},
|
||||
sounds = node_sound,
|
||||
drop = BAMBOO,
|
||||
|
||||
drop = {
|
||||
max_items = 1,
|
||||
-- From the API:
|
||||
-- max_items: Maximum number of item lists to drop.
|
||||
-- The entries in 'items' are processed in order. For each:
|
||||
-- Item filtering is applied, chance of drop is applied, if both are
|
||||
-- successful the entire item list is dropped.
|
||||
-- Entry processing continues until the number of dropped item lists
|
||||
-- equals 'max_items'.
|
||||
-- Therefore, entries should progress from low to high drop chance.
|
||||
items = {
|
||||
-- Examples:
|
||||
{
|
||||
-- 1 in DOUBLE_DROP_CHANCE chance of dropping.
|
||||
-- Default rarity is '1'.
|
||||
rarity = DOUBLE_DROP_CHANCE,
|
||||
items = {BAMBOO .. " 2"},
|
||||
},
|
||||
{
|
||||
-- 1 in 1 chance of dropping. (Note: this means that it will drop 100% of the time.)
|
||||
-- Default rarity is '1'.
|
||||
rarity = 1,
|
||||
items = {BAMBOO},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
inventory_image = "mcl_bamboo_bamboo_shoot.png",
|
||||
wield_image = "mcl_bamboo_bamboo_shoot.png",
|
||||
|
@ -57,6 +86,7 @@ local bamboo_def = {
|
|||
on_rotate = on_rotate,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
|
||||
if not pointed_thing then
|
||||
return itemstack
|
||||
end
|
||||
|
@ -211,6 +241,9 @@ local bamboo_def = {
|
|||
if node_above and ((bamboo_node and bamboo_node > 0) or node_above.name == BAMBOO_ENDCAP_NAME) then
|
||||
minetest.remove_node(new_pos)
|
||||
minetest.sound_play(node_sound.dug, sound_params, true)
|
||||
if pr:next(1, DOUBLE_DROP_CHANCE) == 1 then
|
||||
minetest.add_item(new_pos, istack)
|
||||
end
|
||||
minetest.add_item(new_pos, istack)
|
||||
end
|
||||
end,
|
||||
|
|
|
@ -9,6 +9,8 @@ local SIDE_SCAFFOLDING = false
|
|||
local SIDE_SCAFFOLD_NAME = "mcl_bamboo:scaffolding_horizontal"
|
||||
-- ---------------------------------------------------------------------------
|
||||
local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding"
|
||||
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
|
||||
-- "BAMBOO" goes here.
|
||||
local BAMBOO = "mcl_bamboo:bamboo"
|
||||
local BAMBOO_PLANK = BAMBOO .. "_plank"
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ function mcl_bamboo.break_orphaned(pos)
|
|||
local node_name = node_below.name
|
||||
|
||||
-- short circuit checks.
|
||||
if node_name == "ignore" or mcl_bamboo.is_dirt(node_name) or mcl_bamboo.is_bamboo(node_name) or mcl_bamboo.is_bamboo(minetest.get_node(pos).name) == false then
|
||||
if mcl_bamboo.is_dirt(node_name) or mcl_bamboo.is_bamboo(node_name) or mcl_bamboo.is_bamboo(minetest.get_node(pos).name) == false then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
-- LOCALS
|
||||
local modname = minetest.get_current_modname()
|
||||
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
|
||||
-- "BAMBOO" goes here.
|
||||
local BAMBOO = "mcl_bamboo:bamboo"
|
||||
|
||||
mcl_bamboo = {}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
--- These are all of the fuel recipes and all of the crafting recipes, consolidated into one place.
|
||||
--- Copyright (C) 2022 - 2023, Michieal. See License.txt
|
||||
|
||||
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
|
||||
-- "BAMBOO" goes here.
|
||||
local BAMBOO = "mcl_bamboo:bamboo"
|
||||
local BAMBOO_PLANK = BAMBOO .. "_plank"
|
||||
-- Craftings
|
||||
|
|
|
@ -79,7 +79,7 @@ minetest.register_lbm({
|
|||
local node_name = node.name
|
||||
node.name = node_name .. "_small"
|
||||
minetest.swap_node(pos, node)
|
||||
mcl_chests.select_and_spawn_entity(pos, node)
|
||||
select_and_spawn_entity(pos, node)
|
||||
if node_name == "mcl_chests:trapped_chest_on" then
|
||||
minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos))
|
||||
mcl_chests.chest_update_after_close(pos)
|
||||
|
|
|
@ -1239,6 +1239,10 @@ end
|
|||
|
||||
local function vinedecay_particles(pos, node)
|
||||
local dir = minetest.wallmounted_to_dir(node.param2)
|
||||
|
||||
-- Don't crash if the map data got corrupted somehow
|
||||
if not dir then return end
|
||||
|
||||
local relpos1, relpos2
|
||||
if dir.x < 0 then
|
||||
relpos1 = { x = -0.45, y = -0.4, z = -0.5 }
|
||||
|
@ -1475,6 +1479,10 @@ Vines are considered “supported” if they face a walkable+solid block or “h
|
|||
function mcl_core.check_vines_supported(pos, node)
|
||||
local supported = false
|
||||
local dir = minetest.wallmounted_to_dir(node.param2)
|
||||
|
||||
-- Don't crash if the map data got corrupted somehow
|
||||
if not dir then return false end
|
||||
|
||||
local pos1 = vector.add(pos, dir)
|
||||
local node_neighbor = minetest.get_node(pos1)
|
||||
-- Check if vines are attached to a solid block.
|
||||
|
|
|
@ -44,12 +44,34 @@ shuffle_table(adjacents)
|
|||
local function has_flammable(pos)
|
||||
for k,v in pairs(adjacents) do
|
||||
local p=vector.add(pos,v)
|
||||
local n=minetest.get_node_or_nil(p)
|
||||
if n and minetest.get_item_group(n.name, "flammable") ~= 0 then
|
||||
local n=get_node_or_nil(p)
|
||||
if n and get_item_group(n.name, "flammable") ~= 0 then
|
||||
return p
|
||||
end
|
||||
end
|
||||
end
|
||||
local all_adjacents = {}
|
||||
for x = 0,1 do
|
||||
for y = 0,1 do
|
||||
for z = 0,1 do
|
||||
all_adjacents[#all_adjacents+1] = vector.new(x*2-1, y*2-1, z*2-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_adjacent_fire_age(pos)
|
||||
local lowest_age = nil
|
||||
for k,v in pairs(all_adjacents) do
|
||||
local p = vector.add(pos, v)
|
||||
local node = get_node_or_nil(p)
|
||||
if node and get_item_group(node.name, "fire") ~= 0 then
|
||||
if not lowest_age or node.param2 < lowest_age then
|
||||
lowest_age = node.param2
|
||||
end
|
||||
end
|
||||
end
|
||||
return lowest_age
|
||||
end
|
||||
|
||||
local smoke_pdef = {
|
||||
amount = 0.009,
|
||||
|
@ -90,7 +112,40 @@ else
|
|||
eternal_fire_help = S("Eternal fire is a damaging block. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.")
|
||||
end
|
||||
|
||||
local function spawn_fire(pos, age)
|
||||
-- exponential constant is such that at age=255, p=0.5%
|
||||
local K1 = ( math.log(0.005) / math.log(10) ) / 255
|
||||
local function spawn_fire(pos, age, force)
|
||||
if not age then
|
||||
minetest.log("warning","No age specified at "..debug.traceback())
|
||||
|
||||
-- Get adjacent age
|
||||
local adjacent_age = get_adjacent_fire_age(pos)
|
||||
|
||||
-- Don't create new fire if we can't find adjacent fire from this position
|
||||
if not adjacent_age then return end
|
||||
|
||||
age = adjacent_age + math.ceil(minetest.get_humidity(pos)/10) + math.random(5)
|
||||
end
|
||||
if age <= 1 then
|
||||
minetest.log("warning","new flash point at "..vector.to_string(pos).." age="..tostring(age)..",backtrace = "..debug.traceback())
|
||||
end
|
||||
if age >= 255 then
|
||||
age = 255
|
||||
end
|
||||
|
||||
local node = get_node(pos)
|
||||
local node_is_flammable = get_item_group(node.name, "flammable")
|
||||
|
||||
-- Limit fire spread
|
||||
local probability_age = age
|
||||
if node_is_flammable then
|
||||
probability_age = probability_age * 0.80
|
||||
end
|
||||
local probability = math.pow(10,K1 * probability_age)
|
||||
if not force and math.random(65536)/65536 >= probability then
|
||||
return
|
||||
end
|
||||
|
||||
set_node(pos, {name="mcl_fire:fire", param2 = age})
|
||||
minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
end
|
||||
|
@ -358,19 +413,47 @@ if not fire_enabled then
|
|||
|
||||
else -- Fire enabled
|
||||
|
||||
-- Extinguish parameters
|
||||
local C2 = math.log(1/20) / math.log(10)
|
||||
local K2 = -C2 / 255
|
||||
|
||||
-- Fire Spread
|
||||
minetest.register_abm({
|
||||
label = "Ignite flame",
|
||||
nodenames ={"mcl_fire:fire","mcl_fire:eternal_fire"},
|
||||
interval = 7,
|
||||
chance = 12,
|
||||
chance = 5,
|
||||
catch_up = false,
|
||||
action = function(pos)
|
||||
local node = get_node(pos)
|
||||
local age = node.param2
|
||||
|
||||
-- Always age the source fire
|
||||
age = age + math.ceil(minetest.get_humidity(pos)/10) + math.random(5)
|
||||
if age > 255 then age = 255 end
|
||||
node.param2 = age
|
||||
|
||||
local p = get_ignitable(pos)
|
||||
if p then
|
||||
spawn_fire(p)
|
||||
-- Spawn new fire with an age based on this node's age
|
||||
spawn_fire(p, age + math.ceil(minetest.get_humidity(p)/10) + math.random(5))
|
||||
shuffle_table(adjacents)
|
||||
end
|
||||
|
||||
if node.name ~= "mcl_fire:eternal_fire" then
|
||||
-- Randomly extinguish fires with increasing probability the older they are
|
||||
local extinguish_probability = math.pow(10,K2 * age + C2)
|
||||
if math.random(65536)/65536 <= extinguish_probability then
|
||||
node.name = "air"
|
||||
node.param2 = 0
|
||||
|
||||
-- Extinguish fires not adjacent to flammable materials
|
||||
elseif not has_flammable(pos) then
|
||||
node.name = "air"
|
||||
node.param2 = 0
|
||||
end
|
||||
end
|
||||
set_node(pos, node)
|
||||
end
|
||||
})
|
||||
|
||||
|
@ -385,26 +468,7 @@ else -- Fire enabled
|
|||
action = function(pos)
|
||||
local p=get_ignitable_by_lava(pos)
|
||||
if p then
|
||||
spawn_fire(p)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Remove fires",
|
||||
nodenames = {"mcl_fire:fire"},
|
||||
interval = 7,
|
||||
chance = 3,
|
||||
catch_up = false,
|
||||
action = function(pos)
|
||||
local p=has_flammable(pos)
|
||||
if p then
|
||||
local n=minetest.get_node_or_nil(p)
|
||||
if n and minetest.get_item_group(n.name, "flammable") < 1 then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
else
|
||||
minetest.remove_node(pos)
|
||||
spawn_fire(p, 0)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -423,15 +487,27 @@ else -- Fire enabled
|
|||
return
|
||||
end
|
||||
|
||||
local nn = minetest.get_node(p).name
|
||||
local def = minetest.registered_nodes[nn]
|
||||
local fgroup = minetest.get_item_group(nn, "flammable")
|
||||
local node = get_node(p)
|
||||
local node_name = node.name
|
||||
local def = minetest.registered_nodes[node_name]
|
||||
local fgroup = minetest.get_item_group(node_name, "flammable")
|
||||
|
||||
if def and def._on_burn then
|
||||
def._on_burn(p)
|
||||
elseif fgroup ~= -1 then
|
||||
spawn_fire(p)
|
||||
local source_node = get_node(pos)
|
||||
local age = source_node.param2
|
||||
|
||||
spawn_fire(p, age + math.ceil(minetest.get_humidity(p)/10) + math.random(5), true)
|
||||
minetest.check_for_falling(p)
|
||||
|
||||
if source_node.name == "mcl_fire:fire" then
|
||||
-- Always age the source fire
|
||||
age = age + math.ceil(minetest.get_humidity(pos)/10) + math.random(5)
|
||||
if age > 255 then age = 255 end
|
||||
source_node.param2 = age
|
||||
set_node(pos, source_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -454,17 +530,17 @@ function mcl_fire.set_fire(pointed_thing, player, allow_on_fire)
|
|||
return
|
||||
end
|
||||
|
||||
local n_pointed = minetest.get_node(pointed_thing.under)
|
||||
local n_pointed = get_node(pointed_thing.under)
|
||||
if allow_on_fire == false and get_item_group(n_pointed.name, "fire") ~= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local n_fire_pos = minetest.get_node(pointed_thing.above)
|
||||
local n_fire_pos = get_node(pointed_thing.above)
|
||||
if n_fire_pos.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
local n_below = minetest.get_node(vector.offset(pointed_thing.above, 0, -1, 0))
|
||||
local n_below = get_node(vector.offset(pointed_thing.above, 0, -1, 0))
|
||||
if minetest.get_item_group(n_below.name, "water") ~= 0 then
|
||||
return
|
||||
end
|
||||
|
|
|
@ -196,7 +196,7 @@ function kelp.find_unsubmerged(pos, node, height)
|
|||
for i=1,height do
|
||||
walk_pos.y = y + i
|
||||
local walk_node = mt_get_node(walk_pos)
|
||||
if walk_node.name ~= "ignore" and not kelp.is_submerged(walk_node) then
|
||||
if not kelp.is_submerged(walk_node) then
|
||||
return walk_pos, walk_node, height, i
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue