initial pass at naming volcanoes

This commit is contained in:
FaceDeer
2020-01-23 16:43:21 -07:00
parent 4e3bf5b442
commit 4cd2d39393
4 changed files with 202 additions and 3 deletions

164
hud.lua Normal file
View File

@ -0,0 +1,164 @@
local worldpath = minetest.get_worldpath()
local areastore_filename = worldpath.."/volcano_areastore.txt"
local area_file = io.open(areastore_filename, "r")
local areastore = AreaStore()
if area_file then
areastore:from_file(areastore_filename)
end
local function volcano_save()
areastore:to_file(areastore_filename)
end
magma_conduits.name_volcano = function(pos, name, override)
local existing_area = areastore:get_areas_for_pos(pos, true, true)
local id = next(existing_area)
if id and not override then
return
end
local data
if id then
local data = minetest.deserialize(existing_area[id].data)
data.name = name
areastore:remove_area(id)
else
data = {name = name, discovered_by = {}}
end
areastore:insert_area(pos, pos, minetest.serialize(data), id)
volcano_save()
end
if not minetest.settings:get_bool("magma_conduits_show_volcanoes_in_hud", true) then
return
end
local modpath = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(modpath.."/intllib.lua")
local requires_mappingkit = minetest.settings:get_bool("magma_conduits_hud_requires_mapping_kit", true)
and minetest.registered_items["map:mapping_kit"] -- rather than test for the map modpath, test whether the mapping_kit has been registered.
local discovery_range = tonumber(minetest.settings:get("magma_conduits_volcano_discovery_range")) or 60
local visual_range = tonumber(minetest.settings:get("magma_conduits_volcano_visibility_range")) or 1200
local test_interval = 5 -- check every test_interval seconds
local player_huds = {}
-- Each player will have a table of [position_hash] = hud_id pairs in here
local add_hud_marker = function(player, player_name, pos, label)
local waypoints = player_huds[player_name] or {}
player_huds[player_name] = waypoints
local pos_hash = minetest.hash_node_position(pos)
if waypoints[pos_hash] then
return
end
local hud_id = player:hud_add({
hud_elem_type = "waypoint",
name = label,
text = "m",
number = 0xFFFFFF,
world_pos = pos})
waypoints[pos_hash] = hud_id
end
local remove_distant_hud_markers = function()
local players_to_remove = {}
for player_name, waypoints in pairs(player_huds) do
local player = minetest.get_player_by_name(player_name)
if player then
local has_map = (not requires_mappingkit) or (player:get_inventory():contains_item("main", "map:mapping_kit"))
local player_pos = player:get_pos()
local waypoints_to_remove = {}
for pos_hash, hud_id in pairs(waypoints) do
local pos = minetest.get_position_from_hash(pos_hash)
if (not has_map) or vector.distance(pos, player_pos) > visual_range then
table.insert(waypoints_to_remove, pos_hash)
player:hud_remove(hud_id)
end
end
for _, pos_hash in ipairs(waypoints_to_remove) do
waypoints[pos_hash] = nil
end
if not next(waypoints) then -- player's waypoint list is empty, remove it
table.insert(players_to_remove, player_name)
end
else
table.insert(players_to_remove, player_name)
end
end
for _, player_name in ipairs(players_to_remove) do
player_huds[player_name] = nil
end
end
-- For flushing outdated HUD markers when certain admin commands are performed.
local remove_all_hud_markers = function()
for player_name, waypoints in pairs(player_huds) do
local player = minetest.get_player_by_name(player_name)
if player then
for pos_hash, hud_id in pairs(waypoints) do
player:hud_remove(hud_id)
end
end
end
player_huds = {}
end
local elapsed = 0
minetest.register_globalstep(function(dtime)
elapsed = elapsed + dtime
if elapsed < test_interval then
return
end
elapsed = 0
local connected_players = minetest.get_connected_players()
local new_discovery = false
for _, player in ipairs(connected_players) do
local player_pos = player:get_pos()
local player_name = player:get_player_name()
local min_visual_edge = vector.subtract(player_pos, visual_range)
local max_visual_edge = vector.add(player_pos, visual_range)
local visual_volcanos = areastore:get_areas_in_area(min_visual_edge, max_visual_edge, true, true, true)
for id, settlement in pairs(visual_volcanos) do
local data = minetest.deserialize(settlement.data)
local distance = vector.distance(player_pos, settlement.min)
local discovered_by = data.discovered_by
local settlement_pos = vector.add(settlement.min, {x=0, y=2, z=0})
if distance < discovery_range and not discovered_by[player_name] then
-- Update areastore
data.discovered_by[player_name] = true
areastore:remove_area(id)
areastore:insert_area(settlement.min, settlement.min, minetest.serialize(data), id)
-- Mark that we'll need to save volcanoes
new_discovery = true
-- Notify player of their find
local note_name = data.name or "a volcano"
local discovery_note = S("You've discovered @1!", note_name)
local formspec = "size[4,1]" ..
"label[1.0,0.0;" .. minetest.formspec_escape(discovery_note) ..
"]button_exit[0.5,0.75;3,0.5;btn_ok;".. S("OK") .."]"
minetest.show_formspec(player_name, "magma_conduits:discovery_popup",
formspec)
minetest.chat_send_player(player_name, discovery_note)
minetest.log("action", "[magma_conduits] " .. player_name .. " discovered " .. note_name)
--minetest.sound_play({name = "settlements_chime01", gain = 0.25}, {to_player=player_name})
end
local has_map = (not requires_mappingkit) or (player:get_inventory():contains_item("main", "map:mapping_kit"))
if has_map and distance < visual_range and discovered_by[player_name] then
local settlement_name = data.name or "Volcano"
add_hud_marker(player, player_name, settlement_pos, settlement_name)
end
end
end
remove_distant_hud_markers()
if new_discovery then
volcano_save()
end
end)

