Extra error checking.

This commit is contained in:
Duane 2016-07-15 02:58:33 -05:00
parent aa999e2ed5
commit bf26b8bee1
25 changed files with 897 additions and 314 deletions

View file

@ -43,11 +43,17 @@ local plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z =
local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = -1471, octaves = 3, persist = 0.5, lacunarity = 2.0} local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = -1471, octaves = 3, persist = 0.5, lacunarity = 2.0}
fun_caves.asteroids = function(minp, maxp, data, p2data, area, node) fun_caves.asteroids = function(minp, maxp, data, p2data, area, node)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
if minp.y < 11168 or minp.y > 15168 then if minp.y < 11168 or minp.y > 15168 then
return return
end end
math.randomseed(minetest.get_us_time()) -- What's this for?
--math.randomseed(minetest.get_us_time())
local density = 4 + math.abs(minp.y - 13168) / 500 local density = 4 + math.abs(minp.y - 13168) / 500
local empty = false local empty = false
if math.random(math.floor(density)) ~= 1 then if math.random(math.floor(density)) ~= 1 then
@ -60,6 +66,9 @@ fun_caves.asteroids = function(minp, maxp, data, p2data, area, node)
local map_min = {x = minp.x, y = minp.y, z = minp.z} local map_min = {x = minp.x, y = minp.y, z = minp.z}
local asteroid_1 = minetest.get_perlin_map(asteroid_noise_1, map_max):get3dMap_flat(map_min) local asteroid_1 = minetest.get_perlin_map(asteroid_noise_1, map_max):get3dMap_flat(map_min)
if not asteroid_1 then
return
end
local write = false local write = false

View file

