New MainMenu, update WversionManager, Makefile change

New MainMenu by 4aiman
WVersionManager - 1.3
Makefile - rename output apk
This commit is contained in:
Maksim Gamarnik 2015-05-12 10:59:17 +03:00
parent 14eb9b1bb1
commit 6d3dc6ce06
58 changed files with 7559 additions and 3255 deletions

View File

@ -693,8 +693,8 @@ apk: $(PATHCFGFILE) assets $(IRRLICHT_LIB) $(CURL_LIB) $(LEVELDB_TARGET) \
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" && \ TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" && \
ant $$BUILD_TYPE && \ ant $$BUILD_TYPE && \
echo "++ Success!" && \ echo "++ Success!" && \
echo "APK: bin/Minetest-$$BUILD_TYPE.apk" && \ echo "APK: bin/MultiCraft-$$BUILD_TYPE.apk" && \
echo "You can install it with \`adb install -r bin/Minetest-$$BUILD_TYPE.apk\`" echo "You can install it with \`adb install -r bin/MultiCraft-$$BUILD_TYPE.apk\`"
prep_srcdir : prep_srcdir :
@rm ${ROOT}/jni/src; \ @rm ${ROOT}/jni/src; \
@ -707,11 +707,11 @@ clean_apk : manifest
install_debug : install_debug :
@export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \ @export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \
adb install -r ${ROOT}/bin/Minetest-debug.apk adb install -r ${ROOT}/bin/MultiCraft-debug.apk
install : install :
@export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \ @export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}; \
adb install -r ${ROOT}/bin/Minetest-release.apk adb install -r ${ROOT}/bin/MultiCraft-release.apk
envpaths : envpaths :
@echo "export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}" > and_env;\ @echo "export PATH=$$PATH:${SDKFOLDER}platform-tools:${ANDROID_NDK}" > and_env;\

Binary file not shown.

463
builtin/ProFi.lua Normal file
View File

@ -0,0 +1,463 @@
--[[
ProFi v1.3, by Luke Perkin 2012. MIT Licence http://www.opensource.org/licenses/mit-license.php.
Example:
ProFi = require 'ProFi'
ProFi:start()
some_function()
another_function()
coroutine.resume( some_coroutine )
ProFi:stop()
ProFi:writeReport( 'MyProfilingReport.txt' )
API:
*Arguments are specified as: type/name/default.
ProFi:start( string/once/nil )
ProFi:stop()
ProFi:checkMemory( number/interval/0, string/note/'' )
ProFi:writeReport( string/filename/'ProFi.txt' )
ProFi:reset()
ProFi:setHookCount( number/hookCount/0 )
ProFi:setGetTimeMethod( function/getTimeMethod/os.clock )
ProFi:setInspect( string/methodName, number/levels/1 )
]]
-----------------------
-- Locals:
-----------------------
local ProFi = {}
local onDebugHook, sortByDurationDesc, sortByCallCount, getTime
local DEFAULT_DEBUG_HOOK_COUNT = 0
local FORMAT_HEADER_LINE = "| %-50s: %-40s: %-20s: %-12s: %-12s: %-12s|\n"
local FORMAT_OUTPUT_LINE = "| %s: %-12s: %-12s: %-12s|\n"
local FORMAT_INSPECTION_LINE = "> %s: %-12s\n"
local FORMAT_TOTALTIME_LINE = "| TOTAL TIME = %f\n"
local FORMAT_MEMORY_LINE = "| %-20s: %-16s: %-16s| %s\n"
local FORMAT_HIGH_MEMORY_LINE = "H %-20s: %-16s: %-16sH %s\n"
local FORMAT_LOW_MEMORY_LINE = "L %-20s: %-16s: %-16sL %s\n"
local FORMAT_TITLE = "%-50.50s: %-40.40s: %-20s"
local FORMAT_LINENUM = "%4i"
local FORMAT_TIME = "%04.3f"
local FORMAT_RELATIVE = "%03.2f%%"
local FORMAT_COUNT = "%7i"
local FORMAT_KBYTES = "%7i Kbytes"
local FORMAT_MBYTES = "%7.1f Mbytes"
local FORMAT_MEMORY_HEADER1 = "\n=== HIGH & LOW MEMORY USAGE ===============================\n"
local FORMAT_MEMORY_HEADER2 = "=== MEMORY USAGE ==========================================\n"
local FORMAT_BANNER = [[
###############################################################################################################
##### ProFi, a lua profiler. This profile was generated on: %s
##### ProFi is created by Luke Perkin 2012 under the MIT Licence, www.locofilm.co.uk
##### Version 1.3. Get the most recent version at this gist: https://gist.github.com/2838755
###############################################################################################################
]]
-----------------------
-- Public Methods:
-----------------------
--[[
Starts profiling any method that is called between this and ProFi:stop().
Pass the parameter 'once' to so that this methodis only run once.
Example:
ProFi:start( 'once' )
]]
function ProFi:start( param )
if param == 'once' then
if self:shouldReturn() then
return
else
self.should_run_once = true
end
end
self.has_started = true
self.has_finished = false
self:resetReports( self.reports )
self:startHooks()
self.startTime = getTime()
end
--[[
Stops profiling.
]]
function ProFi:stop()
if self:shouldReturn() then
return
end
self.stopTime = getTime()
self:stopHooks()
self.has_finished = true
end
function ProFi:checkMemory( interval, note )
local time = getTime()
local interval = interval or 0
if self.lastCheckMemoryTime and time < self.lastCheckMemoryTime + interval then
return
end
self.lastCheckMemoryTime = time
local memoryReport = {
['time'] = time;
['memory'] = collectgarbage('count');
['note'] = note or '';
}
table.insert( self.memoryReports, memoryReport )
self:setHighestMemoryReport( memoryReport )
self:setLowestMemoryReport( memoryReport )
end
--[[
Writes the profile report to a file.
Param: [filename:string:optional] defaults to 'ProFi.txt' if not specified.
]]
function ProFi:writeReport( filename )
if #self.reports > 0 or #self.memoryReports > 0 then
filename = filename or 'ProFi.txt'
self:sortReportsWithSortMethod( self.reports, self.sortMethod )
self:writeReportsToFilename( filename )
print( string.format("[ProFi]\t Report written to %s", filename) )
end
end
--[[
Resets any profile information stored.
]]
function ProFi:reset()
self.reports = {}
self.reportsByTitle = {}
self.memoryReports = {}
self.highestMemoryReport = nil
self.lowestMemoryReport = nil
self.has_started = false
self.has_finished = false
self.should_run_once = false
self.lastCheckMemoryTime = nil
self.hookCount = self.hookCount or DEFAULT_DEBUG_HOOK_COUNT
self.sortMethod = self.sortMethod or sortByDurationDesc
self.inspect = nil
end
--[[
Set how often a hook is called.
See http://pgl.yoyo.org/luai/i/debug.sethook for information.
Param: [hookCount:number] if 0 ProFi counts every time a function is called.
if 2 ProFi counts every other 2 function calls.
]]
function ProFi:setHookCount( hookCount )
self.hookCount = hookCount
end
--[[
Set how the report is sorted when written to file.
Param: [sortType:string] either 'duration' or 'count'.
'duration' sorts by the time a method took to run.
'count' sorts by the number of times a method was called.
]]
function ProFi:setSortMethod( sortType )
if sortType == 'duration' then
self.sortMethod = sortByDurationDesc
elseif sortType == 'count' then
self.sortMethod = sortByCallCount
end
end
--[[
By default the getTime method is os.clock (CPU time),
If you wish to use other time methods pass it to this function.
Param: [getTimeMethod:function]
]]
function ProFi:setGetTimeMethod( getTimeMethod )
getTime = getTimeMethod
end
--[[
Allows you to inspect a specific method.
Will write to the report a list of methods that
call this method you're inspecting, you can optionally
provide a levels parameter to traceback a number of levels.
Params: [methodName:string] the name of the method you wish to inspect.
[levels:number:optional] the amount of levels you wish to traceback, defaults to 1.
]]
function ProFi:setInspect( methodName, levels )
if self.inspect then
self.inspect.methodName = methodName
self.inspect.levels = levels or 1
else
self.inspect = {
['methodName'] = methodName;
['levels'] = levels or 1;
}
end
end
-----------------------
-- Implementations methods:
-----------------------
function ProFi:shouldReturn( )
return self.should_run_once and self.has_finished
end
function ProFi:getFuncReport( funcInfo )
local title = self:getTitleFromFuncInfo( funcInfo )
local funcReport = self.reportsByTitle[ title ]
if not funcReport then
funcReport = self:createFuncReport( funcInfo )
self.reportsByTitle[ title ] = funcReport
table.insert( self.reports, funcReport )
end
return funcReport
end
function ProFi:getTitleFromFuncInfo( funcInfo )
local name = funcInfo.name or 'anonymous'
-- TODO (freeminer): remove common path, i.e. /home/xyz/freeminer/games/default/, from the source
local source = funcInfo.source:sub(-50) or 'C_FUNC'
local linedefined = funcInfo.linedefined or 0
linedefined = string.format( FORMAT_LINENUM, linedefined )
return string.format(FORMAT_TITLE, source, name, linedefined)
end
function ProFi:createFuncReport( funcInfo )
local name = funcInfo.name or 'anonymous'
local source = funcInfo.source or 'C Func'
local linedefined = funcInfo.linedefined or 0
local funcReport = {
['title'] = self:getTitleFromFuncInfo( funcInfo );
['count'] = 0;
['timer'] = 0;
}
return funcReport
end
function ProFi:startHooks()
debug.sethook( onDebugHook, 'cr', self.hookCount )
end
function ProFi:stopHooks()
debug.sethook()
end
function ProFi:sortReportsWithSortMethod( reports, sortMethod )
if reports then
table.sort( reports, sortMethod )
end
end
function ProFi:writeReportsToFilename( filename )
local file, err = io.open( filename, 'w' )
assert( file, err )
self:writeBannerToFile( file )
if #self.reports > 0 then
self:writeProfilingReportsToFile( self.reports, file )
end
if #self.memoryReports > 0 then
self:writeMemoryReportsToFile( self.memoryReports, file )
end
file:close()
end
function ProFi:writeProfilingReportsToFile( reports, file )
local totalTime = self.stopTime - self.startTime
local totalTimeOutput = string.format(FORMAT_TOTALTIME_LINE, totalTime)
file:write( totalTimeOutput )
local header = string.format( FORMAT_HEADER_LINE, "FILE", "FUNCTION", "LINE", "TIME", "RELATIVE", "CALLED" )
file:write( header )
for i, funcReport in ipairs( reports ) do
local timer = string.format(FORMAT_TIME, funcReport.timer)
local count = string.format(FORMAT_COUNT, funcReport.count)
local relTime = string.format(FORMAT_RELATIVE, (funcReport.timer / totalTime) * 100 )
local outputLine = string.format(FORMAT_OUTPUT_LINE, funcReport.title, timer, relTime, count )
file:write( outputLine )
if funcReport.inspections then
self:writeInpsectionsToFile( funcReport.inspections, file )
end
end
end
function ProFi:writeMemoryReportsToFile( reports, file )
file:write( FORMAT_MEMORY_HEADER1 )
self:writeHighestMemoryReportToFile( file )
self:writeLowestMemoryReportToFile( file )
file:write( FORMAT_MEMORY_HEADER2 )
for i, memoryReport in ipairs( reports ) do
local outputLine = self:formatMemoryReportWithFormatter( memoryReport, FORMAT_MEMORY_LINE )
file:write( outputLine )
end
end
function ProFi:writeHighestMemoryReportToFile( file )
local memoryReport = self.highestMemoryReport
local outputLine = self:formatMemoryReportWithFormatter( memoryReport, FORMAT_HIGH_MEMORY_LINE )
file:write( outputLine )
end
function ProFi:writeLowestMemoryReportToFile( file )
local memoryReport = self.lowestMemoryReport
local outputLine = self:formatMemoryReportWithFormatter( memoryReport, FORMAT_LOW_MEMORY_LINE )
file:write( outputLine )
end
function ProFi:formatMemoryReportWithFormatter( memoryReport, formatter )
local time = string.format(FORMAT_TIME, memoryReport.time)
local kbytes = string.format(FORMAT_KBYTES, memoryReport.memory)
local mbytes = string.format(FORMAT_MBYTES, memoryReport.memory/1024)
local outputLine = string.format(formatter, time, kbytes, mbytes, memoryReport.note)
return outputLine
end
function ProFi:writeBannerToFile( file )
local banner = string.format(FORMAT_BANNER, os.date())
file:write( banner )
end
function ProFi:writeInpsectionsToFile( inspections, file )
local inspectionsList = self:sortInspectionsIntoList( inspections )
file:write('\n==^ INSPECT ^======================================================================================================== COUNT ===\n')
for i, inspection in ipairs( inspectionsList ) do
local line = string.format(FORMAT_LINENUM, inspection.line)
local title = string.format(FORMAT_TITLE, inspection.source, inspection.name, line)
local count = string.format(FORMAT_COUNT, inspection.count)
local outputLine = string.format(FORMAT_INSPECTION_LINE, title, count )
file:write( outputLine )
end
file:write('===============================================================================================================================\n\n')
end
function ProFi:sortInspectionsIntoList( inspections )
local inspectionsList = {}
for k, inspection in pairs(inspections) do
inspectionsList[#inspectionsList+1] = inspection
end
table.sort( inspectionsList, sortByCallCount )
return inspectionsList
end
function ProFi:resetReports( reports )
for i, report in ipairs( reports ) do
report.timer = 0
report.count = 0
report.inspections = nil
end
end
function ProFi:shouldInspect( funcInfo )
return self.inspect and self.inspect.methodName == funcInfo.name
end
function ProFi:getInspectionsFromReport( funcReport )
local inspections = funcReport.inspections
if not inspections then
inspections = {}
funcReport.inspections = inspections
end
return inspections
end
function ProFi:getInspectionWithKeyFromInspections( key, inspections )
local inspection = inspections[key]
if not inspection then
inspection = {
['count'] = 0;
}
inspections[key] = inspection
end
return inspection
end
function ProFi:doInspection( inspect, funcReport )
local inspections = self:getInspectionsFromReport( funcReport )
local levels = 5 + inspect.levels
local currentLevel = 5
while currentLevel < levels do
local funcInfo = debug.getinfo( currentLevel, 'nS' )
if funcInfo then
local source = funcInfo.short_src or '[C]'
local name = funcInfo.name or 'anonymous'
local line = funcInfo.linedefined
local key = source..name..line
local inspection = self:getInspectionWithKeyFromInspections( key, inspections )
inspection.source = source
inspection.name = name
inspection.line = line
inspection.count = inspection.count + 1
currentLevel = currentLevel + 1
else
break
end
end
end
function ProFi:onFunctionCall( funcInfo )
local funcReport = ProFi:getFuncReport( funcInfo )
funcReport.callTime = getTime()
funcReport.count = funcReport.count + 1
if self:shouldInspect( funcInfo ) then
self:doInspection( self.inspect, funcReport )
end
end
function ProFi:onFunctionReturn( funcInfo )
local funcReport = ProFi:getFuncReport( funcInfo )
if funcReport.callTime then
local time = getTime() - funcReport.callTime
-- handle overflow for unsigned 32-bit time
-- if for some reason `unsigned int` is 64-bit then overflows don't happen!
if time < 0 then
time = 4294967296 / 1000000 + time
end
funcReport.timer = funcReport.timer + time
end
end
function ProFi:setHighestMemoryReport( memoryReport )
if not self.highestMemoryReport then
self.highestMemoryReport = memoryReport
else
if memoryReport.memory > self.highestMemoryReport.memory then
self.highestMemoryReport = memoryReport
end
end
end
function ProFi:setLowestMemoryReport( memoryReport )
if not self.lowestMemoryReport then
self.lowestMemoryReport = memoryReport
else
if memoryReport.memory < self.lowestMemoryReport.memory then
self.lowestMemoryReport = memoryReport
end
end
end
-----------------------
-- Local Functions:
-----------------------
getTime = os.clock
onDebugHook = function( hookType )
local funcInfo = debug.getinfo( 2, 'nS' )
if hookType == "call" then
ProFi:onFunctionCall( funcInfo )
elseif hookType == "return" then
ProFi:onFunctionReturn( funcInfo )
end
end
sortByDurationDesc = function( a, b )
return a.timer > b.timer
end
sortByCallCount = function( a, b )
return a.count > b.count
end
-----------------------
-- Return Module:
-----------------------
ProFi:reset()
return ProFi

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/misc_helpers.lua -- Minetest: builtin/misc_helpers.lua
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function basic_dump(o) function basic_dump(o)
@ -441,6 +441,114 @@ if INIT == "game" then
end end
--------------------------------------------------------------------------------
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation.
--------------------------------------------------------------------------------
minetest.rotate_node = function(itemstack, placer, pointed_thing)
minetest.rotate_and_place(itemstack, placer, pointed_thing,
minetest.setting_getbool("creative_mode"),
{invert_wall = placer:get_player_control().sneak})
return itemstack
end
--------------------------------------------------------------------------------
-- Function to make a copy of an existing node definition, to be used
-- by mods that need to redefine some aspect of a node, but without
-- them having to copy&paste the entire node definition.
--------------------------------------------------------------------------------
function minetest.clone_node(name)
node2={}
node=minetest.registered_nodes[name]
for k,v in pairs(node) do
node2[k]=v
end
return node2
end
end
--------------------------------------------------------------------------------
if minetest then
local dirs1 = { 9, 18, 7, 12 }
local dirs2 = { 20, 23, 22, 21 }
function minetest.rotate_and_place(itemstack, placer, pointed_thing, infinitestacks, orient_flags)
orient_flags = orient_flags or {}
local node = minetest.get_node(pointed_thing.under)
if not minetest.registered_nodes[node.name]
or not minetest.registered_nodes[node.name].on_rightclick then
local above = pointed_thing.above
local under = pointed_thing.under
local pitch = placer:get_look_pitch()
local pname = minetest.get_node(under).name
local node = minetest.get_node(above)
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local wield_name = itemstack:get_name()
local reg_node = minetest.registered_nodes[pname]
if not reg_node or not reg_node.on_rightclick then
local iswall = (above.x ~= under.x) or (above.z ~= under.z)
local isceiling = (above.x == under.x) and (above.z == under.z)
and (pitch > 0)
local pos1 = above
if reg_node and reg_node.buildable_to then
pos1 = under
iswall = false
end
reg_node = minetest.registered_nodes[minetest.get_node(pos1).name]
if not reg_node or not reg_node.buildable_to then
return
end
if orient_flags.force_floor then
iswall = false
isceiling = false
elseif orient_flags.force_ceiling then
iswall = false
isceiling = true
elseif orient_flags.force_wall then
iswall = true
isceiling = false
elseif orient_flags.invert_wall then
iswall = not iswall
end
if iswall then
minetest.add_node(pos1, {name = wield_name, param2 = dirs1[fdir+1] })
elseif isceiling then
if orient_flags.force_facedir then
minetest.add_node(pos1, {name = wield_name, param2 = 20 })
else
minetest.add_node(pos1, {name = wield_name, param2 = dirs2[fdir+1] })
end
else -- place right side up
if orient_flags.force_facedir then
minetest.add_node(pos1, {name = wield_name, param2 = 0 })
else
minetest.add_node(pos1, {name = wield_name, param2 = fdir })
end
end
if not infinitestacks then
itemstack:take_item()
return itemstack
end
end
else
minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack)
end
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode --Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation. --implies infinite stacks when performing a 6d rotation.
@ -593,4 +701,3 @@ if INIT == "mainmenu" then
return core.formspec_escape(fgettext_ne(text, ...)) return core.formspec_escape(fgettext_ne(text, ...))
end end
end end

View File

@ -115,20 +115,11 @@ function core.serialize(x)
function dump_val(x) function dump_val(x)
local tp = type(x) local tp = type(x)
if x == nil then return "nil" if x == nil then return "nil"
elseif tp == "number" then return string.format("%d", x)
elseif tp == "string" then return string.format("%q", x) elseif tp == "string" then return string.format("%q", x)
elseif tp == "boolean" then return x and "true" or "false" elseif tp == "boolean" then return x and "true" or "false"
elseif tp == "function" then elseif tp == "function" then
return string.format("loadstring(%q)", string.dump(x)) return string.format("loadstring(%q)", string.dump(x))
elseif tp == "number" then
-- Serialize integers with string.format to prevent
-- scientific notation, which doesn't preserve
-- precision and breaks things like node position
-- hashes. Serialize floats normally.
if math.floor(x) == x then
return string.format("%d", x)
else
return tostring(x)
end
elseif tp == "table" then elseif tp == "table" then
local vals = {} local vals = {}
local idx_dumped = {} local idx_dumped = {}

View File

@ -4,11 +4,6 @@
local WARN_INIT = false local WARN_INIT = false
function core.global_exists(name)
return rawget(_G, name) ~= nil
end
local function warn(message) local function warn(message)
print(os.date("%H:%M:%S: WARNING: ")..message) print(os.date("%H:%M:%S: WARNING: ")..message)
end end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--self program is free software; you can redistribute it and/or modify --self program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--self program is free software; you can redistribute it and/or modify --self program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--self program is free software; you can redistribute it and/or modify --self program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--self program is free software; you can redistribute it and/or modify --self program is free software; you can redistribute it and/or modify
@ -109,7 +109,7 @@ function ui.handle_buttons(fields)
if fields["btn_error_confirm"] then if fields["btn_error_confirm"] then
gamedata.errormessage = nil gamedata.errormessage = nil
update_menu() menu.update()
return return
end end

View File