View File

@ -1 +1,4 @@
name = magma_conduits
name = magma_conduits
description = Removes default mapgen lava and adds widely-spaced volcanoes and lava "veins".
depends = default
optional_depends = namegen, intllib, doc, map

9
volcano_names.cfg Normal file
View File

@ -0,0 +1,9 @@
name "active_volcano" {
syllablesStart = "Fire, Smoulder, Grey, Ash, Pyre, Ember, Forge, Crack, Earth, Stone, Boulder"
syllablesEnd = "forge, mouth, heap, cone, pit, vent"
syllablesPost = "Peak, Crag, Spire"
rules = "Mount_$s$e, $s$e_$80p"
}

View File

@ -7,6 +7,10 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath .. "/volcano_lava.lua") -- https://github.com/minetest/minetest/issues/7864, https://github.com/minetest/minetest/issues/7878
dofile(modpath .. "/hud.lua")
local S, NS = dofile(modpath.."/intllib.lua")
local depth_root = magma_conduits.config.volcano_min_depth
local depth_base = -50 -- point where the mountain root starts expanding
local depth_maxwidth = -30 -- point of maximum width
@ -94,6 +98,12 @@ local get_corner = function(pos)
return {x = math.floor((pos.x+32) / volcano_region_size) * volcano_region_size - 32, z = math.floor((pos.z+32) / volcano_region_size) * volcano_region_size - 32}
end
local namegen_path = minetest.get_modpath("namegen")
if namegen_path then
namegen.parse_lines(io.lines(modpath.."/volcano_names.cfg"))
end
local get_volcano = function(pos)
local corner_xz = get_corner(pos)
local next_seed = math.random(1, 1000000000)
@ -104,20 +114,33 @@ local get_volcano = function(pos)
math.randomseed(next_seed)
return nil
end
local name = S("a volcano")
local location = scatter_2d(corner_xz, volcano_region_size, radius_cone_max)
local depth_peak = math.random(depth_minpeak, depth_maxpeak)
local depth_lava
if state < state_extinct then
depth_lava = - math.random(1, math.abs(depth_root)) -- extinct, put the lava somewhere deep.
if namegen_path then
name = namegen.generate("active_volcano")
end
elseif state < state_dormant then
depth_lava = depth_peak - math.random(5, 50) -- dormant
if namegen_path then
name = namegen.generate("active_volcano")
end
else
depth_lava = depth_peak - math.random(1, 25) -- active, put the lava near the top
if namegen_path then
name = namegen.generate("active_volcano")
end
end
local slope = math.random() * (slope_max - slope_min) + slope_min
local caldera = math.random() * (caldera_max - caldera_min) + caldera_min
magma_conduits.name_volcano({x=location.x, y=depth_peak, z=location.z}, name)
math.randomseed(next_seed)
return {location = location, depth_peak = depth_peak, depth_lava = depth_lava, slope = slope, state = state, caldera = caldera}
end