Snippets

Leslie Krause Beds Redux Conversion Script

Created by Leslie Krause
--------------------------------------------------------
-- Minetest :: Beds Redux Mod (beds)
--
-- See README.txt for licensing and release notes.
-- Copyright (c) 2020, Leslie E. Krause
--------------------------------------------------------

local path = "."
local name = "beds_spawns"
local player_spawns = { }

-- with lower bed at (-140,4,337) and upper_bed at (-139,4,337)
-- * BlockMen's mod saves spawn at (-139.5,4.0,337.0), so between lower and upper bed
-- * PilzAdam's mod saves spawn at (-139,3,337), so one node below upper bed
-- * sorcerykid's mod saves spawn at (-140,4,337), so exactly at lower bed

local function is_match( text, glob )
     -- use underscore variable to preserve captures
     _ = { string.match( text, glob ) }
     return #_ > 0
end

local function serialize( input )
	local entries = { }
	for k, v in pairs( input ) do
		table.insert( entries, string.format( '["%s"] = {["y"] = %d, ["x"] = %d, ["z"] = %d}', k, v.y, v.x, v.z ) )
	end
	return string.format( "return {%s}", table.concat( entries, ", " ) )
end

local function import_spawns( filepath )
	local file, err = io.open( filepath, "r" )
	if not file then
		error( "Cannot read player spawn data" )
	end

	local data = file:read( "*all" )
	file:close( )

	if string.find( data, "^-?%d" ) then
		-- BlockMen's mod (saved to 'beds_spawns')
		-- -139.5 4.0 337.0 singleplayer\n...
		print( "Converting data from BlockMen's mod..." )
		for v in string.gmatch( string.gsub( data, "\r", "" ), "(.-)\n" ) do
			assert( is_match( v, "^(-?[0-9.]+) (-?[0-9.]+) (-?[0-9.]+) ([A-Za-z0-9_-]+)$" ), "Invalid player spawn." )
			player_spawns[ _[ 4 ] ] = {
				x = math.floor( tonumber( _[ 1 ] ) + 0.5 ),
				y = math.ceil( tonumber( _[ 2 ] ) ),
				z = math.floor( tonumber( _[ 3 ] ) + 0.5 )
			}
		end

	elseif string.find( data, "^return {%[\".-\"%] = {%[" ) then
		-- PilzAdam's mod (saved to 'beds_player_spawns')
		-- return {["singleplayer"] = {["y"] = 3, ["x"] = -139, ["z"] = 337} ...
		print( "Converting data from PilzAdam's mod..." )

		local t = loadstring( data )( )
		for k, v in pairs( t ) do
			assert( type( v ) == "table" and v.x and v.y and v.z, "Invalid player spawn." )
			player_spawns[ k ] = { x = v.x, y = v.y + 1, z = v.z }
		end

	elseif string.find( data, "^return {%[\".-\"%] = \"%(" ) then
		-- sorcerykid's mod (saved to 'beds_spawns.mt')
		-- return {["singleplayer"] = "(-140,4,337)", ...
		print( "Converting data from sorcerykid's mod..." )

		local t = loadstring( data )( )
		for k, v in pairs( t ) do
			assert( is_match( v, "^%((-?[%d.]+),(-?[%d.]+),(-?[%d.]+)%)$" ), "Invalid player spawn." )
			player_spawns[ k ] = { x = tonumber( _[ 1 ] ), y = tonumber( _[ 2 ] ), z = tonumber( _[ 3 ] ) }

		end

	else
		error( "Unknown file format. Conversion failed!" )
	end
end

local function export_spawns( filepath )
	local data = serialize( player_spawns )
	if not data then
		error( "Could not serialize player spawn data." )
	end

	local file = io.open( filepath, "w" )
	if not file then
		error( "Could not save player spawn data." )
	end

	file:write( data )
	file:close( )
end

print( "*********************************************************" )
print( "* This script will convert the data files from existing *" )
print( "* Beds mods into a format suitable for Beds Redux.      *" )
print( "* ----------------------------------------------------- *" )
print( "* Usage Example:                                        *" )
print( "* lua convert.lua ~/.minetest/worlds/world/beds_spawns  *" )
print( "*********************************************************" )

if arg[ 1 ] then
	if is_match( arg[ 1 ], "^(.*)/([^/]+)$" ) then
		path = _[ 1 ]
		name = _[ 2 ]
	elseif is_match( arg[ 1 ], "^([^/]+)$" ) then
		path = "."
		name = _[ 1 ]
	else
		error( "Invalid arguments specified." )
	end
end

print( "The following file will be converted:" )
print( "  " .. path .. "/" .. name )
print( )

print( "The results will be saved to the file 'player_spawns.txt'." )
print( )

io.write( "Do you wish to continue (y/n)? " )
local opt = io.read( 1 )

if opt == "y" then
	import_spawns( path .. "/" .. name )
	export_spawns( path .. "/player_spawns.txt" )

	print( "Conversion completed." )
end

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.