-- SPAWNING --If default, and with biomes, spawn with biomes, otherwise randomly chosen. --Here are the four combos: -- | High Heat | Low Heat | -------------------------------- --High Humidity | Earth | Water | --Low Humidity | Fire | Air | -- -------------------------------- --Returns true on success, false on failure local time_between = adv_core.setting("base_time_between_spawns", 60) * 1000000 local spread = adv_core.setting("spawn_time_spread", 15) * 1000000 local base_dist = adv_core.setting("base_distance", 500) local spawn_adjust = adv_core.setting("spawn_adjustment_time", 180) * 1000000 local dist_adjust = adv_core.setting("distance_adjustment_time", 2) * 1000000 local min_time = adv_core.setting("minimum_spawn_time", 30) * 1000000 local spawn_point = adv_core.setting("spawn_location",{x=0,y=0,z=0}) local biome_spawns = adv_core.setting("enable_spawn_biome", true) local spawn_dist = adv_core.setting("distance_from_player", 12) local default_en = (minetest.get_modpath("default")) ~= nil local air_id = minetest.get_content_id("air") local ignore_id = minetest.get_content_id("ignore") local init_time = (time_between + spawn_adjust) --Used to randomly spawn element near a player local function spawn_element(player, with_biomes) local function biome_spawn(environment, position) if environment.heat > 50 then if environment.humidity > 50 then --Earth adv_core.spawn_element("earth", position) else --Fire adv_core.spawn_element("fire", position) end else if environment.humidity > 50 then --Water adv_core.spawn_element("water", position) else --Air adv_core.spawn_element("air", position) end end end local function random_spawn(position) local rand = math.random(0,3) if rand == 0 then adv_core.spawn_element("fire", position) elseif rand == 1 then adv_core.spawn_element("water", position) elseif rand == 2 then adv_core.spawn_element("earth", position) else adv_core.spawn_element("air", position) end end local position = player:get_pos() position.x = math.floor(position.x + math.random(-spawn_dist,spawn_dist)) position.z = math.floor(position.z + math.random(-spawn_dist,spawn_dist)) position.y = math.floor(position.y + math.random(0 , 10)) if (minetest.get_node(position).name == "air") then --find lowest node that's not air local vm = minetest.get_voxel_manip() local position2 = position position2.y = position2.y - 2 local emin, emax = vm:read_from_map(position, position2) local a = VoxelArea:new{ MinEdge = emin, MaxEdge = emax, } local data = vm:get_data() local stop = position.y-10 for y = position.y, stop, -1 do local idx = a:index(position.x, y, position.z) if data[idx] ~= air_id or data[idx] == ignore_id then position.y = y+3 if with_biomes then biome_spawn(minetest.get_biome_data(position), position) else random_spawn(position) end return true end end --Didn't find the ground, spawn at low position position.y = position.y - 7 if with_biomes then biome_spawn(minetest.get_biome_data(position), position) else random_spawn(position) end return true else return false end end local total_time = 0 minetest.register_globalstep(function(dtime) total_time = total_time + dtime if total_time > 1 then -- every second total_time = 0 local new_time = minetest.get_us_time() for _,player in ipairs(minetest.get_connected_players()) do local name = player:get_player_name() local player_old_time = tonumber(adv_core.mod_storage:get_string(name .. "old_time")) if player_old_time == nil then adv_core.mod_storage:set_string(name .. "old_time", new_time) player_old_time = new_time end local player_countdown = tonumber(adv_core.mod_storage:get_string(name .. "countdown")) or init_time if player_old_time + player_countdown < new_time then local spawned = nil if biome_spawns and default_en then spawned = spawn_element(player, true) else spawned = spawn_element(player, false) end if spawned then local countdown = time_between + math.random(-spread,spread) local dist = vector.distance(player:get_pos(), spawn_point) if dist > base_dist then countdown = countdown - math.floor(base_dist / 1000) * dist_adjust else countdown = countdown + spawn_adjust end adv_core.mod_storage:set_string(name .. "countdown", math.max(min_time, countdown)) --math.max(countdown, min_time) * 1000000) else adv_core.mod_storage:set_string(name .. "countdown", 2000000) -- try again in 2 seconds... end adv_core.mod_storage:set_string(name .. "old_time", new_time) end end end end) minetest.register_on_joinplayer(function(ObjectRef, last_login) local name = ObjectRef:get_player_name() if name == nil then return end adv_core.mod_storage:set_string(name .. "countdown", init_time) adv_core.mod_storage:set_string(name .. "old_time", minetest.get_us_time()) end ) --Do players start with a guidebook and pouch? if adv_core.setting("enable_starting_items", true) then -- for give command local function give(player_name, item) local itemstack = ItemStack(item) if itemstack:is_empty() then return false elseif (not itemstack:is_known()) or (itemstack:get_name() == "unknown") then return false -- "Cannot give an unknown item" -- Forbid giving 'ignore' due to unwanted side effects elseif itemstack:get_name() == "ignore" then return false -- "Giving 'ignore' is not allowed" end local playerref = minetest.get_player_by_name(player_name) --Give to Player local leftover = playerref:get_inventory():add_item("main", itemstack) if not leftover:is_empty() then return false end return true end minetest.register_on_newplayer( function(player) give(player:get_player_name(), "adventure_core:guidebook") give(player:get_player_name(), "adventure_core:pouch") end ) end