@ -19,6 +19,10 @@ ground_nodes[minetest.get_content_id('default:dirt_with_dry_grass')] = true
fun_caves.cavegen = function(minp, maxp, data, area, node, heightmap, underzone) fun_caves.cavegen = function(minp, maxp, data, area, node, heightmap, underzone)
if not (minp and maxp and data and area and node and type(data) == 'table') then
return
end
local csize = vector.add(vector.subtract(maxp, minp), 1) local csize = vector.add(vector.subtract(maxp, minp), 1)
local map_max = {x = csize.x, y = csize.y + 2, z = csize.z} local map_max = {x = csize.x, y = csize.y + 2, z = csize.z}
local map_min = {x = minp.x, y = minp.y - 1, z = minp.z} local map_min = {x = minp.x, y = minp.y - 1, z = minp.z}
@ -32,6 +36,9 @@ fun_caves.cavegen = function(minp, maxp, data, area, node, heightmap, underzone)
local cave_1 = minetest.get_perlin_map(fun_caves.cave_noise_1, map_max):get3dMap_flat(map_min) local cave_1 = minetest.get_perlin_map(fun_caves.cave_noise_1, map_max):get3dMap_flat(map_min)
local cave_2 = minetest.get_perlin_map(fun_caves.cave_noise_2, map_max):get3dMap_flat(map_min) local cave_2 = minetest.get_perlin_map(fun_caves.cave_noise_2, map_max):get3dMap_flat(map_min)
local cave_3 = minetest.get_perlin_map(cave_noise_3, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local cave_3 = minetest.get_perlin_map(cave_noise_3, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
if not (cave_1 and cave_2 and cave_3) then
return
end
local write = false local write = false

View file

@ -3,7 +3,15 @@ minetest.register_chatcommand("armor", {
description = "Display your armor values", description = "Display your armor values",
privs = {}, privs = {},
func = function(player_name, param) func = function(player_name, param)
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
local player = minetest.get_player_by_name(player_name) local player = minetest.get_player_by_name(player_name)
if not player then
return
end
local armor = player:get_armor_groups() local armor = player:get_armor_groups()
if armor then if armor then
minetest.chat_send_player(player_name, "Armor:") minetest.chat_send_player(player_name, "Armor:")
@ -13,7 +21,12 @@ minetest.register_chatcommand("armor", {
if fun_caves.db.status[player_name].armor_elixir then if fun_caves.db.status[player_name].armor_elixir then
local armor_time = fun_caves.db.status[player_name].armor_elixir.remove local armor_time = fun_caves.db.status[player_name].armor_elixir.remove
local min = math.floor(math.max(0, armor_time - minetest.get_gametime()) / 60) local game_time = minetest.get_gametime()
if not (armor_time and type(armor_time) == 'number' and game_time and type(game_time) == 'number') then
return
end
local min = math.floor(math.max(0, armor_time - game_time) / 60)
minetest.chat_send_player(player_name, "Your armor elixir will expire in "..min..' minutes.') minetest.chat_send_player(player_name, "Your armor elixir will expire in "..min..' minutes.')
end end
end end
@ -25,11 +38,19 @@ minetest.register_chatcommand("setspawn", {
params = "", params = "",
description = "change your spawn position", description = "change your spawn position",
privs = {}, privs = {},
func = function(name, param) func = function(player_name, param)
local player = minetest.get_player_by_name(name) if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
local player = minetest.get_player_by_name(player_name)
if not player then
return
end
local pos = player:getpos() local pos = player:getpos()
beds.spawn[name] = pos beds.spawn[player_name] = pos
minetest.chat_send_player(name, 'Your spawn position has been changed.') minetest.chat_send_player(player_name, 'Your spawn position has been changed.')
end, end,
}) })
@ -38,21 +59,38 @@ minetest.register_chatcommand("fixlight", {
params = "<radius>", params = "<radius>",
description = "attempt to fix light bugs", description = "attempt to fix light bugs",
privs = {}, privs = {},
func = function(name, param) func = function(player_name, param)
local privs = minetest.check_player_privs(name, {server=true}) if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
local privs = minetest.check_player_privs(player_name, {server=true})
if not privs then if not privs then
return return
end end
print('Fun Caves: '..name..' used the fixlight command') print('Fun Caves: '..player_name..' used the fixlight command')
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(player_name)
local pos = vector.round(player:getpos()) if not player then
return
end
local pos = player:getpos()
if not pos then
return
end
pos = vector.round(pos)
local radius = tonumber(param) or 50 local radius = tonumber(param) or 50
radius = math.floor(radius) radius = math.floor(radius)
local minp = vector.subtract(pos, radius) local minp = vector.subtract(pos, radius)
local maxp = vector.add(pos, radius) local maxp = vector.add(pos, radius)
local vm = minetest.get_voxel_manip(minp, maxp) local vm = minetest.get_voxel_manip(minp, maxp)
if not vm then
return
end
--vm:set_lighting({day = 0, night = 0}, minp, maxp) --vm:set_lighting({day = 0, night = 0}, minp, maxp)
vm:calc_lighting(minp, maxp) vm:calc_lighting(minp, maxp)
vm:update_liquids() vm:update_liquids()
@ -66,24 +104,39 @@ minetest.register_chatcommand("flatten", {
params = "<radius>", params = "<radius>",
description = "flatten terrain", description = "flatten terrain",
privs = {}, privs = {},
func = function(name, param) func = function(player_name, param)
local privs = minetest.check_player_privs(name, {server=true}) if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
local privs = minetest.check_player_privs(player_name, {server=true})
if not privs then if not privs then
return return
end end
print('Fun Caves: '..name..' used the flatten command') print('Fun Caves: '..player_name..' used the flatten command')
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(player_name)
local pos = vector.round(player:getpos()) if not player then
return
end
local pos = player:getpos()
if not pos then
return
end
pos = vector.round(pos)
local radius = tonumber(param) or 50 local radius = tonumber(param) or 50
radius = math.floor(radius) radius = math.floor(radius)
local minp = vector.subtract(pos, radius) local minp = vector.subtract(pos, radius)
minp.y = minp.y - math.ceil(radius / 2) minp.y = minp.y - math.ceil(radius / 2)
local maxp = vector.add(pos, radius) local maxp = vector.add(pos, radius)
maxp.y = maxp.y + math.ceil(radius / 2) maxp.y = maxp.y + math.ceil(radius / 2)
local air = minetest.get_content_id('air') local air = minetest.get_content_id('air')
local stone = minetest.get_content_id('default:stone') local stone = minetest.get_content_id('default:stone')
local water = minetest.get_content_id('default:water_source') local water = minetest.get_content_id('default:water_source')
local waters = {} local waters = {}
waters[minetest.get_content_id('default:water_source')] = true waters[minetest.get_content_id('default:water_source')] = true
waters[minetest.get_content_id('default:river_water_source')] = true waters[minetest.get_content_id('default:river_water_source')] = true
@ -94,6 +147,10 @@ minetest.register_chatcommand("flatten", {
end end
local vm = minetest.get_voxel_manip(minp, maxp) local vm = minetest.get_voxel_manip(minp, maxp)
if not vm then
return
end
local emin, emax = vm:read_from_map(minp, maxp) local emin, emax = vm:read_from_map(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local data = vm:get_data() local data = vm:get_data()
@ -107,7 +164,7 @@ minetest.register_chatcommand("flatten", {
for y = maxp.y, minp.y, -1 do for y = maxp.y, minp.y, -1 do
if stones[data[ivm]] then if stones[data[ivm]] then
if y >= maxp.y then if y >= maxp.y then
print('Terrain altitude exceeds the radius.') minetest.chat_send_player(player_name, 'Terrain altitude exceeds the given radius.')
return return
end end
heightmap[index] = y heightmap[index] = y
@ -119,7 +176,7 @@ minetest.register_chatcommand("flatten", {
end end
if not heightmap[index] then if not heightmap[index] then
print('Terrain altitude exceeds the radius.') minetest.chat_send_player(player_name, 'Terrain altitude exceeds the given radius.')
return return
end end

View file

@ -1,4 +1,117 @@
dofile(fun_caves.path .. "/deco_clouds.lua")
local newnode = fun_caves.clone_node("default:dirt")
newnode.description = "Cloud"
newnode.tiles = {'fun_caves_cloud.png'}
newnode.sunlight_propagates = true
minetest.register_node("fun_caves:cloud", newnode)
newnode = fun_caves.clone_node("default:dirt")
newnode.description = "Storm Cloud"
newnode.tiles = {'fun_caves_storm_cloud.png'}
--newnode.sunlight_propagates = true
minetest.register_node("fun_caves:storm_cloud", newnode)
minetest.register_node("fun_caves:wispy_cloud", {
description = "Wispy Cloud",
tiles = {'fun_caves_wisp.png'},
sunlight_propagates = true,
use_texture_alpha = true,
drawtype = "glasslike",
paramtype = 'light',
walkable = false,
buildable_to = true,
pointable = false,
})
minetest.register_node("fun_caves:moon_weed", {
description = "Moon Weed",
drawtype = "plantlike",
tiles = {"fun_caves_moon_weed.png"},
inventory_image = "fun_caves_moon_weed.png",
waving = false,
sunlight_propagates = true,
paramtype = "light",
light_source = 8,
walkable = false,
groups = {snappy=3,flammable=2,flora=1,attached_node=1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
},
})
minetest.register_node("fun_caves:leaves_lumin", {
description = "Leaves",
drawtype = "allfaces_optional",
waving = 1,
visual_scale = 1.3,
tiles = {"default_leaves.png^[colorize:#FFDF00:150"},
special_tiles = {"default_leaves_simple.png^[colorize:#FFDF00:150"},
paramtype = "light",
is_ground_content = false,
light_source = 8,
groups = {snappy = 3, leafdecay = 4, flammable = 2, leaves = 1},
drop = {
max_items = 1,
items = {
--{
-- -- player will get sapling with 1/20 chance
-- items = {'default:sapling'},
-- rarity = 20,
--},
{
-- player will get leaves only if he get no saplings,
-- this is because max_items is 1
items = {'fun_caves:leaves_lumin'},
}
}
},
sounds = default.node_sound_leaves_defaults(),
after_place_node = default.after_place_leaves,
})
minetest.register_node("fun_caves:lumin_tree", {
description = "Lumin Tree",
tiles = {
"default_tree_top.png", "default_tree_top.png", "fun_caves_lumin_tree.png"
},
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = { {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, }
},
paramtype2 = "facedir",
is_ground_content = false,
groups = {tree = 1, choppy = 2, flammable = 2},
sounds = default.node_sound_wood_defaults(),
on_place = minetest.rotate_node
})
newnode = fun_caves.clone_node("default:stone_with_iron")
newnode.description = "Silver Lining"
newnode.tiles = {'fun_caves_cloud.png^default_mineral_coal.png^[colorize:#FFFFFF:175'}
newnode.drop = "fun_caves:silver_lump"
minetest.register_node("fun_caves:silver_lining", newnode)
minetest.register_craftitem("fun_caves:silver_lump", {
description = "Lump of Silver",
inventory_image = 'default_coal_lump.png^[colorize:#FFFFFF:175',
})
minetest.register_craftitem("fun_caves:silver_ingot", {
description = "Silver Ingot",
inventory_image = 'default_steel_ingot.png^[colorize:#FFFFFF:175',
})
minetest.register_craft({
type = "cooking",
output = "fun_caves:silver_ingot",
recipe = "fun_caves:silver_lump",
})
local max_depth = 31000 local max_depth = 31000
@ -10,6 +123,10 @@ local plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z =
local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = -1471, octaves = 3, persist = 0.5, lacunarity = 2.0} local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = -1471, octaves = 3, persist = 0.5, lacunarity = 2.0}
fun_caves.cloudgen = function(minp, maxp, data, p2data, area, node) fun_caves.cloudgen = function(minp, maxp, data, p2data, area, node)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
if minp.y ~= 4368 then if minp.y ~= 4368 then
return return
end end
@ -22,6 +139,9 @@ fun_caves.cloudgen = function(minp, maxp, data, p2data, area, node)
local cloud_2 = minetest.get_perlin_map(cloud_noise_2, map_max):get3dMap_flat(map_min) local cloud_2 = minetest.get_perlin_map(cloud_noise_2, map_max):get3dMap_flat(map_min)
local plant_n = minetest.get_perlin_map(plant_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local plant_n = minetest.get_perlin_map(plant_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
local biome_n = minetest.get_perlin_map(biome_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local biome_n = minetest.get_perlin_map(biome_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
if not (cloud_1 and cloud_2 and plant_n and biome_n) then
return
end
local write = false local write = false

View file

@ -137,6 +137,10 @@ end
-- Create and initialize a table for a schematic. -- Create and initialize a table for a schematic.
function fun_caves.schematic_array(width, height, depth) function fun_caves.schematic_array(width, height, depth)
if not (width and height and depth and type(width) == 'number' and type(height) == 'number' and type(depth) == 'number') then
return
end
-- Dimensions of data array. -- Dimensions of data array.
local s = {size={x=width, y=height, z=depth}} local s = {size={x=width, y=height, z=depth}}
s.data = {} s.data = {}

View file

@ -1,114 +0,0 @@
local newnode = fun_caves.clone_node("default:dirt")
newnode.description = "Cloud"
newnode.tiles = {'fun_caves_cloud.png'}
newnode.sunlight_propagates = true
minetest.register_node("fun_caves:cloud", newnode)
newnode = fun_caves.clone_node("default:dirt")
newnode.description = "Storm Cloud"
newnode.tiles = {'fun_caves_storm_cloud.png'}
--newnode.sunlight_propagates = true
minetest.register_node("fun_caves:storm_cloud", newnode)
minetest.register_node("fun_caves:wispy_cloud", {
description = "Wispy Cloud",
tiles = {'fun_caves_wisp.png'},
sunlight_propagates = true,
use_texture_alpha = true,
drawtype = "glasslike",
paramtype = 'light',
walkable = false,
buildable_to = true,
pointable = false,
})
minetest.register_node("fun_caves:moon_weed", {
description = "Moon Weed",
drawtype = "plantlike",
tiles = {"fun_caves_moon_weed.png"},
inventory_image = "fun_caves_moon_weed.png",
waving = false,
sunlight_propagates = true,
paramtype = "light",
light_source = 8,
walkable = false,
groups = {snappy=3,flammable=2,flora=1,attached_node=1},
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
},
})
minetest.register_node("fun_caves:leaves_lumin", {
description = "Leaves",
drawtype = "allfaces_optional",
waving = 1,
visual_scale = 1.3,
tiles = {"default_leaves.png^[colorize:#FFDF00:150"},
special_tiles = {"default_leaves_simple.png^[colorize:#FFDF00:150"},
paramtype = "light",
is_ground_content = false,
light_source = 8,
groups = {snappy = 3, leafdecay = 4, flammable = 2, leaves = 1},
drop = {
max_items = 1,
items = {
--{
-- -- player will get sapling with 1/20 chance
-- items = {'default:sapling'},
-- rarity = 20,
--},
{
-- player will get leaves only if he get no saplings,
-- this is because max_items is 1
items = {'fun_caves:leaves_lumin'},
}
}
},
sounds = default.node_sound_leaves_defaults(),
after_place_node = default.after_place_leaves,
})
minetest.register_node("fun_caves:lumin_tree", {
description = "Lumin Tree",
tiles = {
"default_tree_top.png", "default_tree_top.png", "fun_caves_lumin_tree.png"
},
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = { {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}, }
},
paramtype2 = "facedir",
is_ground_content = false,
groups = {tree = 1, choppy = 2, flammable = 2},
sounds = default.node_sound_wood_defaults(),
on_place = minetest.rotate_node
})
newnode = fun_caves.clone_node("default:stone_with_iron")
newnode.description = "Silver Lining"
newnode.tiles = {'fun_caves_cloud.png^default_mineral_coal.png^[colorize:#FFFFFF:175'}
newnode.drop = "fun_caves:silver_lump"
minetest.register_node("fun_caves:silver_lining", newnode)
minetest.register_craftitem("fun_caves:silver_lump", {
description = "Lump of Silver",
inventory_image = 'default_coal_lump.png^[colorize:#FFFFFF:175',
})
minetest.register_craftitem("fun_caves:silver_ingot", {
description = "Silver Ingot",
inventory_image = 'default_steel_ingot.png^[colorize:#FFFFFF:175',
})
minetest.register_craft({
type = "cooking",
output = "fun_caves:silver_ingot",
recipe = "fun_caves:silver_lump",
})

View file

@ -1,5 +1,9 @@
fun_caves.water_plants = {} fun_caves.water_plants = {}
local function register_water_plant(desc) local function register_water_plant(desc)
if not (desc and type(desc) == 'table') then
return
end
fun_caves.water_plants[#fun_caves.water_plants+1] = desc fun_caves.water_plants[#fun_caves.water_plants+1] = desc
end end
@ -129,6 +133,10 @@ for _, plant in ipairs(fun_caves.plantlist) do
}, },
sounds = plant.sounds or default.node_sound_leaves_defaults(), sounds = plant.sounds or default.node_sound_leaves_defaults(),
after_dig_node = function(pos, oldnode, oldmetadata, digger) after_dig_node = function(pos, oldnode, oldmetadata, digger)
if not (pos and oldnode) then
return
end
local replacement = oldnode.name:gsub('.*_water_(.*)', 'default:%1') local replacement = oldnode.name:gsub('.*_water_(.*)', 'default:%1')
if replacement:find('cloud$') then if replacement:find('cloud$') then
replacement = replacement:gsub('^default', 'fun_caves') replacement = replacement:gsub('^default', 'fun_caves')
@ -151,6 +159,10 @@ end
local function register_flower(name, seed, biomes) local function register_flower(name, seed, biomes)
if not (name and seed and biomes and type(name) == 'string' and type(seed) == 'number' and type(biomes) == 'table') then
return
end
local param = { local param = {
deco_type = "simple", deco_type = "simple",
place_on = {"default:dirt_with_grass"}, place_on = {"default:dirt_with_grass"},

View file

@ -1,5 +1,9 @@
-- Place a small nodebox. -- Place a small nodebox.
local function small_cube(grid, pos, diameters) local function small_cube(grid, pos, diameters)
if not (grid and pos and diameters and type(grid) == 'table' and type(diameters) == 'table') then
return
end
local rock = {} local rock = {}
rock[1] = pos.x rock[1] = pos.x
@ -83,6 +87,10 @@ minetest.register_node("fun_caves:small_rocks", {
groups = {stone=1, oddly_breakable_by_hand=3, dig_immediate = 3}, groups = {stone=1, oddly_breakable_by_hand=3, dig_immediate = 3},
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
if not pos then
return
end
minetest.set_node(pos, {name = "fun_caves:small_rocks"..math.random(6)}) minetest.set_node(pos, {name = "fun_caves:small_rocks"..math.random(6)})
end, end,
}) })

View file

@ -25,7 +25,11 @@ local plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z =
-- Air needs to be placed prior to decorations. -- Air needs to be placed prior to decorations.
fun_caves.decogen = function(minp, maxp, data, p2data, area, node, heightmap, biomemap, biome_ids, underzone, dis_map) fun_caves.decogen = function(minp, maxp, data, p2data, area, node, heightmap, biomemap, biome_ids, underzone)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
csize = vector.add(vector.subtract(maxp, minp), 1) csize = vector.add(vector.subtract(maxp, minp), 1)
local map_max = {x = csize.x, y = csize.y + 2, z = csize.z} local map_max = {x = csize.x, y = csize.y + 2, z = csize.z}
@ -33,6 +37,9 @@ fun_caves.decogen = function(minp, maxp, data, p2data, area, node, heightmap, bi
local biome_n = minetest.get_perlin_map(biome_noise, map_max):get3dMap_flat(map_min) local biome_n = minetest.get_perlin_map(biome_noise, map_max):get3dMap_flat(map_min)
local plant_n = minetest.get_perlin_map(plant_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local plant_n = minetest.get_perlin_map(plant_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
if not (biome_n and plant_n) then
return
end
local math_random = math.random local math_random = math.random
local dis_map = {} local dis_map = {}
@ -350,7 +357,11 @@ fun_caves.decogen = function(minp, maxp, data, p2data, area, node, heightmap, bi
pos.x = x pos.x = x
pos.y = y pos.y = y
pos.z = z pos.z = z
local posm, count = minetest.find_nodes_in_area(pos, pos, desc.place_on) local posm = minetest.find_nodes_in_area(pos, pos, desc.place_on)
if not (posm and type(posm) == 'table') then
return
end
if #posm > 0 then if #posm > 0 then
node_match_cache[desc.content_id][data[ivm]] = "good" node_match_cache[desc.content_id][data[ivm]] = "good"
else else

View file

@ -14,6 +14,10 @@ minetest.register_node("fun_caves:freezing_vapor", {
}) })
local function snow_effect(pos, radius) local function snow_effect(pos, radius)
if not (pos and radius and type(radius) == 'number') then
return
end
minetest.add_particlespawner({ minetest.add_particlespawner({
amount = 30, amount = 30,
time = 1, time = 1,
@ -86,6 +90,10 @@ mobs:register_mob("fun_caves:ice_demon", {
animation_speed = 30, animation_speed = 30,
fly_in = 'fun_caves:freezing_vapor', fly_in = 'fun_caves:freezing_vapor',
do_custom = function(self) do_custom = function(self)
if not self then
return
end
-- This has to happen fast. -- This has to happen fast.
if self.attack then if self.attack then
self.fly = true self.fly = true
@ -163,6 +171,10 @@ local snow_demon = {
}, },
animation_speed = 30, animation_speed = 30,
do_custom = function(self) do_custom = function(self)
if not self then
return
end
if not self.attack then if not self.attack then
self.fly = false self.fly = false
end end
@ -185,9 +197,17 @@ local snow_demon = {
fun_caves.register_status({ fun_caves.register_status({
name = 'slow_cold', name = 'slow_cold',
start = function(player) start = function(player)
if not player then
return
end
player:set_physics_override({speed=0.3}) player:set_physics_override({speed=0.3})
end, end,
terminate = function(player) terminate = function(player)
if not player then
return
end
player:set_physics_override({speed=1}) player:set_physics_override({speed=1})
end, end,
}) })

View file

@ -74,6 +74,7 @@ local elixir_ingredients = {
'fun_caves:orchid', 'fun_caves:orchid',
'fun_caves:petrified_wood', 'fun_caves:petrified_wood',
'fun_caves:pillar_coral', 'fun_caves:pillar_coral',
'fun_caves:silver_lump',
'fun_caves:small_rocks', 'fun_caves:small_rocks',
'fun_caves:staghorn_coral', 'fun_caves:staghorn_coral',
'fun_caves:stalactite', 'fun_caves:stalactite',
@ -148,16 +149,20 @@ if count > 15 then
}) })
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() ~= "fun_caves:elixir" then if not (player and itemstack and old_craft_grid and itemstack:get_name() == "fun_caves:elixir") then
return return
end end
local ingredients = {} local ingredients = {}
for i = 1, player:get_inventory():get_size("craft") do local inv = player:get_inventory()
if not inv then
return
end
for i = 1, inv:get_size("craft") do
local name = old_craft_grid[i]:get_name() local name = old_craft_grid[i]:get_name()
if name ~= '' and name ~= 'fun_caves:syrup' and not name:find('green_slimeball$') then if name ~= '' and name ~= 'fun_caves:syrup' and type(name) == 'string' and not name:find('green_slimeball$') then
ingredients[#ingredients+1] = name ingredients[#ingredients+1] = name
--print(name)
end end
end end
end) end)
@ -167,6 +172,10 @@ end
fun_caves.register_status({ fun_caves.register_status({
name = 'breathe', name = 'breathe',
terminate = function(player) terminate = function(player)
if not player then
return
end
local player_name = player:get_player_name() local player_name = player:get_player_name()
minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'Your breathing becomes more difficult...')) minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'Your breathing becomes more difficult...'))
end, end,
@ -176,8 +185,16 @@ minetest.register_craftitem("fun_caves:elixir_breathe", {
description = 'Dr Robertson\'s Patented Easy Breathing Elixir', description = 'Dr Robertson\'s Patented Easy Breathing Elixir',
inventory_image = "fun_caves_elixir_breathe.png", inventory_image = "fun_caves_elixir_breathe.png",
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not (itemstack and user) then
return
end
local player_name = user:get_player_name() local player_name = user:get_player_name()
fun_caves.set_status(user:get_player_name(), 'breathe', elixir_duration) if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
fun_caves.set_status(player_name, 'breathe', elixir_duration)
minetest.chat_send_player(player_name, 'Your breathing becomes easier...') minetest.chat_send_player(player_name, 'Your breathing becomes easier...')
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack
@ -207,6 +224,10 @@ minetest.register_craft({
fun_caves.register_status({ fun_caves.register_status({
name = 'damage_elixir', name = 'damage_elixir',
terminate = function(player) terminate = function(player)
if not player then
return
end
local player_name = player:get_player_name() local player_name = player:get_player_name()
minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'You feel weaker...')) minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'You feel weaker...'))
fun_caves.db.status[player_name].damage_elixir = nil fun_caves.db.status[player_name].damage_elixir = nil
@ -217,10 +238,22 @@ fun_caves.register_status({
fun_caves.register_status({ fun_caves.register_status({
name = 'armor_elixir', name = 'armor_elixir',
terminate = function(player) terminate = function(player)
if not player then
return
end
local player_name = player:get_player_name() local player_name = player:get_player_name()
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
local armor_elixir = fun_caves.db.status[player_name].armor_elixir local armor_elixir = fun_caves.db.status[player_name].armor_elixir
local factor = armor_elixir.factor local factor = armor_elixir.factor
local armor = player:get_armor_groups() local armor = player:get_armor_groups()
if not (armor and armor.fleshy) then
return
end
armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / factor))) armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / factor)))
player:set_armor_groups(armor) player:set_armor_groups(armor)
minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'Your skin feels softer...')) minetest.chat_send_player(player_name, minetest.colorize('#FF0000', 'Your skin feels softer...'))
@ -232,10 +265,22 @@ fun_caves.register_status({
if fun_caves.expire_elixir_on_death then if fun_caves.expire_elixir_on_death then
minetest.register_on_dieplayer(function(player) minetest.register_on_dieplayer(function(player)
if not player then
return
end
local player_name = player:get_player_name() local player_name = player:get_player_name()
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
if fun_caves.db.status[player_name] and fun_caves.db.status[player_name].armor_elixir then if fun_caves.db.status[player_name] and fun_caves.db.status[player_name].armor_elixir then
local factor = fun_caves.db.status[player_name].armor_elixir.factor local factor = fun_caves.db.status[player_name].armor_elixir.factor
local armor = player:get_armor_groups() local armor = player:get_armor_groups()
if not (armor and armor.fleshy) then
return
end
armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / factor))) armor.fleshy = math.min(100, math.max(1, math.ceil(armor.fleshy / factor)))
player:set_armor_groups(armor) player:set_armor_groups(armor)
fun_caves.db.status[player_name].armor_elixir = nil fun_caves.db.status[player_name].armor_elixir = nil
@ -246,7 +291,14 @@ end
local function increase_damage(user, bonus) local function increase_damage(user, bonus)
if not user then
return
end
local player_name = user:get_player_name() local player_name = user:get_player_name()
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
minetest.chat_send_player(player_name, 'You feel strong...') minetest.chat_send_player(player_name, 'You feel strong...')
fun_caves.set_status(player_name, 'damage_elixir', elixir_duration, {bonus = bonus}) fun_caves.set_status(player_name, 'damage_elixir', elixir_duration, {bonus = bonus})
@ -254,8 +306,19 @@ end
local function armor(user, factor) local function armor(user, factor)
if not user then
return
end
local player_name = user:get_player_name() local player_name = user:get_player_name()
if not (player_name and type(player_name) == 'string' and player_name ~= '') then
return
end
local armor = user:get_armor_groups() local armor = user:get_armor_groups()
if not (armor and armor.fleshy) then
return
end
if fun_caves.db.status[player_name].armor_elixir then if fun_caves.db.status[player_name].armor_elixir then
local old_factor = fun_caves.db.status[player_name].armor_elixir.factor local old_factor = fun_caves.db.status[player_name].armor_elixir.factor
@ -297,6 +360,10 @@ if fun_caves.elixir_armor then
groups = {dig_immediate = 3, vessel = 1}, groups = {dig_immediate = 3, vessel = 1},
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not (itemstack and user) then
return
end
armor(user, value) armor(user, value)
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack
@ -347,6 +414,10 @@ for _, desc in pairs(descs) do
groups = {dig_immediate = 3, vessel = 1}, groups = {dig_immediate = 3, vessel = 1},
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not (itemstack and user) then
return
end
increase_damage(user, bonus) increase_damage(user, bonus)
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack

View file

@ -89,7 +89,15 @@ newnode.description = "Treasure Chest"
newnode.on_construct = nil newnode.on_construct = nil
newnode.drop = 'default:chest' newnode.drop = 'default:chest'
newnode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) newnode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if not pos then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
local ready = meta:get_string('formspec') local ready = meta:get_string('formspec')
if ready == '' then if ready == '' then
local level = math.max(6, math.ceil(pos.y / math.floor(max_depth / 6))) local level = math.max(6, math.ceil(pos.y / math.floor(max_depth / 6)))
@ -123,6 +131,10 @@ function table.shuffle(self)
end end
function unionfind(max) function unionfind(max)
if not (max and type(max) == 'number') then
return
end
local u = { _parent = {}, _rank = {} } local u = { _parent = {}, _rank = {} }
for i = 0, max-1 do for i = 0, max-1 do
@ -164,6 +176,10 @@ end
local function maze_floor(y2, minp, maxp, data, area, node) local function maze_floor(y2, minp, maxp, data, area, node)
if not (y2 and minp and maxp and data and area and node and type(y2) == 'number' and type(data) == 'table') then
return
end
-- walls is zero-based. -- walls is zero-based.
local walls = {} local walls = {}
for i = 0, 2 * cells * cells - 1 do for i = 0, 2 * cells * cells - 1 do
@ -290,7 +306,12 @@ local designs = {
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0}, {0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
}, },
} }
local function design_floor(y2, minp, maxp, data, area, node) local function design_floor(y2, minp, maxp, data, area, node)
if not (y2 and minp and maxp and data and area and node and type(y2) == 'number' and type(data) == 'table') then
return
end
local design = designs[math.random(#designs)] local design = designs[math.random(#designs)]
local py = minp.y + y2 * cell_size local py = minp.y + y2 * cell_size
@ -341,6 +362,10 @@ end
fun_caves.fortress = function(minp_in, maxp_in, data, area, node) fun_caves.fortress = function(minp_in, maxp_in, data, area, node)
if not (minp_in and maxp_in and data and area and node and type(data) == 'table') then
return
end
-- hungry maze -- hungry maze
-- chests (w traps) -- chests (w traps)
-- step traps (math based) -- step traps (math based)
@ -357,6 +382,9 @@ fun_caves.fortress = function(minp_in, maxp_in, data, area, node)
local treasure_count = 0 local treasure_count = 0
local csize = vector.add(vector.subtract(maxp_in, minp_in), 1) local csize = vector.add(vector.subtract(maxp_in, minp_in), 1)
local floor_1 = minetest.get_perlin_map(floor_noise_1, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp_in.x, y=minp_in.z}) local floor_1 = minetest.get_perlin_map(floor_noise_1, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp_in.x, y=minp_in.z})
if not floor_1 then
return
end
for y2 = 0, cells-1 do for y2 = 0, cells-1 do
local floor_type = math.random(20) local floor_type = math.random(20)

View file

@ -39,6 +39,10 @@ minetest.register_node("fun_caves:fungal_tree_fruit", {
local fruit = minetest.get_content_id("fun_caves:fungal_tree_fruit") local fruit = minetest.get_content_id("fun_caves:fungal_tree_fruit")
function fun_caves.make_fungal_tree(data, area, ivm, height) function fun_caves.make_fungal_tree(data, area, ivm, height)
if not (data and area and ivm and height and type(data) == 'table' and type(ivm) == 'number' and type(height) == 'number') then
return
end
local leaf = minetest.get_content_id(fungal_tree_leaves[math.random(#fungal_tree_leaves)]) local leaf = minetest.get_content_id(fungal_tree_leaves[math.random(#fungal_tree_leaves)])
local air = minetest.get_content_id('air') local air = minetest.get_content_id('air')
for y = 0, height do for y = 0, height do

View file

@ -61,7 +61,7 @@ local traps = {
local function goblin_do(self) local function goblin_do(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -412,7 +412,16 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 0.95)) do -- IDKWTF this is but it works if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 0.95)
if not (objects and type(objects) == 'table') then
return
end
for _, object in ipairs(objects) do -- IDKWTF this is but it works
if object:is_player() then if object:is_player() then
object:set_physics_override({speed = 0.1}) object:set_physics_override({speed = 0.1})
minetest.after(1, function() -- this effect is temporary minetest.after(1, function() -- this effect is temporary
@ -442,7 +451,16 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 2)
if not (objects and type(objects) == 'table') then
return
end
for _, object in ipairs(objects) do
if object:is_player() then if object:is_player() then
minetest.set_node(pos, {name="fire:basic_flame"}) minetest.set_node(pos, {name="fire:basic_flame"})
if object:get_hp() > 0 then if object:get_hp() > 0 then
@ -459,6 +477,10 @@ local diamond_trap
if (not singleplayer and setting ~= true) or (singleplayer and setting == false) then if (not singleplayer and setting ~= true) or (singleplayer and setting == false) then
-- wimpier trap for non-tnt settings -- wimpier trap for non-tnt settings
diamond_trap = function(pos, player) diamond_trap = function(pos, player)
if not (pos and player) then
return
end
minetest.set_node(pos, {name="default:lava_source"}) minetest.set_node(pos, {name="default:lava_source"})
if player:get_hp() > 0 then if player:get_hp() > 0 then
player:set_hp(player:get_hp()-2) player:set_hp(player:get_hp()-2)
@ -468,8 +490,15 @@ if (not singleplayer and setting ~= true) or (singleplayer and setting == false)
else else
-- 5... 4... 3... 2... 1... -- 5... 4... 3... 2... 1...
diamond_trap = function(pos, player) diamond_trap = function(pos, player)
if not (pos and player) then
return
end
minetest.set_node(pos, {name="tnt:tnt_burning"}) minetest.set_node(pos, {name="tnt:tnt_burning"})
minetest.get_node_timer(pos):start(5) local timer = minetest.get_node_timer(pos)
if timer then
timer:start(5)
end
minetest.sound_play("default_dig_crumbly", {pos = pos, gain = 0.5, max_hear_distance = 10}) minetest.sound_play("default_dig_crumbly", {pos = pos, gain = 0.5, max_hear_distance = 10})
end end
end end
@ -482,6 +511,10 @@ minetest.register_node("fun_caves:stone_with_diamond_trap", {
is_ground_content = false, is_ground_content = false,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_dig = function(pos, node, digger) on_dig = function(pos, node, digger)
if not (pos and digger) then
return
end
if math.random(3) == 1 then if math.random(3) == 1 then
diamond_trap(pos, digger) diamond_trap(pos, digger)
else else
@ -495,7 +528,16 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos) action = function(pos)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 3)) do if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 3)
if not (objects and type(objects) == 'table') then
return
end
for _,object in ipairs(objects) do
if object:is_player() then if object:is_player() then
diamond_trap(pos, object) diamond_trap(pos, object)
end end
@ -536,6 +578,10 @@ bucket.register_liquid(
) )
local gold_trap = function(pos, player) local gold_trap = function(pos, player)
if not (pos and player) then
return
end
minetest.set_node(pos, {name="fun_caves:molten_gold_source"}) minetest.set_node(pos, {name="fun_caves:molten_gold_source"})
minetest.sound_play("default_dig_crumbly", {pos = pos, gain = 0.5, max_hear_distance = 10}) minetest.sound_play("default_dig_crumbly", {pos = pos, gain = 0.5, max_hear_distance = 10})
end end
@ -548,6 +594,10 @@ minetest.register_node("fun_caves:stone_with_gold_trap", {
is_ground_content = false, is_ground_content = false,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_dig = function(pos, node, digger) on_dig = function(pos, node, digger)
if not (pos and digger) then
return
end
if math.random(3) == 1 then if math.random(3) == 1 then
gold_trap(pos, digger) gold_trap(pos, digger)
else else
@ -561,7 +611,16 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos) action = function(pos)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 2)
if not (objects and type(objects) == 'table') then
return
end
for _,object in ipairs(objects) do
if object:is_player() then if object:is_player() then
gold_trap(pos, object) gold_trap(pos, object)
end end
@ -571,15 +630,24 @@ minetest.register_abm({
local ice_trap = function(pos, player) local ice_trap = function(pos, player)
if not (pos and player) then
return
end
local ppos = player:getpos() local ppos = player:getpos()
if ppos then if ppos then
ppos.y = ppos.y + 1 ppos.y = ppos.y + 1
local p1 = vector.subtract(ppos, 2) local p1 = vector.subtract(ppos, 2)
local p2 = vector.add(ppos, 2) local p2 = vector.add(ppos, 2)
local nodes = minetest.find_nodes_in_area(p1, p2, 'air') local nodes = minetest.find_nodes_in_area(p1, p2, 'air')
if not (nodes and type(nodes) == 'table') then
return
end
for _, npos in pairs(nodes) do for _, npos in pairs(nodes) do
minetest.set_node(npos, {name="default:ice"}) minetest.set_node(npos, {name="default:ice"})
end end
minetest.set_node(pos, {name="default:ice"}) minetest.set_node(pos, {name="default:ice"})
end end
end end
@ -592,6 +660,10 @@ minetest.register_node("fun_caves:ice_trap", {
is_ground_content = false, is_ground_content = false,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_dig = function(pos, node, digger) on_dig = function(pos, node, digger)
if not (pos and digger) then
return
end
if math.random(3) == 1 then if math.random(3) == 1 then
ice_trap(pos, digger) ice_trap(pos, digger)
else else
@ -605,7 +677,16 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos) action = function(pos)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 2)
if not (objects and type(objects) == 'table') then
return
end
for _,object in ipairs(objects) do
if object:is_player() then if object:is_player() then
ice_trap(pos, object) ice_trap(pos, object)
end end
@ -615,6 +696,10 @@ minetest.register_abm({
local function lightning_effects(pos, radius) local function lightning_effects(pos, radius)
if not (pos and radius) then
return
end
minetest.add_particlespawner({ minetest.add_particlespawner({
amount = 30, amount = 30,
time = 1, time = 1,
@ -633,6 +718,10 @@ local function lightning_effects(pos, radius)
end end
local copper_trap = function(pos, player) local copper_trap = function(pos, player)
if not (pos and player) then
return
end
if player:get_hp() > 0 then if player:get_hp() > 0 then
player:set_hp(player:get_hp()-1) player:set_hp(player:get_hp()-1)
lightning_effects(pos, 3) lightning_effects(pos, 3)
@ -648,6 +737,10 @@ minetest.register_node("fun_caves:stone_with_copper_trap", {
is_ground_content = false, is_ground_content = false,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_dig = function(pos, node, digger) on_dig = function(pos, node, digger)
if not (pos and digger) then
return
end
if math.random(3) == 1 then if math.random(3) == 1 then
copper_trap(pos, digger) copper_trap(pos, digger)
else else
@ -662,7 +755,16 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 2, chance = 2,
action = function(pos) action = function(pos)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 3)) do if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 3)
if not (objects and type(objects) == 'table') then
return
end
for _,object in ipairs(objects) do
if object:is_player() then if object:is_player() then
copper_trap(pos, object) copper_trap(pos, object)
end end
@ -681,6 +783,10 @@ minetest.register_node("fun_caves:stone_with_iron_trap", {
is_ground_content = false, is_ground_content = false,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_dig = function(pos, node, digger) on_dig = function(pos, node, digger)
if not (pos and digger) then
return
end
if math.random(3) == 1 then if math.random(3) == 1 then
copper_trap(pos, digger) copper_trap(pos, digger)
else else
@ -694,7 +800,16 @@ minetest.register_abm({
interval = 2, interval = 2,
chance = 2, chance = 2,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do if not pos then
return
end
local objects = minetest.get_objects_inside_radius(pos, 3)
if not (objects and type(objects) == 'table') then
return
end
for _, object in ipairs(objects) do
if object:is_player() then if object:is_player() then
copper_trap(pos, object) copper_trap(pos, object)
end end

View file

@ -8,9 +8,14 @@ local fortress_noise = {offset = 0, scale = 1, seed = -4082, spread = {x = 7, y
-- This tables looks up nodes that aren't already stored. -- This tables looks up nodes that aren't already stored.
local node = setmetatable({}, { local node = setmetatable({}, {
__index = function(t, k) __index = function(t, k)
if not (t and k and type(t) == 'table') then
return
end
t[k] = minetest.get_content_id(k) t[k] = minetest.get_content_id(k)
return t[k] return t[k]
end}) end
})
local data = {} local data = {}
local p2data = {} -- vm rotation data buffer local p2data = {} -- vm rotation data buffer
@ -41,6 +46,10 @@ end
--end --end
fun_caves.is_fortress = function(pos, cs) fun_caves.is_fortress = function(pos, cs)
if not pos then
return
end
-- Fix this to get csize, somehow. -- Fix this to get csize, somehow.
-- Remember that this function may be called -- Remember that this function may be called
-- before any chunks are generated. -- before any chunks are generated.
@ -60,6 +69,10 @@ fun_caves.is_fortress = function(pos, cs)
local z = math.floor((pos.z + offset) / cs.z) local z = math.floor((pos.z + offset) / cs.z)
local n = minetest.get_perlin(fortress_noise):get3d({x=x, y=y, z=z}) local n = minetest.get_perlin(fortress_noise):get3d({x=x, y=y, z=z})
if not (n and type(n) == 'number') then
return
end
if math.floor((n * 10000) % (fun_caves.DEBUG and 4 or 19)) == 1 then if math.floor((n * 10000) % (fun_caves.DEBUG and 4 or 19)) == 1 then
return true return true
end end
@ -68,6 +81,10 @@ fun_caves.is_fortress = function(pos, cs)
end end
fun_caves.place_schematic = function(minp, maxp, data, p2data, area, node, pos, schem, center) fun_caves.place_schematic = function(minp, maxp, data, p2data, area, node, pos, schem, center)
if not (minp and maxp and data and p2data and area and node and pos and schem and type(data) == 'table' and type(p2data) == 'table' and type(schem) == 'table') then
return
end
local rot = math.random(4) - 1 local rot = math.random(4) - 1
local yslice = {} local yslice = {}
if schem.yslice_prob then if schem.yslice_prob then
@ -119,6 +136,10 @@ fun_caves.place_schematic = function(minp, maxp, data, p2data, area, node, pos,
end end
fun_caves.surround = function(node, data, area, ivm) fun_caves.surround = function(node, data, area, ivm)
if not (node and data and area and ivm and type(data) == 'table' and type(ivm) == 'number') then
return
end
-- Check to make sure that a plant root is fully surrounded. -- Check to make sure that a plant root is fully surrounded.
-- This is due to the kludgy way you have to make water plants -- This is due to the kludgy way you have to make water plants
-- in minetest, to avoid bubbles. -- in minetest, to avoid bubbles.
@ -345,8 +366,16 @@ fun_caves.cave_biomes = {
local function generate(p_minp, p_maxp, seed) local function generate(p_minp, p_maxp, seed)
if not (p_minp and p_maxp and seed) then
return
end
local minp, maxp = p_minp, p_maxp local minp, maxp = p_minp, p_maxp
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
if not (vm and emin and emax) then
return
end
vm:get_data(data) vm:get_data(data)
p2data = vm:get_param2_data() p2data = vm:get_param2_data()
local heightmap local heightmap
@ -358,7 +387,14 @@ local function generate(p_minp, p_maxp, seed)
end end
-- use the same seed (based on perlin noise). -- use the same seed (based on perlin noise).
math.randomseed(minetest.get_perlin(seed_noise):get2d({x=minp.x, y=minp.z})) do
local seed = minetest.get_perlin(seed_noise):get2d({x=minp.x, y=minp.z})
if not (seed and type(seed) == 'number') then
return
end
math.randomseed(seed)
end
local write = false local write = false
local write_p2, write_p4 = false, false local write_p2, write_p4 = false, false

116
mobs.lua
View file

@ -1,12 +1,19 @@
-- search/replace -- lets mobs change the terrain -- search/replace -- lets mobs change the terrain
-- used for goblin traps and torch thieving -- used for goblin traps and torch thieving
fun_caves.search_replace = function(pos, search_rate, replace_what, replace_with) fun_caves.search_replace = function(pos, search_rate, replace_what, replace_with)
if not (pos and search_rate and replace_what and replace_with and type(search_rate) == 'number' and type(replace_what) == 'string' and type(replace_with) == 'string') then
return
end
if math.random(search_rate) == 1 then if math.random(search_rate) == 1 then
local p1 = vector.subtract(pos, 1) local p1 = vector.subtract(pos, 1)
local p2 = vector.add(pos, 1) local p2 = vector.add(pos, 1)
--look for nodes --look for nodes
local nodelist = minetest.find_nodes_in_area(p1, p2, replace_what) local nodelist = minetest.find_nodes_in_area(p1, p2, replace_what)
if not (nodelist and type(nodelist) == 'table') then
return
end
if #nodelist > 0 then if #nodelist > 0 then
for _, new_pos in pairs(nodelist) do for _, new_pos in pairs(nodelist) do
@ -18,6 +25,10 @@ fun_caves.search_replace = function(pos, search_rate, replace_what, replace_with
end end
function fun_caves.climb(self) function fun_caves.climb(self)
if not self then
return
end
if self.state == "stand" and math.random() < 0.2 then if self.state == "stand" and math.random() < 0.2 then
if self.fall_speed == 2 then if self.fall_speed == 2 then
self.fall_speed = -2 self.fall_speed = -2
@ -31,44 +42,61 @@ end
-- causes mobs to take damage from hot/cold surfaces -- causes mobs to take damage from hot/cold surfaces
fun_caves.surface_damage = function(self, cold_natured) fun_caves.surface_damage = function(self, cold_natured)
--if not self.fun_caves_damage_timer then if not self then
-- self.fun_caves_damage_timer = 0 return
--end end
--self.fun_caves_damage_timer = self.fun_caves_damage_timer + 1 local pos = self.object:getpos()
--if self.fun_caves_damage_timer > 30 then if not pos then
-- self.fun_caves_damage_timer = 0 return
local pos = self.object:getpos() end
local minp = vector.subtract(pos, 1.5)
local maxp = vector.add(pos, 1.5) local minp = vector.subtract(pos, 1.5)
local counts = 0 local maxp = vector.add(pos, 1.5)
if self.lava_damage > 1 then local counts = 0
counts = minetest.find_nodes_in_area(minp, maxp, {"group:surface_hot"}) if self.lava_damage > 1 then
if #counts > 0 then counts = minetest.find_nodes_in_area(minp, maxp, {"group:surface_hot"})
self.health = self.health - math.floor(self.lava_damage / 2) if not (counts and type(counts) == 'table') then
effect(pos, 5, "fire_basic_flame.png") return
end
end end
if not cold_natured then if #counts > 0 then
counts = minetest.find_nodes_in_area(minp, maxp, {"group:surface_cold"}) self.health = self.health - math.floor(self.lava_damage / 2)
if #counts > 0 then effect(pos, 5, "fire_basic_flame.png")
self.health = self.health - 1 end
end end
if not cold_natured then
counts = minetest.find_nodes_in_area(minp, maxp, {"group:surface_cold"})
if not (counts and type(counts) == 'table') then
return
end end
check_for_death(self) if #counts > 0 then
--end self.health = self.health - 1
end
end
check_for_death(self)
end end
-- executed in a mob's do_custom() to regulate their actions -- executed in a mob's do_custom() to regulate their actions
-- if false, do nothing -- if false, do nothing
local custom_delay = 2000000 local custom_delay = 2000000
fun_caves.custom_ready = function(self, delay) fun_caves.custom_ready = function(self, delay)
if not self then
return
end
local time = minetest.get_us_time() local time = minetest.get_us_time()
if not (time and type(time) == 'number') then
return
end
if not delay then if not delay then
delay = custom_delay delay = custom_delay
end end
if not self.custom_time or time - self.custom_time > delay then if not self.custom_time or time - self.custom_time > delay then
self.custom_time = time self.custom_time = time
return true return true
@ -156,12 +184,17 @@ for _, mob in pairs(mob_stats) do
end end
local function fun_caves_punch(self, puncher, time_from_last_punch, tool_capabilities, dir) local function fun_caves_punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
if not self then
return
end
if puncher and puncher.get_player_name then if puncher and puncher.get_player_name then
local player_name = puncher:get_player_name() local player_name = puncher:get_player_name()
if player_name and player_name ~= '' and fun_caves.db.status[player_name] and fun_caves.db.status[player_name].damage_elixir and tool_capabilities and tool_capabilities.damage_groups and tool_capabilities.damage_groups.fleshy then if player_name and type(player_name) == 'string' and player_name ~= '' and fun_caves.db.status[player_name] and fun_caves.db.status[player_name].damage_elixir and tool_capabilities and tool_capabilities.damage_groups and tool_capabilities.damage_groups.fleshy then
tool_capabilities.damage_groups.fleshy = tool_capabilities.damage_groups.fleshy + fun_caves.db.status[player_name].damage_elixir.bonus tool_capabilities.damage_groups.fleshy = tool_capabilities.damage_groups.fleshy + fun_caves.db.status[player_name].damage_elixir.bonus
end end
end end
self.on_punch_orig(self, puncher, time_from_last_punch, tool_capabilities, dir) self.on_punch_orig(self, puncher, time_from_last_punch, tool_capabilities, dir)
end end
@ -214,6 +247,10 @@ if minetest.registered_entities["dmobs:dragon"] and minetest.registered_entities
local m = table.copy(minetest.registered_entities["mobs_yeti:snowball"]) local m = table.copy(minetest.registered_entities["mobs_yeti:snowball"])
m.hit_player = function(self, player) m.hit_player = function(self, player)
if not (self and player) then
return
end
player:punch(self.object, 1.0, { player:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = 8}, damage_groups = {fleshy = 8},
@ -221,6 +258,10 @@ if minetest.registered_entities["dmobs:dragon"] and minetest.registered_entities
end end
m.hit_mob = function(self, player) m.hit_mob = function(self, player)
if not (self and player) then
return
end
player:punch(self.object, 1.0, { player:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = 8}, damage_groups = {fleshy = 8},
@ -236,7 +277,7 @@ if minetest.registered_entities["dmobs:fox"] then
-- fire_walk overwrites bones, under some circumstances. -- fire_walk overwrites bones, under some circumstances.
-- Keep it disabled until it's definitely working. -- Keep it disabled until it's definitely working.
local function fire_walk(self) local function fire_walk(self)
if not fun_caves.custom_ready(self, 1000000) then if not (self and fun_caves.custom_ready(self, 1000000)) then
return return
end end
@ -246,6 +287,10 @@ if minetest.registered_entities["dmobs:fox"] then
--look for nodes --look for nodes
local nodelist = minetest.find_nodes_in_area(p1, p2, "air") local nodelist = minetest.find_nodes_in_area(p1, p2, "air")
if not (nodelist and type(nodelist) == 'table') then
return
end
for n in pairs(nodelist) do for n in pairs(nodelist) do
--minetest.set_node(pos, {name='fire:basic_flame'}) --minetest.set_node(pos, {name='fire:basic_flame'})
end end
@ -310,7 +355,7 @@ mobs:register_mob("fun_caves:star", {
fall_damage = 0, fall_damage = 0,
lifetimer = 360, lifetimer = 360,
do_custom = function(self) do_custom = function(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -326,7 +371,7 @@ mobs:spawn_specific("fun_caves:star", {'default:stone', 'fun_caves:asteroid_wate
if minetest.registered_entities["mobs:bee"] then if minetest.registered_entities["mobs:bee"] then
local function bee_summon(self) local function bee_summon(self)
if self.state ~= 'attack' then if not (self and self.state == 'attack') then
return return
end end
@ -345,11 +390,14 @@ if minetest.registered_entities["mobs:bee"] then
--look for nodes --look for nodes
local nodelist = minetest.find_nodes_in_area(p1, p2, "air") local nodelist = minetest.find_nodes_in_area(p1, p2, "air")
if not (nodelist and type(nodelist) == 'table') then
return
end
if #nodelist > 0 then if #nodelist > 0 then
for key,value in pairs(nodelist) do for key,value in pairs(nodelist) do
minetest.add_entity(value, "fun_caves:killer_bee_drone") minetest.add_entity(value, "fun_caves:killer_bee_drone")
print("A bee summons reinforcement.") print("Fun Caves: A bee summons reinforcement.")
return -- only one at a time return -- only one at a time
end end
end end
@ -357,7 +405,7 @@ if minetest.registered_entities["mobs:bee"] then
end end
local function bee_do(self) local function bee_do(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -513,7 +561,7 @@ if minetest.registered_entities["mobs_monster:spider"] then
} }
m.water_damage = 0 m.water_damage = 0
m.do_custom = function(self) m.do_custom = function(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -540,7 +588,7 @@ if minetest.registered_entities["mobs_monster:spider"] then
} }
m.water_damage = 0 m.water_damage = 0
m.do_custom = function(self) m.do_custom = function(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -573,7 +621,7 @@ if minetest.registered_entities["mobs_monster:spider"] then
{name = "farming:cotton", chance = 2, min = 1, max = 2}, {name = "farming:cotton", chance = 2, min = 1, max = 2},
} }
m.do_custom = function(self) m.do_custom = function(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -608,6 +656,10 @@ if minetest.registered_entities["mobs_monster:spider"] then
m.jump = false m.jump = false
m.drops = { {name = "mobs:meat_raw", chance = 1, min = 1, max = 1}, } m.drops = { {name = "mobs:meat_raw", chance = 1, min = 1, max = 1}, }
m.do_custom = function(self) m.do_custom = function(self)
if not self then
return
end
if not self.fun_caves_damage_timer then if not self.fun_caves_damage_timer then
self.fun_caves_damage_timer = 0 self.fun_caves_damage_timer = 0
end end

View file

@ -4,6 +4,10 @@ local max_depth = 31000
local old_is_protected = minetest.is_protected local old_is_protected = minetest.is_protected
function minetest.is_protected(pos, name) function minetest.is_protected(pos, name)
if not (pos and name and type(name) == 'string') then
return
end
local node = get_node_or_nil(pos) local node = get_node_or_nil(pos)
if node and get_item_group(node.name, "fortress") ~= 0 then if node and get_item_group(node.name, "fortress") ~= 0 then
return true return true
@ -133,6 +137,10 @@ minetest.register_craft({
}) })
local function rope_remove(pos) local function rope_remove(pos)
if not pos then
return
end
for i = 1, 100 do for i = 1, 100 do
local newpos = table.copy(pos) local newpos = table.copy(pos)
newpos.y = newpos.y - i newpos.y = newpos.y - i
@ -166,19 +174,21 @@ for length = 10, 50, 10 do
legacy_wallmounted = true, legacy_wallmounted = true,
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
after_place_node = function(pos, placer, itemstack, pointed_thing) after_place_node = function(pos, placer, itemstack, pointed_thing)
if pointed_thing and pointed_thing.above then if not (pointed_thing and pointed_thing.above) then
local pos = pointed_thing.above return
local orig = minetest.get_node_or_nil(pos) end
if orig and orig.name and orig.param2 and good_params[orig.param2] then
for i = 1, length do local pos_old = pointed_thing.above
local newpos = table.copy(pos) local orig = minetest.get_node_or_nil(pos_old)
newpos.y = newpos.y - i if orig and orig.name and orig.param2 and good_params[orig.param2] then
local node = minetest.get_node_or_nil(newpos) for i = 1, length do
if node and node.name and node.name == 'air' then local newpos = table.copy(pos_old)
minetest.set_node(newpos, {name='fun_caves:rope_ladder_piece', param2=orig.param2}) newpos.y = newpos.y - i
else local node = minetest.get_node_or_nil(newpos)
break if node and node.name and node.name == 'air' then
end minetest.set_node(newpos, {name='fun_caves:rope_ladder_piece', param2=orig.param2})
else
break
end end
end end
end end

View file

@ -34,7 +34,15 @@ newnode.light_source = 1
newnode.on_construct = nil newnode.on_construct = nil
newnode.drop = 'default:chest' newnode.drop = 'default:chest'
newnode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) newnode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if not (pos and clicker) then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
local ready = meta:get_string('formspec') local ready = meta:get_string('formspec')
if ready == '' then if ready == '' then
@ -65,6 +73,10 @@ local pyramid_noise_1 = {offset = 0, scale = 1, seed = -6012, spread = {x = 20,
fun_caves.pyramid = function(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap) fun_caves.pyramid = function(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
if math.random(20) ~= 1 then if math.random(20) ~= 1 then
return return
end end
@ -104,6 +116,9 @@ fun_caves.pyramid = function(minp, maxp, data, p2data, area, biomemap, biome_ids
local map_min = {x = minp.x, y = minp.y, z = minp.z} local map_min = {x = minp.x, y = minp.y, z = minp.z}
local pyramid_1 = minetest.get_perlin_map(pyramid_noise_1, map_max):get3dMap_flat(map_min) local pyramid_1 = minetest.get_perlin_map(pyramid_noise_1, map_max):get3dMap_flat(map_min)
if not pyramid_1 then
return
end
local write = true local write = true
local p2write = false local p2write = false

View file

@ -17,6 +17,10 @@ local plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z =
local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = -1471, octaves = 3, persist = 0.5, lacunarity = 2.0} local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = 400}, seed = -1471, octaves = 3, persist = 0.5, lacunarity = 2.0}
fun_caves.skysea = function(minp, maxp, data, p2data, area, node) fun_caves.skysea = function(minp, maxp, data, p2data, area, node)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
if minp.y ~= 8768 then if minp.y ~= 8768 then
return return
end end
@ -26,6 +30,9 @@ fun_caves.skysea = function(minp, maxp, data, p2data, area, node)
local terrain_1 = minetest.get_perlin_map(terrain_noise_1, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local terrain_1 = minetest.get_perlin_map(terrain_noise_1, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
local plant_n = minetest.get_perlin_map(plant_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local plant_n = minetest.get_perlin_map(plant_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
local biome_n = minetest.get_perlin_map(biome_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z}) local biome_n = minetest.get_perlin_map(biome_noise, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp.x, y=minp.z})
if not (terrain_1 and plant_n and biome_n) then
return
end
local write = false local write = false

View file

@ -1,9 +1,17 @@
local function disintigrate(pos, radius, node_name, user_name, dropped) local function disintigrate(pos, radius, node_name, user_name, dropped)
if not (pos and radius and node_name and user_name and type(radius) == 'number' and type(user_name) == 'string') then
return
end
local node_id = minetest.get_content_id(node_name) local node_id = minetest.get_content_id(node_name)
local air = minetest.get_content_id('air') local air = minetest.get_content_id('air')
local minp = vector.subtract(pos, radius) local minp = vector.subtract(pos, radius)
local maxp = vector.add(pos, radius) local maxp = vector.add(pos, radius)
local vm = minetest.get_voxel_manip() local vm = minetest.get_voxel_manip()
if not vm then
return
end
local emin, emax = vm:read_from_map(minp, maxp) local emin, emax = vm:read_from_map(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local data = vm:get_data() local data = vm:get_data()
@ -50,6 +58,10 @@ end
local function floor(pos, blocks, node_name, user_name) local function floor(pos, blocks, node_name, user_name)
if not (pos and blocks and node_name and user_name and type(blocks) == 'number' and type(node_name) == 'string' and type(user_name) == 'string') then
return
end
local p = {y = pos.y} local p = {y = pos.y}
local count = 0 local count = 0
for r = 1, blocks do for r = 1, blocks do
@ -90,14 +102,21 @@ for _, node in pairs(nodes) do
newnode.inventory_image = '[inventorycube{tnt_top.png{'..node_texture..'{tnt_side.png' newnode.inventory_image = '[inventorycube{tnt_top.png{'..node_texture..'{tnt_side.png'
newnode.drop = bomb_name newnode.drop = bomb_name
newnode.on_punch = function(pos, node, puncher, pointed_thing) newnode.on_punch = function(pos, node, puncher, pointed_thing)
if puncher:get_wielded_item():get_name() ~= "default:torch" then if not (pos and puncher) then
return return
end end
local wield = puncher:get_wielded_item()
if not wield or wield:get_name() ~= "default:torch" then
return
end
minetest.after(5, function() minetest.after(5, function()
local pos_node = minetest.get_node_or_nil(pos) local pos_node = minetest.get_node_or_nil(pos)
if pos_node.name ~= bomb_name then if not (pos_node and pos_node.name == bomb_name) then
return return
end end
disintigrate(pos, 5, node_name, puncher:get_player_name(), comp) disintigrate(pos, 5, node_name, puncher:get_player_name(), comp)
minetest.remove_node(pos) minetest.remove_node(pos)
end) end)
@ -137,14 +156,21 @@ for _, node in pairs(nodes) do
newnode.inventory_image = '[inventorycube{'..node_texture..'{'..node_texture..'{'..node_texture..'^fun_caves_expand.png' newnode.inventory_image = '[inventorycube{'..node_texture..'{'..node_texture..'{'..node_texture..'^fun_caves_expand.png'
newnode.drop = bomb_name newnode.drop = bomb_name
newnode.on_punch = function(pos, node, puncher, pointed_thing) newnode.on_punch = function(pos, node, puncher, pointed_thing)
if puncher:get_wielded_item():get_name() ~= "default:torch" then if not (pos and puncher) then
return return
end end
local wield = puncher:get_wielded_item()
if not wield or wield:get_name() ~= "default:torch" then
return
end
minetest.after(5, function() minetest.after(5, function()
local pos_node = minetest.get_node_or_nil(pos) local pos_node = minetest.get_node_or_nil(pos)
if pos_node.name ~= bomb_name then if not (pos_node and pos_node.name == bomb_name) then
return return
end end
floor(pos, 100, node_name, puncher:get_player_name()) floor(pos, 100, node_name, puncher:get_player_name())
minetest.set_node(pos, {name = node_name}) minetest.set_node(pos, {name = node_name})
end) end)
@ -217,6 +243,10 @@ local function power(player, pos, tool_type, max)
local air = minetest.get_content_id('air') local air = minetest.get_content_id('air')
local vm = minetest.get_voxel_manip() local vm = minetest.get_voxel_manip()
if not vm then
return
end
local emin, emax = vm:read_from_map(minp, maxp) local emin, emax = vm:read_from_map(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local data = vm:get_data() local data = vm:get_data()
@ -270,7 +300,10 @@ local function power(player, pos, tool_type, max)
local tp = tool:get_tool_capabilities() local tp = tool:get_tool_capabilities()
local def = ItemStack({name=names[id]}):get_definition() local def = ItemStack({name=names[id]}):get_definition()
local dp = minetest.get_dig_params(def.groups, tp) local dp = minetest.get_dig_params(def.groups, tp)
print(dp.wear) if not dp then
return
end
tool:add_wear(dp.wear * number) tool:add_wear(dp.wear * number)
end end
@ -289,11 +322,16 @@ minetest.register_tool("fun_caves:chainsaw", {
damage_groups = {fleshy=4}, damage_groups = {fleshy=4},
}, },
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not (user and pointed_thing) then
return
end
minetest.sound_play('chainsaw', { minetest.sound_play('chainsaw', {
object = user, object = user,
gain = 0.1, gain = 0.1,
max_hear_distance = 30 max_hear_distance = 30
}) })
return power(user, pointed_thing.under, 'axe') return power(user, pointed_thing.under, 'axe')
end, end,
}) })
@ -310,11 +348,16 @@ minetest.register_tool("fun_caves:jackhammer", {
damage_groups = {fleshy=4}, damage_groups = {fleshy=4},
}, },
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not (user and pointed_thing) then
return
end
minetest.sound_play('jackhammer', { minetest.sound_play('jackhammer', {
object = user, object = user,
gain = 0.1, gain = 0.1,
max_hear_distance = 30 max_hear_distance = 30
}) })
return power(user, pointed_thing.under, 'pick') return power(user, pointed_thing.under, 'pick')
end, end,
}) })

View file

@ -1,12 +1,15 @@
local max_depth = 31000 local max_depth = 31000
local function teleporter(user, area, power) local function teleporter(user, area, power)
if not user then if not (user and area and power and type(power) == 'number') then
return return
end end
local name = user:get_player_name() local name = user:get_player_name()
local pos = user:getpos() local pos = user:getpos()
if not (name and pos and name ~= '' and type(name) == 'string') then
return
end
if not fun_caves.db.teleport_data[name] then if not fun_caves.db.teleport_data[name] then
fun_caves.db.teleport_data[name] = {} fun_caves.db.teleport_data[name] = {}
@ -84,10 +87,18 @@ local function teleporter(user, area, power)
c1 = minetest.get_perlin(fun_caves.cave_noise_1):get3d(newpos) c1 = minetest.get_perlin(fun_caves.cave_noise_1):get3d(newpos)
c2 = minetest.get_perlin(fun_caves.cave_noise_2):get3d(newpos) c2 = minetest.get_perlin(fun_caves.cave_noise_2):get3d(newpos)
if not (c1 and c2 and type(c1) == 'number' and type(c2) == 'number') then
return
end
if c1 * c2 > fun_caves.cave_width then if c1 * c2 > fun_caves.cave_width then
newpos.y = newpos.y - 1 newpos.y = newpos.y - 1
c1 = minetest.get_perlin(fun_caves.cave_noise_1):get3d(newpos) c1 = minetest.get_perlin(fun_caves.cave_noise_1):get3d(newpos)
c2 = minetest.get_perlin(fun_caves.cave_noise_2):get3d(newpos) c2 = minetest.get_perlin(fun_caves.cave_noise_2):get3d(newpos)
if not (c1 and c2 and type(c1) == 'number' and type(c2) == 'number') then
return
end
if c1 * c2 > fun_caves.cave_width then if c1 * c2 > fun_caves.cave_width then
good = true good = true
break break
@ -312,7 +323,15 @@ minetest.register_craft({
local function translocate(pos, node, clicker, itemstack, pointed_thing) local function translocate(pos, node, clicker, itemstack, pointed_thing)
if not (pos and clicker) then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
local id = meta:get_string('id') local id = meta:get_string('id')
local owner = meta:get_string('owner') local owner = meta:get_string('owner')
if not (id and tonumber(id)) then if not (id and tonumber(id)) then
@ -348,6 +367,10 @@ local function translocate(pos, node, clicker, itemstack, pointed_thing)
minetest.set_node(pos2, {name = 'fun_caves:translocator'}) minetest.set_node(pos2, {name = 'fun_caves:translocator'})
local meta = minetest.get_meta(pos2) local meta = minetest.get_meta(pos2)
if not meta then
return
end
meta:set_string('id', id) meta:set_string('id', id)
meta:set_string('owner', owner) meta:set_string('owner', owner)
@ -357,19 +380,21 @@ local function translocate(pos, node, clicker, itemstack, pointed_thing)
end end
local function trans_use(itemstack, user, pointed_thing) local function trans_use(itemstack, user, pointed_thing)
if not itemstack then if not (itemstack and user) then
return return
end end
local data = minetest.deserialize(itemstack:get_metadata()) local data = minetest.deserialize(itemstack:get_metadata())
if not (data and data.id) then if not (data and data.id) then
return return
end end
local player_name = user:get_player_name() local player_name = user:get_player_name()
minetest.chat_send_player(player_name, "You see a serial number: "..data.id) minetest.chat_send_player(player_name, "You see a serial number: "..data.id)
end end
local function trans_place(itemstack, placer, pointed_thing) local function trans_place(itemstack, placer, pointed_thing)
if not (itemstack and pointed_thing) then if not (itemstack and placer and pointed_thing) then
return return
end end
@ -395,6 +420,10 @@ local function trans_place(itemstack, placer, pointed_thing)
if place_good then if place_good then
pair[#pair+1] = pos pair[#pair+1] = pos
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
meta:set_string('id', data.id) meta:set_string('id', data.id)
meta:set_string('owner', data.owner) meta:set_string('owner', data.owner)
end end
@ -402,7 +431,7 @@ local function trans_place(itemstack, placer, pointed_thing)
end end
local function trans_dig(pos, node, digger) local function trans_dig(pos, node, digger)
if not (pos and digger) then if not (pos and node and digger) then
return return
end end
@ -412,6 +441,10 @@ local function trans_dig(pos, node, digger)
end end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
local id = meta:get_string('id') local id = meta:get_string('id')
local owner = meta:get_string('owner') local owner = meta:get_string('owner')
if owner == '' then if owner == '' then
@ -452,7 +485,15 @@ local function trans_dig(pos, node, digger)
end end
local function trans_dest(pos) local function trans_dest(pos)
if not pos then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
local id = meta:get_string('id') local id = meta:get_string('id')
local owner = meta:get_string('owner') local owner = meta:get_string('owner')
if not (id and owner) then if not (id and owner) then
@ -470,6 +511,10 @@ local function trans_dest(pos)
end end
minetest.set_node(pos, {name = 'fun_caves:translocator'}) minetest.set_node(pos, {name = 'fun_caves:translocator'})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if not meta then
return
end
meta:set_string('id', id) meta:set_string('id', id)
meta:set_string('owner', owner) meta:set_string('owner', owner)
@ -515,7 +560,7 @@ for _, gem in pairs(gems) do
end end
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() ~= "fun_caves:translocator" then if not (itemstack and player and itemstack:get_name() == "fun_caves:translocator") then
return return
end end

View file

@ -178,28 +178,6 @@ minetest.register_node("fun_caves:syrup", {
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
}) })
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
local name = itemstack:get_name()
if not (name and name == 'fun_caves:syrup') then
return
end
local bucket
local index
for i = 1, player:get_inventory():get_size("craft") do
if (old_craft_grid[i]:get_name()):find('^fun_caves:bucket') then
bucket = old_craft_grid[i]:get_name()
index = i
end
end
if not bucket then
return
end
bucket = bucket:gsub('sap', 'empty')
craft_inv:set_stack("craft", index, bucket)
end)
newnode = fun_caves.clone_node("default:tree") newnode = fun_caves.clone_node("default:tree")
newnode.description = "Glowing Fungal Wood" newnode.description = "Glowing Fungal Wood"
newnode.tiles = {"fun_caves_tree.png^vmg_glowing_fungal.png",} newnode.tiles = {"fun_caves_tree.png^vmg_glowing_fungal.png",}
@ -282,6 +260,32 @@ minetest.register_craft({
}, },
}) })
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if not (itemstack and player and old_craft_grid and craft_inv) then
return
end
local name = itemstack:get_name()
if not (name and name == 'fun_caves:syrup') then
return
end
local bucket
local index
for i = 1, player:get_inventory():get_size("craft") do
if (old_craft_grid[i]:get_name()):find('^fun_caves:bucket') then
bucket = old_craft_grid[i]:get_name()
index = i
end
end
if not bucket then
return
end
bucket = bucket:gsub('sap', 'empty')
craft_inv:set_stack("craft", index, bucket)
end)
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "fun_caves:amber", output = "fun_caves:amber",
@ -305,8 +309,12 @@ local wood_noise = {offset = 0, scale = 1, seed = -4640, spread = {x = 32, y = 3
fun_caves.treegen = function(minp, maxp, data, p2data, area, node) fun_caves.treegen = function(minp, maxp, data, p2data, area, node)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
local tree_n = minetest.get_perlin(tree_noise_1):get2d({x=math.floor((minp.x + 32) / 160) * 80, y=math.floor((minp.z + 32) / 160) * 80}) local tree_n = minetest.get_perlin(tree_noise_1):get2d({x=math.floor((minp.x + 32) / 160) * 80, y=math.floor((minp.z + 32) / 160) * 80})
if minp.y < -112 or minp.y > 208 or (not fun_caves.DEBUG and tree_n < 1) then if not tree_n or minp.y < -112 or minp.y > 208 or (not fun_caves.DEBUG and tree_n < 1) then
return return
end end
@ -315,6 +323,9 @@ fun_caves.treegen = function(minp, maxp, data, p2data, area, node)
local map_min = {x = minp.x, y = minp.y - 1, z = minp.z} local map_min = {x = minp.x, y = minp.y - 1, z = minp.z}
local wood_1 = minetest.get_perlin_map(wood_noise, map_max):get3dMap_flat(map_min) local wood_1 = minetest.get_perlin_map(wood_noise, map_max):get3dMap_flat(map_min)
if not wood_1 then
return
end
local write = false local write = false

View file

@ -29,7 +29,7 @@ if mobs and mobs.mod == "redo" then
end end
end end
local function savage_gathering(self) local function savage_gathering(self)
if not fun_caves.custom_ready(self) then if not (self and fun_caves.custom_ready(self)) then
return return
end end
@ -45,7 +45,10 @@ if mobs and mobs.mod == "redo" then
local p = soil[math.random(#soil)] local p = soil[math.random(#soil)]
p.y = p.y + 1 p.y = p.y + 1
minetest.add_node(p, {name = 'farming:seed_wheat', param2 = 1}) minetest.add_node(p, {name = 'farming:seed_wheat', param2 = 1})
minetest.get_node_timer(p):start(math.random(166, 286)) local timer = minetest.get_node_timer(p)
if timer then
timer:start(math.random(166, 286))
end
end end
end end
@ -115,6 +118,10 @@ end
local function build_hut(data, area, node, pos, turf) local function build_hut(data, area, node, pos, turf)
if not (data and area and node and pos and turf and type(data) == 'table') then
return
end
local door = {x = ({2,7})[math.random(2)], z = ({2,7})[math.random(2)]} local door = {x = ({2,7})[math.random(2)], z = ({2,7})[math.random(2)]}
for z = 1, 8 do for z = 1, 8 do
@ -151,6 +158,10 @@ local function build_hut(data, area, node, pos, turf)
end end
fun_caves.village = function(minp, maxp, data, p2data, area, node, biome, heightmap) fun_caves.village = function(minp, maxp, data, p2data, area, node, biome, heightmap)
if not (minp and maxp and data and p2data and area and node and type(data) == 'table' and type(p2data) == 'table') then
return
end
if not biome or math.random(10) ~= 1 then if not biome or math.random(10) ~= 1 then
return return
end end

View file

@ -23,34 +23,11 @@ local default_material = {
} }
local function parti(pos) local function parti(pos)
minetest.add_particlespawner(25, 0.3,
pos, pos,
{x=2, y=0.2, z=2}, {x=-2, y=2, z=-2},
{x=0, y=-6, z=0}, {x=0, y=-10, z=0},
0.2, 1,
0.2, 2,
true, "wallhammer_parti.png")
end
local function get_pointed_thing(player, range)
local plpos = player:getpos()
plpos.y = plpos.y+1.625
local dir = player:get_look_dir()
local p2 = vector.add(plpos, vector.multiply(dir, range))
local _,pos = minetest.line_of_sight(plpos, p2)
if not pos then if not pos then
return return
end end
local check = minetest.get_node(pos)
if string.find(check.name, '_foot') then minetest.add_particlespawner(25, 0.3, pos, pos, {x=2, y=0.2, z=2}, {x=-2, y=2, z=-2}, {x=0, y=-6, z=0}, {x=0, y=-10, z=0}, 0.2, 1, 0.2, 2, true, "wallhammer_parti.png")
pos = vector.add(pos, dir)
print('added')
end
return {
under = vector.round(pos),
above = vector.round(vector.subtract(pos, dir)),
type = "node"
}
end end
minetest.register_tool( "fun_caves:wall_hammer",{ minetest.register_tool( "fun_caves:wall_hammer",{
@ -66,13 +43,23 @@ minetest.register_tool( "fun_caves:wall_hammer",{
damage_groups = {fleshy=4}, damage_groups = {fleshy=4},
}, },
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not (pointed_thing and user and itemstack) then
return
end
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
return return
end end
local pos = pointed_thing.under local pos = pointed_thing.under
if not pos then
return
end
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if not node then
return
end
for i in ipairs (default_material) do for i in ipairs (default_material) do
local item = default_material [i][1] local item = default_material [i][1]
@ -85,7 +72,11 @@ minetest.register_tool( "fun_caves:wall_hammer",{
end end
if node.name == item then if node.name == item then
minetest.set_node(pos,{name = "fun_caves:"..mat.."_foot", param2=minetest.dir_to_facedir(user:get_look_dir())}) local node = {
name = "fun_caves:"..mat.."_foot",
param2=minetest.dir_to_facedir(user:get_look_dir())
}
minetest.set_node(pos, node)
parti(pos) parti(pos)
end end
end end

View file

@ -1,61 +1,66 @@
local function register_liquid_wood(source, itemname, inventory_image, name, groups) local function register_liquid_wood(source, itemname, inventory_image, name, groups)
if itemname ~= nil then if not (source and itemname and inventory_image and name and type(source) == 'string' and type(itemname) == 'string' and type(inventory_image) == 'string') then
if inventory_image then return
inventory_image = inventory_image..'^fun_caves_wood_bucket_overlay.png'
end
minetest.register_craftitem(itemname, {
description = name,
inventory_image = inventory_image,
stack_max = 1,
liquids_pointable = true,
groups = groups,
on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
local node = minetest.get_node_or_nil(pointed_thing.under)
local ndef = node and minetest.registered_nodes[node.name]
-- Call on_rightclick if the pointed node defines it
if ndef and ndef.on_rightclick and
user and not user:get_player_control().sneak then
return ndef.on_rightclick(
pointed_thing.under,
node, user,
itemstack)
end
local lpos
-- Check if pointing to a buildable node
if ndef and ndef.buildable_to then
-- buildable; replace the node
lpos = pointed_thing.under
else
-- not buildable to; place the liquid above
-- check if the node above can be replaced
lpos = pointed_thing.above
local node = minetest.get_node_or_nil(lpos)
local above_ndef = node and minetest.registered_nodes[node.name]
if not above_ndef or not above_ndef.buildable_to then
-- do not remove the bucket with the liquid
return itemstack
end
end
if minetest.is_protected(lpos, user and user:get_player_name() or "") then
return
end
minetest.set_node(lpos, {name = source})
return ItemStack("fun_caves:bucket_wood_empty")
end
})
end end
inventory_image = inventory_image..'^fun_caves_wood_bucket_overlay.png'
minetest.register_craftitem(itemname, {
description = name,
inventory_image = inventory_image,
stack_max = 1,
liquids_pointable = true,
groups = groups,
on_place = function(itemstack, user, pointed_thing)
if not (user and pointed_thing) then
return
end
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
local node = minetest.get_node_or_nil(pointed_thing.under)
local ndef = node and minetest.registered_nodes[node.name]
-- Call on_rightclick if the pointed node defines it
if ndef and ndef.on_rightclick and
user and not user:get_player_control().sneak then
return ndef.on_rightclick(pointed_thing.under, node, user, itemstack)
end
local lpos
-- Check if pointing to a buildable node
if ndef and ndef.buildable_to then
-- buildable; replace the node
lpos = pointed_thing.under
else
-- not buildable to; place the liquid above
-- check if the node above can be replaced
lpos = pointed_thing.above
local node = minetest.get_node_or_nil(lpos)
if not node then
return
end
local above_ndef = node and minetest.registered_nodes[node.name]
if not above_ndef or not above_ndef.buildable_to then
-- do not remove the bucket with the liquid
return itemstack
end
end
if minetest.is_protected(lpos, user and user:get_player_name() or "") then
return
end
minetest.set_node(lpos, {name = source})
return ItemStack("fun_caves:bucket_wood_empty")
end
})
end end
for fluid, def in pairs(bucket.liquids) do for fluid, def in pairs(bucket.liquids) do
@ -86,11 +91,16 @@ minetest.register_craftitem("fun_caves:bucket_wood_empty", {
liquids_pointable = true, liquids_pointable = true,
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
-- Must be pointing to node -- Must be pointing to node
if pointed_thing.type ~= "node" then if not (user and pointed_thing and pointed_thing.type == "node") then
return return
end end
-- Check if pointing to a liquid source -- Check if pointing to a liquid source
local node = minetest.get_node(pointed_thing.under) local node = minetest.get_node(pointed_thing.under)
if not node then
return
end
local liquiddef = bucket.liquids[node.name] local liquiddef = bucket.liquids[node.name]
if node.name ~= liquiddef.source then if node.name ~= liquiddef.source then
return return