Compare commits

..

4 Commits

19 changed files with 215 additions and 131 deletions

View File

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

View File

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

View File

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

View File

@ -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
else
-- stop accelerating once max fall speed hit
new_acceleration =vector.zero()

View File

@ -72,23 +72,17 @@ 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,
}

View File

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

View File

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

View File

@ -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,
}

View File

@ -75,7 +75,6 @@ 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},
@ -83,7 +82,6 @@ function mcl_weather.snow.set_sky_box()
{r=135, g=135, b=135},
{r=85, g=86, b=86},
{r=0, g=0, b=0}})
end
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#ADADADE8"})

View File

@ -23,7 +23,6 @@ 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},
@ -31,7 +30,6 @@ minetest.register_globalstep(function(dtime)
{r=40, g=40, b=40},
{r=0, g=0, b=0},
})
end
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#3D3D3FE8"})

View File

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

View File

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

View File

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

View File

@ -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 = {}

View File

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

View File

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

View File

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

View File

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

View File

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