123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- local function splitname(name)
- local c = string.find(name, ":", 1)
- return string.sub(name, 1, c - 1), string.sub(name, c + 1, string.len(name))
- end
- function deepclone(t)
- if type(t) ~= "table" then
- return t
- end
-
- local meta = getmetatable(t)
- local target = {}
-
- for k, v in pairs(t) do
- if type(v) == "table" then
- target[k] = deepclone(v)
- else
- target[k] = v
- end
- end
-
- setmetatable(target, meta)
-
- return target
- end
- local spill_nodes = {
- "default:cobble",
- "default:mossycobble",
- "default:desert_cobble",
- "default:sand",
- "default:silver_sand",
- "default:desert_sand",
- "default:gravel",
- "default:snow",
- "default:snowblock",
- "default:dirt",
- "default:dirt_with_grass",
- "default:dirt_with_grass_footsteps",
- "default:dirt_with_dry_grass",
- "default:dirt_with_snow",
- "default:dirt_with_rainforest_litter",
- "default:dirt_with_coniferous_litter",
- -- "default:water_source",
- }
- local soil_more = {}
- local soil_less = {}
- local soil_abm_nodes = {}
- local soil_abm_neighbors = {}
- local burnable_soiled_nodes = {}
- local function spill_name(orig, lvl)
- local mod, node = splitname(orig)
- return "bitumen:oily_"..mod.."_"..node.."_"..lvl
- end
- local function reg_level(old, modname, nodename, level)
- local def = deepclone(minetest.registered_nodes[old])
- if not def then
- return nil
- end
-
- --def.groups.not_in_creative_inventory = 1
- def.groups.bitumen_oily = level
- def.description = "Oily " .. def.description
-
- local name1 = "bitumen:oily_"..modname.."_"..nodename.."_"..level
- -- table.insert(abm_list_1, old)
- -- downgrades[old] = name1
-
- for k, v in pairs(def.tiles) do
- local o = def.tiles[k]
- if type(o) == 'string' then
- def.tiles[k] = def.tiles[k].."^bitumen_oil_splat_"..level..".png"
- elseif type(o) == 'table' then
- o.name = o.name .. "^bitumen_oil_splat_"..level..".png"
- end
- end
-
- def.drops = name1
-
- minetest.register_node(name1, def)
-
- return name1
- end
- local register_spill_node = function(old)
- local modname, nodename = splitname(old)
-
- local n1 = reg_level(old, modname, nodename, 1)
- local n2 = reg_level(old, modname, nodename, 2)
- local n3 = reg_level(old, modname, nodename, 3)
-
- if n1 and n2 and n3 then
- soil_more[old] = n1
- soil_more[n1] = n2
- soil_more[n2] = n3
-
- soil_less[n3] = n2
- soil_less[n2] = n1
- soil_less[n1] = old
-
- table.insert(soil_abm_nodes, n3)
- table.insert(soil_abm_nodes, n2)
- table.insert(soil_abm_neighbors, n2)
- table.insert(soil_abm_neighbors, n1)
- table.insert(soil_abm_neighbors, old)
-
- table.insert(burnable_soiled_nodes, n3)
- table.insert(burnable_soiled_nodes, n2)
- end
- end
- -- TODO: wool, stairs, walls, seasons
- for _,n in ipairs(spill_nodes) do
- register_spill_node(n)
- end
- -- water is handled differently
- local function reg_oily_water(level)
- local color = 120 + (level * 3)
- local aff = (level + 2)
- minetest.register_node("bitumen:oily_default_water_source_"..level, {
- description = "Oily Water Source",
- drawtype = "liquid",
- tiles = {
- {
- name = "default_water_source_animated.png^[colorize:black:"..color,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- },
- },
- special_tiles = {
- -- New-style water source material (mostly unused)
- {
- name = "default_water_source_animated.png^[colorize:black:"..color,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- backface_culling = false,
- },
- },
- alpha = 160,
- paramtype = "light",
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drop = "",
- drowning = 1,
- liquidtype = "source",
- liquid_alternative_flowing = "bitumen:oily_default_water_flowing_"..level,
- liquid_alternative_source = "bitumen:oily_default_water_source_"..level,
- liquid_viscosity = 1,
- post_effect_color = {a = 103 + (level * 50), r = 30 / aff, g = 60 / aff, b = 90 / aff},
- groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1, bitumen_oily = level},
- sounds = default.node_sound_water_defaults(),
- })
- minetest.register_node("bitumen:oily_default_water_flowing_"..level, {
- description = "Oily Flowing Water",
- drawtype = "flowingliquid",
- tiles = {"default_water.png^[colorize:black:"..color},
- special_tiles = {
- {
- name = "default_water_flowing_animated.png^[colorize:black:"..color,
- backface_culling = false,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 0.8,
- },
- },
- {
- name = "default_water_flowing_animated.png^[colorize:black:"..color,
- backface_culling = true,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 0.8,
- },
- },
- },
- alpha = 160,
- paramtype = "light",
- paramtype2 = "flowingliquid",
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drop = "",
- drowning = 1,
- liquidtype = "flowing",
- liquid_alternative_flowing = "bitumen:oily_default_water_flowing_"..level,
- liquid_alternative_source = "bitumen:oily_default_water_source_"..level,
- liquid_viscosity = 1,
- post_effect_color = {a = 103 + (level * 50), r = 30 / aff, g = 60 / aff, b = 90 / aff},
- groups = {water = 3, liquid = 3, puts_out_fire = 1,
- not_in_creative_inventory = 1, cools_lava = 1, bitumen_oily = level},
- sounds = default.node_sound_water_defaults(),
- })
- minetest.register_node("bitumen:oily_default_river_water_source_"..level, {
- description = "Oily River Water Source",
- drawtype = "liquid",
- tiles = {
- {
- name = "default_river_water_source_animated.png^[colorize:black:"..color,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- },
- },
- special_tiles = {
- {
- name = "default_river_water_source_animated.png^[colorize:black:"..color,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 2.0,
- },
- backface_culling = false,
- },
- },
- alpha = 160,
- paramtype = "light",
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drop = "",
- drowning = 1,
- liquidtype = "source",
- liquid_alternative_flowing = "bitumen:oily_default_river_water_flowing_"..level,
- liquid_alternative_source = "bitumen:oily_default_river_water_source_"..level,
- liquid_viscosity = 1,
- -- Not renewable to avoid horizontal spread of water sources in sloping
- -- rivers that can cause water to overflow riverbanks and cause floods.
- -- River water source is instead made renewable by the 'force renew'
- -- option used in the 'bucket' mod by the river water bucket.
- liquid_renewable = false,
- liquid_range = 2,
- post_effect_color = {a = 103 + (level * 50), r = 30 / aff, g = 76 / aff, b = 90 / aff},
- groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1, bitumen_oily = level},
- sounds = default.node_sound_water_defaults(),
- })
- minetest.register_node("bitumen:oily_default_river_water_flowing_"..level, {
- description = "Oily Flowing River Water",
- drawtype = "flowingliquid",
- tiles = {"default_river_water.png^[colorize:black:"..color},
- special_tiles = {
- {
- name = "default_river_water_flowing_animated.png^[colorize:black:"..color,
- backface_culling = false,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 0.8,
- },
- },
- {
- name = "default_river_water_flowing_animated.png^[colorize:black:"..color,
- backface_culling = true,
- animation = {
- type = "vertical_frames",
- aspect_w = 16,
- aspect_h = 16,
- length = 0.8,
- },
- },
- },
- alpha = 160,
- paramtype = "light",
- paramtype2 = "flowingliquid",
- walkable = false,
- pointable = false,
- diggable = false,
- buildable_to = true,
- is_ground_content = false,
- drop = "",
- drowning = 1,
- liquidtype = "flowing",
- liquid_alternative_flowing = "bitumen:oily_default_river_water_flowing_"..level,
- liquid_alternative_source = "bitumen:oily_default_river_water_source_"..level,
- liquid_viscosity = 1,
- liquid_renewable = false,
- liquid_range = 2,
- post_effect_color = {a = 103 + (level * 50), r = 30 / aff, g = 76 / aff, b = 90 / aff},
- groups = {water = 3, liquid = 3, puts_out_fire = 1,
- not_in_creative_inventory = 1, cools_lava = 1, bitumen_oily = level},
- sounds = default.node_sound_water_defaults(),
- })
- end
- local function insert_soiling(mod, node)
- local old = mod .. ":" .. node
- local n1 = "bitumen:oily_"..mod.."_"..node.."_1"
- local n2 = "bitumen:oily_"..mod.."_"..node.."_2"
- local n3 = "bitumen:oily_"..mod.."_"..node.."_3"
-
- soil_more[old] = n1
- soil_more[n1] = n2
- soil_more[n2] = n3
-
- soil_less[n3] = n2
- soil_less[n2] = n1
- soil_less[n1] = old
-
- table.insert(soil_abm_nodes, n3)
- table.insert(soil_abm_nodes, n2)
- table.insert(soil_abm_neighbors, n2)
- table.insert(soil_abm_neighbors, n1)
- table.insert(soil_abm_neighbors, old)
- end
- reg_oily_water(1)
- reg_oily_water(2)
- reg_oily_water(3)
- insert_soiling("default", "water_source")
- insert_soiling("default", "river_water_source")
- -- abms
- minetest.register_abm({
- nodenames = soil_abm_nodes,
- neighbors = soil_abm_neighbors,
- interval = 5,
- chance = 20,
- action = function(pos, node, active_object_count, active_object_count_wider)
-
- local alvl = minetest.registered_nodes[node.name].groups.bitumen_oily or 0
-
- local unsoiled = minetest.find_nodes_in_area(
- {x=pos.x-1, y=pos.y-1, z=pos.z-1},
- {x=pos.x+1, y=pos.y , z=pos.z+1},
- soil_abm_neighbors
- )
- if not unsoiled then
- return
- end
-
- local off = math.random(#unsoiled)
- for i = 1, #unsoiled do
- local bp = unsoiled[((i + off) % #unsoiled) + 1]
-
- local bnode = minetest.get_node(bp)
- local blvl = minetest.registered_nodes[bnode.name].groups.bitumen_oily or 0
-
- if alvl > blvl then
- minetest.set_node(pos, {name = soil_less[node.name]})
- minetest.set_node(bp, {name = soil_more[bnode.name]})
- return
- end
- end
-
- end
- })
-
- -- crude oil spreads into certain tiles
- minetest.register_abm({
- nodenames = {"bitumen:crude_oil", "bitumen:crude_oil_full"},
- neighbors = soil_abm_neighbors,
- interval = 3,
- chance = 10,
- action = function(pos, node, active_object_count, active_object_count_wider)
-
- local unsoiled = minetest.find_nodes_in_area(
- {x=pos.x-1, y=pos.y-1, z=pos.z-1},
- {x=pos.x+1, y=pos.y , z=pos.z+1},
- soil_abm_neighbors
- )
- if not unsoiled then
- return
- end
-
- local off = math.random(#unsoiled)
- for i = 1, #unsoiled do
- local bp = unsoiled[((i + off) % #unsoiled) + 1]
- local bnode = minetest.get_node(bp)
-
- local x = soil_more[bnode.name]
- if x == nil then
- -- print(dump2(x).. " -> " ..dump2(bnode.name))
- else
- local lvl = minetest.get_node_level(pos)
- local nl = math.max(0, lvl - 10)
-
- if nl == 0 then
- minetest.set_node(pos, {name="air"})
- else
- minetest.set_node_level(pos, nl)
- end
-
- minetest.set_node(bp, {name=x})
-
- return
- end
- end
-
- end
- })
-
- minetest.register_abm({
- label = "Spilled nodes burn slowly",
- nodenames = burnable_soiled_nodes,
- neighbors = {"fire:basic_flame"},
- interval = 4,
- chance = 20,
- catch_up = true,
- action = function(pos, node, active_object_count, active_object_count_wider)
- local n = minetest.get_node(pos)
- if n then
- local less = soil_less[n.name]
- if less then
- minetest.set_node(pos, {name = less})
- end
- end
- end,
- })
- minetest.register_abm({
- label = "Spilled nodes catch fire",
- nodenames = burnable_soiled_nodes,
- neighbors = {"fire:basic_flame"},
- interval = 3,
- chance = 5,
- catch_up = true,
- action = function(pos, node, active_object_count, active_object_count_wider)
- local n = minetest.find_node_near(pos, 1, {"air"})
- if n then
- minetest.set_node(n, {name = "fire:basic_flame"})
- end
- end,
- })
|