@ -1,11 +1,11 @@
-- multicraft: builtin/auth.lua -- Minetest: builtin/auth.lua
-- --
-- Authentication handler -- Authentication handler
-- --
function core.string_to_privs(str, delim) function core.string_to_privs(str, delim)
assert(type(str) == "string") if type(str) ~= "string" then return end
delim = delim or ',' delim = delim or ','
local privs = {} local privs = {}
for _, priv in pairs(string.split(str, delim)) do for _, priv in pairs(string.split(str, delim)) do
@ -32,6 +32,23 @@ assert(core.privs_to_string({a=true,b=true}) == "a,b")
core.auth_file_path = core.get_worldpath().."/auth.txt" core.auth_file_path = core.get_worldpath().."/auth.txt"
core.auth_table = {} core.auth_table = {}
local hex={}
for i=0,255 do
hex[string.format("%0x",i)]=string.char(i)
hex[string.format("%0X",i)]=string.char(i)
end
local function uri_decode(str)
str = string.gsub (str, "+", " ")
return (str:gsub('%%(%x%x)',hex))
end
function uri_encode (str)
str = string.gsub (str, "([^0-9a-zA-Z_ -])", function (c) return string.format ("%%%02X", string.byte(c)) end)
str = string.gsub (str, " ", "+")
return str
end
local function read_auth_file() local function read_auth_file()
local newtable = {} local newtable = {}
local file, errmsg = io.open(core.auth_file_path, 'rb') local file, errmsg = io.open(core.auth_file_path, 'rb')
@ -48,7 +65,7 @@ local function read_auth_file()
error("Invalid line in auth.txt: "..dump(line)) error("Invalid line in auth.txt: "..dump(line))
end end
local privileges = core.string_to_privs(privilege_string) local privileges = core.string_to_privs(privilege_string)
newtable[name] = {password=password, privileges=privileges, last_login=last_login} newtable[uri_decode(name)] = {password=password, privileges=privileges, last_login=last_login}
end end
end end
io.close(file) io.close(file)
@ -73,7 +90,7 @@ local function save_auth_file()
end end
for name, stuff in pairs(core.auth_table) do for name, stuff in pairs(core.auth_table) do
local priv_string = core.privs_to_string(stuff.privileges) local priv_string = core.privs_to_string(stuff.privileges)
local parts = {name, stuff.password, priv_string, stuff.last_login or ""} local parts = {uri_encode(name), stuff.password, priv_string, stuff.last_login or ""}
file:write(table.concat(parts, ":").."\n") file:write(table.concat(parts, ":").."\n")
end end
io.close(file) io.close(file)
@ -123,9 +140,13 @@ core.builtin_auth_handler = {
assert(type(name) == "string") assert(type(name) == "string")
assert(type(password) == "string") assert(type(password) == "string")
core.log('info', "Built-in authentication handler adding player '"..name.."'") core.log('info', "Built-in authentication handler adding player '"..name.."'")
local privs = core.setting_get("default_privs")
if core.setting_getbool("creative_mode") and core.setting_get("default_privs_creative") then
privs = core.setting_get("default_privs_creative")
end
core.auth_table[name] = { core.auth_table[name] = {
password = password, password = password,
privileges = core.string_to_privs(core.setting_get("default_privs")), privileges = core.string_to_privs(privs),
last_login = os.time(), last_login = os.time(),
} }
save_auth_file() save_auth_file()

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/chatcommands.lua -- Minetest: builtin/chatcommands.lua
-- --
-- Chat command handler -- Chat command handler
@ -67,9 +67,10 @@ core.register_chatcommand("help", {
description = "Get help for commands or list privileges", description = "Get help for commands or list privileges",
func = function(name, param) func = function(name, param)
local function format_help_line(cmd, def) local function format_help_line(cmd, def)
local msg = freeminer.colorize("00ffff", "/"..cmd)
local msg = "/"..cmd local msg = "/"..cmd
if def.params and def.params ~= "" then if def.params and def.params ~= "" then
msg = msg .. " " .. def.params msg = msg .. " " .. freeminer.colorize("eeeeee", def.params)
end end
if def.description and def.description ~= "" then if def.description and def.description ~= "" then
msg = msg .. ": " .. def.description msg = msg .. ": " .. def.description
@ -229,28 +230,21 @@ core.register_chatcommand("setpassword", {
if not toname then if not toname then
return false, "Name field required" return false, "Name field required"
end end
local act_str_past = "?" local actstr = "?"
local act_str_pres = "?"
if not raw_password then if not raw_password then
core.set_player_password(toname, "") core.set_player_password(toname, "")
act_str_past = "cleared" actstr = "cleared"
act_str_pres = "clears"
else else
core.set_player_password(toname, core.set_player_password(toname,
core.get_password_hash(toname, core.get_password_hash(toname,
raw_password)) raw_password))
act_str_past = "set" actstr = "set"
act_str_pres = "sets"
end end
if toname ~= name then if toname ~= name then
core.chat_send_player(toname, "Your password was " core.chat_send_player(toname, "Your password was "
.. act_str_past .. " by " .. name) .. actstr .. " by " .. name)
end end
return true, "Password of player \"" .. toname .. "\" " .. actstr
core.log("action", name .. " " .. act_str_pres
.. " password of " .. toname .. ".")
return true, "Password of player \"" .. toname .. "\" " .. act_str_past
end, end,
}) })
@ -264,9 +258,6 @@ core.register_chatcommand("clearpassword", {
return false, "Name field required" return false, "Name field required"
end end
core.set_player_password(toname, '') core.set_player_password(toname, '')
core.log("action", name .. " clears password of " .. toname .. ".")
return true, "Password of player \"" .. toname .. "\" cleared" return true, "Password of player \"" .. toname .. "\" cleared"
end, end,
}) })
@ -414,14 +405,13 @@ core.register_chatcommand("set", {
}) })
core.register_chatcommand("deleteblocks", { core.register_chatcommand("deleteblocks", {
params = "(here [radius]) | (<pos1> <pos2>)", params = "[here] [<pos1> <pos2>]",
description = "delete map blocks contained in area pos1 to pos2", description = "delete map blocks contained in area pos1 to pos2",
privs = {server=true}, privs = {server=true},
func = function(name, param) func = function(name, param)
local p1 = {} local p1 = {}
local p2 = {} local p2 = {}
local args = param:split(" ") if param == "here" then
if args[1] == "here" then
local player = core.get_player_by_name(name) local player = core.get_player_by_name(name)
if player == nil then if player == nil then
core.log("error", "player is nil") core.log("error", "player is nil")
@ -429,12 +419,6 @@ core.register_chatcommand("deleteblocks", {
end end
p1 = player:getpos() p1 = player:getpos()
p2 = p1 p2 = p1
if #args >= 2 then
local radius = tonumber(args[2]) or 0
p1 = vector.add(p1, radius)
p2 = vector.subtract(p2, radius)
end
else else
local pos1, pos2 = unpack(param:split(") (")) local pos1, pos2 = unpack(param:split(") ("))
if pos1 == nil or pos2 == nil then if pos1 == nil or pos2 == nil then
@ -525,6 +509,7 @@ core.register_chatcommand("giveme", {
if not itemstring then if not itemstring then
return false, "ItemString required" return false, "ItemString required"
end end
core.stat_add("giveme", name)
return handle_give_command("/giveme", name, name, itemstring) return handle_give_command("/giveme", name, name, itemstring)
end, end,
}) })
@ -749,11 +734,7 @@ core.register_chatcommand("kick", {
if not core.kick_player(tokick, reason) then if not core.kick_player(tokick, reason) then
return false, "Failed to kick player " .. tokick return false, "Failed to kick player " .. tokick
end end
local log_reason = "" core.log("action", name .. " kicked " .. tokick)
if reason then
log_reason = " with reason \"" .. reason .. "\""
end
core.log("action", name .. " kicks " .. tokick .. log_reason)
return true, "Kicked " .. tokick return true, "Kicked " .. tokick
end, end,
}) })
@ -793,6 +774,19 @@ core.register_chatcommand("msg", {
end, end,
}) })
core.register_chatcommand("die", {
params = "",
description = "Kills yourself.",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return
end
player:set_hp(0)
core.stat_add("suicide", name)
end,
})
core.register_chatcommand("last-login", { core.register_chatcommand("last-login", {
params = "[name]", params = "[name]",
description = "Get the last login time of a player", description = "Get the last login time of a player",
@ -810,3 +804,16 @@ core.register_chatcommand("last-login", {
end, end,
}) })
core.register_chatcommand( "stat", {
params = "[name]",
description = "show in-game action statistics",
func = function(name, param)
if param == "" then
param = name
elseif not core.get_player_by_name(param) then
return false, "No such player."
end
local formspec = core.stat_formspec(param)
core.show_formspec(name, 'stat', formspec)
end
})

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/deprecated.lua -- Minetest: builtin/deprecated.lua
-- --
-- Default material types -- Default material types

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/detached_inventory.lua -- Minetest: builtin/detached_inventory.lua
core.detached_inventories = {} core.detached_inventories = {}

View File

@ -1,9 +1,34 @@
-- multicraft: builtin/item.lua -- Minetest: builtin/item.lua
-- --
-- Falling stuff -- Falling stuff
-- --
function node_drop(np, remove_fast)
local n2 = minetest.get_node(np)
-- If it's not air or liquid, remove node and replace it with
-- it's drops
if n2.name ~= "air" and (not core.registered_nodes[n2.name] or
core.registered_nodes[n2.name].liquidtype == "none") then
core.remove_node(np, remove_fast)
if core.registered_nodes[n2.name].buildable_to == false then
-- Add dropped items
local drops = core.get_node_drops(n2.name, "")
local _, dropped_item
for _, dropped_item in ipairs(drops) do
core.add_item(np, dropped_item)
end
end
-- Run script hook
local _, callback
for _, callback in ipairs(core.registered_on_dignodes) do
callback(np, n2, nil)
end
end
end
local remove_fast = 0
core.register_entity(":__builtin:falling_node", { core.register_entity(":__builtin:falling_node", {
initial_properties = { initial_properties = {
physical = true, physical = true,
@ -47,6 +72,7 @@ core.register_entity(":__builtin:falling_node", {
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
if dtime > 0.2 then remove_fast = 2 else remove_fast = 0 end
-- Set gravity -- Set gravity
self.object:setacceleration({x=0, y=-10, z=0}) self.object:setacceleration({x=0, y=-10, z=0})
-- Turn to actual sand when collides to ground or just move -- Turn to actual sand when collides to ground or just move
@ -59,7 +85,7 @@ core.register_entity(":__builtin:falling_node", {
(bcd.walkable or (bcd.walkable or
(core.get_item_group(self.node.name, "float") ~= 0 and (core.get_item_group(self.node.name, "float") ~= 0 and
bcd.liquidtype ~= "none")) then bcd.liquidtype ~= "none")) then
if bcd and bcd.leveled and if bcd and bcd.leveled and bcd.leveled > 0 and
bcn.name == self.node.name then bcn.name == self.node.name then
local addlevel = self.node.level local addlevel = self.node.level
if addlevel == nil or addlevel <= 0 then if addlevel == nil or addlevel <= 0 then
@ -72,31 +98,14 @@ core.register_entity(":__builtin:falling_node", {
elseif bcd and bcd.buildable_to and elseif bcd and bcd.buildable_to and
(core.get_item_group(self.node.name, "float") == 0 or (core.get_item_group(self.node.name, "float") == 0 or
bcd.liquidtype == "none") then bcd.liquidtype == "none") then
core.remove_node(bcp) core.remove_node(bcp, remove_fast)
return return
end end
local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
-- Check what's here -- Check what's here
local n2 = core.get_node(np) local n2 = core.get_node(np)
-- If it's not air or liquid, remove node and replace it with -- remove node and replace it with it's drops
-- it's drops node_drop(np, remove_fast)
if n2.name ~= "air" and (not core.registered_nodes[n2.name] or
core.registered_nodes[n2.name].liquidtype == "none") then
core.remove_node(np)
if core.registered_nodes[n2.name].buildable_to == false then
-- Add dropped items
local drops = core.get_node_drops(n2.name, "")
local _, dropped_item
for _, dropped_item in ipairs(drops) do
core.add_item(np, dropped_item)
end
end
-- Run script hook
local _, callback
for _, callback in ipairs(core.registered_on_dignodes) do
callback(np, n2, nil)
end
end
-- Create node and remove entity -- Create node and remove entity
core.add_node(np, self.node) core.add_node(np, self.node)
self.object:remove() self.object:remove()
@ -113,12 +122,13 @@ core.register_entity(":__builtin:falling_node", {
function spawn_falling_node(p, node) function spawn_falling_node(p, node)
local obj = core.add_entity(p, "__builtin:falling_node") local obj = core.add_entity(p, "__builtin:falling_node")
if not obj then return end
obj:get_luaentity():set_node(node) obj:get_luaentity():set_node(node)
end end
function drop_attached_node(p) function drop_attached_node(p)
local nn = core.get_node(p).name local nn = core.get_node(p).name
core.remove_node(p) core.remove_node(p, remove_fast)
for _,item in ipairs(core.get_node_drops(nn, "")) do for _,item in ipairs(core.get_node_drops(nn, "")) do
local pos = { local pos = {
x = p.x + math.random()/2 - 0.25, x = p.x + math.random()/2 - 0.25,
@ -179,7 +189,7 @@ function nodeupdate_single(p, delay)
core.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false) core.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false)
else else
n.level = core.get_node_level(p) n.level = core.get_node_level(p)
core.remove_node(p) core.remove_node(p, remove_fast)
spawn_falling_node(p, n) spawn_falling_node(p, n)
nodeupdate(p) nodeupdate(p)
end end

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/features.lua -- Minetest: builtin/features.lua
core.features = { core.features = {
glasslike_framed = true, glasslike_framed = true,

View File

@ -1,5 +1,5 @@
local scriptpath = multicraft.get_builtin_path()..DIR_DELIM local scriptpath = minetest.get_builtin_path()..DIR_DELIM
local commonpath = scriptpath.."common"..DIR_DELIM local commonpath = scriptpath.."common"..DIR_DELIM
local gamepath = scriptpath.."game"..DIR_DELIM local gamepath = scriptpath.."game"..DIR_DELIM
@ -17,6 +17,7 @@ dofile(gamepath.."deprecated.lua")
dofile(gamepath.."misc.lua") dofile(gamepath.."misc.lua")
dofile(gamepath.."privileges.lua") dofile(gamepath.."privileges.lua")
dofile(gamepath.."auth.lua") dofile(gamepath.."auth.lua")
dofile(gamepath.."stat.lua")
dofile(gamepath.."chatcommands.lua") dofile(gamepath.."chatcommands.lua")
dofile(gamepath.."static_spawn.lua") dofile(gamepath.."static_spawn.lua")
dofile(gamepath.."detached_inventory.lua") dofile(gamepath.."detached_inventory.lua")
@ -26,3 +27,6 @@ dofile(gamepath.."voxelarea.lua")
dofile(gamepath.."forceloading.lua") dofile(gamepath.."forceloading.lua")
dofile(gamepath.."statbars.lua") dofile(gamepath.."statbars.lua")
if core.setting_getbool("mod_debugging") then
dofile(gamepath.."mod_debugging.lua")
end

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/item.lua -- Minetest: builtin/item.lua
local function copy_pointed_thing(pointed_thing) local function copy_pointed_thing(pointed_thing)
return { return {
@ -273,7 +273,13 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
end end
-- Add node and update -- Add node and update
local olddef = core.registered_nodes[oldnode.name]
if olddef.leveled and olddef.leveled>0 and olddef.liquidtype ~= "none" and
(newnode.name == oldnode.name or newnode.name == olddef.liquid_alternative_flowing or newnode.name == olddef.liquid_alternative_source) then
core.add_node_level(place_to, olddef.leveled)
else
core.add_node(place_to, newnode) core.add_node(place_to, newnode)
end
local take_item = true local take_item = true
@ -357,7 +363,8 @@ function core.item_drop(itemstack, dropper, pos)
return itemstack return itemstack
end end
function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing) function core.item_eat(hp_change, replace_with_item)
return function(itemstack, user, pointed_thing) -- closure
for _, callback in pairs(core.registered_on_item_eats) do for _, callback in pairs(core.registered_on_item_eats) do
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing) local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
if result then if result then
@ -366,29 +373,10 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
end end
if itemstack:take_item() ~= nil then if itemstack:take_item() ~= nil then
user:set_hp(user:get_hp() + hp_change) user:set_hp(user:get_hp() + hp_change)
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
if replace_with_item then
if itemstack:is_empty() then
itemstack:add_item(replace_with_item)
else
local inv = user:get_inventory()
if inv:room_for_item("main", {name=replace_with_item}) then
inv:add_item("main", replace_with_item)
else
local pos = user:getpos()
pos.y = math.floor(pos.y + 0.5)
core.add_item(pos, replace_with_item)
end
end
end
end end
return itemstack return itemstack
end end
function core.item_eat(hp_change, replace_with_item)
return function(itemstack, user, pointed_thing) -- closure
return core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
end
end end
function core.node_punch(pos, node, puncher, pointed_thing) function core.node_punch(pos, node, puncher, pointed_thing)

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/item_entity.lua -- Minetest: builtin/item_entity.lua
function core.spawn_item(pos, item) function core.spawn_item(pos, item)
-- Take item in any format -- Take item in any format
@ -13,7 +13,7 @@ end
local time_to_live = tonumber(core.setting_get("item_entity_ttl")) local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
if not time_to_live then if not time_to_live then
time_to_live = 900 time_to_live = -1
end end
core.register_entity(":__builtin:item", { core.register_entity(":__builtin:item", {
@ -108,7 +108,7 @@ core.register_entity(":__builtin:item", {
local nn = core.get_node(p).name local nn = core.get_node(p).name
-- If node is not registered or node is walkably solid and resting on nodebox -- If node is not registered or node is walkably solid and resting on nodebox
local v = self.object:getvelocity() local v = self.object:getvelocity()
if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then if not core.registered_nodes[nn] or (core.registered_nodes[nn].walkable and core.get_item_group(nn, "slippery")==0) and v.y == 0 then
if self.physical_state then if self.physical_state then
local own_stack = ItemStack(self.object:get_luaentity().itemstring) local own_stack = ItemStack(self.object:get_luaentity().itemstring)
for _,object in ipairs(core.get_objects_inside_radius(p, 0.8)) do for _,object in ipairs(core.get_objects_inside_radius(p, 0.8)) do
@ -171,6 +171,17 @@ core.register_entity(":__builtin:item", {
self.object:setacceleration({x = 0, y = -10, z = 0}) self.object:setacceleration({x = 0, y = -10, z = 0})
self.physical_state = true self.physical_state = true
self.object:set_properties({physical = true}) self.object:set_properties({physical = true})
elseif core.get_item_group(nn, "slippery") ~= 0 then
if math.abs(v.x) < .2 and math.abs(v.z) < .2 then
self.object:setvelocity({x=0,y=0,z=0})
self.object:setacceleration({x=0, y=0, z=0})
self.physical_state = false
self.object:set_properties({
physical = false
})
else
self.object:setacceleration({x=-v.x, y=-10, z=-v.z})
end
end end
end end
end, end,

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/misc.lua -- Minetest: builtin/misc.lua
-- --
-- Misc. API functions -- Misc. API functions
@ -11,6 +11,7 @@ core.register_globalstep(function(dtime)
table.insert(core.timers, timer) table.insert(core.timers, timer)
end end
core.timers_to_add = {} core.timers_to_add = {}
local end_ms = os.clock() * 1000 + 50
local index = 1 local index = 1
while index <= #core.timers do while index <= #core.timers do
local timer = core.timers[index] local timer = core.timers[index]
@ -21,6 +22,7 @@ core.register_globalstep(function(dtime)
else else
index = index + 1 index = index + 1
end end
if os.clock() * 1000 > end_ms then return end
end end
end) end)
@ -112,3 +114,11 @@ function core.record_protection_violation(pos, name)
end end
end end
function freeminer.color(color)
assert(#color == 6, "Color must be six characters in length.")
return "\v" .. color
end
function freeminer.colorize(color, message)
return freeminer.color(color) .. message .. freeminer.color("ffffff")
end

View File

@ -0,0 +1,126 @@
-- Freeminer: builtin/game/mod_debugging.lua
-- by rubenwardy
local mod = {}
mod.recipes = {}
mod.aliases = {}
core.log("action", 'Mod debugging enabled')
-- Sees if there is a node with this group/these groups
-- Supports AND view group:name, name
local function group_exists(groupname)
local flags = groupname:split(",")
for name, def in pairs(core.registered_items) do
local flag = true
for k, v in pairs(flags) do
local g = def.groups and def.groups[v:gsub('%group:', '')] or 0
if not g or g <= 0 then
flag = false
break
end
end
if flag then
return true
end
end
return false
end
-- Check that the item exists
function mod.assert(recipe, _name, output)
local name = mod.strip_name(_name)
if name == nil then
core.log('error', 'nil in recipe for '..mod.strip_name(output))
print(recipe.from)
return
end
if mod.aliases[name] ~= nil then
name = mod.aliases[name]
end
if core.registered_items[name] == nil and not group_exists(name) then
core.log( 'error', 'missing item '..name.." in recipe for "..mod.strip_name(output) )
print(recipe.from)
end
end
-- Turns a itemstack name into just its item name
-- For example: "mod:item 99" -> "mod:item"
function mod.strip_name(name)
if name == nil then
return
end
res = name:gsub('%"', '')
if res:sub(1, 1) == ":" then
res = table.concat{res:sub(1, 1-1), "", res:sub(1+1)}
end
for str in string.gmatch(res, "([^ ]+)") do
if str ~= " " and str ~= nil then
res=str
break
end
end
if res == nil then
res=""
end
return res
end
-- Cycles through the recipe table, checking the items.
-- Recursive
function mod.check_recipe(recipe, table, output)
if type(table) == "table" then
for i=1,# table do
mod.check_recipe(recipe, table[i], output)
end
else
mod.assert(recipe, table,output)
end
end
-- Check recipes once the game has loaded
core.after(0, function()
for i=1, #mod.recipes do
if mod.recipes[i] and mod.recipes[i].output then
mod.assert(mod.recipes[i], mod.recipes[i].output, mod.recipes[i].output)
if type(mod.recipes[i].recipe) == "table" then
for a=1,# mod.recipes[i].recipe do
mod.check_recipe(mod.recipes[i], mod.recipes[i].recipe[a], mod.recipes[i].output)
end
else
mod.assert(mod.recipes[i], mod.recipes[i].recipe, mod.recipes[i].output)
end
end
end
end)
-- Override register_craft to catch craft recipes
local register_craft = core.register_craft
core.register_craft = function(recipe)
register_craft(recipe)
local name = mod.strip_name(recipe.output)
recipe.from = debug.traceback()
if name~=nil then
table.insert(mod.recipes, recipe)
end
end
-- Override register_alias to catch aliases
local register_alias = core.register_alias
core.register_alias = function(new, old)
register_alias(new, old)
local name = mod.strip_name(new)
local name2 = mod.strip_name(old)
if name~=nil and name2~=nil then
mod.aliases[new] = old
end
end

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/game/mod_profiling.lua -- Minetest: builtin/game/mod_profiling.lua
local mod_statistics = {} local mod_statistics = {}
mod_statistics.step_total = 0 mod_statistics.step_total = 0

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/privileges.lua -- Minetest: builtin/privileges.lua
-- --
-- Privileges -- Privileges

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/misc_register.lua -- Minetest: builtin/misc_register.lua
-- --
-- Make raw registration functions inaccessible to anyone except this file -- Make raw registration functions inaccessible to anyone except this file
@ -125,7 +125,7 @@ function core.register_item(name, itemdef)
end end
-- Flowing liquid uses param2 -- Flowing liquid uses param2
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then if itemdef.type == "node" and itemdef.liquidtype == "flowing" and itemdef.paramtype2 == nil then
itemdef.paramtype2 = "flowingliquid" itemdef.paramtype2 = "flowingliquid"
end end
@ -261,12 +261,15 @@ end
core.register_item(":unknown", { core.register_item(":unknown", {
type = "none", type = "none",
walkable = true,
description = "Unknown Item", description = "Unknown Item",
tiles = {"trans.png"},
inventory_image = "unknown_item.png", inventory_image = "unknown_item.png",
on_place = core.item_place, on_place = core.item_place,
on_drop = core.item_drop, on_drop = core.item_drop,
groups = {not_in_creative_inventory=1}, groups = {not_in_creative_inventory=1},
diggable = true, diggable = true,
pointable = false,
}) })
core.register_node(":air", { core.register_node(":air", {
@ -398,9 +401,7 @@ local function make_registration_wrap(reg_fn_name, clear_fn_name)
local orig_clear_fn = core[clear_fn_name] local orig_clear_fn = core[clear_fn_name]
core[clear_fn_name] = function() core[clear_fn_name] = function()
for k in pairs(list) do list = {}
list[k] = nil
end
return orig_clear_fn() return orig_clear_fn()
end end
@ -420,6 +421,7 @@ core.registered_on_placenodes, core.register_on_placenode = make_registration()
core.registered_on_dignodes, core.register_on_dignode = make_registration() core.registered_on_dignodes, core.register_on_dignode = make_registration()
core.registered_on_generateds, core.register_on_generated = make_registration() core.registered_on_generateds, core.register_on_generated = make_registration()
core.registered_on_newplayers, core.register_on_newplayer = make_registration() core.registered_on_newplayers, core.register_on_newplayer = make_registration()
core.registered_on_open_inventories, core.register_on_open_inventory = make_registration()
core.registered_on_dieplayers, core.register_on_dieplayer = make_registration() core.registered_on_dieplayers, core.register_on_dieplayer = make_registration()
core.registered_on_respawnplayers, core.register_on_respawnplayer = make_registration() core.registered_on_respawnplayers, core.register_on_respawnplayer = make_registration()
core.registered_on_prejoinplayers, core.register_on_prejoinplayer = make_registration() core.registered_on_prejoinplayers, core.register_on_prejoinplayer = make_registration()
@ -432,6 +434,38 @@ core.registered_craft_predicts, core.register_craft_predict = make_registration(
core.registered_on_protection_violation, core.register_on_protection_violation = make_registration() core.registered_on_protection_violation, core.register_on_protection_violation = make_registration()
core.registered_on_item_eats, core.register_on_item_eat = make_registration() core.registered_on_item_eats, core.register_on_item_eat = make_registration()
minetest.register_on_joinplayer(function(player)
if minetest.is_singleplayer() then
return
end
local player_name = player:get_player_name()
minetest.chat_send_all("*** " .. player_name .. " joined the game.")
end)
minetest.register_on_dieplayer(function(player)
local player_name = player:get_player_name()
if minetest.is_singleplayer() then
player_name = "You"
end
-- Idea from https://github.com/4Evergreen4/death_messages
-- Death by lava
local nodename = minetest.get_node(player:getpos()).name
if nodename == "default:lava_source" or nodename == "default:lava_flowing" then
minetest.chat_send_all(player_name .. " melted into a ball of fire.")
-- Death by drowning
elseif nodename == "default:water_source" or nodename == "default:water_flowing" then
minetest.chat_send_all(player_name .. " ran out of air.")
--Death by fire
elseif nodename == "fire:basic_flame" then
minetest.chat_send_all(player_name .. " burned up.")
--Death by something else
else
minetest.chat_send_all(player_name .. " \vbb0000died.")
end
end)
-- --
-- Compatibility for on_mapgen_init() -- Compatibility for on_mapgen_init()
-- --

75
builtin/game/stat.lua Normal file
View File

@ -0,0 +1,75 @@
-- TODO: move this function to builtin/common/misc_helpers.lua
--
-- Formats numbers according to SI multiplies and
-- appends a correspending prefix symbol (e.g. 1234000 -> 1.234 M)
function string.number_to_si(value, precision)
precision = precision or 3
local symbol = { "Y", "Z", "E", "P", "T", "G", "M", "k" }
local multiplies = { 10^24, 10^21, 10^18, 10^15, 10^12, 10^9, 10^6, 10^3 }
local abs_value = math.abs(value)
for k,v in ipairs(multiplies) do
if abs_value >= v then
return string.format("%."..precision.."f "..symbol[k], value / v)
end
end
return math.ceil(value)
end
-- returns formspec with table of stats
function core.stat_formspec(name)
local stat_table = {
chat = "Messages",
craft = "Crafted",
damage = "Damage",
die = "Deaths",
dig = "Digged",
drop = "Dropped",
join = "Join",
move = "Traveled",
place = "Placed",
punch = "Punches",
use = "Uses",
}
local formspec
local y = -.1
if core.is_singleplayer() then
-- collumns
local x = { .25, 1.8 }
formspec = "size[3.2,4.6]"
.."label["..x[1]..","..y..";Stat]"
.."label["..x[2]..","..y..";Value]"
.."label[-.25,"..(y+0.1)..";"..string.rep("_", 45).."]"
y = y + 0.2
for key, eng_name in pairs(stat_table) do
-- leading
y = y + 0.4
formspec = formspec
.."label["..x[1]..","..y..";"..eng_name.."]"
.."label["..x[2]..","..y..";"
..string.number_to_si(core.stat_get("player|"..key.."|"..name)).."]"
end
else
-- collumns
local x = { .25, 1.8, 3.5 }
formspec = "size[4.9,4.6]"
.."label["..x[1]..","..y..";Stat]"
.."label["..x[2]..","..y..";Player]"
.."label["..x[3]..","..y..";Total]"
.."label[-.25,"..(y+0.1)..";"..string.rep("_", 60).."]"
y = y + 0.2
for key, eng_name in pairs(stat_table) do
-- leading
y = y + 0.4
formspec = formspec
.."label["..x[1]..","..y..";"..eng_name.."]"
.."label["..x[2]..","..y..";"
..string.number_to_si(core.stat_get("player|"..key.."|"..name)).."]"
.."label["..x[3]..","..y..";"
..string.number_to_si(core.stat_get("total|"..key), 4).."]"
end
end
return formspec
end

View File

@ -1,4 +1,4 @@
-- multicraft: builtin/static_spawn.lua -- Minetest: builtin/static_spawn.lua
local function warn_invalid_static_spawnpoint() local function warn_invalid_static_spawnpoint()
if core.setting_get("static_spawnpoint") and if core.setting_get("static_spawnpoint") and

View File

@ -1,5 +1,5 @@
-- --
-- This file contains built-in stuff in multicraft implemented in Lua. -- This file contains built-in stuff in Minetest implemented in Lua.
-- --
-- It is always loaded and executed after registration of the C API, -- It is always loaded and executed after registration of the C API,
-- before loading and running any mods. -- before loading and running any mods.
@ -9,7 +9,9 @@
print = core.debug print = core.debug
math.randomseed(os.time()) math.randomseed(os.time())
os.setlocale("C", "numeric") os.setlocale("C", "numeric")
multicraft = core minetest = core
freeminer = core
magichet = core
-- Load other files -- Load other files
local scriptdir = core.get_builtin_path()..DIR_DELIM local scriptdir = core.get_builtin_path()..DIR_DELIM
@ -17,10 +19,15 @@ local gamepath = scriptdir.."game"..DIR_DELIM
local commonpath = scriptdir.."common"..DIR_DELIM local commonpath = scriptdir.."common"..DIR_DELIM
local asyncpath = scriptdir.."async"..DIR_DELIM local asyncpath = scriptdir.."async"..DIR_DELIM
--dofile(scriptdir.."profiler.lua") --TODO: repair me
--[[ too buggy
dofile(commonpath.."strict.lua") dofile(commonpath.."strict.lua")
]]
dofile(commonpath.."serialize.lua") dofile(commonpath.."serialize.lua")
dofile(commonpath.."misc_helpers.lua") dofile(commonpath.."misc_helpers.lua")
dofile(scriptdir.."key_value_storage.lua")
if INIT == "game" then if INIT == "game" then
dofile(gamepath.."init.lua") dofile(gamepath.."init.lua")
elseif INIT == "mainmenu" then elseif INIT == "mainmenu" then
@ -28,7 +35,7 @@ elseif INIT == "mainmenu" then
if mainmenuscript ~= nil and mainmenuscript ~= "" then if mainmenuscript ~= nil and mainmenuscript ~= "" then
dofile(mainmenuscript) dofile(mainmenuscript)
else else
dofile(core.get_mainmenu_path()..DIR_DELIM.."init.lua") dofile(core.get_mainmenu_path()..DIR_DELIM.."fm_init.lua")
end end
elseif INIT == "async" then elseif INIT == "async" then
dofile(asyncpath.."init.lua") dofile(asyncpath.."init.lua")

View File

@ -0,0 +1,26 @@
--
-- Key-value storage stuff
--
function core.kv_put(key, data)
local json = core.write_json(data)
if not json then
core.log("error", "kv_put: Error in json serialize key=".. key .. " luaized_data=" .. core.serialize(data))
return
end
return core.kv_put_string(key, json)
end
function core.kv_get(key)
local data = core.kv_get_string(key)
if data ~= nil then
data = core.parse_json(data)
end
return data
end
function core.kv_rename(key1, key2)
local data = core.kv_get_string(key1)
core.kv_delete(key1)
core.kv_put_string(key2, data)
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -16,70 +16,24 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Global menu data -- Global menu data
-------------------------------------------------------------------------------- ---------------------------------------------------------------------------------
menudata = {} menudata = {}
--------------------------------------------------------------------------------
-- Local cached values
--------------------------------------------------------------------------------
local min_supp_proto = core.get_min_supp_proto()
local max_supp_proto = core.get_max_supp_proto()
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Menu helper functions -- Menu helper functions
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function render_client_count(n) local function render_client_count(n)
n = tonumber(n) if tonumber(n) > 99 then
if n > 99 then
return '99+' return '99+'
elseif n >= 0 then elseif tonumber(n) >= 0 then
return tostring(n) return tostring(n)
else else
return '?' return '?'
end end
end end
local function configure_selected_world_params(idx)
local worldconfig = modmgr.get_worldconfig(
menudata.worldlist:get_list()[idx].path)
if worldconfig.creative_mode ~= nil then
core.setting_set("creative_mode", worldconfig.creative_mode)
end
if worldconfig.enable_damage ~= nil then
core.setting_set("enable_damage", worldconfig.enable_damage)
end
end
--------------------------------------------------------------------------------
function image_column(tooltip, flagname)
return "image," ..
"tooltip=" .. core.formspec_escape(tooltip) .. "," ..
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
end
--------------------------------------------------------------------------------
function order_favorite_list(list)
local res = {}
--orders the favorite list after support
for i=1,#list,1 do
local fav = list[i]
if is_server_protocol_compat(tonumber(fav.proto_min), tonumber(fav.proto_max)) then
table.insert(res, fav)
end
end
for i=1,#list,1 do
local fav = list[i]
if not is_server_protocol_compat(tonumber(fav.proto_min), tonumber(fav.proto_max)) then
table.insert(res, fav)
end
end
return res
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function render_favorite(spec,render_details) function render_favorite(spec,render_details)
local text = "" local text = ""
@ -101,12 +55,7 @@ function render_favorite(spec,render_details)
end end
end end
if not render_details then
return text
end
local details = "" local details = ""
local grey_out = not is_server_protocol_compat(tonumber(spec.proto_max), tonumber(spec.proto_min))
if spec.clients ~= nil and spec.clients_max ~= nil then if spec.clients ~= nil and spec.clients_max ~= nil then
local clients_color = '' local clients_color = ''
@ -126,17 +75,11 @@ function render_favorite(spec,render_details)
clients_color = '#ffba97' -- 90-100%: orange clients_color = '#ffba97' -- 90-100%: orange
end end
if grey_out then
clients_color = '#aaaaaa'
end
details = details .. details = details ..
clients_color .. ',' .. clients_color .. ',' ..
render_client_count(spec.clients) .. ',' .. render_client_count(spec.clients) .. ',' ..
'/,' .. '/,' ..
render_client_count(spec.clients_max) .. ',' render_client_count(spec.clients_max) .. ','
elseif grey_out then
details = details .. '#aaaaaa,?,/,?,'
else else
details = details .. ',?,/,?,' details = details .. ',?,/,?,'
end end
@ -159,7 +102,8 @@ function render_favorite(spec,render_details)
details = details .. "0," details = details .. "0,"
end end
return details .. (grey_out and '#aaaaaa,' or ',') .. text details = details .. text
return details
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -202,6 +146,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function menu_handle_key_up_down(fields,textlist,settingname) function menu_handle_key_up_down(fields,textlist,settingname)
if fields["key_up"] then if fields["key_up"] then
local oldidx = core.get_textlist_index(textlist) local oldidx = core.get_textlist_index(textlist)
@ -209,8 +154,6 @@ function menu_handle_key_up_down(fields,textlist,settingname)
local newidx = oldidx -1 local newidx = oldidx -1
core.setting_set(settingname, core.setting_set(settingname,
menudata.worldlist:get_raw_index(newidx)) menudata.worldlist:get_raw_index(newidx))
configure_selected_world_params(newidx)
end end
return true return true
end end
@ -222,8 +165,6 @@ function menu_handle_key_up_down(fields,textlist,settingname)
local newidx = oldidx + 1 local newidx = oldidx + 1
core.setting_set(settingname, core.setting_set(settingname,
menudata.worldlist:get_raw_index(newidx)) menudata.worldlist:get_raw_index(newidx))
configure_selected_world_params(newidx)
end end
return true return true
@ -238,15 +179,20 @@ function asyncOnlineFavourites()
menudata.favorites = {} menudata.favorites = {}
core.handle_async( core.handle_async(
function(param) function(param)
return core.get_favorites("online") local ret = core.get_favorites("online")
local num = core.get_favorites("local")
local cou = 0
for k,v in ipairs(core.get_favorites("local")) do
cou = cou+1
table.insert(ret,cou,v)
end
return ret
end, end,
nil, nil,
function(result) function(result)
if core.setting_getbool("public_serverlist") then menudata.favorites = result
menudata.favorites = order_favorite_list(result)
core.event_handler("Refresh") core.event_handler("Refresh")
end end
end
) )
end end
@ -273,21 +219,3 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
return retval return retval
end end
--------------------------------------------------------------------------------
function is_server_protocol_compat(proto_min, proto_max)
return not ((min_supp_proto > (proto_max or 24)) or (max_supp_proto < (proto_min or 13)))
end
--------------------------------------------------------------------------------
function is_server_protocol_compat_or_error(proto_min, proto_max)
if not is_server_protocol_compat(proto_min, proto_max) then
gamedata.errormessage = fgettext_ne("Protocol version mismatch, server " ..
((proto_min ~= proto_max) and "supports protocols between $1 and $2" or "enforces protocol version $1") ..
", we " ..
((min_supp_proto ~= max_supp_proto) and "support protocols between version $3 and $4." or "only support protocol version $3"),
proto_min or 13, proto_max or 24, min_supp_proto, max_supp_proto)
return false
end
return true
end

View File

@ -0,0 +1,111 @@
--Minetest
--Copyright (C) 2014 sapier
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
local function add_server_formspec(dialogdata)
local retval =
"size[16,11]"..
"bgcolor[#00000070;true]"..
"box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"label[4,3;" .. fgettext("Name") .. "]"..
"field[6.5,3.4;6,0.5;servername;;]" ..
"label[4,4;" .. fgettext("Address") .. "]"..
"field[6.5,4.4;6,0.5;address;;]" ..
"label[4,5;" .. fgettext("Port") .. "]"..
"field[6.5,5.4;6,0.5;port;;30000]" ..
"label[4,6;" .. fgettext("Description") .. "]"..
"field[6.5,6.4;6,0.5;desc;;Added on ".. os.date() .."]" ..
"image_button[8,9.54;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;server_add_confirm;".. fgettext("Add") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;server_add_cancel;".. fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
return retval
end
local function add_server_buttonhandler(this, fields)
if fields["server_add_cancel"] then
this:delete()
return true
end
if fields["server_add_confirm"]
or fields["key_enter"] then
if fields["address"] and fields["port"] then
----------------------
local path = core.get_modpath('')..'/../client/'..core.formspec_escape(core.setting_get("serverlist_file"))
local favourites
if path then
local input = io.open(path, "r")
if input then
favourites = input:read("*all")
io.close(input)
--else
--gamedata.errormessage = fgettext("Can't find serverlist_file! ("..path..')')
end
if favourites then
favourites = minetest.parse_json(favourites)
else
favourites = {["list"]={},}
end
table.insert(favourites.list,{
["address"] = fields["te_address"],
["description"] = "Saved at ".. os.date(),
["name"] = fields["te_address"],
["playername"] = fields["te_name"],
["playerpassword"] = fields["te_pwd"],
["port"] = fields["te_port"],
}
)
favourites = minetest.write_json(favourites)
--print(path)
local output = io.open(path, "w")
if output then
output:write(favourites or '')
io.close(output)
else
gamedata.errormessage = err..' ('..errcode..')'
end
end
----------------------
asyncOnlineFavourites()
this:delete()
end
return true
end
return false
end
function create_add_server_dlg(update_worldlistfilter)
local retval = dialog_create("add_server_dlg",
add_server_formspec,
add_server_buttonhandler,
nil)
return retval
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -16,29 +16,30 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function modname_valid(name)
return not name:find("[^a-z0-9_]")
end
local function get_formspec(data) local function get_formspec(data)
local mod = data.list:get_list()[data.selected_mod] local mod = data.list:get_list()[data.selected_mod]
local retval = local retval =
"size[11,6.5,false]" .. "size[16,11]"..
"label[0.5,-0.25;" .. fgettext("World:") .. "]" .. "bgcolor[#00000070;true]"..
"label[1.75,-0.25;" .. data.worldspec.name .. "]" "box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"label[1, 2.5;" .. fgettext("World:") .. "]" ..
"label[2.75,2.5;" .. data.worldspec.name .. "]"
if data.hide_gamemods then if data.hide_gamemods then
retval = retval .. "checkbox[0,5.75;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]" retval = retval .. "checkbox[1,7.55;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]"
else else
retval = retval .. "checkbox[0,5.75;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]" retval = retval .. "checkbox[1,7.55;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]"
end end
if data.hide_modpackcontents then if data.hide_modpackcontents then
retval = retval .. "checkbox[2,5.75;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]" retval = retval .. "checkbox[4,7.55;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]"
else else
retval = retval .. "checkbox[2,5.75;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]" retval = retval .. "checkbox[4,7.55;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]"
end end
if mod == nil then if mod == nil then
@ -46,13 +47,13 @@ local function get_formspec(data)
end end
retval = retval .. retval = retval ..
"label[0,0.45;" .. fgettext("Mod:") .. "]" .. "label[1,3;" .. fgettext("Mod:") .. "]" ..
"label[0.75,0.45;" .. mod.name .. "]" .. "label[2.75,3;" .. mod.name .. "]" ..
"label[0,1;" .. fgettext("Depends:") .. "]" .. "label[8,3;" .. fgettext("Depends:") .. "]" ..
"textlist[0,1.5;5,4.25;world_config_depends;" .. "textlist[8,3.5;7,4.0;world_config_depends;" ..
modmgr.get_dependencies(mod.path) .. ";0]" .. modmgr.get_dependencies(mod.path) .. ";0]" ..
"image_button[9.25,6.35;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_config_world_save;" .. fgettext("Save") .. "]" .. "image_button[8,9.55;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_config_world_save;" .. fgettext("Save") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[7.4,6.35;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_config_world_cancel;" .. fgettext("Cancel") .. "]" "image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_config_world_cancel;".. fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
if mod ~= nil and mod.name ~= "" and mod.typ ~= "game_mod" then if mod ~= nil and mod.name ~= "" and mod.typ ~= "game_mod" then
if mod.is_modpack then if mod.is_modpack then
@ -68,22 +69,23 @@ local function get_formspec(data)
end end
if all_enabled == false then if all_enabled == false then
retval = retval .. "image_button[5.5,-0.125;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_enable;" .. fgettext("Enable MP") .. "]" retval = retval .. "image_button[8,7.55;3.5,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_enable;" .. fgettext("Enable MP") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
else else
retval = retval .. "image_button[5.5,-0.125;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_disable;" .. fgettext("Disable MP") .. "]" retval = retval .. "image_button[8,7.85;3.5,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_disable;" .. fgettext("Disable MP") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
end end
else else
if mod.enabled then if mod.enabled then
retval = retval .. "checkbox[5.5,-0.375;cb_mod_enable;" .. fgettext("enabled") .. ";true]" retval = retval .. "checkbox[8.25,7.55;cb_mod_enable;" .. fgettext("enabled") .. ";true]"
else else
retval = retval .. "checkbox[5.5,-0.375;cb_mod_enable;" .. fgettext("enabled") .. ";false]" retval = retval .. "checkbox[8.25,7.55;cb_mod_enable;" .. fgettext("enabled") .. ";false]"
end end
end end
end end
retval = retval .. retval = retval ..
"image_button[8.5,-0.125;2.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_all_mods;" .. fgettext("Enable all") .. "]" .. "image_button[11.75,7.55;3.5,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_all_mods;" .. fgettext("Enable all") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"textlist[5.5,0.5;5.5,5.75;world_config_modlist;" "textlist[1,3.5;6,4.0;world_config_modlist;"
--"textlist[5.5,0.5;5.5,5.75;world_config_modlist;"
retval = retval .. modmgr.render_modlist(data.list) retval = retval .. modmgr.render_modlist(data.list)
retval = retval .. ";" .. data.selected_mod .."]" retval = retval .. ";" .. data.selected_mod .."]"
@ -198,12 +200,10 @@ local function handle_buttons(this, fields)
for i,mod in ipairs(rawlist) do for i,mod in ipairs(rawlist) do
if not mod.is_modpack and if not mod.is_modpack and
mod.typ ~= "game_mod" then mod.typ ~= "game_mod" then
if modname_valid(mod.name) then
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
else
if mod.enabled then if mod.enabled then
gamedata.errormessage = fgettext_ne("Failed to enable mod \"$1\" as it contains disallowed characters. Only chararacters [a-z0-9_] are allowed.", mod.name) worldfile:set("load_mod_"..mod.name, "true")
end else
worldfile:set("load_mod_"..mod.name, "false")
end end
mods["load_mod_"..mod.name] = nil mods["load_mod_"..mod.name] = nil
end end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -40,37 +40,42 @@ local function create_world_formspec(dialogdata)
game, gameidx = gamemgr.find_by_gameid(gameid) game, gameidx = gamemgr.find_by_gameid(gameid)
if gameidx == nil then if gameidx == nil then
gameidx = 0 gameidx = 1
end end
end end
current_seed = core.formspec_escape(current_seed) current_seed = core.formspec_escape(current_seed)
local retval = local retval =
"size[12,6,false]" .. "size[16,11]"..
"label[2,0;" .. fgettext("World name") .. "]".. "bgcolor[#00000070;true]"..
"field[4.5,0.4;6,0.5;te_world_name;;]" .. "box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"label[2,1;" .. fgettext("Seed") .. "]".. "label[4,3;" .. fgettext("World name") .. "]"..
"field[4.5,1.4;6,0.5;te_seed;;".. current_seed .. "]" .. "field[6.5,3.4;6,0.5;te_world_name;;]" ..
"label[2,2;" .. fgettext("Mapgen") .. "]".. "label[4,4;" .. fgettext("Seed") .. "]"..
"dropdown[4.2,2;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" .. "field[6.5,4.4;6,0.5;te_seed;;".. current_seed .. "]" ..
"label[2,3;" .. fgettext("Game") .. "]".. "label[4,5;" .. fgettext("Mapgen") .. "]"..
"textlist[4.2,3;5.8,2.3;games;" .. gamemgr.gamelist() .. "dropdown[6.2,5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
";" .. gameidx .. ";true]" ..
"image_button[5,5.5;2.6,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create_confirm;" .. fgettext("Create") .. "]" .. "label[4,6;" .. fgettext("Game") .. "]"..
"image_button[7.5,5.5;2.8,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create_cancel;" .. fgettext("Cancel") .. "]" "dropdown[6.2,6;6.3;games;" .. gamemgr.gamelist() ..
";" .. gameidx .. "]" ..
"image_button[8,9.55;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create_confirm;".. fgettext("Create") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create_cancel;".. fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
if #gamemgr.games == 0 then if #gamemgr.games == 0 then
retval = retval .. "box[2,4;8,1;#ff8800]label[2.25,4;" .. retval = retval .. "box[4,7;8,1;#ff8800]label[4.25,7;" ..
fgettext("You have no subgames installed.") .. "]label[2.25,4.4;" .. fgettext("You have no subgames installed.") .. "]label[4.25,7.4;" ..
fgettext("Download one from multicraft.net") .. "]" fgettext("Download one from minetest.net") .. "]"
elseif #gamemgr.games == 1 and gamemgr.games[1].id == "minimal" then elseif #gamemgr.games == 1 and gamemgr.games[1].id == "minimal" then
retval = retval .. "box[1.75,4;8.7,1;#ff8800]label[2,4;" .. retval = retval .. "box[3.50,7;9,1;#ff8800]label[3.75,7;" ..
fgettext("Warning: The minimal development test is meant for developers.") .. "]label[2,4.4;" .. fgettext("Warning: The minimal development test is meant for developers.") .. "]label[3.75,7.4;" ..
fgettext("Download a subgame, such as multicraft_game, from multicraft.net") .. "]" fgettext("Download a subgame, such as minetest_game, from minetest.net") .. "]"
end end
return retval return retval
@ -79,19 +84,26 @@ end
local function create_world_buttonhandler(this, fields) local function create_world_buttonhandler(this, fields)
if fields["world_create_cancel"] then
this:delete()
return true
end
if fields["world_create_confirm"] or if fields["world_create_confirm"] or
fields["key_enter"] then fields["key_enter"] then
local worldname = fields["te_world_name"] local worldname = fields["te_world_name"]
local gameindex = core.get_textlist_index("games") local gameindex
for i,item in ipairs(gamemgr.games) do
if item.name == fields["games"] then
gameindex = i
end
end
if gameindex ~= nil and if gameindex ~= nil and
worldname ~= "" then worldname ~= "" then
local message = nil local message = nil
core.setting_set("fixed_map_seed", fields["te_seed"])
if not menudata.worldlist:uid_exists_raw(worldname) then if not menudata.worldlist:uid_exists_raw(worldname) then
core.setting_set("mg_name",fields["dd_mapgen"]) core.setting_set("mg_name",fields["dd_mapgen"])
message = core.create_world(worldname,gameindex) message = core.create_world(worldname,gameindex)
@ -99,13 +111,15 @@ local function create_world_buttonhandler(this, fields)
message = fgettext("A world named \"$1\" already exists", worldname) message = fgettext("A world named \"$1\" already exists", worldname)
end end
core.setting_set("fixed_map_seed", fields["te_seed"])
if message ~= nil then if message ~= nil then
gamedata.errormessage = message gamedata.errormessage = message
else else
core.setting_set("menu_last_game",gamemgr.games[gameindex].id) core.setting_set("menu_last_game",gamemgr.games[gameindex].id)
if this.data.update_worldlist_filter then if this.data.update_worldlist_filter then
menudata.worldlist:set_filtercriteria(gamemgr.games[gameindex].id) menudata.worldlist:set_filtercriteria(gamemgr.games[gameindex].id)
mm_texture.update("singleplayer", gamemgr.games[gameindex].id) -- mm_texture.update("singleplayer", gamemgr.games[gameindex].id)
end end
menudata.worldlist:refresh() menudata.worldlist:refresh()
core.setting_set("mainmenu_last_selected_world", core.setting_set("mainmenu_last_selected_world",
@ -123,11 +137,6 @@ local function create_world_buttonhandler(this, fields)
return true return true
end end
if fields["world_create_cancel"] then
this:delete()
return true
end
return false return false
end end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -22,11 +22,14 @@ local function delete_mod_formspec(dialogdata)
dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected] dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected]
local retval = local retval =
"size[12.4,5,false]" .. "size[16,11]"..
"field[1.75,1;10,3;;" .. fgettext("Are you sure you want to delete \"$1\"?", dialogdata.mod.name) .. ";]".. "bgcolor[#00000070;true]"..
"image_button[4,4.2;1,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_delete_mod_confirm;" .. fgettext("Yes") .. "]" .. "box[-100,8.5;200,10;#999999]" ..
"image_button[6.5,4.2;3,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_delete_mod_cancel;" .. fgettext("No of course not!") .. "]" "box[-100,-10;200,12;#999999]" ..
"label[6.5,4.5;" ..
fgettext("Are you sure you want to delete \"$1\"?", dialogdata.mod.name) .. ";]"..
"image_button[4,5.7;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_delete_mod_confirm;" .. fgettext("Yes").. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[8,5.7;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_delete_mod_cancel;" .. fgettext("No") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
return retval return retval
end end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -19,11 +19,14 @@
local function delete_world_formspec(dialogdata) local function delete_world_formspec(dialogdata)
local retval = local retval =
"size[12,6,false]" .. "size[16,11]"..
"label[2,2;" .. "bgcolor[#00000070;true]"..
"box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"label[6.5,4.5;" ..
fgettext("Delete World \"$1\"?", dialogdata.delete_name) .. "]".. fgettext("Delete World \"$1\"?", dialogdata.delete_name) .. "]"..
"image_button[3.5,4.2;2.6,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete_confirm;" .. fgettext("Yes").. "]" .. "image_button[4,5.7;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete_confirm;" .. fgettext("Yes").. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[6,4.2;2.8,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete_cancel;" .. fgettext("No") .. "]" "image_button[8,5.7;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete_cancel;" .. fgettext("No") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
return retval return retval
end end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -22,15 +22,15 @@ local function rename_modpack_formspec(dialogdata)
dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected] dialogdata.mod = modmgr.global_mods:get_list()[dialogdata.selected]
local retval = local retval =
"size[12.4,5,false]" .. "size[12.4,5,true]" ..
"label[1.75,1;".. fgettext("Rename Modpack:") .. "]".. "label[1.75,1;".. fgettext("Rename Modpack:") .. "]"..
"field[4.5,1.4;6,0.5;te_modpack_name;;" .. "field[4.5,1.4;6,0.5;te_modpack_name;;" ..
dialogdata.mod.name .. dialogdata.mod.name ..
"]" .. "]" ..
"image_button[5,4.2;2.6,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_rename_modpack_confirm;".. "image_button[5,4.2;2.6,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_rename_modpack_confirm;"..
fgettext("Accept") .. "]" .. fgettext("Accept") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[7.5,4.2;2.8,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_rename_modpack_cancel;".. "image_button[7.5,4.2;2.8,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_rename_modpack_cancel;"..
fgettext("Cancel") .. "]" fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
return retval return retval
end end

View File

@ -0,0 +1,321 @@
--Minetest
--Copyright (C) 2013 sapier
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
gamemgr = {}
--------------------------------------------------------------------------------
function gamemgr.dialog_new_game()
local retval =
"label[2,2;" .. fgettext("Game Name") .. "]"..
"field[4.5,2.4;6,0.5;te_game_name;;]" ..
"button[5,4.2;2.6,0.5;new_game_confirm;" .. fgettext("Create") .. "]" ..
"button[7.5,4.2;2.8,0.5;new_game_cancel;" .. fgettext("Cancel") .. "]"
return retval
end
--------------------------------------------------------------------------------
function gamemgr.handle_games_buttons(fields)
if fields["gamelist"] ~= nil then
local event = core.explode_textlist_event(fields["gamelist"])
gamemgr.selected_game = event.index
end
if fields["btn_game_mgr_edit_game"] ~= nil then
return {
is_dialog = true,
show_buttons = false,
current_tab = "dialog_edit_game"
}
end
if fields["btn_game_mgr_new_game"] ~= nil then
return {
is_dialog = true,
show_buttons = false,
current_tab = "dialog_new_game"
}
end
return nil
end
--------------------------------------------------------------------------------
function gamemgr.handle_new_game_buttons(fields)
if fields["new_game_confirm"] and
fields["te_game_name"] ~= nil and
fields["te_game_name"] ~= "" then
local gamepath = core.get_gamepath()
if gamepath ~= nil and
gamepath ~= "" then
local gamefolder = cleanup_path(fields["te_game_name"])
--TODO check for already existing first
core.create_dir(gamepath .. DIR_DELIM .. gamefolder)
core.create_dir(gamepath .. DIR_DELIM .. gamefolder .. DIR_DELIM .. "mods")
core.create_dir(gamepath .. DIR_DELIM .. gamefolder .. DIR_DELIM .. "menu")
local gameconf =
io.open(gamepath .. DIR_DELIM .. gamefolder .. DIR_DELIM .. "game.conf","w")
if gameconf then
gameconf:write("name = " .. fields["te_game_name"])
gameconf:close()
end
end
end
return {
is_dialog = false,
show_buttons = true,
current_tab = core.setting_get("main_menu_tab")
}
end
--------------------------------------------------------------------------------
function gamemgr.handle_edit_game_buttons(fields)
local current_game = gamemgr.get_game(gamemgr.selected_game)
if fields["btn_close_edit_game"] ~= nil or
current_game == nil then
return {
is_dialog = false,
show_buttons = true,
current_tab = core.setting_get("main_menu_tab")
}
end
if fields["btn_remove_mod_from_game"] ~= nil then
gamemgr.delete_mod(current_game,core.get_textlist_index("mods_current"))
end
if fields["btn_add_mod_to_game"] ~= nil then
local modindex = core.get_textlist_index("mods_available")
local mod = modmgr.get_global_mod(modindex)
if mod ~= nil then
local sourcepath = mod.path
if not gamemgr.add_mod(current_game,sourcepath) then
gamedata.errormessage =
fgettext("Gamemgr: Unable to copy mod \"$1\" to game \"$2\"", mod.name, current_game.id)
end
end
end
return nil
end
--------------------------------------------------------------------------------
function gamemgr.add_mod(gamespec,sourcepath)
if gamespec.gamemods_path ~= nil and
gamespec.gamemods_path ~= "" then
local modname = get_last_folder(sourcepath)
return core.copy_dir(sourcepath,gamespec.gamemods_path .. DIR_DELIM .. modname);
end
return false
end
--------------------------------------------------------------------------------
function gamemgr.delete_mod(gamespec,modindex)
if gamespec.gamemods_path ~= nil and
gamespec.gamemods_path ~= "" then
local game_mods = {}
get_mods(gamespec.gamemods_path,game_mods)
if modindex > 0 and
#game_mods >= modindex then
if game_mods[modindex].path:sub(0,gamespec.gamemods_path:len())
== gamespec.gamemods_path then
core.delete_dir(game_mods[modindex].path)
end
end
end
end
--------------------------------------------------------------------------------
function gamemgr.find_by_gameid(gameid)
for i=1,#gamemgr.games,1 do
if gamemgr.games[i].id == gameid then
return gamemgr.games[i], i
end
end
return nil, nil
end
--------------------------------------------------------------------------------
function gamemgr.get_game_mods(gamespec, retval)
if gamespec ~= nil and
gamespec.gamemods_path ~= nil and
gamespec.gamemods_path ~= "" then
get_mods(gamespec.gamemods_path, retval)
end
end
--------------------------------------------------------------------------------
function gamemgr.get_game_modlist(gamespec)
local retval = ""
local game_mods = {}
gamemgr.get_game_mods(gamespec, game_mods)
for i=1,#game_mods,1 do
if retval ~= "" then
retval = retval..","
end
retval = retval .. game_mods[i].name
end
return retval
end
--------------------------------------------------------------------------------
function gamemgr.gettab(name)
local retval = ""
if name == "dialog_edit_game" then
retval = retval .. gamemgr.dialog_edit_game()
end
if name == "dialog_new_game" then
retval = retval .. gamemgr.dialog_new_game()
end
if name == "game_mgr" then
retval = retval .. gamemgr.tab()
end
return retval
end
--------------------------------------------------------------------------------
function gamemgr.tab()
if gamemgr.selected_game == nil then
gamemgr.selected_game = 1
end
local retval =
"label[6.5,-0.25;" .. fgettext("Games") .. ":]" ..
"textlist[6.5,0.25;8,4.4;gamelist;" ..
gamemgr.gamelist() ..
";" .. gamemgr.selected_game .. "]"
local current_game = gamemgr.get_game(gamemgr.selected_game)
if current_game ~= nil then
if current_game.menuicon_path ~= nil and
current_game.menuicon_path ~= "" then
retval = retval ..
"image[6.5,5.5;2,2;" ..
core.formspec_escape(current_game.menuicon_path) .. "]"
end
retval = retval ..
"field[9,5.5;6,2;;" .. current_game.name .. ";]"..
"label[6.5,7.2;" .. fgettext("Mods:") .."]" ..
"button[6.5,11.4;3.2,0.2;btn_game_mgr_edit_game;" .. fgettext("edit game") .. "]" ..
"textlist[6.5,7.7;8,3.3;game_mgr_modlist;"
.. gamemgr.get_game_modlist(current_game) ..";0]" ..
"button[6.5,4.9;3.2,0.5;btn_game_mgr_new_game;" .. fgettext("new game") .. "]"
end
return retval
end
--------------------------------------------------------------------------------
function gamemgr.dialog_edit_game()
local current_game = gamemgr.get_game(gamemgr.selected_game)
if current_game ~= nil then
local retval =
"vertlabel[0,-0.25;" .. fgettext("EDIT GAME") .."]" ..
"label[0,-0.25;" .. current_game.name .. "]" ..
"button[11.55,-0.2;0.75,0.5;btn_close_edit_game;x]"
if current_game.menuicon_path ~= nil and
current_game.menuicon_path ~= "" then
retval = retval ..
"image[5.25,0;2,2;" ..
core.formspec_escape(current_game.menuicon_path) .. "]"
end
retval = retval ..
"textlist[0.5,0.5;4.5,4.3;mods_current;"
.. gamemgr.get_game_modlist(current_game) ..";0]"
retval = retval ..
"textlist[7,0.5;4.5,4.3;mods_available;"
.. modmgr.render_modlist() .. ";0]"
retval = retval ..
"button[0.55,4.95;4.7,0.5;btn_remove_mod_from_game;" .. fgettext("Remove selected mod") .."]"
retval = retval ..
"button[7.05,4.95;4.7,0.5;btn_add_mod_to_game;" .. fgettext("<<-- Add mod") .."]"
return retval
end
end
--------------------------------------------------------------------------------
function gamemgr.handle_buttons(tab,fields)
local retval = nil
if tab == "dialog_edit_game" then
retval = gamemgr.handle_edit_game_buttons(fields)
end
if tab == "dialog_new_game" then
retval = gamemgr.handle_new_game_buttons(fields)
end
if tab == "game_mgr" then
retval = gamemgr.handle_games_buttons(fields)
end
return retval
end
--------------------------------------------------------------------------------
function gamemgr.get_game(index)
if index > 0 and index <= #gamemgr.games then
return gamemgr.games[index]
end
return nil
end
--------------------------------------------------------------------------------
function gamemgr.update_gamelist()
gamemgr.games = core.get_games()
end
--------------------------------------------------------------------------------
function gamemgr.gamelist()
local retval = ""
if #gamemgr.games > 0 then
retval = retval .. gamemgr.games[1].name
for i=2,#gamemgr.games,1 do
retval = retval .. "," .. gamemgr.games[i].name
end
end
return retval
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -41,10 +41,12 @@ dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
dofile(menupath .. DIR_DELIM .. "tab_credits.lua") dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
dofile(menupath .. DIR_DELIM .. "tab_mods.lua") dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
dofile(menupath .. DIR_DELIM .. "tab_settings.lua") dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
dofile(menupath .. DIR_DELIM .. "tab_help.lua")
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua") dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua") dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua") dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
dofile(menupath .. DIR_DELIM .. "dlg_add_server.lua")
dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua") dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
dofile(menupath .. DIR_DELIM .. "tab_server.lua") dofile(menupath .. DIR_DELIM .. "tab_server.lua")
dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua") dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
@ -56,42 +58,38 @@ local function main_event_handler(tabview, event)
if event == "MenuQuit" then if event == "MenuQuit" then
core.close() core.close()
end end
return true return true
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function get_formspec2(tabview, name, tabdata) local function get_formspec2(tabview, name, tabdata)
local retval = 'size[12,5.2,false]' local retval = ""
retval = retval .. "bgcolor[#00000000;true]" retval = retval .. "bgcolor[#00000000;false]"
retval = retval .. "image_button[2.5,3.4;7,1;"..multicraft.formspec_escape(mm_texture.basetexturedir) .. "menu_button.png;btn_show_multiplayer;" .. fgettext("Multiplayer") .. ";true;true;" .. multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]" retval = retval .. "image_button[2.5,3.4;7,1;"..minetest.formspec_escape(mm_texture.basetexturedir) .. "menu_button.png;btn_show_multiplayer;" .. fgettext("Multiplayer") .. ";true;true;" .. minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
retval = retval .. "image_button[2.5,4.8;7,1;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_options;".. fgettext("Options") .. ";true;true;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]" retval = retval .. "image_button[2.5,4.8;6,1;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_options;".. fgettext("Options") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
--retval = retval .. "image_button[8.5,4.8;1,1;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_help;?;true;true;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]" retval = retval .. "image_button[8.5,4.8;1,1;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_help;?;true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
retval = retval .. "image_button[2.5,6.2;7,1;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_exit;".. fgettext("Exit") .. ";true;true;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]" retval = retval .. "image_button[2.5,6.2;7,1;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_exit;".. fgettext("Exit") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
retval = retval .. "image_button[2.5,2.0;7,1;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_singleplayer;".. fgettext("Singleplayer") .. ";true;true;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]" retval = retval .. "image_button[2.5,2.0;7,1;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_singleplayer;".. fgettext("Singleplayer") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
local si = core.get_screen_info() local si = core.get_screen_info()
local ydiv = si.window_height/5.2 local ydiv = si.window_height/5.2
local xdiv = si.window_width/12.5 local xdiv = si.window_width/12.5
local ratio = xdiv/ydiv local ratio = xdiv/ydiv
print('Width: '..si.window_width) --print(xdiv..' x '..ydiv..' = '..ratio)
print('Height: '..si.window_height)
print(xdiv..' x '..ydiv..' = '..ratio) math.randomseed(os.time())
--math.randomseed(os.time()) local rnd = 'image['.. 12*ratio ..','.. 1 .. ';6,0.5;'..minetest.formspec_escape(mm_texture.basetexturedir)..'ad_label'..tostring(math.random(1,14))..'.png]'
print('Chosen font size: '.. math.floor(si.window_width/53.33)+0.5)
core.setting_set('font_size', tostring(math.floor(si.window_width/53.33)+0.5)) return retval .. rnd
--local rnd = 'image['.. 12*ratio ..','.. 1 .. ';6,0.5;'..multicraft.formspec_escape(mm_texture.basetexturedir)..'ad_label'..tostring(math.random(1,14))..'.png]'
print('----')
print(retval)
print('----')
return retval --.. rnd
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function main_button_handler2(tabview, fields, name, tabdata) local function main_button_handler2(tabview, fields, name, tabdata)
local index = '' local index = ''
if fields["btn_show_singleplayer"] then index = "singleplayer" end if fields["btn_show_singleplayer"] then index = "server" end
if fields["btn_show_multiplayer"] then index = "multiplayer" end if fields["btn_show_multiplayer"] then index = "multiplayer" end
if fields["btn_show_options"] then index = "settings" end if fields["btn_show_options"] then index = "settings" end
if fields["btn_show_help"] then index = "help" end if fields["btn_show_help"] then index = "help" end
@ -99,19 +97,17 @@ local function main_button_handler2(tabview, fields, name, tabdata)
if index == '' then return end if index == '' then return end
for name,def in pairs(tabview.tablist) do for name,def in pairs(tabview.tablist) do
local fs if index == def.name then
if index == 'singleplayer' then local get_fs = function()
fs = create_tab_single(true) local retval = def.get_formspec(tabview, name, tabdata)
elseif index == 'multiplayer' then retval = 'size[12,5.2]'..retval
fs = create_tab_multiplayer() return retval
elseif index == 'settings' then
fs = create_tab_settings(true)
end end
if fs then local dlg = dialog_create(def.name, get_fs, def.button_handler, def.on_change)
fs:set_parent(tabview.parent or tabview) dlg:set_parent(tabview)
tabview:hide() tabview:hide()
fs:show() dlg:show()
return true return dlg
end end
end end
return false return false
@ -130,8 +126,8 @@ local function on_activate2(type,old_tab,new_tab)
mm_texture.clear("header") mm_texture.clear("header")
mm_texture.clear("footer") mm_texture.clear("footer")
core.set_clouds(false) core.set_clouds(false)
core.set_background("background",multicraft.formspec_escape(mm_texture.basetexturedir)..'background.png') core.set_background("background",minetest.formspec_escape(mm_texture.basetexturedir)..'background.png')
core.set_background("header",multicraft.formspec_escape(mm_texture.basetexturedir)..'header.png') core.set_background("header",minetest.formspec_escape(mm_texture.basetexturedir)..'header.png')
end end
@ -175,8 +171,10 @@ local function init_globals()
-- Create main tabview -- Create main tabview
local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=-1,y=0}) local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=0,y=0})
tv_main:set_autosave_tab(false) tv_main:set_autosave_tab(false)
--tv_main:add(tab_simple_main)
tv_main:add(tab_main) tv_main:add(tab_main)
tv_main:add(tab_singleplayer) tv_main:add(tab_singleplayer)
tv_main:add(tab_multiplayer) tv_main:add(tab_multiplayer)
@ -184,10 +182,13 @@ local function init_globals()
tv_main:add(tab_settings) tv_main:add(tab_settings)
tv_main:add(tab_texturepacks) tv_main:add(tab_texturepacks)
tv_main:add(tab_mods) tv_main:add(tab_mods)
tv_main:add(tab_help)
tv_main:add(tab_credits) tv_main:add(tab_credits)
tv_main:set_global_event_handler(main_event_handler) tv_main:set_global_event_handler(main_event_handler)
tv_main:set_fixed_size(false) tv_main:set_fixed_size(false)
ui.set_default("main") ui.set_default("main")
tv_main:show() tv_main:show()
-- Create modstore ui -- Create modstore ui

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify

View File

@ -1,164 +0,0 @@
--multicraft
--Copyright (C) 2014 sapier
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
mt_color_grey = "#AAAAAA"
mt_color_blue = "#0000DD"
mt_color_green = "#00DD00"
mt_color_dark_green = "#003300"
--for all other colors ask sfan5 to complete his work!
local menupath = core.get_mainmenu_path()
local basepath = core.get_builtin_path()
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM
dofile(basepath .. DIR_DELIM .. "common" .. DIR_DELIM .. "async_event.lua")
dofile(basepath .. DIR_DELIM .. "common" .. DIR_DELIM .. "filterlist.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "buttonbar.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "dialog.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "tabview.lua")
dofile(basepath .. DIR_DELIM .. "fstk" .. DIR_DELIM .. "ui.lua")
dofile(menupath .. DIR_DELIM .. "common.lua")
dofile(menupath .. DIR_DELIM .. "gamemgr.lua")
dofile(menupath .. DIR_DELIM .. "modmgr.lua")
dofile(menupath .. DIR_DELIM .. "store.lua")
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
dofile(menupath .. DIR_DELIM .. "tab_mods.lua")
dofile(menupath .. DIR_DELIM .. "tab_settings.lua")
--if PLATFORM ~= "Android" then
dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_mod.lua")
dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
dofile(menupath .. DIR_DELIM .. "tab_server.lua")
dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
dofile(menupath .. DIR_DELIM .. "textures.lua")
--else
-- dofile(menupath .. DIR_DELIM .. "tab_simple_main.lua")
--end
--------------------------------------------------------------------------------
local function main_event_handler(tabview, event)
if event == "MenuQuit" then
core.close()
end
return true
end
--------------------------------------------------------------------------------
local function init_globals()
-- Init gamedata
gamedata.worldindex = 0
if PLATFORM ~= "Android" then
menudata.worldlist = filterlist.create(
core.get_worlds,
compare_worlds,
-- Unique id comparison function
function(element, uid)
return element.name == uid
end,
-- Filter function
function(element, gameid)
return element.gameid == gameid
end
)
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
menudata.worldlist:set_sortmode("alphabetic")
if not core.setting_get("menu_last_game") then
local default_game = core.setting_get("default_game") or "multicraft"
core.setting_set("menu_last_game", default_game )
end
mm_texture.init()
else
local world_list = core.get_worlds()
local found_singleplayerworld = false
for i,world in pairs(world_list) do
if world.name == "singleplayerworld" then
found_singleplayerworld = true
gamedata.worldindex = i
break
end
end
if not found_singleplayerworld then
core.create_world("singleplayerworld", 1)
local world_list = core.get_worlds()
for i,world in pairs(world_list) do
if world.name == "singleplayerworld" then
gamedata.worldindex = i
break
end
end
end
end
-- Create main tabview
local tv_main = tabview_create("maintab",{x=12,y=5.2},{x=0,y=0})
if PLATFORM ~= "Android" then
tv_main:set_autosave_tab(true)
end
if PLATFORM ~= "Android" then
tv_main:add(tab_singleplayer)
tv_main:add(tab_multiplayer)
tv_main:add(tab_server)
else
tv_main:add(tab_simple_main)
end
tv_main:add(tab_settings)
if PLATFORM ~= "Android" then
tv_main:add(tab_texturepacks)
end
tv_main:add(tab_mods)
tv_main:add(tab_credits)
tv_main:set_global_event_handler(main_event_handler)
tv_main:set_fixed_size(false)
if not (PLATFORM == "Android") then
tv_main:set_tab(core.setting_get("maintab_LAST"))
end
ui.set_default("maintab")
tv_main:show()
-- Create modstore ui
if PLATFORM == "Android" then
modstore.init({x=12, y=6}, 3, 2)
else
modstore.init({x=12, y=8}, 4, 3)
end
ui.update()
core.sound_play("main_menu", true)
end
init_globals()

View File

@ -0,0 +1,80 @@
--Minetest
--Copyright (C) 2013 sapier
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
menubar = {}
--------------------------------------------------------------------------------
function menubar.handle_buttons(fields)
for i=1,#menubar.buttons,1 do
if fields[menubar.buttons[i].btn_name] ~= nil then
menu.last_game = menubar.buttons[i].index
core.setting_set("main_menu_last_game_idx",menu.last_game)
menu.update_gametype()
end
end
end
--------------------------------------------------------------------------------
function menubar.refresh()
menubar.formspec = "box[-0.3,5.625;12.4,1.2;#000000]" ..
"box[-0.3,5.6;12.4,0.05;#FFFFFF]"
menubar.buttons = {}
local button_base = -0.08
local maxbuttons = #gamemgr.games
if maxbuttons > 11 then
maxbuttons = 11
end
for i=1,maxbuttons,1 do
local btn_name = "menubar_btn_" .. gamemgr.games[i].id
local buttonpos = button_base + (i-1) * 1.1
if gamemgr.games[i].menuicon_path ~= nil and
gamemgr.games[i].menuicon_path ~= "" then
menubar.formspec = menubar.formspec ..
"image_button[" .. buttonpos .. ",11.2;1.165,1.175;" ..
core.formspec_escape(gamemgr.games[i].menuicon_path) .. ";" ..
btn_name .. ";;true;false]"
else
local part1 = gamemgr.games[i].id:sub(1,5)
local part2 = gamemgr.games[i].id:sub(6,10)
local part3 = gamemgr.games[i].id:sub(11)
local text = part1 .. "\n" .. part2
if part3 ~= nil and
part3 ~= "" then
text = text .. "\n" .. part3
end
menubar.formspec = menubar.formspec ..
"image_button[" .. buttonpos .. ",5.72;1.165,1.175;;" ..btn_name ..
";" .. text .. ";true;true]"
end
local toadd = {
btn_name = btn_name,
index = i,
}
table.insert(menubar.buttons,toadd)
end
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -195,16 +195,16 @@ function modmgr.identify_modname(modpath,filename)
while line~= nil do while line~= nil do
local modname = nil local modname = nil
if line:find("multicraft.register_tool") then if line:find("minetest.register_tool") then
modname = modmgr.parse_register_line(line) modname = modmgr.parse_register_line(line)
end end
if line:find("multicraft.register_craftitem") then if line:find("minetest.register_craftitem") then
modname = modmgr.parse_register_line(line) modname = modmgr.parse_register_line(line)
end end
if line:find("multicraft.register_node") then if line:find("minetest.register_node") then
modname = modmgr.parse_register_line(line) modname = modmgr.parse_register_line(line)
end end
@ -321,10 +321,8 @@ function modmgr.get_worldconfig(worldpath)
for key,value in pairs(worldfile:to_table()) do for key,value in pairs(worldfile:to_table()) do
if key == "gameid" then if key == "gameid" then
worldconfig.id = value worldconfig.id = value
elseif key:sub(0, 9) == "load_mod_" then
worldconfig.global_mods[key] = core.is_yes(value)
else else
worldconfig[key] = value worldconfig.global_mods[key] = core.is_yes(value)
end end
end end

View File

@ -0,0 +1,615 @@
--Minetest
--Copyright (C) 2013 sapier
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--------------------------------------------------------------------------------
--modstore implementation
modstore = {}
--------------------------------------------------------------------------------
-- @function [parent=#modstore] init
function modstore.init()
modstore.tabnames = {}
table.insert(modstore.tabnames,"dialog_modstore_unsorted")
table.insert(modstore.tabnames,"dialog_modstore_search")
modstore.modsperpage = 5
modstore.basetexturedir = core.get_texturepath() .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM
modstore.lastmodtitle = ""
modstore.last_search = ""
modstore.searchlist = filterlist.create(
function()
if modstore.modlist_unsorted ~= nil and
modstore.modlist_unsorted.data ~= nil then
return modstore.modlist_unsorted.data
end
return {}
end,
function(element,modid)
if element.id == modid then
return true
end
return false
end, --compare fct
nil, --uid match fct
function(element,substring)
if substring == nil or
substring == "" then
return false
end
substring = substring:upper()
if element.title ~= nil and
element.title:upper():find(substring) ~= nil then
return true
end
if element.details ~= nil and
element.details.author ~= nil and
element.details.author:upper():find(substring) ~= nil then
return true
end
if element.details ~= nil and
element.details.description ~= nil and
element.details.description:upper():find(substring) ~= nil then
return true
end
return false
end --filter fct
)
modstore.current_list = nil
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] nametoindex
function modstore.nametoindex(name)
for i=1,#modstore.tabnames,1 do
if modstore.tabnames[i] == name then
return i
end
end
return 1
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] getsuccessfuldialog
function modstore.getsuccessfuldialog()
local retval = ""
retval = retval .. "size[6,2,true]"
if modstore.lastmodentry ~= nil then
retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]"
retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]"
retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]"
retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]"
end
retval = retval .. "button[2.5,1.5;1,0.5;btn_confirm_mod_successfull;" .. fgettext("ok") .. "]"
return retval
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] gettab
function modstore.gettab(tabname)
local retval = ""
local is_modstore_tab = false
if tabname == "dialog_modstore_unsorted" then
modstore.modsperpage = 5
retval = modstore.getmodlist(modstore.modlist_unsorted)
is_modstore_tab = true
end
if tabname == "dialog_modstore_search" then
retval = modstore.getsearchpage()
is_modstore_tab = true
end
if is_modstore_tab then
return modstore.tabheader(tabname) .. retval
end
if tabname == "modstore_mod_installed" then
return modstore.getsuccessfuldialog()
end
if tabname == "modstore_downloading" then
return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") ..
" " .. modstore.lastmodtitle .. " " ..
fgettext("please wait...") .. "]"
end
return ""
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] tabheader
function modstore.tabheader(tabname)
local retval = "size[12,10.25,true]"
retval = retval .. "tabheader[-0.3,-0.99;modstore_tab;" ..
"Unsorted,Search;" ..
modstore.nametoindex(tabname) .. ";true;false]" ..
"button[4,9.9;4,0.5;btn_modstore_close;" ..
fgettext("Close modstore") .. "]"
return retval
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] handle_buttons
function modstore.handle_buttons(current_tab,fields)
if fields["modstore_tab"] then
local index = tonumber(fields["modstore_tab"])
if index > 0 and
index <= #modstore.tabnames then
if modstore.tabnames[index] == "dialog_modstore_search" then
filterlist.set_filtercriteria(modstore.searchlist,modstore.last_search)
filterlist.refresh(modstore.searchlist)
modstore.modsperpage = 4
modstore.currentlist = {
page = 0,
pagecount =
math.ceil(filterlist.size(modstore.searchlist) / modstore.modsperpage),
data = filterlist.get_list(modstore.searchlist),
}
end
return {
current_tab = modstore.tabnames[index],
is_dialog = true,
show_buttons = false
}
end
end
if fields["btn_modstore_page_up"] then
if modstore.current_list ~= nil and modstore.current_list.page > 0 then
modstore.current_list.page = modstore.current_list.page - 1
end
end
if fields["btn_modstore_page_down"] then
if modstore.current_list ~= nil and
modstore.current_list.page <modstore.current_list.pagecount-1 then
modstore.current_list.page = modstore.current_list.page +1
end
end
if fields["btn_hidden_close_download"] ~= nil then
if fields["btn_hidden_close_download"].successfull then
modstore.lastmodentry = fields["btn_hidden_close_download"]
return {
current_tab = "modstore_mod_installed",
is_dialog = true,
show_buttons = false
}
else
modstore.lastmodtitle = ""
return {
current_tab = modstore.tabnames[1],
is_dialog = true,
show_buttons = false
}
end
end
if fields["btn_confirm_mod_successfull"] then
modstore.lastmodentry = nil
modstore.lastmodtitle = ""
return {
current_tab = modstore.tabnames[1],
is_dialog = true,
show_buttons = false
}
end
if fields["btn_modstore_search"] or
(fields["key_enter"] and fields["te_modstore_search"] ~= nil) then
modstore.last_search = fields["te_modstore_search"]
filterlist.set_filtercriteria(modstore.searchlist,fields["te_modstore_search"])
filterlist.refresh(modstore.searchlist)
modstore.currentlist = {
page = 0,
pagecount = math.ceil(filterlist.size(modstore.searchlist) / modstore.modsperpage),
data = filterlist.get_list(modstore.searchlist),
}
end
if fields["btn_modstore_close"] then
return {
is_dialog = false,
show_buttons = true,
current_tab = core.setting_get("main_menu_tab")
}
end
for key,value in pairs(fields) do
local foundat = key:find("btn_install_mod_")
if ( foundat == 1) then
local modid = tonumber(key:sub(17))
for i=1,#modstore.modlist_unsorted.data,1 do
if modstore.modlist_unsorted.data[i].id == modid then
local moddetails = modstore.modlist_unsorted.data[i].details
if modstore.lastmodtitle ~= "" then
modstore.lastmodtitle = modstore.lastmodtitle .. ", "
end
modstore.lastmodtitle = modstore.lastmodtitle .. moddetails.title
core.handle_async(
function(param)
local fullurl = core.setting_get("modstore_download_url") ..
param.moddetails.download_url
if param.version ~= nil then
local found = false
for i=1,#param.moddetails.versions, 1 do
if param.moddetails.versions[i].date:sub(1,10) == param.version then
fullurl = core.setting_get("modstore_download_url") ..
param.moddetails.versions[i].download_url
found = true
end
end
if not found then
return {
moddetails = param.moddetails,
successfull = false
}
end
end
if core.download_file(fullurl,param.filename) then
return {
texturename = param.texturename,
moddetails = param.moddetails,
filename = param.filename,
successfull = true
}
else
return {
moddetails = param.moddetails,
successfull = false
}
end
end,
{
moddetails = moddetails,
version = fields["dd_version" .. modid],
filename = os.tempfolder() .. "_MODNAME_" .. moddetails.basename .. ".zip",
texturename = modstore.modlist_unsorted.data[i].texturename
},
function(result)
if result.successfull then
modmgr.installmod(result.filename,result.moddetails.basename)
os.remove(result.filename)
else
gamedata.errormessage = "Failed to download " .. result.moddetails.title
end
if gamedata.errormessage == nil then
core.button_handler({btn_hidden_close_download=result})
else
core.button_handler({btn_hidden_close_download={successfull=false}})
end
end
)
return {
current_tab = "modstore_downloading",
is_dialog = true,
show_buttons = false,
ignore_menu_quit = true
}
end
end
break
end
end
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] update_modlist
function modstore.update_modlist()
modstore.modlist_unsorted = {}
modstore.modlist_unsorted.data = {}
modstore.modlist_unsorted.pagecount = 1
modstore.modlist_unsorted.page = 0
core.handle_async(
function(param)
return core.get_modstore_list()
end,
nil,
function(result)
if result ~= nil then
modstore.modlist_unsorted = {}
modstore.modlist_unsorted.data = result
if modstore.modlist_unsorted.data ~= nil then
modstore.modlist_unsorted.pagecount =
math.ceil((#modstore.modlist_unsorted.data / modstore.modsperpage))
else
modstore.modlist_unsorted.data = {}
modstore.modlist_unsorted.pagecount = 1
end
modstore.modlist_unsorted.page = 0
modstore.fetchdetails()
core.event_handler("Refresh")
end
end
)
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] fetchdetails
function modstore.fetchdetails()
for i=1,#modstore.modlist_unsorted.data,1 do
core.handle_async(
function(param)
param.details = core.get_modstore_details(tostring(param.modid))
return param
end,
{
modid=modstore.modlist_unsorted.data[i].id,
listindex=i
},
function(result)
if result ~= nil and
modstore.modlist_unsorted ~= nil
and modstore.modlist_unsorted.data ~= nil and
modstore.modlist_unsorted.data[result.listindex] ~= nil and
modstore.modlist_unsorted.data[result.listindex].id ~= nil then
modstore.modlist_unsorted.data[result.listindex].details = result.details
core.event_handler("Refresh")
end
end
)
end
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] getscreenshot
function modstore.getscreenshot(ypos,listentry)
if listentry.details ~= nil and
(listentry.details.screenshot_url == nil or
listentry.details.screenshot_url == "") then
if listentry.texturename == nil then
listentry.texturename = modstore.basetexturedir .. "no_screenshot.png"
end
return "image[0,".. ypos .. ";3,2;" ..
core.formspec_escape(listentry.texturename) .. "]"
end
if listentry.details ~= nil and
listentry.texturename == nil then
--make sure we don't download multiple times
listentry.texturename = "in progress"
--prepare url and filename
local fullurl = core.setting_get("modstore_download_url") ..
listentry.details.screenshot_url
local filename = os.tempfolder() .. "_MID_" .. listentry.id
--trigger download
core.handle_async(
--first param is downloadfct
function(param)
param.successfull = core.download_file(param.fullurl,param.filename)
return param
end,
--second parameter is data passed to async job
{
fullurl = fullurl,
filename = filename,
modid = listentry.id
},
--integrate result to raw list
function(result)
if result.successfull then
local found = false
for i=1,#modstore.modlist_unsorted.data,1 do
if modstore.modlist_unsorted.data[i].id == result.modid then
found = true
modstore.modlist_unsorted.data[i].texturename = result.filename
break
end
end
if found then
core.event_handler("Refresh")
else
core.log("error","got screenshot but didn't find matching mod: " .. result.modid)
end
end
end
)
end
if listentry.texturename ~= nil and
listentry.texturename ~= "in progress" then
return "image[0,".. ypos .. ";3,2;" ..
core.formspec_escape(listentry.texturename) .. "]"
end
return ""
end
--------------------------------------------------------------------------------
--@function [parent=#modstore] getshortmodinfo
function modstore.getshortmodinfo(ypos,listentry,details)
local retval = ""
retval = retval .. "box[0," .. ypos .. ";11.4,1.75;#FFFFFF]"
--screenshot
retval = retval .. modstore.getscreenshot(ypos,listentry)
--title + author
retval = retval .."label[2.75," .. ypos .. ";" ..
core.formspec_escape(details.title) .. " (" .. details.author .. ")]"
--description
local descriptiony = ypos + 0.5
retval = retval .. "textarea[3," .. descriptiony .. ";6.5,1.55;;" ..
core.formspec_escape(details.description) .. ";]"
--rating
local ratingy = ypos
retval = retval .."label[7," .. ratingy .. ";" ..
fgettext("Rating") .. ":]"
retval = retval .. "label[8.7," .. ratingy .. ";" .. details.rating .."]"
--versions (IMPORTANT has to be defined AFTER rating)
if details.versions ~= nil and
#details.versions > 1 then
local versiony = ypos + 0.05
retval = retval .. "dropdown[9.1," .. versiony .. ";2.48,0.25;dd_version" .. details.id .. ";"
local versions = ""
for i=1,#details.versions , 1 do
if versions ~= "" then
versions = versions .. ","
end
versions = versions .. details.versions[i].date:sub(1,10)
end
retval = retval .. versions .. ";1]"
end
if details.basename then
--install button
local buttony = ypos + 1.2
retval = retval .."button[9.1," .. buttony .. ";2.5,0.5;btn_install_mod_" .. details.id .. ";"
if modmgr.mod_exists(details.basename) then
retval = retval .. fgettext("re-Install") .."]"
else
retval = retval .. fgettext("Install") .."]"
end
end
return retval
end
--------------------------------------------------------------------------------
--@function [parent=#modstore] getmodlist
function modstore.getmodlist(list,yoffset)
modstore.current_list = list
if #list.data == 0 then
return ""
end
if yoffset == nil then
yoffset = 0
end
local scrollbar = ""
scrollbar = scrollbar .. "label[0.1,9.5;"
.. fgettext("Page $1 of $2", list.page+1, list.pagecount) .. "]"
scrollbar = scrollbar .. "box[11.6," .. (yoffset + 0.35) .. ";0.28,"
.. (8.6 - yoffset) .. ";#000000]"
local scrollbarpos = (yoffset + 0.75) +
((7.7 -yoffset)/(list.pagecount-1)) * list.page
scrollbar = scrollbar .. "box[11.6," ..scrollbarpos .. ";0.28,0.5;#32CD32]"
scrollbar = scrollbar .. "button[11.6," .. (yoffset + (0.3))
.. ";0.5,0.5;btn_modstore_page_up;^]"
scrollbar = scrollbar .. "button[11.6," .. 9.0
.. ";0.5,0.5;btn_modstore_page_down;v]"
local retval = ""
local endmod = (list.page * modstore.modsperpage) + modstore.modsperpage
if (endmod > #list.data) then
endmod = #list.data
end
for i=(list.page * modstore.modsperpage) +1, endmod, 1 do
--getmoddetails
local details = list.data[i].details
if details == nil then
details = {}
details.title = list.data[i].title
details.author = ""
details.rating = -1
details.description = ""
end
if details ~= nil then
local screenshot_ypos =
yoffset +(i-1 - (list.page * modstore.modsperpage))*1.9 +0.2
retval = retval .. modstore.getshortmodinfo(screenshot_ypos,
list.data[i],
details)
end
end
return retval .. scrollbar
end
--------------------------------------------------------------------------------
--@function [parent=#modstore] getsearchpage
function modstore.getsearchpage()
local retval = ""
local search = ""
if modstore.last_search ~= nil then
search = modstore.last_search
end
retval = retval ..
"button[9.5,0.2;2.5,0.5;btn_modstore_search;".. fgettext("Search") .. "]" ..
"field[0.5,0.5;9,0.5;te_modstore_search;;" .. search .. "]"
--show 4 mods only
modstore.modsperpage = 4
retval = retval ..
modstore.getmodlist(
modstore.currentlist,
1.75)
return retval;
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -122,36 +122,35 @@ end
function modstore.showdownloading(title) function modstore.showdownloading(title)
local new_dlg = dialog_create("store_downloading", local new_dlg = dialog_create("store_downloading",
function(data) function(data)
return "size[6,2]label[0.25,0.75;" .. return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") ..
fgettext("Downloading $1, please wait...", data.title) .. "]" " " .. data.title .. " " ..
fgettext("please wait...") .. "]"
end, end,
function(this,fields) function(this,fields)
if fields["btn_hidden_close_download"] ~= nil then if fields["btn_hidden_close_download"] ~= nil then
if fields["btn_hidden_close_download"].successfull then if fields["btn_hidden_close_download"].successfull then
modstore.lastmodentry = fields["btn_hidden_close_download"] modstore.lastmodentry = fields["btn_hidden_close_download"]
modstore.successfulldialog(this) modstore.successfulldialog()
else else
this.parent:show()
this:delete()
modstore.lastmodtitle = "" modstore.lastmodtitle = ""
end end
this:delete()
return true return true
end end
return false return false
end, end,
nil) nil,
modstore.tv_store)
new_dlg:set_parent(modstore.tv_store)
modstore.tv_store:hide()
new_dlg.data.title = title new_dlg.data.title = title
new_dlg:show() new_dlg:show()
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- @function [parent=#modstore] successfulldialog -- @function [parent=#modstore] successfulldialog
function modstore.successfulldialog(downloading_dlg) function modstore.successfulldialog()
local new_dlg = dialog_create("store_downloading", local new_dlg = dialog_create("store_downloading",
function(data) function(data)
local retval = "" local retval = ""
@ -159,16 +158,18 @@ function modstore.successfulldialog(downloading_dlg)
if modstore.lastmodentry ~= nil then if modstore.lastmodentry ~= nil then
retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]" retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]"
retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]" retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]"
retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]" retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]"
retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]" retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]"
end end
retval = retval .. "image_button[2.2,1.5;1.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_confirm_mod_successfull;" .. fgettext("Ok") .. "]" retval = retval .. "image_button[2.5,1.5;1,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_confirm_mod_successfull;" .. fgettext("ok") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
return retval
end, end,
function(this,fields) function(this,fields)
if fields["btn_confirm_mod_successfull"] ~= nil then if fields["btn_confirm_mod_successfull"] ~= nil then
this.parent:show() this.parent:show()
downloading_dlg:delete() this:hide()
this:delete() this:delete()
return true return true
@ -176,10 +177,10 @@ function modstore.successfulldialog(downloading_dlg)
return false return false
end, end,
nil) nil,
modstore.tv_store)
new_dlg:set_parent(modstore.tv_store) new_dlg.data.title = title
modstore.tv_store:hide()
new_dlg:show() new_dlg:show()
end end
@ -216,9 +217,7 @@ function modstore.handle_buttons(parent, fields, name, data)
end end
if fields["btn_modstore_close"] then if fields["btn_modstore_close"] then
local maintab = ui.find_by_name("maintab")
parent:hide() parent:hide()
maintab:show()
return true return true
end end
@ -229,7 +228,12 @@ function modstore.handle_buttons(parent, fields, name, data)
for i=1,#modstore.modlist_unsorted.data,1 do for i=1,#modstore.modlist_unsorted.data,1 do
if modstore.modlist_unsorted.data[i].id == modid then if modstore.modlist_unsorted.data[i].id == modid then
local moddetails = modstore.modlist_unsorted.data[i].details local moddetails = modstore.modlist_unsorted.data[i].details
modstore.lastmodtitle = moddetails.title
if modstore.lastmodtitle ~= "" then
modstore.lastmodtitle = modstore.lastmodtitle .. ", "
end
modstore.lastmodtitle = modstore.lastmodtitle .. moddetails.title
if not core.handle_async( if not core.handle_async(
function(param) function(param)
@ -277,7 +281,7 @@ function modstore.handle_buttons(parent, fields, name, data)
texturename = modstore.modlist_unsorted.data[i].texturename texturename = modstore.modlist_unsorted.data[i].texturename
}, },
function(result) function(result)
--print("Result from async: " .. dump(result.successfull)) print("Result from async: " .. dump(result.successfull))
if result.successfull then if result.successfull then
modmgr.installmod(result.filename,result.moddetails.basename) modmgr.installmod(result.filename,result.moddetails.basename)
os.remove(result.filename) os.remove(result.filename)
@ -295,7 +299,7 @@ function modstore.handle_buttons(parent, fields, name, data)
print("ERROR: async event failed") print("ERROR: async event failed")
gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle
end end
parent:hide()
modstore.showdownloading(modstore.lastmodtitle) modstore.showdownloading(modstore.lastmodtitle)
return true return true
end end
@ -387,7 +391,7 @@ function modstore.getscreenshot(ypos,listentry)
listentry.details.screenshot_url == "") then listentry.details.screenshot_url == "") then
if listentry.texturename == nil then if listentry.texturename == nil then
listentry.texturename = defaulttexturedir .. "no_screenshot.png" listentry.texturename = modstore.basetexturedir .. "no_screenshot.png"
end end
return "image[0,".. ypos .. ";3,2;" .. return "image[0,".. ypos .. ";3,2;" ..
@ -491,12 +495,12 @@ function modstore.getshortmodinfo(ypos,listentry,details)
if details.basename then if details.basename then
--install button --install button
local buttony = ypos + 1.2 local buttony = ypos + 1.2
retval = retval .."image_button[9.1," .. buttony .. ";2.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_install_mod_" .. details.id .. ";" retval = retval .."image_button[9.1," .. buttony .. ";2.5,0.5;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_install_mod_" .. details.id .. ";"
if modmgr.mod_exists(details.basename) then if modmgr.mod_exists(details.basename) then
retval = retval .. fgettext("re-Install") .."]" retval = retval .. fgettext("re-Install") ..";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
else else
retval = retval .. fgettext("Install") .."]" retval = retval .. fgettext("Install") ..";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
end end
end end
@ -515,7 +519,7 @@ function modstore.getmodlist(list,yoffset)
local sb_y_start = 0.2 + yoffset local sb_y_start = 0.2 + yoffset
local sb_y_end = (modstore.modsperpage * 1.75) + ((modstore.modsperpage-1) * 0.15) local sb_y_end = (modstore.modsperpage * 1.75) + ((modstore.modsperpage-1) * 0.15)
local close_button = "image_button[4," .. (sb_y_end + 0.3 + yoffset) .. local close_button = "image_button[4," .. (sb_y_end + 0.3 + yoffset) ..
";4,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_close;" .. fgettext("Close store") .. "]" ";4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_close;" .. fgettext("Close store") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
if #list.data == 0 then if #list.data == 0 then
return close_button return close_button
@ -529,9 +533,9 @@ function modstore.getmodlist(list,yoffset)
((sb_y_end -1.6)/(list.pagecount-1)) * list.page ((sb_y_end -1.6)/(list.pagecount-1)) * list.page
scrollbar = scrollbar .. "box[11.6," ..scrollbarpos .. ";0.28,0.5;#32CD32]" scrollbar = scrollbar .. "box[11.6," ..scrollbarpos .. ";0.28,0.5;#32CD32]"
scrollbar = scrollbar .. "image_button[11.6," .. (sb_y_start) scrollbar = scrollbar .. "image_button[11.6," .. (sb_y_start)
.. ";0.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_page_up;^]" .. ";0.5,0.5;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_page_up;^;true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
scrollbar = scrollbar .. "image_button[11.6," .. (sb_y_start + sb_y_end - 0.5) scrollbar = scrollbar .. "image_button[11.6," .. (sb_y_start + sb_y_end - 0.5)
.. ";0.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_page_down;v]" .. ";0.5,0.5;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_page_down;v;true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
local retval = "" local retval = ""
@ -577,7 +581,7 @@ function modstore.getsearchpage(tabview, name, tabdata)
end end
retval = retval .. retval = retval ..
"image_button[9.5,0.2;2.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_search;".. fgettext("Search") .. "]" .. "image_button[9.5,0.2;2.5,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore_search;".. fgettext("Search") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"field[0.5,0.5;9,0.5;te_modstore_search;;" .. search .. "]" "field[0.5,0.5;9,0.5;te_modstore_search;;" .. search .. "]"
retval = retval .. retval = retval ..

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -22,33 +22,35 @@ tab_credits = {
caption = fgettext("Credits"), caption = fgettext("Credits"),
cbf_formspec = function (tabview, name, tabdata) cbf_formspec = function (tabview, name, tabdata)
local logofile = defaulttexturedir .. "logo.png" local logofile = defaulttexturedir .. "logo.png"
return "label[0.5,3.2;multicraft " .. core.get_version() .. "]" .. return "size[16,11]"..
"label[0.5,3.5;http://multicraft.net]" .. "bgcolor[#00000070;true]"..
"image[0.5,1;" .. core.formspec_escape(logofile) .. "]" .. "box[-100,8.5;200,10;#999999]" ..
"textlist[3.5,-0.25;8.5,5.8;list_credits;" .. "box[-100,-10;200,12;#999999]" ..
"image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_cancel;".. fgettext("OK") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"label[3.5,9.75;Magichet 1.0 (based on FM " .. core.get_version() .. ")]" ..
"image[0.25,9;2,2;"..core.formspec_escape(logofile).."]"..
"textlist[0,2.0;15.8,6.25;list_credits;" ..
"#FFFF00" .. fgettext("Core Developers") .."," .. "#FFFF00" .. fgettext("Core Developers") .."," ..
" Perttu Ahola (celeron55) <celeron55@gmail.com>,".. " Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
"Ryan Kwolek (kwolekr) <kwolekr@multicraft.net>,".. " Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
"PilzAdam <pilzadam@multicraft.net>," ..
"Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
"Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
"sfan5 <sfan5@live.de>,"..
" kahrl <kahrl@gmx.net>,".. " kahrl <kahrl@gmx.net>,"..
"sapier,".. " proller <proler@gmail.com>,"..
"ShadowNinja <shadowninja@multicraft.net>,".. " PilzAdam <pilzadam@minetest.net>," ..
"Nathanael Courant (Nore/Novatux) <nore@mesecons.net>,".. " ShadowNinja <shadowninja@minetest.net>,"..
"BlockMen,".. " sfan5 <sfan5@live.de>,"..
"Craig Robbins (Zeno),".. " ...,"..
"Loic Blot (nerzhul/nrz),"..
"paramat,"..
",".. ","..
"#FFFF00" .. fgettext("Active Contributors") .. "," .. "#FFFF00" .. fgettext("Active Contributors") .. "," ..
"SmallJoker <mk939@ymail.com>," .. " sapier,"..
"est31 <MTest31@outlook.com>," .. " Craig Robbins (Zeno) <craig.d.robbins@gmail.com>,"..
"gregorycu,".. " kilbith,"..
"Andrew Ward (rubenwardy) <rubenwardy@gmail.com>," .. " paramat,"..
"TriBlade9 <triblade9@mail.com>,".. " ...,"..
"Zefram <zefram@fysh.org>,".. ","..
"#FFFF00" .. fgettext("Magichet Developers") .. "," ..
" 4aiman Konsorumaniakku <4aiman@inbox.ru>,"..
" ...,"..
"," .. "," ..
"#FFFF00" .. fgettext("Previous Contributors") .. "," .. "#FFFF00" .. fgettext("Previous Contributors") .. "," ..
" Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,".. " Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
@ -57,14 +59,22 @@ tab_credits = {
" MirceaKitsune <mirceakitsune@gmail.com>,".. " MirceaKitsune <mirceakitsune@gmail.com>,"..
" dannydark <the_skeleton_of_a_child@yahoo.co.uk>,".. " dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
" 0gb.us <0gb.us@0gb.us>,".. " 0gb.us <0gb.us@0gb.us>,"..
"proller <proler@gmail.com>,".. " Ilya Zhuravlev (xyz) <xyz@minetest.net>,"..
"Ilya Zhuravlev (xyz) <xyz@multicraft.net>,"..
" Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,".. " Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
" Jonathan Neuschafer <j.neuschaefer@gmx.net>,".. " Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
" Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,".. " Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
" Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,".. " Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
" matttpt <matttpt@gmail.com>,".. " matttpt <matttpt@gmail.com>,"..
" JacobF <queatz@gmail.com>,".. " JacobF <queatz@gmail.com>,"..
" ...,"..
";0;true]" ";0;true]"
end,
cbf_button_handler = function(tabview, fields, name, tabdata)
if fields["btn_cancel"] ~= nil then
tabview:hide()
tabview.parent:show()
return true
end
return false
end end
} }

View File

@ -0,0 +1,59 @@
--Minetest
--Copyright (C) 2013 sapier
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--------------------------------------------------------------------------------
tab_help = {
name = "help",
caption = fgettext("Help"),
cbf_formspec = function (tabview, name, tabdata)
local logofile = defaulttexturedir .. "logo.png"
return "size[16,11]"..
"bgcolor[#00000070;true]"..
"box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_cancel;".. fgettext("OK") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"label[3.5,9.75;Magichet 1.0 (based on FM " .. core.get_version() .. ")]" ..
"image[0.25,9;2,2;"..core.formspec_escape(logofile).."]"..
"textlist[0,2;15.8,6.25;list_help;" ..
"#FFFF00How to begin to play (ENG)," ..
" - Press and hold to dig a block,"..
" - Doubletap to place a block,"..
" - To split a stack 'long pess' on it and,"..
" w/o releasing it tap a separate inventory cell,"..
","..
","..
"#FFFF00Как начать играть (RUS)," ..
" - Долгое нажатие = сломать блок,"..
" - Двойное нажатие = поставить блок,"..
" - Для разделения стака на части,"..
" нажмите на стак и удерживая его,"..
" нажмите вторым пальцем на свободной,"..
" ячейке интвентаря"..
";0;true]"
end,
cbf_button_handler = function(tabview, fields, name, tabdata)
if fields["btn_cancel"] ~= nil then
tabview:hide()
tabview.parent:show()
return true
end
return false
end
}

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -35,8 +35,8 @@ local function get_formspec(tabview, name, tabdata)
retval = retval .. retval = retval ..
-- "label[0.8,4.2;" .. fgettext("Add mod:") .. "]" .. -- "label[0.8,4.2;" .. fgettext("Add mod:") .. "]" ..
-- TODO Disabled due to upcoming release 0.4.8 and irrlicht messing up localization -- TODO Disabled due to upcoming release 0.4.8 and irrlicht messing up localization
-- "image_button[0.75,4.85;1.8,0.5;btn_mod_mgr_install_local;".. fgettext("Local install") .. "]" .. -- "button[0.75,4.85;1.8,0.5;btn_mod_mgr_install_local;".. fgettext("Local install") .. "]" ..
"image_button[0,4.85;5.25,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore;".. fgettext("Online mod repository") .. "]" "image_button[0,4.85;5.25,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_modstore;".. fgettext("Online mod repository") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
local selected_mod = nil local selected_mod = nil
@ -57,7 +57,7 @@ local function get_formspec(tabview, name, tabdata)
end end
if modscreenshot == nil then if modscreenshot == nil then
modscreenshot = defaulttexturedir .. "no_screenshot.png" modscreenshot = modstore.basetexturedir .. "no_screenshot.png"
end end
retval = retval retval = retval
@ -89,21 +89,21 @@ local function get_formspec(tabview, name, tabdata)
if selected_mod.is_modpack then if selected_mod.is_modpack then
retval = retval .. ";0]" .. retval = retval .. ";0]" ..
"image_button[10,4.85;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mod_mgr_rename_modpack;" .. "image_button[10,4.85;2,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mod_mgr_rename_modpack;" ..
fgettext("Rename") .. "]" fgettext("Rename") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
retval = retval .. "image_button[5.5,4.85;4.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mod_mgr_delete_mod;" retval = retval .. "image_button[5.5,4.85;4.5,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mod_mgr_delete_mod;"
.. fgettext("Uninstall selected modpack") .. "]" .. fgettext("Uninstall selected modpack") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
else else
--show dependencies --show dependencies
retval = retval .. "," .. fgettext("Depends:") .. "," retval = retval .. ",Depends:,"
local toadd = modmgr.get_dependencies(selected_mod.path) local toadd = modmgr.get_dependencies(selected_mod.path)
retval = retval .. toadd .. ";0]" retval = retval .. toadd .. ";0]"
retval = retval .. "image_button[5.5,4.85;4.5,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mod_mgr_delete_mod;" retval = retval .. "image_button[5.5,4.85;4.5,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mod_mgr_delete_mod;"
.. fgettext("Uninstall selected mod") .. "]" .. fgettext("Uninstall selected mod") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
end end
end end
return retval return retval

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -17,31 +17,46 @@
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function get_formspec(tabview, name, tabdata) local function get_formspec(tabview, name, tabdata)
if not tabdata then tabdata = {} end
local render_details = core.is_yes(core.setting_getbool("public_serverlist"))
local retval = local retval =
"label[7.75,-0.15;" .. fgettext("Address / Port :") .. "]" .. "size[16,11]"..
"label[7.75,1.05;" .. fgettext("Name / Password :") .. "]" .. "box[-100,8.5;200,10;#999999]" ..
"field[8,0.75;3.4,0.5;te_address;;" .. "box[-100,-10;200,12;#999999]" ..
core.formspec_escape(core.setting_get("address")) .. "]" .. "bgcolor[#00000070;true]"..
"field[11.25,0.75;1.3,0.5;te_port;;" ..
core.formspec_escape(core.setting_get("remote_port")) .. "]" ..
"checkbox[0,4.85;cb_public_serverlist;" .. fgettext("Public Serverlist") .. ";" ..
dump(core.setting_getbool("public_serverlist")) .. "]"
if not core.setting_getbool("public_serverlist") then "image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;cancel;".. fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
--"label[0,1.25;" .. fgettext("Address/Port") .. "]" ..
"field[1000.25,5.25;5.5,0.5;te_address;;" ..
core.formspec_escape(core.setting_get("address")) .. "]" ..
"field[1005.75,5.25;2.25,0.5;te_port;;" ..
core.formspec_escape(core.setting_get("remote_port")) .. "]" ..
"checkbox[1000,3.6;cb_public_serverlist;" .. fgettext("Public Serverlist") .. ";" ..
dump(core.setting_getbool("public_serverlist")) .. "]"..
"label[7,1.5;" .. fgettext("Select Server:") .. "]" ..
"label[0,0.25;Address: "..core.formspec_escape(core.setting_get("address")) .. "]" ..
"label[0,0.75;Port: "..core.formspec_escape(core.setting_get("remote_port")) .. "]"
--if not core.setting_getbool("public_serverlist") then
if (core.get_table_index("favourites") or 10000) <= #core.get_favorites("local") then
retval = retval .. retval = retval ..
"image_button[8,4.9;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_delete_favorite;" .. fgettext("Delete") .. "]" "image_button[4,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_delete_favorite;" .. fgettext("Delete") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
else
retval = retval ..
"image_button[4,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;add_server;" .. fgettext("Add") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
end end
retval = retval .. retval = retval ..
"image_button[10,4.9;2,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_connect;" .. fgettext("Connect") .. "]" .. "image_button[8,9.55;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_connect;" .. fgettext("Connect") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"field[8,1.95;2.95,0.5;te_name;;" .. "image_button[3.2,9.55;0.8,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."server_flags_favourite.png;btn_mp_favour;;true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"label[8,8;" .. fgettext("Name") .. ":]" ..
"field[8.3,9;3.95,0.8;te_name;;" ..
core.formspec_escape(core.setting_get("name")) .. "]" .. core.formspec_escape(core.setting_get("name")) .. "]" ..
"pwdfield[10.78,1.95;1.77,0.5;te_pwd;]" .. "label[12,8;" .. fgettext("Password") .. ":]" ..
"box[7.73,2.35;4.3,2.28;#999999]" .. "pwdfield[12.3,9;4,0.8;te_pwd;]" ..
"textarea[8.1,2.4;4.26,2.6;;" "textarea[9.3,0;2.5,3.0;;"
if tabdata.fav_selected ~= nil and if tabdata.fav_selected ~= nil and
menudata.favorites[tabdata.fav_selected] ~= nil and menudata.favorites[tabdata.fav_selected] ~= nil and
@ -54,28 +69,41 @@ if not tabdata then tabdata = {} end
";]" ";]"
--favourites --favourites
if render_details then local function image_column(tooltip, flagname)
local ret = "image," ..
"tooltip=" .. core.formspec_escape(tooltip) .. ","
if flagname ~= 'favourite' then
ret = ret .. "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. ","
else
ret = ret .. "0=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. "_off.png") .. ","
end
ret = ret .. "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
return ret
end
retval = retval .. "tablecolumns[" .. retval = retval .. "tablecolumns[" ..
"color,span=3;" .. "color,span=3;" ..
"text,align=right;" .. -- clients "text,align=right;" .. -- clients
"text,align=center,padding=0.25;" .. -- "/" "text,align=center,padding=0.25;" .. -- "/"
"text,align=right,padding=0.25;" .. -- clients_max "text,align=right,padding=0.25;" .. -- clients_max
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. image_column("Creative mode", "creative") .. ",padding=1;" ..
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
"color,span=1;" .. "text,padding=1]"--..
"text,padding=1]" -- name --image_column("Favourite", "favourite") .. ",align=right]"
else
retval = retval .. "tablecolumns[text]"
end
retval = retval .. retval = retval ..
"table[-0.15,-0.1;7.75,5;favourites;" "tableoptions[background=#00000000;border=false]"..
"table[0,2.2;16,6.25;favourites;"
if #menudata.favorites == 0 then
asyncOnlineFavourites()
end
if #menudata.favorites > 0 then if #menudata.favorites > 0 then
retval = retval .. render_favorite(menudata.favorites[1],render_details) retval = retval .. render_favorite(menudata.favorites[1])
for i=2,#menudata.favorites,1 do for i=2,#menudata.favorites,1 do
retval = retval .. "," .. render_favorite(menudata.favorites[i],render_details) retval = retval .. "," .. render_favorite(menudata.favorites[i])
end end
end end
@ -84,13 +112,22 @@ if not tabdata then tabdata = {} end
else else
retval = retval .. ";0]" retval = retval .. ";0]"
end end
--print(retval)
return 'size[12,5.4;false]'..retval return retval
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function main_button_handler(tabview, fields, name, tabdata) local function main_button_handler(tabview, fields, name, tabdata)
if not tabdata then tabdata = {} end if not tabdata then tabdata = {} end
if fields["add_server"] ~= nil then
local add_server_dlg = create_add_server_dlg(true)
add_server_dlg:set_parent(tabview)
add_server_dlg:show()
tabview:hide()
return true
end
if fields["te_name"] ~= nil then if fields["te_name"] ~= nil then
gamedata.playername = fields["te_name"] gamedata.playername = fields["te_name"]
core.setting_set("name", fields["te_name"]) core.setting_set("name", fields["te_name"])
@ -100,10 +137,6 @@ if not tabdata then tabdata = {} end
local event = core.explode_table_event(fields["favourites"]) local event = core.explode_table_event(fields["favourites"])
if event.type == "DCL" then if event.type == "DCL" then
if event.row <= #menudata.favorites then if event.row <= #menudata.favorites then
if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min,
menudata.favorites[event.row].proto_max) then
return true
end
gamedata.address = menudata.favorites[event.row].address gamedata.address = menudata.favorites[event.row].address
gamedata.port = menudata.favorites[event.row].port gamedata.port = menudata.favorites[event.row].port
gamedata.playername = fields["te_name"] gamedata.playername = fields["te_name"]
@ -140,7 +173,6 @@ if not tabdata then tabdata = {} end
tabdata.fav_selected = event.row tabdata.fav_selected = event.row
end end
return true return true
end end
end end
@ -181,22 +213,60 @@ if not tabdata then tabdata = {} end
if fields["cb_public_serverlist"] ~= nil then if fields["cb_public_serverlist"] ~= nil then
core.setting_set("public_serverlist", fields["cb_public_serverlist"]) core.setting_set("public_serverlist", fields["cb_public_serverlist"])
if core.setting_getbool("public_serverlist") then
asyncOnlineFavourites() asyncOnlineFavourites()
else
menudata.favorites = core.get_favorites("local")
end
tabdata.fav_selected = nil tabdata.fav_selected = nil
return true return true
end end
if fields["btn_mp_favour"] ~= nil then
local current_favourite = core.get_table_index("favourites")
local path = core.get_modpath('')..'/../client/'..core.formspec_escape(core.setting_get("serverlist_file"))
local favourites
if path then
local input,err,errcode = io.open(path, "r")
if input then
favourites = input:read("*all")
io.close(input)
--else
--gamedata.errormessage = err..' ('..errcode..')'
end
if favourites then
favourites = minetest.parse_json(favourites)
else
favourites = {["list"]={},}
end
table.insert(favourites.list,{
["address"] = fields["te_address"],
["description"] = "Saved at ".. os.date(),
["name"] = fields["te_address"],
["playername"] = fields["te_name"],
["playerpassword"] = fields["te_pwd"],
["port"] = fields["te_port"],
}
)
favourites = minetest.write_json(favourites)
local output,err,errcode = io.open(path, "w")
if output then
output:write(favourites or '')
io.close(output)
else
--gamedata.errormessage = fgettext("Can't write to serverlist_file! ("..path..')')
gamedata.errormessage = err..' ('..errcode..')'
end
end
asyncOnlineFavourites()
end
if fields["btn_delete_favorite"] ~= nil then if fields["btn_delete_favorite"] ~= nil then
local current_favourite = core.get_table_index("favourites") local current_favourite = core.get_table_index("favourites")
if current_favourite == nil then return end if current_favourite == nil then return end
if current_favourite > #core.get_favorites('offline') then return end
core.delete_favorite(current_favourite) core.delete_favorite(current_favourite)
menudata.favorites = order_favorite_list(core.get_favorites())
tabdata.fav_selected = nil tabdata.fav_selected = nil
asyncOnlineFavourites()
core.setting_set("address","") core.setting_set("address","")
core.setting_set("remote_port","30000") core.setting_set("remote_port","30000")
@ -204,9 +274,8 @@ if not tabdata then tabdata = {} end
return true return true
end end
if (fields["btn_mp_connect"] ~= nil or if fields["btn_mp_connect"] ~= nil or
fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and fields["key_enter"] ~= nil then
fields["te_port"] ~= nil then
gamedata.playername = fields["te_name"] gamedata.playername = fields["te_name"]
gamedata.password = fields["te_pwd"] gamedata.password = fields["te_pwd"]
@ -214,18 +283,9 @@ if not tabdata then tabdata = {} end
gamedata.port = fields["te_port"] gamedata.port = fields["te_port"]
local fav_idx = core.get_table_index("favourites") local fav_idx = core.get_table_index("favourites")
if fav_idx ~= nil and fav_idx <= #menudata.favorites and if fav_idx ~= nil and fav_idx <= #menudata.favorites and
menudata.favorites[fav_idx].address == fields["te_address"] and menudata.favorites[fav_idx].address == fields["te_address"] and
menudata.favorites[fav_idx].port == fields["te_port"] then menudata.favorites[fav_idx].port == fields["te_port"] then
gamedata.servername = menudata.favorites[fav_idx].name
gamedata.serverdescription = menudata.favorites[fav_idx].description
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
menudata.favorites[fav_idx].proto_max)then
return true
end
else else
gamedata.servername = "" gamedata.servername = ""
gamedata.serverdescription = "" gamedata.serverdescription = ""
@ -239,6 +299,13 @@ if not tabdata then tabdata = {} end
core.start() core.start()
return true return true
end end
if fields["cancel"] ~= nil then
tabview:hide()
tabview.parent:show()
return true
end
return false return false
end end
@ -246,14 +313,6 @@ local function on_change(type,old_tab,new_tab)
if type == "LEAVE" then if type == "LEAVE" then
return return
end end
if core.setting_getbool("public_serverlist") then
asyncOnlineFavourites()
else
menudata.favorites = core.get_favorites("local")
end
if type == "MenuQuit" then
return true
end
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -264,12 +323,3 @@ tab_multiplayer = {
cbf_button_handler = main_button_handler, cbf_button_handler = main_button_handler,
-- on_change = on_change -- on_change = on_change
} }
function create_tab_multiplayer()
local retval = dialog_create("multiplayer",
get_formspec,
main_button_handler
--on_change
)
return retval
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -23,44 +23,52 @@ local function get_formspec(tabview, name, tabdata)
) )
local retval = local retval =
"image_button[4,4.15;2.6,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete;" .. fgettext("Delete") .. "]" .. "size[16,11]"..
"image_button[6.5,4.15;2.8,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create;" .. fgettext("New") .. "]" .. "box[-100,8.5;200,10;#999999]" ..
"image_button[9.2,4.15;2.55,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_configure;" .. fgettext("Configure") .. "]" .. "box[-100,-10;200,12;#999999]" ..
"image_button[8.5,4.95;3.25,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;start_server;" .. fgettext("Start Game") .. "]" .. "bgcolor[#00000070;true]"..
"label[4,-0.25;" .. fgettext("Select World:") .. "]" .. "image_button[4,8.7;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;start_server;".. fgettext("Play") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"checkbox[0.25,0.15;cb_creative_mode;" .. fgettext("Creative Mode") .. ";" .. "image_button[7.8,8.7;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create;".. fgettext("New") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
dump(core.setting_getbool("creative_mode")) .. "]" ..
"checkbox[0.25,0.6;cb_enable_damage;" .. fgettext("Enable Damage") .. ";" .. "image_button[4,9.55;2.68,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete;".. fgettext("Delete") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
dump(core.setting_getbool("enable_damage")) .. "]" .. "image_button[6.53,9.55;2.68,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_configure;".. fgettext("Configure") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image[0.25,1.3;0.58,0.55;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_checkf.png]".. "image_button[9.07,9.55;2.68,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;cancel;".. fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image[0.25,1.3;0.58,0.55;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_check.png]".. "label[7,1.5;" .. fgettext("Select World:") .. "]" ..
"image_button[0.8,1.3;3,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_trans.png;btn_single;Local Server;false;false]"..
"checkbox[0.25,1.6;cb_server_announce;" .. fgettext("Public") .. ";" .. "checkbox[12,8.70;cb_creative_mode;" .. fgettext("Creative Mode") .. ";" .. dump(core.setting_getbool("creative_mode")) .. "]" ..
dump(core.setting_getbool("server_announce")) .. "]" .. --"checkbox[1000,9.20;cb_enable_damage;" .. fgettext("Enable Damage") .. ";" .. dump(core.setting_getbool("enable_damage")) .. "]" ..
"label[0.25,2.2;" .. fgettext("Name/Password") .. "]" .. "checkbox[12,9.50;cb_server_announce;" .. fgettext("Public") .. ";" .. dump(core.setting_getbool("server_announce")) .. "]" ..
"field[0.55,3.2;3.5,0.5;te_playername;;" .. "label[0.2,8.55;" .. fgettext("Name/Password") .. "]" ..
core.formspec_escape(core.setting_get("name")) .. "]" .. "field[0.5,9.45;3.5,0.5;te_playername;;"
"pwdfield[0.55,4;3.5,0.5;te_passwd;]"
local nm = core.formspec_escape(core.setting_get("name"))
if nm=='' then
nm='Wanderer'
end
retval = retval ..
nm .. "]" ..
"pwdfield[0.5,10.15;3.5,0.5;te_passwd;]"
local bind_addr = core.setting_get("bind_address") local bind_addr = core.setting_get("bind_address")
if bind_addr ~= nil and bind_addr ~= "" then
if not PLATFORM=="android" and bind_addr ~= nil and bind_addr ~= "" then
retval = retval .. retval = retval ..
"field[0.55,5.2;2.25,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" .. "field[300,0;2.25,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" ..
core.formspec_escape(core.setting_get("bind_address")) .. "]".. core.formspec_escape(core.setting_get("bind_address")) .. "]"..
"field[2.8,5.2;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" .. "field[300,1;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" ..
core.formspec_escape(core.setting_get("port")) .. "]" core.formspec_escape(core.setting_get("port")) .. "]"
else else
retval = retval .. retval = retval ..
"field[0.55,5.2;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" .. "field[300,1;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
core.formspec_escape(core.setting_get("port")) .. "]" core.formspec_escape(core.setting_get("port")) .. "]"
end end
retval = retval .. retval = retval ..
"textlist[4,0.25;7.5,3.7;srv_worlds;" .. "textlist[0,2.2;16,6.5;srv_worlds;" ..
menu_render_worldlist() .. menu_render_worldlist() ..
";" .. index .. "]" ";" .. (index or 1) .. ";true]"
return 'size[12,5.4;false]'..retval return retval
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -68,43 +76,9 @@ local function main_button_handler(this, fields, name, tabdata)
local world_doubleclick = false local world_doubleclick = false
if fields["btn_single"]~=nil then
local single = create_tab_single(true)
single:set_parent(this.parent)
single:show()
this:hide()
return true
end
if fields["srv_worlds"] ~= nil then if fields["srv_worlds"] ~= nil then
local event = core.explode_textlist_event(fields["srv_worlds"]) local event = core.explode_textlist_event(fields["srv_worlds"])
local selected = core.get_textlist_index("srv_worlds")
if selected ~= nil then
local filename = menudata.worldlist:get_list()[selected].path
local worldconfig = modmgr.get_worldconfig(filename)
filename = filename .. DIR_DELIM .. "world.mt"
if worldconfig.creative_mode ~= nil then
core.setting_set("creative_mode", worldconfig.creative_mode)
else
local worldfile = Settings(filename)
worldfile:set("creative_mode", core.setting_get("creative_mode"))
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end
end
if worldconfig.enable_damage ~= nil then
core.setting_set("enable_damage", worldconfig.enable_damage)
else
local worldfile = Settings(filename)
worldfile:set("enable_damage", core.setting_get("enable_damage"))
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end
end
end
if event.type == "DCL" then if event.type == "DCL" then
world_doubleclick = true world_doubleclick = true
end end
@ -121,29 +95,19 @@ local function main_button_handler(this, fields, name, tabdata)
if fields["cb_creative_mode"] then if fields["cb_creative_mode"] then
core.setting_set("creative_mode", fields["cb_creative_mode"]) core.setting_set("creative_mode", fields["cb_creative_mode"])
local selected = core.get_textlist_index("srv_worlds") local bool = fields["cb_creative_mode"]
local filename = menudata.worldlist:get_list()[selected].path .. if bool == 'true' then
DIR_DELIM .. "world.mt" bool = 'false'
else
local worldfile = Settings(filename) bool = 'true'
worldfile:set("creative_mode", fields["cb_creative_mode"])
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end end
core.setting_set("enable_damage", bool)
print(bool)
return true return true
end end
if fields["cb_enable_damage"] then if fields["cb_enable_damage"] then
core.setting_set("enable_damage", fields["cb_enable_damage"]) core.setting_set("enable_damage", fields["cb_enable_damage"])
local selected = core.get_textlist_index("srv_worlds")
local filename = menudata.worldlist:get_list()[selected].path ..
DIR_DELIM .. "world.mt"
local worldfile = Settings(filename)
worldfile:set("enable_damage", fields["cb_enable_damage"])
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end
return true return true
end end
@ -220,6 +184,13 @@ local function main_button_handler(this, fields, name, tabdata)
end end
return true return true
end end
if fields["cancel"] ~= nil then
this:hide()
this.parent:show()
return true
end
return false return false
end end
@ -231,11 +202,3 @@ tab_server = {
cbf_button_handler = main_button_handler, cbf_button_handler = main_button_handler,
on_change = nil on_change = nil
} }
function create_tab_server()
local retval = dialog_create("server",
get_formspec,
main_button_handler,
nil)
return retval
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -16,7 +16,6 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local dd_filter_labels = { local dd_filter_labels = {
fgettext("No Filter"), fgettext("No Filter"),
fgettext("Bilinear Filter"), fgettext("Bilinear Filter"),
@ -70,15 +69,14 @@ local function video_driver_fname_to_name(selected_driver)
return "" return ""
end end
local function dlg_confirm_reset_formspec(data) local function dlg_confirm_reset_formspec(data)
local retval = local retval =
"size[8,3]" .. "size[8,3]" ..
"label[1,1;".. fgettext("Are you sure to reset your singleplayer world?") .. "]".. "label[1,1;".. fgettext("Are you sure to reset your singleplayer world?") .. "]"..
"image_button[1,2;2.6,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_reset_singleplayer_confirm;".. "image_button[1,2;2.6,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_reset_singleplayer_confirm;"..
fgettext("Yes") .. "]" .. fgettext("Yes") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[4,2;2.8,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_reset_singleplayer_cancel;".. "image_button[4,2;2.8,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;dlg_reset_singleplayer_cancel;"..
fgettext("No!!!") .. "]" fgettext("No!!!") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
return retval return retval
end end
@ -130,14 +128,17 @@ local function showconfirm_reset(tabview)
end end
local function gui_scale_to_scrollbar() local function gui_scale_to_scrollbar()
local current_value = tonumber(core.setting_get("gui_scaling")) local current_value = tonumber(core.setting_get("gui_scaling"))
if (current_value == nil) or current_value < 0.25 then if (current_value == nil) or current_value < 0.25 then
return 0 return 0
end end
if current_value <= 1.25 then if current_value <= 1.25 then
return ((current_value - 0.25)/ 1.0) * 700 return ((current_value - 0.25)/ 1.0) * 700
end end
if current_value <= 6 then if current_value <= 6 then
return ((current_value -1.25) * 100) + 700 return ((current_value -1.25) * 100) + 700
end end
@ -146,11 +147,13 @@ local function gui_scale_to_scrollbar()
end end
local function scrollbar_to_gui_scale(value) local function scrollbar_to_gui_scale(value)
value = tonumber(value) value = tonumber(value)
if (value <= 700) then if (value <= 700) then
return ((value / 700) * 1.0) + 0.25 return ((value / 700) * 1.0) + 0.25
end end
if (value <=1000) then if (value <=1000) then
return ((value - 700) / 100) + 1.25 return ((value - 700) / 100) + 1.25
end end
@ -176,65 +179,114 @@ local function formspec(tabview, name, tabdata)
end end
end end
local tab_string = local tab_string =
"box[0,0;3.5,3.9;#999999]" .. "size[16,11]"..
"checkbox[0.25,0;cb_smooth_lighting;".. fgettext("Smooth Lighting") "bgcolor[#00000070;true]"..
"box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"box[0.75,2.5;4.5,3.9;#999999]" ..
"checkbox[1.0,2.5;cb_smooth_lighting;".. fgettext("Smooth Lighting")
.. ";".. dump(core.setting_getbool("smooth_lighting")) .. "]".. .. ";".. dump(core.setting_getbool("smooth_lighting")) .. "]"..
"checkbox[0.25,0.5;cb_particles;".. fgettext("Enable Particles") .. ";" "checkbox[1.0,3.0;cb_particles;".. fgettext("Enable Particles") .. ";"
.. dump(core.setting_getbool("enable_particles")) .. "]".. .. dump(core.setting_getbool("enable_particles")) .. "]"..
"checkbox[0.25,1;cb_3d_clouds;".. fgettext("3D Clouds") .. ";" "checkbox[1.0,3.5;cb_3d_clouds;".. fgettext("3D Clouds") .. ";"
.. dump(core.setting_getbool("enable_3d_clouds")) .. "]".. .. dump(core.setting_getbool("enable_3d_clouds")) .. "]"..
"checkbox[0.25,1.5;cb_fancy_trees;".. fgettext("Fancy Trees") .. ";" "checkbox[1.0,4.0;cb_fancy_trees;".. fgettext("Fancy Trees") .. ";"
.. dump(core.setting_getbool("new_style_leaves")) .. "]".. .. dump(core.setting_getbool("new_style_leaves")) .. "]"..
"checkbox[0.25,2.0;cb_opaque_water;".. fgettext("Opaque Water") .. ";" "checkbox[1.0,4.5;cb_opaque_water;".. fgettext("Opaque Water") .. ";"
.. dump(core.setting_getbool("opaque_water")) .. "]".. .. dump(core.setting_getbool("opaque_water")) .. "]"..
"checkbox[0.25,2.5;cb_connected_glass;".. fgettext("Connected Glass") .. ";" "checkbox[1.0,5.0;cb_connected_glass;".. fgettext("Connected Glass") .. ";"
.. dump(core.setting_getbool("connected_glass")) .. "]".. .. dump(core.setting_getbool("connected_glass")) .. "]"..
"checkbox[0.25,3.0;cb_node_highlighting;".. fgettext("Node Highlighting") .. ";" "checkbox[1.0,5.5;cb_node_highlighting;".. fgettext("Node Highlighting") .. ";"
.. dump(core.setting_getbool("enable_node_highlighting")) .. "]".. .. dump(core.setting_getbool("enable_node_highlighting")) .. "]"..
"box[3.75,0;3.75,3.45;#999999]" ..
"label[3.85,0.1;".. fgettext("Texturing:") .. "]"..
"dropdown[3.85,0.55;3.85;dd_filters;" .. filters[1][1] .. ";" "box[5.5,2.5;4,3.45;#999999]" ..
"label[5.85,2.5;".. fgettext("Texturing:") .. "]"..
"dropdown[5.85,3.05;3.85;dd_filters;" .. filters[1][1] .. ";"
.. getFilterSettingIndex() .. "]" .. .. getFilterSettingIndex() .. "]" ..
"dropdown[3.85,1.35;3.85;dd_mipmap;" .. mipmap[1][1] .. ";" "dropdown[5.85,3.85;3.85;dd_mipmap;" .. mipmap[1][1] .. ";"
.. getMipmapSettingIndex() .. "]" .. .. getMipmapSettingIndex() .. "]" ..
"label[3.85,2.15;".. fgettext("Rendering:") .. "]".. "label[5.85,4.65;".. fgettext("Rendering:") .. "]"..
"dropdown[3.85,2.6;3.85;dd_video_driver;" "dropdown[5.85,5.1;3.85;dd_video_driver;"
.. driver_formspec_string .. ";" .. driver_current_idx .. "]" .. .. driver_formspec_string .. ";" .. driver_current_idx .. "]" ..
"tooltip[dd_video_driver;" .. "tooltip[dd_video_driver;" ..
fgettext("Restart MultiCraft for driver change to take effect") .. "]" fgettext("Restart minetest for driver change to take effect") .. "]"
if PLATFORM ~= "Android" then if PLATFORM ~= "Android" then
tab_string = tab_string .. tab_string = tab_string ..
"image_button[8,4.75;3.75,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_change_keys;".. fgettext("Change keys") .. "]" "box[9.75,2.5;5.25,4;#999999]"..
"checkbox[10,2.5;cb_shaders;".. fgettext("Shaders") .. ";"
.. dump(core.setting_getbool("enable_shaders")) .. "]"..
"image_button[0,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_change_keys;".. fgettext("Change keys") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"--..
-- "image_button[3.75,5;3.88,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_reset_singleplayer;".. fgettext("Reset singleplayer world") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
else else
tab_string = tab_string .. --tab_string = tab_string ..
"image_button[3.75,5.5;3.95,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_reset_singleplayer;".. fgettext("Reset singleplayer world") .. "]" -- "image_button[3.75,5;3.88,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_reset_singleplayer;".. fgettext("Reset singleplayer world") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
end end
tab_string = tab_string .. tab_string = tab_string ..
"box[0,4.25;3.5,1.1;#999999]" .. "image_button[4,9.55;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_textures;".. fgettext("Texturepacks") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir)..
"label[0.25,4.25;" .. fgettext("GUI scale factor") .. "]" .. "menu_button_b.png]"..
"scrollbar[0.25,4.75;3,0.4;sb_gui_scaling;horizontal;" .. "image_button[8,9.55;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_show_credits;".. fgettext("Credits") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
gui_scale_to_scrollbar() .. "]" .. "image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_cancel;".. fgettext("OK") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"
"tooltip[sb_gui_scaling;" ..
fgettext("Scaling factor applied to menu elements: ") ..
dump(core.setting_get("gui_scaling")) .. "]"
if PLATFORM == "Android" then if PLATFORM == "Android" then
tab_string = tab_string .. tab_string = tab_string ..
"box[3.75,3.55;3.75,1.8;#999999]" .. "box[9.75,2.5;5.25,2.5;#999999]" ..
"checkbox[3.9,3.45;cb_touchscreen_target;".. fgettext("Touch free target") .. ";" "checkbox[10,2.75;cb_touchscreen_target;".. fgettext("Touch free target") .. ";" .. dump(core.setting_getbool("touchtarget")) .. "]"..
.. dump(core.setting_getbool("touchtarget")) .. "]"
end
if core.setting_get("touchscreen_threshold") ~= nil then "box[0.75,6.8;14.25,1.35;#999999]" ..
"label[1.5,6.8;" .. fgettext("GUI scale factor") .. "]"..
"scrollbar[1.0,7.2;13.75,0.7;sb_gui_scaling;horizontal;" .. gui_scale_to_scrollbar() .. "]" ..
"tooltip[sb_gui_scaling;" .. fgettext("Scaling factor applied to menu elements: ") .. dump(core.setting_get("gui_scaling")) .. "]"
-- if core.setting_get("touchscreen_threshold") ~= nil then
tab_string = tab_string .. tab_string = tab_string ..
"label[4.3,4.1;" .. fgettext("Touchthreshold (px)") .. "]" .. "label[10,3.5;" .. fgettext("Touchthreshold (px)") .. "]" ..
"dropdown[3.85,4.55;3.85;dd_touchthreshold;0,10,20,30,40,50;" .. "dropdown[10,4.0;5.18;dd_touchthreshold;0,10,20,30,40,50;" .. ((tonumber(core.setting_get("touchscreen_threshold") or 20)/10)+1) .. "]"
((tonumber(core.setting_get("touchscreen_threshold"))/10)+1) .. "]" -- end
else
tab_string = tab_string ..
"box[0.75,6.8;14.25,1.35;#999999]" ..
"label[1.5,6.8;" .. fgettext("GUI scale factor") .. "]"..
"scrollbar[1.0,7.5;13.75,0.4;sb_gui_scaling;horizontal;" .. gui_scale_to_scrollbar() .. "]" ..
"tooltip[sb_gui_scaling;" .. fgettext("Scaling factor applied to menu elements: ") .. dump(core.setting_get("gui_scaling")) .. "]"
end end
return 'size[7.70,6.2,false]'..tab_string if PLATFORM ~= "Android" then
if core.setting_getbool("enable_shaders") then
tab_string = tab_string ..
"checkbox[10,3.0;cb_bumpmapping;".. fgettext("Bumpmapping") .. ";"
.. dump(core.setting_getbool("enable_bumpmapping")) .. "]"..
"checkbox[10,3.5;cb_generate_normalmaps;".. fgettext("Generate Normalmaps") .. ";"
.. dump(core.setting_getbool("generate_normalmaps")) .. "]"..
"checkbox[10,4.0;cb_parallax;".. fgettext("Parallax Occlusion") .. ";"
.. dump(core.setting_getbool("enable_parallax_occlusion")) .. "]"..
"checkbox[10,4.5;cb_waving_water;".. fgettext("Waving Water") .. ";"
.. dump(core.setting_getbool("enable_waving_water")) .. "]"..
"checkbox[10,5.0;cb_waving_leaves;".. fgettext("Waving Leaves") .. ";"
.. dump(core.setting_getbool("enable_waving_leaves")) .. "]"..
"checkbox[10,5.5;cb_waving_plants;".. fgettext("Waving Plants") .. ";"
.. dump(core.setting_getbool("enable_waving_plants")) .. "]"
else
tab_string = tab_string ..
"textlist[10.3,3.2;4,1;;#888888" .. fgettext("Bumpmapping") .. ";0;true]" ..
"textlist[10.3,3.7;4,1;;#888888" .. fgettext("Generate Normalmaps") .. ";0;true]" ..
"textlist[10.3,4.2;4,1;;#888888" .. fgettext("Parallax Occlusion") .. ";0;true]" ..
"textlist[10.3,4.7;4,1;;#888888" .. fgettext("Waving Water") .. ";0;true]" ..
"textlist[10.3,5.2;4,1;;#888888" .. fgettext("Waving Leaves") .. ";0;true]" ..
"textlist[10.3,5.7;4,1;;#888888" .. fgettext("Waving Plants") .. ";0;true]"
end
end
return tab_string
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -255,6 +307,22 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
core.setting_set("opaque_water", fields["cb_opaque_water"]) core.setting_set("opaque_water", fields["cb_opaque_water"])
return true return true
end end
if fields["cb_mipmapping"] then
core.setting_set("mip_map", fields["cb_mipmapping"])
return true
end
if fields["cb_anisotrophic"] then
core.setting_set("anisotropic_filter", fields["cb_anisotrophic"])
return true
end
if fields["cb_bilinear"] then
core.setting_set("bilinear_filter", fields["cb_bilinear"])
return true
end
if fields["cb_trilinear"] then
core.setting_set("trilinear_filter", fields["cb_trilinear"])
return true
end
if fields["cb_shaders"] then if fields["cb_shaders"] then
if (core.setting_get("video_driver") == "direct3d8" or core.setting_get("video_driver") == "direct3d9") then if (core.setting_get("video_driver") == "direct3d8" or core.setting_get("video_driver") == "direct3d9") then
core.setting_set("enable_shaders", "false") core.setting_set("enable_shaders", "false")
@ -268,10 +336,6 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
core.setting_set("connected_glass", fields["cb_connected_glass"]) core.setting_set("connected_glass", fields["cb_connected_glass"])
return true return true
end end
if fields["cb_node_highlighting"] then
core.setting_set("enable_node_highlighting", fields["cb_node_highlighting"])
return true
end
if fields["cb_particles"] then if fields["cb_particles"] then
core.setting_set("enable_particles", fields["cb_particles"]) core.setting_set("enable_particles", fields["cb_particles"])
return true return true
@ -320,6 +384,32 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
return true return true
end end
if fields["btn_cancel"] ~= nil then
this:hide()
this.parent:show()
return true
end
local index = ''
if fields["btn_show_textures"] then index = "texturepacks" end
if fields["btn_show_credits"] then index = "credits" end
for name,def in pairs(this.parent.tablist) do
if index == def.name then
local get_fs = function()
local retval = def.get_formspec(this.parent, name, tabdata)
retval = 'size[12,5.2]'..retval
return retval
end
local dlg = dialog_create(def.name, get_fs, def.button_handler, def.on_change)
dlg:set_parent(this)
this:hide()
dlg:show()
return dlg
end
end
--Note dropdowns have to be handled LAST! --Note dropdowns have to be handled LAST!
local ddhandled = false local ddhandled = false
@ -373,11 +463,3 @@ tab_settings = {
cbf_formspec = formspec, cbf_formspec = formspec,
cbf_button_handler = handle_settings_buttons cbf_button_handler = handle_settings_buttons
} }
function create_tab_settings()
local retval = dialog_create("settings",
formspec,
handle_settings_buttons,
nil)
return retval
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -16,171 +16,34 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
--favourites
local function image_column(tooltip, flagname)
return "image," ..
"tooltip=" .. core.formspec_escape(tooltip) .. "," ..
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
end
local function get_formspec(tabview, name, tabdata) local function get_formspec(tabview, name, tabdata)
local retval = "" local retval = ""
retval = retval .. "bgcolor[#00000000;false]"
local render_details = dump(core.setting_getbool("public_serverlist")) retval = retval .. "image_button[2.5,1.0;7,1;multicraftbutton.png;btn_show_singleplayer;".. fgettext("Singleplayer") .. ";true;true;multicraftbutton.png]"
retval = retval .. "image_button[2.5,2.4;7,1;multicraftbutton.png;btn_show_multiplayer;" .. fgettext("Multiplayer") .. ";true;true;multicraftbutton.png]"
retval = retval .. retval = retval .. "image_button[2.5,3.8;7,1;multicraftbutton.png;btn_show_options;".. fgettext("Options") .. ";true;true;multicraftbutton.png]"
"label[8,0.8;".. fgettext("Name/Password") .. "]" .. retval = retval .. "image_button[2.5,5.2;7,1;multicraftbutton.png;btn_exit;".. fgettext("Exit") .. ";true;true;multicraftbutton.png]"
"field[0.25,3.25;5.5,0.5;te_address;;" ..
core.formspec_escape(core.setting_get("address")) .."]" ..
"field[5.75,3.25;2.25,0.5;te_port;;" ..
core.formspec_escape(core.setting_get("remote_port")) .."]" ..
"checkbox[8,-0.25;cb_public_serverlist;".. fgettext("Public Serverlist") .. ";" ..
render_details .. "]"
retval = retval ..
"image_button[8,2.5;4,1.5;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_mp_connect;".. fgettext("Connect") .. "]" ..
"field[8.75,1.5;3.5,0.5;te_name;;" ..
core.formspec_escape(core.setting_get("name")) .."]" ..
"pwdfield[8.75,2.3;3.5,0.5;te_pwd;]"
if render_details then
retval = retval .. "tablecolumns[" ..
"color,span=3;" ..
"text,align=right;" .. -- clients
"text,align=center,padding=0.25;" .. -- "/"
"text,align=right,padding=0.25;" .. -- clients_max
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
"color,span=1;" ..
"text,padding=1]" -- name
else
retval = retval .. "tablecolumns[text]"
end
retval = retval ..
"table[-0.05,0;7.55,2.75;favourites;"
if #menudata.favorites > 0 then
retval = retval .. render_favorite(menudata.favorites[1],render_details)
for i=2,#menudata.favorites,1 do
retval = retval .. "," .. render_favorite(menudata.favorites[i],render_details)
end
end
if tabdata.fav_selected ~= nil then
retval = retval .. ";" .. tabdata.fav_selected .. "]"
else
retval = retval .. ";0]"
end
-- separator
retval = retval ..
"box[-0.28,3.75;12.4,0.1;#FFFFFF]"
-- checkboxes
retval = retval ..
"checkbox[8.0,3.9;cb_creative;".. fgettext("Creative Mode") .. ";" ..
dump(core.setting_getbool("creative_mode")) .. "]"..
"checkbox[8.0,4.4;cb_damage;".. fgettext("Enable Damage") .. ";" ..
dump(core.setting_getbool("enable_damage")) .. "]"
-- buttons
retval = retval ..
"image_button[2.0,4.5;6,1.5;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_start_singleplayer;" .. fgettext("Start Singleplayer") .. "]" ..
"image_button[8.25,4.5;2.5,1.5;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_config_sp_world;" .. fgettext("Config mods") .. "]"
return retval return retval
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function main_button_handler(tabview, fields, name, tabdata) local function main_button_handler(tabview, fields, name, tabdata)
local index = 0
if fields["btn_show_singleplayer"] then index = 1 end
if fields["btn_show_multiplayer"] then index = 2 end
if fields["btn_show_options"] then index = 3 end
if fields["btn_exit"] then core.close() end
if fields["btn_start_singleplayer"] then --switch_to_tab(self, index)
gamedata.selected_world = gamedata.worldindex
gamedata.singleplayer = true
core.start()
return true
end
if fields["favourites"] ~= nil then
local event = core.explode_table_event(fields["favourites"])
if event.type == "CHG" then
if event.row <= #menudata.favorites then
local address = menudata.favorites[event.row].address
local port = menudata.favorites[event.row].port
if address ~= nil and
port ~= nil then
core.setting_set("address",address)
core.setting_set("remote_port",port)
end
tabdata.fav_selected = event.row
end
end
return true
end
if fields["cb_public_serverlist"] ~= nil then
core.setting_set("public_serverlist", fields["cb_public_serverlist"])
if core.setting_getbool("public_serverlist") then
asyncOnlineFavourites()
else
menudata.favorites = core.get_favorites("local")
end
return true
end
if fields["cb_creative"] then
core.setting_set("creative_mode", fields["cb_creative"])
return true
end
if fields["cb_damage"] then
core.setting_set("enable_damage", fields["cb_damage"])
return true
end
if fields["btn_mp_connect"] ~= nil or
fields["key_enter"] ~= nil then
gamedata.playername = fields["te_name"]
gamedata.password = fields["te_pwd"]
gamedata.address = fields["te_address"]
gamedata.port = fields["te_port"]
local fav_idx = core.get_textlist_index("favourites")
if fav_idx ~= nil and fav_idx <= #menudata.favorites and
menudata.favorites[fav_idx].address == fields["te_address"] and
menudata.favorites[fav_idx].port == fields["te_port"] then
gamedata.servername = menudata.favorites[fav_idx].name
gamedata.serverdescription = menudata.favorites[fav_idx].description
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
menudata.favorites[fav_idx].proto_max) then
return true
end
else
gamedata.servername = ""
gamedata.serverdescription = ""
end
gamedata.selected_world = 0
core.setting_set("address",fields["te_address"])
core.setting_set("remote_port",fields["te_port"])
core.start()
return true
end
if fields["btn_config_sp_world"] ~= nil then
local configdialog = create_configure_world_dlg(1)
if (configdialog ~= nil) then
configdialog:set_parent(tabview)
tabview:hide()
configdialog:show()
end
return true
end
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -188,6 +51,7 @@ local function on_activate(type,old_tab,new_tab)
if type == "LEAVE" then if type == "LEAVE" then
return return
end end
core.set_topleft_text('Multicraft II')
if core.setting_getbool("public_serverlist") then if core.setting_getbool("public_serverlist") then
asyncOnlineFavourites() asyncOnlineFavourites()
else else

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -35,7 +35,7 @@ local function singleplayer_refresh_gamebar()
for j=1,#gamemgr.games,1 do for j=1,#gamemgr.games,1 do
if ("game_btnbar_" .. gamemgr.games[j].id == key) then if ("game_btnbar_" .. gamemgr.games[j].id == key) then
mm_texture.update("singleplayer", gamemgr.games[j]) mm_texture.update("singleplayer", gamemgr.games[j])
core.set_topleft_text(gamemgr.games[j].name) --core.set_topleft_text(gamemgr.games[j].name)
core.setting_set("menu_last_game",gamemgr.games[j].id) core.setting_set("menu_last_game",gamemgr.games[j].id)
menudata.worldlist:set_filtercriteria(gamemgr.games[j].id) menudata.worldlist:set_filtercriteria(gamemgr.games[j].id)
return true return true
@ -82,73 +82,40 @@ local function get_formspec(tabview, name, tabdata)
) )
retval = retval .. retval = retval ..
"image_button[4,4.15;2.6,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete;".. fgettext("Delete") .. "]" .. "image_button[4,4.05;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;play;".. fgettext("Play") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[6.5,4.15;2.8,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create;".. fgettext("New") .. "]" .. "image_button[7.8,4.05;3.95,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_create;".. fgettext("New") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[9.2,4.15;2.55,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_configure;".. fgettext("Configure") .. "]" ..
"image_button[8.5,4.95;3.25,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_button.png;play;".. fgettext("Play") .. "]" .. "image_button[4,4.8;2.68,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_delete;".. fgettext("Delete") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[6.53,4.8;2.68,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;world_configure;".. fgettext("Configure") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"image_button[9.07,4.8;2.68,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;cancel;".. fgettext("Cancel") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"label[4,-0.25;".. fgettext("Select World:") .. "]".. "label[4,-0.25;".. fgettext("Select World:") .. "]"..
"checkbox[0.25,0.15;cb_creative_mode;".. fgettext("Creative Mode") .. ";" .. "checkbox[0.25,0.25;cb_creative_mode;".. fgettext("Creative Mode") .. ";" ..
dump(core.setting_getbool("creative_mode")) .. "]".. dump(core.setting_getbool("creative_mode")) .. "]"..
"checkbox[0.25,0.6;cb_enable_damage;".. fgettext("Enable Damage") .. ";" .. "checkbox[0.25,0.7;cb_enable_damage;".. fgettext("Enable Damage") .. ";" ..
dump(core.setting_getbool("enable_damage")) .. "]".. dump(core.setting_getbool("enable_damage")) .. "]"..
"image[0.25,1.3;0.58,0.55;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_checkf.png]"..
"image_button[0.8,1.3;3,0.8;"..multicraft.formspec_escape(mm_texture.basetexturedir).."menu_trans.png;btn_server;Local Server;false;false]"..
"textlist[4,0.25;7.5,3.7;sp_worlds;" .. "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
menu_render_worldlist() .. menu_render_worldlist() ..
";" .. index .. "]" ";" .. index .. "]"
return 'size[12,5.4;false]'..retval return retval
end end
local function main_button_handler(this, fields, name, tabdata) local function main_button_handler(this, fields, name, tabdata)
name = "singleplayer" --assert(name == "singleplayer")
local world_doubleclick = false local world_doubleclick = false
if fields["btn_server"]~=nil then
local single = create_tab_server(true)
single:set_parent(this.parent)
single:show()
this:hide()
return true
end
if fields["sp_worlds"] ~= nil then if fields["sp_worlds"] ~= nil then
local event = core.explode_textlist_event(fields["sp_worlds"]) local event = core.explode_textlist_event(fields["sp_worlds"])
local selected = core.get_textlist_index("sp_worlds")
if selected ~= nil then
local filename = menudata.worldlist:get_list()[selected].path
local worldconfig = modmgr.get_worldconfig(filename)
filename = filename .. DIR_DELIM .. "world.mt"
if worldconfig.creative_mode ~= nil then
core.setting_set("creative_mode", worldconfig.creative_mode)
else
local worldfile = Settings(filename)
worldfile:set("creative_mode", core.setting_get("creative_mode"))
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end
end
if worldconfig.enable_damage ~= nil then
core.setting_set("enable_damage", worldconfig.enable_damage)
else
local worldfile = Settings(filename)
worldfile:set("enable_damage", core.setting_get("enable_damage"))
if not worldfile:write() then
core.log("error", "Failed to write world config file")
end
end
end
if event.type == "DCL" then if event.type == "DCL" then
world_doubleclick = true world_doubleclick = true
end end
if event.type == "CHG" and selected ~= nil then if event.type == "CHG" then
core.setting_set("mainmenu_last_selected_world", core.setting_set("mainmenu_last_selected_world",
menudata.worldlist:get_raw_index(selected)) menudata.worldlist:get_raw_index(core.get_textlist_index("sp_worlds")))
return true return true
end end
end end
@ -159,39 +126,11 @@ local function main_button_handler(this, fields, name, tabdata)
if fields["cb_creative_mode"] then if fields["cb_creative_mode"] then
core.setting_set("creative_mode", fields["cb_creative_mode"]) core.setting_set("creative_mode", fields["cb_creative_mode"])
local selected = core.get_textlist_index("sp_worlds")
if selected then
local filename = menudata.worldlist:get_list()[selected].path ..
DIR_DELIM .. "world.mt"
local test = io.open(filename)
if test then
io.close(test)
local worldfile = Settings(filename)
worldfile:set("creative_mode", fields["cb_creative_mode"])
-- if not worldfile:write() then
-- core.log("error", "Failed to write world config file")
-- end
end
end
return true return true
end end
if fields["cb_enable_damage"] then if fields["cb_enable_damage"] then
core.setting_set("enable_damage", fields["cb_enable_damage"]) core.setting_set("enable_damage", fields["cb_enable_damage"])
local selected = core.get_textlist_index("sp_worlds")
if selected then
local filename = menudata.worldlist:get_list()[selected].path ..
DIR_DELIM .. "world.mt"
local test = io.open(filename)
if test then
local worldfile = Settings(filename)
worldfile:set("enable_damage", fields["cb_enable_damage"])
--if not worldfile:write() then
--core.log("error", "Failed to write world config file")
--end
end
end
return true return true
end end
@ -255,6 +194,14 @@ local function main_button_handler(this, fields, name, tabdata)
return true return true
end end
if fields["cancel"] ~= nil then
this:hide()
this.parent:show()
return true
end
return false
end end
local function on_change(type, old_tab, new_tab) local function on_change(type, old_tab, new_tab)
@ -270,14 +217,14 @@ local function on_change(type, old_tab, new_tab)
if game then if game then
menudata.worldlist:set_filtercriteria(game.id) menudata.worldlist:set_filtercriteria(game.id)
core.set_topleft_text(game.name) --core.set_topleft_text(game.name)
mm_texture.update("singleplayer",game) mm_texture.update("singleplayer",game)
end end
buttonbar:show() buttonbar:show()
else else
menudata.worldlist:set_filtercriteria(nil) menudata.worldlist:set_filtercriteria(nil)
buttonbar:hide() buttonbar:hide()
core.set_topleft_text("") --core.set_topleft_text("")
mm_texture.update(new_tab,nil) mm_texture.update(new_tab,nil)
end end
end end
@ -290,11 +237,3 @@ tab_singleplayer = {
cbf_button_handler = main_button_handler, cbf_button_handler = main_button_handler,
on_change = on_change on_change = on_change
} }
function create_tab_single()
local retval = dialog_create("singleplayer",
get_formspec,
main_button_handler,
nil)
return retval
end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2014 sapier --Copyright (C) 2014 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -46,8 +46,13 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function get_formspec(tabview, name, tabdata) local function get_formspec(tabview, name, tabdata)
local retval = "label[4,-0.25;".. fgettext("Select texture pack:") .. "]".. local retval = "size[16,11]"..
"textlist[4,0.25;7.5,5.0;TPs;" "bgcolor[#00000070;true]"..
"box[-100,8.5;200,10;#999999]" ..
"box[-100,-10;200,12;#999999]" ..
"label[4,-0.25;".. fgettext("Select texture pack:") .. "]"..
"image_button[12,9.55;4,0.8;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button.png;btn_cancel;".. fgettext("OK") .. ";true;true;"..minetest.formspec_escape(mm_texture.basetexturedir).."menu_button_b.png]"..
"textlist[0,2.0;15.8,6.25;TPs;"
local current_texture_path = core.setting_get("texture_path") local current_texture_path = core.setting_get("texture_path")
local list = filter_texture_pack_list(core.get_dirlist(core.get_texturepath(), true)) local list = filter_texture_pack_list(core.get_dirlist(core.get_texturepath(), true))
@ -58,7 +63,7 @@ local function get_formspec(tabview, name, tabdata)
if current_texture_path == "" then if current_texture_path == "" then
retval = retval .. retval = retval ..
render_texture_pack_list(list) .. render_texture_pack_list(list) ..
";" .. index .. "]" ";" .. index .. ";true]"
return retval return retval
end end
@ -81,9 +86,9 @@ local function get_formspec(tabview, name, tabdata)
return retval .. return retval ..
render_texture_pack_list(list) .. render_texture_pack_list(list) ..
";" .. index .. "]" .. ";" .. index .. ";true]" ..
"image[0.25,0.25;4.0,3.7;"..core.formspec_escape(screenfile or no_screenshot).."]".. "image[0.25,9.25;4.0,3.7;"..core.formspec_escape(screenfile or no_screenshot).."]"..
"textarea[0.6,3.25;3.7,1.5;;"..core.formspec_escape(infotext or "")..";]" "textarea[4.5,9.75;6.7,2.5;;"..core.formspec_escape(infotext or "")..";]"
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -105,6 +110,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
end end
return true return true
end end
if fields["btn_cancel"] ~= nil then
tabview:hide()
tabview.parent:show()
return true
end
return false return false
end end

View File

@ -1,4 +1,4 @@
--multicraft --Minetest
--Copyright (C) 2013 sapier --Copyright (C) 2013 sapier
-- --
--This program is free software; you can redistribute it and/or modify --This program is free software; you can redistribute it and/or modify
@ -31,11 +31,6 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function mm_texture.update(tab,gamedetails) function mm_texture.update(tab,gamedetails)
if tab ~= "singleplayer" then
mm_texture.reset()
return
end
if gamedetails == nil then if gamedetails == nil then
return return
end end
@ -96,6 +91,7 @@ function mm_texture.update_game(gamedetails)
end end
mm_texture.set_game("footer",gamedetails) mm_texture.set_game("footer",gamedetails)
--print(dump(gamedetails))
mm_texture.set_game("header",gamedetails) mm_texture.set_game("header",gamedetails)
mm_texture.gameid = gamedetails.id mm_texture.gameid = gamedetails.id
@ -154,7 +150,7 @@ end
function mm_texture.set_dirt_bg() function mm_texture.set_dirt_bg()
if mm_texture.texturepack ~= nil then if mm_texture.texturepack ~= nil then
local path = mm_texture.texturepack .. DIR_DELIM .."default_dirt.png" local path = mm_texture.texturepack .. DIR_DELIM .."default_stone.png"
if core.set_background("background", path, true, 128) then if core.set_background("background", path, true, 128) then
return true return true
end end

66
builtin/profiler.lua Normal file
View File

@ -0,0 +1,66 @@
local ffi
-- there's no ffi in Lua, only in LuaJIT
-- when Freeminer is run with Lua the profiler is not available because we can't access precise timer
if not pcall(function() ffi = require("ffi") end) then
return
end
ffi.cdef[[
unsigned int get_time_us();
]]
local modpath = core.get_builtin_path()..DIR_DELIM
package.path = package.path .. ";" .. modpath .. "/?.lua"
ProFi = require 'ProFi'
local function get_time_precise()
return ffi.C.get_time_us() / 1000000
end
ProFi:setGetTimeMethod(get_time_precise)
local started = false
local function start_profiler()
ProFi:start()
started = true
end
if freeminer.setting_getbool("profiler_autostart") then
start_profiler()
freeminer.after(3, function()
freeminer.chat_send_all("The profiler was started. If you don't want this, set " .. freeminer.colorize("61ad6d", "profiler_autostart")
.. " to false in " .. freeminer.colorize("61ad6d", "freeminer.conf"))
end)
end
freeminer.register_chatcommand("profiler_stop", {
description = "stop the profiler and write report",
privs = {server=true},
func = function(name)
if not started then
freeminer.chat_send_player(name, "Profiler has not been started. You can start it using " .. freeminer.colorize("00ffff", "/profiler_start"))
return
end
ProFi:stop()
ProFi:writeReport("profile.txt")
freeminer.chat_send_player(name, "Profiler is stopped.")
end,
})
freeminer.register_chatcommand("profiler_start", {
description = "start the profiler",
privs = {server=true},
func = function(name)
if started then
freeminer.chat_send_player(name, "Profiler is already running.")
return
end
start_profiler()
freeminer.chat_send_player(name, "Profiler is started.")
end
})