update the UI
|
@ -155,33 +155,33 @@ function dump(o, indent, nested, level)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function string.split(str, delim, include_empty, max_splits)
|
||||
-- Localize functions to avoid table lookups (better performance).
|
||||
local table_insert = table.insert
|
||||
local str_sub, str_find = string.sub, string.find
|
||||
function string.split(str, delim, include_empty, max_splits, sep_is_pattern)
|
||||
delim = delim or ","
|
||||
max_splits = max_splits or 0
|
||||
local fields = {}
|
||||
local num_splits = 0
|
||||
local last_pos = 0
|
||||
for part, pos in str:gmatch("(.-)[" .. delim .. "]()") do
|
||||
last_pos = pos
|
||||
if include_empty or part ~= "" then
|
||||
num_splits = num_splits + 1
|
||||
fields[num_splits] = part
|
||||
if max_splits > 0 and num_splits + 1 >= max_splits then
|
||||
break
|
||||
end
|
||||
max_splits = max_splits or -1
|
||||
local items = {}
|
||||
local pos, len, seplen = 1, #str, #delim
|
||||
local plain = not sep_is_pattern
|
||||
max_splits = max_splits + 1
|
||||
repeat
|
||||
local np, npe = str_find(str, delim, pos, plain)
|
||||
np, npe = (np or (len+1)), (npe or (len+1))
|
||||
if (not np) or (max_splits == 1) then
|
||||
np = len + 1
|
||||
npe = np
|
||||
end
|
||||
end
|
||||
-- Handle the last field
|
||||
if max_splits <= 0 or num_splits <= max_splits then
|
||||
local last_part = str:sub(last_pos)
|
||||
if include_empty or last_part ~= "" then
|
||||
fields[num_splits + 1] = last_part
|
||||
local s = str_sub(str, pos, np - 1)
|
||||
if include_empty or (s ~= "") then
|
||||
max_splits = max_splits - 1
|
||||
table_insert(items, s)
|
||||
end
|
||||
end
|
||||
return fields
|
||||
pos = npe + 1
|
||||
until (max_splits == 0) or (pos > (len + 1))
|
||||
return items
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function file_exists(filename)
|
||||
local f = io.open(filename, "r")
|
||||
|
@ -498,22 +498,58 @@ function core.explode_scrollbar_event(evt)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function core.pos_to_string(pos)
|
||||
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
|
||||
function core.pos_to_string(pos, decimal_places)
|
||||
local x = pos.x
|
||||
local y = pos.y
|
||||
local z = pos.z
|
||||
if decimal_places ~= nil then
|
||||
x = string.format("%." .. decimal_places .. "f", x)
|
||||
y = string.format("%." .. decimal_places .. "f", y)
|
||||
z = string.format("%." .. decimal_places .. "f", z)
|
||||
end
|
||||
return "(" .. x .. "," .. y .. "," .. z .. ")"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function core.string_to_pos(value)
|
||||
if value == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||
if p.x and p.y and p.z then
|
||||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
return p
|
||||
end
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
||||
if p.x and p.y and p.z then
|
||||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
return p
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
assert(core.string_to_pos("10.0, 5, -2").x == 10)
|
||||
assert(core.string_to_pos("( 10.0, 5, -2)").z == -2)
|
||||
assert(core.string_to_pos("asd, 5, -2)") == nil)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function table.copy(t, seen)
|
||||
local n = {}
|
||||
seen = seen or {}
|
||||
seen[t] = n
|
||||
for k, v in pairs(t) do
|
||||
n[type(k) ~= "table" and k or seen[k] or table.copy(k, seen)] =
|
||||
type(v) ~= "table" and v or seen[v] or table.copy(v, seen)
|
||||
n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] =
|
||||
(type(v) == "table" and (seen[v] or table.copy(v, seen))) or v
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- mainmenu only functions
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -528,7 +564,7 @@ if INIT == "mainmenu" then
|
|||
return nil
|
||||
end
|
||||
|
||||
function fgettext(text, ...)
|
||||
function fgettext_ne(text, ...)
|
||||
text = core.gettext(text)
|
||||
local arg = {n=select('#', ...), ...}
|
||||
if arg.n >= 1 then
|
||||
|
@ -550,7 +586,11 @@ if INIT == "mainmenu" then
|
|||
end
|
||||
text = result
|
||||
end
|
||||
return core.formspec_escape(text)
|
||||
return text
|
||||
end
|
||||
|
||||
function fgettext(text, ...)
|
||||
return core.formspec_escape(fgettext_ne(text, ...))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -115,11 +115,20 @@ function core.serialize(x)
|
|||
function dump_val(x)
|
||||
local tp = type(x)
|
||||
if x == nil then return "nil"
|
||||
elseif tp == "number" then return tostring(x)
|
||||
elseif tp == "string" then return string.format("%q", x)
|
||||
elseif tp == "boolean" then return x and "true" or "false"
|
||||
elseif tp == "function" then
|
||||
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
|
||||
local vals = {}
|
||||
local idx_dumped = {}
|
||||
|
@ -140,7 +149,7 @@ function core.serialize(x)
|
|||
end
|
||||
return "{"..table.concat(vals, ", ").."}"
|
||||
else
|
||||
error("Can't serialize data of type "..t)
|
||||
error("Can't serialize data of type "..tp)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ function meta:__newindex(name, value)
|
|||
info.currentline, name)
|
||||
if not warned[warn_key] and info.what ~= "main" and
|
||||
info.what ~= "C" then
|
||||
minetest.log("error", ("Assignment to undeclared "..
|
||||
warn(("Assignment to undeclared "..
|
||||
"global %q inside a function at %s.")
|
||||
:format(name, desc))
|
||||
warned[warn_key] = true
|
||||
|
|
|
@ -94,23 +94,31 @@ core.builtin_auth_handler = {
|
|||
end
|
||||
-- Figure out what privileges the player should have.
|
||||
-- Take a copy of the privilege table
|
||||
local privileges = {}
|
||||
for priv, _ in pairs(core.auth_table[name].privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
-- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
|
||||
if core.is_singleplayer() then
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
if def.give_to_singleplayer then
|
||||
privileges[priv] = true
|
||||
end
|
||||
end
|
||||
-- For the admin, give everything
|
||||
elseif name == core.setting_get("name") then
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
end
|
||||
local privileges = {}
|
||||
for priv, _ in pairs(core.auth_table[name].privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
--[[
|
||||
-- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
|
||||
if core.is_singleplayer() then
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
if def.give_to_singleplayer then
|
||||
privileges[priv] = true
|
||||
end
|
||||
end
|
||||
-- For the admin, give everything
|
||||
elseif name == core.setting_get("name") then
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
end
|
||||
--]]
|
||||
if minetest.setting_getbool("creative_mode") then
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
else
|
||||
end
|
||||
-- All done
|
||||
return {
|
||||
password = core.auth_table[name].password,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
minetest.register_biome({
|
||||
name = "Grass",
|
||||
|
||||
heat_point = 50.0,
|
||||
humidity_point = 50.0,
|
||||
height_min = -31000,
|
||||
height_max = 31000,
|
||||
})
|
||||
|
|
@ -229,21 +229,28 @@ core.register_chatcommand("setpassword", {
|
|||
if not toname then
|
||||
return false, "Name field required"
|
||||
end
|
||||
local actstr = "?"
|
||||
local act_str_past = "?"
|
||||
local act_str_pres = "?"
|
||||
if not raw_password then
|
||||
core.set_player_password(toname, "")
|
||||
actstr = "cleared"
|
||||
act_str_past = "cleared"
|
||||
act_str_pres = "clears"
|
||||
else
|
||||
core.set_player_password(toname,
|
||||
core.get_password_hash(toname,
|
||||
raw_password))
|
||||
actstr = "set"
|
||||
act_str_past = "set"
|
||||
act_str_pres = "sets"
|
||||
end
|
||||
if toname ~= name then
|
||||
core.chat_send_player(toname, "Your password was "
|
||||
.. actstr .. " by " .. name)
|
||||
.. act_str_past .. " by " .. name)
|
||||
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,
|
||||
})
|
||||
|
||||
|
@ -257,6 +264,9 @@ core.register_chatcommand("clearpassword", {
|
|||
return false, "Name field required"
|
||||
end
|
||||
core.set_player_password(toname, '')
|
||||
|
||||
core.log("action", name .. " clears password of " .. toname .. ".")
|
||||
|
||||
return true, "Password of player \"" .. toname .. "\" cleared"
|
||||
end,
|
||||
})
|
||||
|
@ -403,6 +413,51 @@ core.register_chatcommand("set", {
|
|||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("deleteblocks", {
|
||||
params = "(here [radius]) | (<pos1> <pos2>)",
|
||||
description = "delete map blocks contained in area pos1 to pos2",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local p1 = {}
|
||||
local p2 = {}
|
||||
local args = param:split(" ")
|
||||
if args[1] == "here" then
|
||||
local player = core.get_player_by_name(name)
|
||||
if player == nil then
|
||||
core.log("error", "player is nil")
|
||||
return false, "Unable to get current position; player is nil"
|
||||
end
|
||||
p1 = player:getpos()
|
||||
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
|
||||
local pos1, pos2 = unpack(param:split(") ("))
|
||||
if pos1 == nil or pos2 == nil then
|
||||
return false, "Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)"
|
||||
end
|
||||
|
||||
p1 = core.string_to_pos(pos1 .. ")")
|
||||
p2 = core.string_to_pos("(" .. pos2)
|
||||
|
||||
if p1 == nil or p2 == nil then
|
||||
return false, "Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)"
|
||||
end
|
||||
end
|
||||
|
||||
if core.delete_area(p1, p2) then
|
||||
return true, "Successfully cleared area ranging from " ..
|
||||
core.pos_to_string(p1, 1) .. " to " .. core.pos_to_string(p2, 1)
|
||||
else
|
||||
return false, "Failed to clear one or more blocks in area"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("mods", {
|
||||
params = "",
|
||||
description = "List mods installed on the server",
|
||||
|
@ -532,6 +587,9 @@ core.register_chatcommand("rollback_check", {
|
|||
.. " seconds=86400=24h, limit=5)",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local range, seconds, limit =
|
||||
param:match("(%d+) *(%d*) *(%d*)")
|
||||
range = tonumber(range) or 0
|
||||
|
@ -545,6 +603,10 @@ core.register_chatcommand("rollback_check", {
|
|||
local name = puncher:get_player_name()
|
||||
core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...")
|
||||
local actions = core.rollback_get_node_actions(pos, range, seconds, limit)
|
||||
if not actions then
|
||||
core.chat_send_player(name, "Rollback functions are disabled")
|
||||
return
|
||||
end
|
||||
local num_actions = #actions
|
||||
if num_actions == 0 then
|
||||
core.chat_send_player(name, "Nobody has touched"
|
||||
|
@ -576,6 +638,9 @@ core.register_chatcommand("rollback", {
|
|||
description = "revert actions of a player; default for <seconds> is 60",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
|
||||
if not target_name then
|
||||
local player_name = nil
|
||||
|
|
|
@ -25,5 +25,4 @@ dofile(gamepath.."features.lua")
|
|||
dofile(gamepath.."voxelarea.lua")
|
||||
dofile(gamepath.."forceloading.lua")
|
||||
dofile(gamepath.."statbars.lua")
|
||||
dofile(gamepath.."builtin_biome.lua")
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ function core.facedir_to_dir(facedir)
|
|||
{x=0, y=1, z=0}})
|
||||
|
||||
--indexed into by a table of correlating facedirs
|
||||
[({[0]=1, 2, 3, 4,
|
||||
[({[0]=1, 2, 3, 4,
|
||||
5, 2, 6, 4,
|
||||
6, 2, 5, 4,
|
||||
1, 5, 3, 6,
|
||||
|
@ -238,7 +238,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
|||
|
||||
core.log("action", placer:get_player_name() .. " places node "
|
||||
.. def.name .. " at " .. core.pos_to_string(place_to))
|
||||
|
||||
|
||||
local oldnode = core.get_node(place_to)
|
||||
local newnode = {name = def.name, param1 = 0, param2 = param2}
|
||||
|
||||
|
@ -357,19 +357,37 @@ function core.item_drop(itemstack, dropper, pos)
|
|||
return itemstack
|
||||
end
|
||||
|
||||
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
|
||||
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||
if result then
|
||||
return result
|
||||
function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||
for _, callback in pairs(core.registered_on_item_eats) do
|
||||
local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
|
||||
if result then
|
||||
return result
|
||||
end
|
||||
end
|
||||
if itemstack:take_item() ~= nil then
|
||||
user:set_hp(user:get_hp() + hp_change)
|
||||
|
||||
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
|
||||
if itemstack:take_item() ~= nil then
|
||||
user:set_hp(user:get_hp() + hp_change)
|
||||
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
return itemstack
|
||||
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
|
||||
|
||||
|
@ -425,7 +443,7 @@ function core.node_dig(pos, node, digger)
|
|||
|
||||
local wielded = digger:get_wielded_item()
|
||||
local drops = core.get_node_drops(node.name, wielded:get_name())
|
||||
|
||||
|
||||
local wdef = wielded:get_definition()
|
||||
local tp = wielded:get_tool_capabilities()
|
||||
local dp = core.get_dig_params(def.groups, tp)
|
||||
|
@ -438,7 +456,7 @@ function core.node_dig(pos, node, digger)
|
|||
end
|
||||
end
|
||||
digger:set_wielded_item(wielded)
|
||||
|
||||
|
||||
-- Handle drops
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
|
||||
|
@ -449,7 +467,7 @@ function core.node_dig(pos, node, digger)
|
|||
|
||||
-- Remove node and update
|
||||
core.remove_node(pos)
|
||||
|
||||
|
||||
-- Run callback
|
||||
if def.after_dig_node then
|
||||
-- Copy pos and node because callback can modify them
|
||||
|
@ -507,7 +525,7 @@ core.nodedef_default = {
|
|||
on_dig = redef_wrapper(core, 'node_dig'), -- core.node_dig
|
||||
|
||||
on_receive_fields = nil,
|
||||
|
||||
|
||||
on_metadata_inventory_move = core.node_metadata_inventory_move_allow_all,
|
||||
on_metadata_inventory_offer = core.node_metadata_inventory_offer_allow_all,
|
||||
on_metadata_inventory_take = core.node_metadata_inventory_take_allow_all,
|
||||
|
|
|
@ -93,30 +93,6 @@ function core.get_node_group(name, group)
|
|||
return core.get_item_group(name, group)
|
||||
end
|
||||
|
||||
function core.string_to_pos(value)
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||
if p.x and p.y and p.z then
|
||||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
return p
|
||||
end
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
||||
if p.x and p.y and p.z then
|
||||
p.x = tonumber(p.x)
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
return p
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
assert(core.string_to_pos("10.0, 5, -2").x == 10)
|
||||
assert(core.string_to_pos("( 10.0, 5, -2)").z == -2)
|
||||
assert(core.string_to_pos("asd, 5, -2)") == nil)
|
||||
|
||||
function core.setting_get_pos(name)
|
||||
local value = core.setting_get(name)
|
||||
if not value then
|
||||
|
|
|
@ -226,13 +226,6 @@ function core.register_alias(name, convert_to)
|
|||
end
|
||||
end
|
||||
|
||||
local register_biome_raw = core.register_biome
|
||||
core.registered_biomes = {}
|
||||
function core.register_biome(biome)
|
||||
core.registered_biomes[biome.name] = biome
|
||||
register_biome_raw(biome)
|
||||
end
|
||||
|
||||
function core.on_craft(itemstack, player, old_craft_list, craft_inv)
|
||||
for _, func in ipairs(core.registered_on_crafts) do
|
||||
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
|
||||
|
@ -387,10 +380,38 @@ local function make_registration_reverse()
|
|||
return t, registerfunc
|
||||
end
|
||||
|
||||
local function make_registration_wrap(reg_fn_name, clear_fn_name)
|
||||
local list = {}
|
||||
|
||||
local orig_reg_fn = core[reg_fn_name]
|
||||
core[reg_fn_name] = function(def)
|
||||
local retval = orig_reg_fn(def)
|
||||
if retval ~= nil then
|
||||
if def.name ~= nil then
|
||||
list[def.name] = def
|
||||
else
|
||||
list[retval] = def
|
||||
end
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
local orig_clear_fn = core[clear_fn_name]
|
||||
core[clear_fn_name] = function()
|
||||
list = {}
|
||||
return orig_clear_fn()
|
||||
end
|
||||
|
||||
return list
|
||||
end
|
||||
|
||||
core.registered_biomes = make_registration_wrap("register_biome", "clear_registered_biomes")
|
||||
core.registered_ores = make_registration_wrap("register_ore", "clear_registered_ores")
|
||||
core.registered_decorations = make_registration_wrap("register_decoration", "clear_registered_decorations")
|
||||
|
||||
core.registered_on_chat_messages, core.register_on_chat_message = make_registration()
|
||||
core.registered_globalsteps, core.register_globalstep = make_registration()
|
||||
core.registered_playerevents, core.register_playerevent = make_registration()
|
||||
core.registered_on_mapgen_inits, core.register_on_mapgen_init = make_registration()
|
||||
core.registered_on_shutdown, core.register_on_shutdown = make_registration()
|
||||
core.registered_on_punchnodes, core.register_on_punchnode = make_registration()
|
||||
core.registered_on_placenodes, core.register_on_placenode = make_registration()
|
||||
|
@ -409,3 +430,9 @@ 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_item_eats, core.register_on_item_eat = make_registration()
|
||||
|
||||
--
|
||||
-- Compatibility for on_mapgen_init()
|
||||
--
|
||||
|
||||
core.register_on_mapgen_init = function(func) func(core.get_mapgen_params()) end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ local health_bar_definition =
|
|||
number = 20,
|
||||
direction = 0,
|
||||
size = { x=24, y=24 },
|
||||
offset = { x=(-10*24)-25, y=-(48+24+10)},
|
||||
offset = { x=(-10*24)-25, y=-(48+24+16)},
|
||||
}
|
||||
|
||||
local breath_bar_definition =
|
||||
|
@ -18,7 +18,7 @@ local breath_bar_definition =
|
|||
number = 20,
|
||||
direction = 0,
|
||||
size = { x=24, y=24 },
|
||||
offset = {x=25,y=-(48+24+10)},
|
||||
offset = {x=25,y=-(48+24+16)},
|
||||
}
|
||||
|
||||
local hud_ids = {}
|
||||
|
|
|
@ -16,9 +16,15 @@
|
|||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
--------------------------------------------------------------------------------
|
||||
-- Global menu data
|
||||
---------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
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
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -34,6 +40,33 @@ local function render_client_count(n)
|
|||
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(fav.proto_min, 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(fav.proto_min, fav.proto_max) then
|
||||
table.insert(res, fav)
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function render_favorite(spec,render_details)
|
||||
local text = ""
|
||||
|
@ -60,6 +93,7 @@ function render_favorite(spec,render_details)
|
|||
end
|
||||
|
||||
local details = ""
|
||||
local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
|
||||
|
||||
if spec.clients ~= nil and spec.clients_max ~= nil then
|
||||
local clients_color = ''
|
||||
|
@ -79,11 +113,17 @@ function render_favorite(spec,render_details)
|
|||
clients_color = '#ffba97' -- 90-100%: orange
|
||||
end
|
||||
|
||||
if grey_out then
|
||||
clients_color = '#aaaaaa'
|
||||
end
|
||||
|
||||
details = details ..
|
||||
clients_color .. ',' ..
|
||||
render_client_count(spec.clients) .. ',' ..
|
||||
'/,' ..
|
||||
render_client_count(spec.clients_max) .. ','
|
||||
elseif grey_out then
|
||||
details = details .. '#aaaaaa,?,/,?,'
|
||||
else
|
||||
details = details .. ',?,/,?,'
|
||||
end
|
||||
|
@ -106,7 +146,7 @@ function render_favorite(spec,render_details)
|
|||
details = details .. "0,"
|
||||
end
|
||||
|
||||
return details .. text
|
||||
return details .. (grey_out and '#aaaaaa,' or ',') .. text
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -186,8 +226,10 @@ function asyncOnlineFavourites()
|
|||
end,
|
||||
nil,
|
||||
function(result)
|
||||
menudata.favorites = result
|
||||
core.event_handler("Refresh")
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
menudata.favorites = order_favorite_list(result)
|
||||
core.event_handler("Refresh")
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
@ -215,3 +257,21 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
|
|||
|
||||
return retval
|
||||
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
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
--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)
|
||||
|
||||
|
@ -118,6 +121,7 @@ local function handle_buttons(this, fields)
|
|||
if fields["world_config_modlist"] ~= nil then
|
||||
local event = core.explode_textlist_event(fields["world_config_modlist"])
|
||||
this.data.selected_mod = event.index
|
||||
core.setting_set("world_config_selected_mod", event.index)
|
||||
|
||||
if event.type == "DCL" then
|
||||
enable_mod(this)
|
||||
|
@ -151,21 +155,29 @@ local function handle_buttons(this, fields)
|
|||
if current == nil then
|
||||
current = {}
|
||||
end
|
||||
|
||||
if core.is_yes(fields["cb_hide_gamemods"]) then
|
||||
current.hide_game = true
|
||||
this.data.hide_gamemods = true
|
||||
else
|
||||
current.hide_game = false
|
||||
this.data.hide_gamemods = false
|
||||
end
|
||||
|
||||
if core.is_yes(fields["cb_hide_mpcontent"]) then
|
||||
current.hide_modpackcontents = true
|
||||
this.data.hide_modpackcontents = true
|
||||
else
|
||||
current.hide_modpackcontents = false
|
||||
this.data.hide_modpackcontents = false
|
||||
if fields["cb_hide_gamemods"] ~= nil then
|
||||
if core.is_yes(fields["cb_hide_gamemods"]) then
|
||||
current.hide_game = true
|
||||
this.data.hide_gamemods = true
|
||||
core.setting_set("world_config_hide_gamemods", "true")
|
||||
else
|
||||
current.hide_game = false
|
||||
this.data.hide_gamemods = false
|
||||
core.setting_set("world_config_hide_gamemods", "false")
|
||||
end
|
||||
end
|
||||
|
||||
if fields["cb_hide_mpcontent"] ~= nil then
|
||||
if core.is_yes(fields["cb_hide_mpcontent"]) then
|
||||
current.hide_modpackcontents = true
|
||||
this.data.hide_modpackcontents = true
|
||||
core.setting_set("world_config_hide_modpackcontents", "true")
|
||||
else
|
||||
current.hide_modpackcontents = false
|
||||
this.data.hide_modpackcontents = false
|
||||
core.setting_set("world_config_hide_modpackcontents", "false")
|
||||
end
|
||||
end
|
||||
|
||||
this.data.list:set_filtercriteria(current)
|
||||
|
@ -186,10 +198,12 @@ local function handle_buttons(this, fields)
|
|||
for i,mod in ipairs(rawlist) do
|
||||
if not mod.is_modpack and
|
||||
mod.typ ~= "game_mod" then
|
||||
if mod.enabled then
|
||||
worldfile:set("load_mod_"..mod.name, "true")
|
||||
if modname_valid(mod.name) then
|
||||
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
|
||||
else
|
||||
worldfile:set("load_mod_"..mod.name, "false")
|
||||
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)
|
||||
end
|
||||
end
|
||||
mods["load_mod_"..mod.name] = nil
|
||||
end
|
||||
|
@ -237,10 +251,12 @@ function create_configure_world_dlg(worldidx)
|
|||
handle_buttons,
|
||||
nil)
|
||||
|
||||
--TODO read from settings
|
||||
dlg.data.hide_gamemods = false
|
||||
dlg.data.hide_modpackcontents = false
|
||||
dlg.data.selected_mod = 0
|
||||
dlg.data.hide_gamemods = core.setting_getbool("world_config_hide_gamemods")
|
||||
dlg.data.hide_modpackcontents = core.setting_getbool("world_config_hide_modpackcontents")
|
||||
dlg.data.selected_mod = tonumber(core.setting_get("world_config_selected_mod"))
|
||||
if dlg.data.selected_mod == nil then
|
||||
dlg.data.selected_mod = 0
|
||||
end
|
||||
|
||||
dlg.data.worldspec = core.get_worlds()[worldidx]
|
||||
if dlg.data.worldspec == nil then dlg:delete() return nil end
|
||||
|
@ -277,7 +293,12 @@ function create_configure_world_dlg(worldidx)
|
|||
{ worldpath= dlg.data.worldspec.path,
|
||||
gameid = dlg.data.worldspec.gameid }
|
||||
)
|
||||
|
||||
|
||||
|
||||
if dlg.data.selected_mod > dlg.data.list:size() then
|
||||
dlg.data.selected_mod = 0
|
||||
end
|
||||
|
||||
dlg.data.list:set_filtercriteria(
|
||||
{
|
||||
hide_game=dlg.data.hide_gamemods,
|
||||
|
@ -285,6 +306,6 @@ function create_configure_world_dlg(worldidx)
|
|||
})
|
||||
dlg.data.list:add_sort_mechanism("alphabetic", sort_mod_list)
|
||||
dlg.data.list:set_sortmode("alphabetic")
|
||||
|
||||
|
||||
return dlg
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local function create_world_formspec(dialogdata)
|
||||
local mapgens = {"v5", "v6", "v7", "singlenode"}
|
||||
local mapgens = core.get_mapgen_names()
|
||||
|
||||
local current_seed = core.setting_get("fixed_map_seed") or ""
|
||||
local current_mg = core.setting_get("mg_name")
|
||||
|
@ -90,6 +90,8 @@ local function create_world_buttonhandler(this, fields)
|
|||
|
||||
local message = nil
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if not menudata.worldlist:uid_exists_raw(worldname) then
|
||||
core.setting_set("mg_name",fields["dd_mapgen"])
|
||||
message = core.create_world(worldname,gameindex)
|
||||
|
@ -97,8 +99,6 @@ local function create_world_buttonhandler(this, fields)
|
|||
message = fgettext("A world named \"$1\" already exists", worldname)
|
||||
end
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if message ~= nil then
|
||||
gamedata.errormessage = message
|
||||
else
|
||||
|
|
|
@ -41,7 +41,7 @@ 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")
|
||||
|
@ -51,9 +51,7 @@ if PLATFORM ~= "Android" then
|
|||
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)
|
||||
|
@ -69,7 +67,6 @@ local function init_globals()
|
|||
gamedata.worldindex = 0
|
||||
|
||||
|
||||
if PLATFORM ~= "Android" then
|
||||
menudata.worldlist = filterlist.create(
|
||||
core.get_worlds,
|
||||
compare_worlds,
|
||||
|
@ -92,68 +89,46 @@ local function init_globals()
|
|||
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)
|
||||
--if PLATFORM ~= "Android" then
|
||||
-- tv_main:add(tab_texturepacks)
|
||||
--end
|
||||
--tv_main:add(tab_mods)
|
||||
|
||||
if core.setting_get("os_type") == "Android" then
|
||||
tv_main:add(tab_credits)
|
||||
end
|
||||
|
||||
tv_main:set_global_event_handler(main_event_handler)
|
||||
-- if PLATFORM ~= "Android" then
|
||||
-- tv_main:set_fixed_size(true)
|
||||
-- else
|
||||
-- tv_main:set_fixed_size(false)
|
||||
-- end
|
||||
|
||||
|
||||
if PLATFORM == "Android" then
|
||||
tv_main:set_fixed_size(false)
|
||||
else
|
||||
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
|
||||
--if PLATFORM == "Android" then
|
||||
-- modstore.init({x=12, y=6}, 3, 2)
|
||||
--else
|
||||
-- modstore.init({x=12, y=8}, 4, 3)
|
||||
--end
|
||||
|
||||
ui.update()
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
-- helper file to be able to debug the simple menu on PC
|
||||
-- without messing around with actual menu code!
|
||||
PLATFORM="mobile"
|
||||
dofile("builtin/mainmenu/init.lua")
|
|
@ -122,35 +122,36 @@ end
|
|||
function modstore.showdownloading(title)
|
||||
local new_dlg = dialog_create("store_downloading",
|
||||
function(data)
|
||||
return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") ..
|
||||
" " .. data.title .. " " ..
|
||||
fgettext("please wait...") .. "]"
|
||||
return "size[6,2]label[0.25,0.75;" ..
|
||||
fgettext("Downloading $1, please wait...", data.title) .. "]"
|
||||
end,
|
||||
function(this,fields)
|
||||
if fields["btn_hidden_close_download"] ~= nil then
|
||||
if fields["btn_hidden_close_download"].successfull then
|
||||
modstore.lastmodentry = fields["btn_hidden_close_download"]
|
||||
modstore.successfulldialog()
|
||||
modstore.successfulldialog(this)
|
||||
else
|
||||
this.parent:show()
|
||||
this:delete()
|
||||
modstore.lastmodtitle = ""
|
||||
end
|
||||
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
nil,
|
||||
modstore.tv_store)
|
||||
nil)
|
||||
|
||||
new_dlg:set_parent(modstore.tv_store)
|
||||
modstore.tv_store:hide()
|
||||
new_dlg.data.title = title
|
||||
new_dlg:show()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- @function [parent=#modstore] successfulldialog
|
||||
function modstore.successfulldialog()
|
||||
function modstore.successfulldialog(downloading_dlg)
|
||||
local new_dlg = dialog_create("store_downloading",
|
||||
function(data)
|
||||
local retval = ""
|
||||
|
@ -158,18 +159,16 @@ function modstore.successfulldialog()
|
|||
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") .. "]"
|
||||
retval = retval .. "button[2.2,1.5;1.5,0.5;btn_confirm_mod_successfull;" .. fgettext("Ok") .. "]"
|
||||
return retval
|
||||
end,
|
||||
function(this,fields)
|
||||
if fields["btn_confirm_mod_successfull"] ~= nil then
|
||||
this.parent:show()
|
||||
this:hide()
|
||||
downloading_dlg:delete()
|
||||
this:delete()
|
||||
|
||||
return true
|
||||
|
@ -177,10 +176,10 @@ function modstore.successfulldialog()
|
|||
|
||||
return false
|
||||
end,
|
||||
nil,
|
||||
modstore.tv_store)
|
||||
nil)
|
||||
|
||||
new_dlg.data.title = title
|
||||
new_dlg:set_parent(modstore.tv_store)
|
||||
modstore.tv_store:hide()
|
||||
new_dlg:show()
|
||||
end
|
||||
|
||||
|
@ -217,7 +216,9 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
end
|
||||
|
||||
if fields["btn_modstore_close"] then
|
||||
local maintab = ui.find_by_name("maintab")
|
||||
parent:hide()
|
||||
maintab:show()
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -228,12 +229,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
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
|
||||
modstore.lastmodtitle = moddetails.title
|
||||
|
||||
if not core.handle_async(
|
||||
function(param)
|
||||
|
@ -281,7 +277,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
texturename = modstore.modlist_unsorted.data[i].texturename
|
||||
},
|
||||
function(result)
|
||||
print("Result from async: " .. dump(result.successfull))
|
||||
--print("Result from async: " .. dump(result.successfull))
|
||||
if result.successfull then
|
||||
modmgr.installmod(result.filename,result.moddetails.basename)
|
||||
os.remove(result.filename)
|
||||
|
@ -299,7 +295,7 @@ function modstore.handle_buttons(parent, fields, name, data)
|
|||
print("ERROR: async event failed")
|
||||
gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle
|
||||
end
|
||||
parent:hide()
|
||||
|
||||
modstore.showdownloading(modstore.lastmodtitle)
|
||||
return true
|
||||
end
|
||||
|
@ -391,7 +387,7 @@ function modstore.getscreenshot(ypos,listentry)
|
|||
listentry.details.screenshot_url == "") then
|
||||
|
||||
if listentry.texturename == nil then
|
||||
listentry.texturename = modstore.basetexturedir .. "no_screenshot.png"
|
||||
listentry.texturename = defaulttexturedir .. "no_screenshot.png"
|
||||
end
|
||||
|
||||
return "image[0,".. ypos .. ";3,2;" ..
|
||||
|
|
|
@ -57,7 +57,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
end
|
||||
|
||||
if modscreenshot == nil then
|
||||
modscreenshot = modstore.basetexturedir .. "no_screenshot.png"
|
||||
modscreenshot = defaulttexturedir .. "no_screenshot.png"
|
||||
end
|
||||
|
||||
retval = retval
|
||||
|
@ -96,7 +96,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
else
|
||||
--show dependencies
|
||||
|
||||
retval = retval .. ",Depends:,"
|
||||
retval = retval .. "," .. fgettext("Depends:") .. ","
|
||||
|
||||
local toadd = modmgr.get_dependencies(selected_mod.path)
|
||||
|
||||
|
|
|
@ -20,26 +20,27 @@ local function get_formspec(tabview, name, tabdata)
|
|||
local render_details = core.is_yes(core.setting_getbool("public_serverlist"))
|
||||
|
||||
local retval =
|
||||
"label[0,4.25;" .. fgettext("Address/Port") .. "]" ..
|
||||
"label[9,2.75;" .. fgettext("Name/Password") .. "]" ..
|
||||
"field[0.25,5.25;5.5,0.5;te_address;;" ..
|
||||
"label[7.75,-0.15;" .. fgettext("Address / Port :") .. "]" ..
|
||||
"label[7.75,1.05;" .. fgettext("Name/Password") .. "]" ..
|
||||
"field[8,0.75;3.4,0.5;te_address;;" ..
|
||||
core.formspec_escape(core.setting_get("address")) .. "]" ..
|
||||
"field[5.75,5.25;2.25,0.5;te_port;;" ..
|
||||
"field[11.25,0.75;1.3,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.setting_get("remote_port")) .. "]" ..
|
||||
"checkbox[0,3.6;cb_public_serverlist;" .. fgettext("Public Serverlist") .. ";" ..
|
||||
"checkbox[0,4.85;cb_public_serverlist;" .. fgettext("Public Serverlist") .. ";" ..
|
||||
dump(core.setting_getbool("public_serverlist")) .. "]"
|
||||
|
||||
if not core.setting_getbool("public_serverlist") then
|
||||
retval = retval ..
|
||||
"button[6.45,3.95;2.25,0.5;btn_delete_favorite;" .. fgettext("Delete") .. "]"
|
||||
"button[8,4.9;2,0.5;btn_delete_favorite;" .. fgettext("Delete") .. "]"
|
||||
end
|
||||
|
||||
retval = retval ..
|
||||
"button[9,4.95;2.5,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" ..
|
||||
"field[9.3,3.75;2.5,0.5;te_name;;" ..
|
||||
"button[10,4.9;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" ..
|
||||
"field[8,1.95;2.95,0.5;te_name;;" ..
|
||||
core.formspec_escape(core.setting_get("name")) .. "]" ..
|
||||
"pwdfield[9.3,4.5;2.5,0.5;te_pwd;]" ..
|
||||
"textarea[9.3,0;2.5,3.1;;"
|
||||
"pwdfield[10.78,1.95;1.77,0.5;te_pwd;]" ..
|
||||
"box[7.73,2.35;4.3,2.28;#999999]" ..
|
||||
"textarea[8.1,2.4;4.26,2.6;;"
|
||||
|
||||
if tabdata.fav_selected ~= nil and
|
||||
menudata.favorites[tabdata.fav_selected] ~= nil and
|
||||
|
@ -52,27 +53,22 @@ local function get_formspec(tabview, name, tabdata)
|
|||
";]"
|
||||
|
||||
--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
|
||||
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("Creative mode", "creative") .. ",padding=1;" ..
|
||||
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||
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,0;8.5,3.7;favourites;"
|
||||
"table[-0.15,-0.1;7.75,5;favourites;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
retval = retval .. render_favorite(menudata.favorites[1],render_details)
|
||||
|
@ -93,7 +89,6 @@ end
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields["te_name"] ~= nil then
|
||||
gamedata.playername = fields["te_name"]
|
||||
core.setting_set("name", fields["te_name"])
|
||||
|
@ -103,6 +98,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
local event = core.explode_table_event(fields["favourites"])
|
||||
if event.type == "DCL" 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.port = menudata.favorites[event.row].port
|
||||
gamedata.playername = fields["te_name"]
|
||||
|
@ -194,7 +193,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
local current_favourite = core.get_table_index("favourites")
|
||||
if current_favourite == nil then return end
|
||||
core.delete_favorite(current_favourite)
|
||||
menudata.favorites = core.get_favorites()
|
||||
menudata.favorites = order_favorite_list(core.get_favorites())
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address","")
|
||||
|
@ -203,8 +202,9 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
return true
|
||||
end
|
||||
|
||||
if fields["btn_mp_connect"] ~= nil or
|
||||
fields["key_enter"] ~= nil then
|
||||
if (fields["btn_mp_connect"] ~= nil or
|
||||
fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and
|
||||
fields["te_port"] ~= nil then
|
||||
|
||||
gamedata.playername = fields["te_name"]
|
||||
gamedata.password = fields["te_pwd"]
|
||||
|
@ -219,6 +219,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
|
||||
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 = ""
|
||||
|
|
|
@ -25,15 +25,15 @@ local function get_formspec(tabview, name, tabdata)
|
|||
local retval =
|
||||
"button[4,4.15;2.6,0.5;world_delete;" .. fgettext("Delete") .. "]" ..
|
||||
"button[6.5,4.15;2.8,0.5;world_create;" .. fgettext("New") .. "]" ..
|
||||
"button[9.2,4.15;2.55,0.5;world_configure;" .. fgettext("Configure") .. "]" ..
|
||||
--"button[9.2,4.15;2.55,0.5;world_configure;" .. fgettext("Configure") .. "]" ..
|
||||
"button[8.5,4.95;3.25,0.5;start_server;" .. fgettext("Start Game") .. "]" ..
|
||||
"label[4,-0.25;" .. fgettext("Select World:") .. "]" ..
|
||||
"checkbox[0.25,0.25;cb_creative_mode;" .. fgettext("Creative Mode") .. ";" ..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]" ..
|
||||
"checkbox[0.25,0.7;cb_enable_damage;" .. fgettext("Enable Damage") .. ";" ..
|
||||
dump(core.setting_getbool("enable_damage")) .. "]" ..
|
||||
"checkbox[0.25,1.15;cb_server_announce;" .. fgettext("Public") .. ";" ..
|
||||
dump(core.setting_getbool("server_announce")) .. "]" ..
|
||||
--"checkbox[0.25,1.15;cb_server_announce;" .. fgettext("Public") .. ";" ..
|
||||
--dump(core.setting_getbool("server_announce")) .. "]" ..
|
||||
"label[0.25,2.2;" .. fgettext("Name/Password") .. "]" ..
|
||||
"field[0.55,3.2;3.5,0.5;te_playername;;" ..
|
||||
core.formspec_escape(core.setting_get("name")) .. "]" ..
|
||||
|
@ -48,6 +48,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
core.formspec_escape(core.setting_get("port")) .. "]"
|
||||
else
|
||||
retval = retval ..
|
||||
"label[4,4.8; IP Address: " .. core.setting_get("mobile_ip_address") .. "]" ..
|
||||
"field[0.55,5.2;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
|
||||
core.formspec_escape(core.setting_get("port")) .. "]"
|
||||
end
|
||||
|
|
|
@ -17,6 +17,60 @@
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local dd_filter_labels = {
|
||||
fgettext("No Filter"),
|
||||
fgettext("Bilinear Filter"),
|
||||
fgettext("Trilinear Filter")
|
||||
}
|
||||
|
||||
local filters = {
|
||||
{dd_filter_labels[1]..","..dd_filter_labels[2]..","..dd_filter_labels[3]},
|
||||
{"", "bilinear_filter", "trilinear_filter"},
|
||||
}
|
||||
|
||||
local dd_mipmap_labels = {
|
||||
fgettext("No Mipmap"),
|
||||
fgettext("Mipmap"),
|
||||
fgettext("Mipmap + Aniso. Filter")
|
||||
}
|
||||
|
||||
local mipmap = {
|
||||
{dd_mipmap_labels[1]..","..dd_mipmap_labels[2]..","..dd_mipmap_labels[3]},
|
||||
{"", "mip_map", "anisotropic_filter"},
|
||||
}
|
||||
|
||||
local function getFilterSettingIndex()
|
||||
if (core.setting_get(filters[2][3]) == "true") then
|
||||
return 3
|
||||
end
|
||||
if (core.setting_get(filters[2][3]) == "false" and core.setting_get(filters[2][2]) == "true") then
|
||||
return 2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
local function getMipmapSettingIndex()
|
||||
if (core.setting_get(mipmap[2][3]) == "true") then
|
||||
return 3
|
||||
end
|
||||
if (core.setting_get(mipmap[2][3]) == "false" and core.setting_get(mipmap[2][2]) == "true") then
|
||||
return 2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
local function video_driver_fname_to_name(selected_driver)
|
||||
local video_drivers = core.get_video_drivers()
|
||||
|
||||
for i=1, #video_drivers do
|
||||
if selected_driver == video_drivers[i].friendly_name then
|
||||
return video_drivers[i].name:lower()
|
||||
end
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
|
||||
local function dlg_confirm_reset_formspec(data)
|
||||
local retval =
|
||||
"size[8,3]" ..
|
||||
|
@ -76,17 +130,14 @@ local function showconfirm_reset(tabview)
|
|||
end
|
||||
|
||||
local function gui_scale_to_scrollbar()
|
||||
|
||||
local current_value = tonumber(core.setting_get("gui_scaling"))
|
||||
|
||||
if (current_value == nil) or current_value < 0.25 then
|
||||
return 0
|
||||
end
|
||||
|
||||
if current_value <= 1.25 then
|
||||
return ((current_value - 0.25)/ 1.0) * 700
|
||||
end
|
||||
|
||||
if current_value <= 6 then
|
||||
return ((current_value -1.25) * 100) + 700
|
||||
end
|
||||
|
@ -94,14 +145,28 @@ local function gui_scale_to_scrollbar()
|
|||
return 1000
|
||||
end
|
||||
|
||||
local function scrollbar_to_gui_scale(value)
|
||||
local function hud_scale_to_scrollbar()
|
||||
local current_value = tonumber(core.setting_get("hud_scaling"))
|
||||
|
||||
if (current_value == nil) or current_value < 0.25 then
|
||||
return 0
|
||||
end
|
||||
if current_value <= 1.25 then
|
||||
return ((current_value - 0.25)/ 1.0) * 700
|
||||
end
|
||||
if current_value <= 6 then
|
||||
return ((current_value -1.25) * 100) + 700
|
||||
end
|
||||
|
||||
return 1000
|
||||
end
|
||||
|
||||
local function scrollbar_to_gui_scale(value)
|
||||
value = tonumber(value)
|
||||
|
||||
if (value <= 700) then
|
||||
return ((value / 700) * 1.0) + 0.25
|
||||
end
|
||||
|
||||
if (value <=1000) then
|
||||
return ((value - 700) / 100) + 1.25
|
||||
end
|
||||
|
@ -111,26 +176,24 @@ end
|
|||
|
||||
local function formspec(tabview, name, tabdata)
|
||||
local video_drivers = core.get_video_drivers()
|
||||
|
||||
local video_driver_string = ""
|
||||
local current_video_driver_idx = 0
|
||||
local current_video_driver = core.setting_get("video_driver")
|
||||
for i=1, #video_drivers, 1 do
|
||||
|
||||
if i ~= 1 then
|
||||
video_driver_string = video_driver_string .. ","
|
||||
local current_video_driver = core.setting_get("video_driver"):lower()
|
||||
|
||||
local driver_formspec_string = ""
|
||||
local driver_current_idx = 0
|
||||
|
||||
for i=2, #video_drivers do
|
||||
driver_formspec_string = driver_formspec_string .. video_drivers[i].friendly_name
|
||||
if i ~= #video_drivers then
|
||||
driver_formspec_string = driver_formspec_string .. ","
|
||||
end
|
||||
video_driver_string = video_driver_string .. video_drivers[i]
|
||||
|
||||
local video_driver = string.gsub(video_drivers[i], " ", "")
|
||||
if current_video_driver:lower() == video_driver:lower() then
|
||||
current_video_driver_idx = i
|
||||
|
||||
if current_video_driver == video_drivers[i].name:lower() then
|
||||
driver_current_idx = i - 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local tab_string =
|
||||
"box[0,0;3.5,4;#999999]" ..
|
||||
"box[0,0;3.5,3.9;#999999]" ..
|
||||
"checkbox[0.25,0;cb_smooth_lighting;".. fgettext("Smooth Lighting")
|
||||
.. ";".. dump(core.setting_getbool("smooth_lighting")) .. "]"..
|
||||
"checkbox[0.25,0.5;cb_particles;".. fgettext("Enable Particles") .. ";"
|
||||
|
@ -143,49 +206,61 @@ local function formspec(tabview, name, tabdata)
|
|||
.. dump(core.setting_getbool("opaque_water")) .. "]"..
|
||||
"checkbox[0.25,2.5;cb_connected_glass;".. fgettext("Connected Glass") .. ";"
|
||||
.. dump(core.setting_getbool("connected_glass")) .. "]"..
|
||||
"dropdown[0.25,3.25;3.25;dd_video_driver;"
|
||||
.. video_driver_string .. ";" .. current_video_driver_idx .. "]" ..
|
||||
"tooltip[dd_video_driver;" ..
|
||||
fgettext("Restart minetest for driver change to take effect") .. "]" ..
|
||||
"checkbox[0.25,3.0;cb_node_highlighting;".. fgettext("Node Highlighting") .. ";"
|
||||
.. dump(core.setting_getbool("enable_node_highlighting")) .. "]"..
|
||||
"box[3.75,0;3.75,2.5;#999999]" ..
|
||||
"checkbox[4,0;cb_mipmapping;".. fgettext("Mip-Mapping") .. ";"
|
||||
.. dump(core.setting_getbool("mip_map")) .. "]"..
|
||||
"checkbox[4,0.5;cb_anisotrophic;".. fgettext("Anisotropic Filtering") .. ";"
|
||||
.. dump(core.setting_getbool("anisotropic_filter")) .. "]"..
|
||||
"checkbox[4,1.0;cb_bilinear;".. fgettext("Bi-Linear Filtering") .. ";"
|
||||
.. dump(core.setting_getbool("bilinear_filter")) .. "]"..
|
||||
"checkbox[4,1.5;cb_trilinear;".. fgettext("Tri-Linear Filtering") .. ";"
|
||||
.. dump(core.setting_getbool("trilinear_filter")) .. "]"..
|
||||
"label[3.85,0.1;".. fgettext("Texturing:") .. "]"..
|
||||
"dropdown[3.85,0.55;3.85;dd_filters;" .. filters[1][1] .. ";"
|
||||
.. getFilterSettingIndex() .. "]" ..
|
||||
"dropdown[3.85,1.35;3.85;dd_mipmap;" .. mipmap[1][1] .. ";"
|
||||
.. getMipmapSettingIndex() .. "]" ..
|
||||
--"label[3.85,2.15;".. fgettext("Rendering:") .. "]"..
|
||||
--"dropdown[3.85,2.6;3.85;dd_video_driver;"
|
||||
-- .. driver_formspec_string .. ";" .. driver_current_idx .. "]" ..
|
||||
--"tooltip[dd_video_driver;" ..
|
||||
-- fgettext("Restart minetest for driver change to take effect") .. "]" ..
|
||||
"box[7.75,0;4,4;#999999]" ..
|
||||
"checkbox[8,0;cb_shaders;".. fgettext("Shaders") .. ";"
|
||||
.. dump(core.setting_getbool("enable_shaders")) .. "]"
|
||||
if PLATFORM ~= "Android" then
|
||||
tab_string = tab_string ..
|
||||
"button[8,4.75;3.75,0.5;btn_change_keys;".. fgettext("Change keys") .. "]"
|
||||
else
|
||||
tab_string = tab_string ..
|
||||
"button[8,4.75;3.75,0.5;btn_reset_singleplayer;".. fgettext("Reset singleplayer world") .. "]"
|
||||
end
|
||||
|
||||
--if PLATFORM ~= "Android" then
|
||||
-- tab_string = tab_string ..
|
||||
-- "button[8,4.75;3.75,0.5;btn_change_keys;".. fgettext("Change keys") .. "]"
|
||||
--else
|
||||
-- tab_string = tab_string ..
|
||||
-- "button[8,4.75;3.75,0.5;btn_reset_singleplayer;".. fgettext("Reset singleplayer world") .. "]"
|
||||
--end
|
||||
tab_string = tab_string ..
|
||||
"box[0,4.25;3.5,1.25;#999999]" ..
|
||||
"box[0,4.25;3.5,1.3;#999999]" ..
|
||||
"label[0.25,4.25;" .. fgettext("GUI scale factor") .. "]" ..
|
||||
"scrollbar[0.25,4.75;3,0.4;sb_gui_scaling;horizontal;" ..
|
||||
"scrollbar[0.25,4.75;3,0.6;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 PLATFORM == "Android" then
|
||||
tab_string = tab_string ..
|
||||
"box[4.25,2.75;3.25,2.15;#999999]" ..
|
||||
"checkbox[4.5,2.75;cb_touchscreen_target;".. fgettext("Touch free target") .. ";"
|
||||
.. dump(core.setting_getbool("touchtarget")) .. "]"
|
||||
end
|
||||
tab_string = tab_string ..
|
||||
"box[3.75,2.9;3.75,1.1;#999999]" ..
|
||||
"label[4.3,2.8;" .. fgettext("Hud scale factor") .. "]" ..
|
||||
"scrollbar[3.9,3.3.5;3.5,0.6;sb_hud_scaling;horizontal;" ..
|
||||
hud_scale_to_scrollbar() .. "]" ..
|
||||
"tooltip[sb_hud_scaling;" ..
|
||||
fgettext("Scaling factor applied to menu elements: ") ..
|
||||
dump(core.setting_get("hud_scaling")) .. "]"
|
||||
|
||||
|
||||
--if PLATFORM == "Android" then
|
||||
-- tab_string = tab_string ..
|
||||
-- "box[3.75,3.55;3.75,1.8;#999999]" ..
|
||||
-- "checkbox[3.9,3.45;cb_touchscreen_target;".. fgettext("Touch free target") .. ";"
|
||||
-- .. dump(core.setting_getbool("touchtarget")) .. "]"
|
||||
--end
|
||||
|
||||
if core.setting_get("touchscreen_threshold") ~= nil then
|
||||
tab_string = tab_string ..
|
||||
"label[4.5,3.5;" .. fgettext("Touchthreshold (px)") .. "]" ..
|
||||
"dropdown[4.5,4;3;dd_touchthreshold;0,10,20,30,40,50;" ..
|
||||
"box[3.75,4.25;3.75,1.3;#999999]" ..
|
||||
"label[4.3,4.25;" .. fgettext("Touchthreshold (px)") .. "]" ..
|
||||
"dropdown[3.85,4.75;3.85;dd_touchthreshold;0,10,20,30,40,50;" ..
|
||||
((tonumber(core.setting_get("touchscreen_threshold"))/10)+1) .. "]"
|
||||
end
|
||||
|
||||
|
@ -233,22 +308,6 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
|||
core.setting_set("opaque_water", fields["cb_opaque_water"])
|
||||
return true
|
||||
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 (core.setting_get("video_driver") == "direct3d8" or core.setting_get("video_driver") == "direct3d9") then
|
||||
core.setting_set("enable_shaders", "false")
|
||||
|
@ -262,6 +321,10 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
|||
core.setting_set("connected_glass", fields["cb_connected_glass"])
|
||||
return true
|
||||
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
|
||||
core.setting_set("enable_particles", fields["cb_particles"])
|
||||
return true
|
||||
|
@ -301,6 +364,17 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
|||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if fields["sb_hud_scaling"] then
|
||||
local event = core.explode_scrollbar_event(fields["sb_hud_scaling"])
|
||||
|
||||
if event.type == "CHG" then
|
||||
local tosave = string.format("%.2f",scrollbar_to_gui_scale(event.value))
|
||||
core.setting_set("hud_scaling",tosave)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if fields["cb_touchscreen_target"] then
|
||||
core.setting_set("touchtarget", fields["cb_touchscreen_target"])
|
||||
return true
|
||||
|
@ -312,16 +386,48 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
|||
|
||||
--Note dropdowns have to be handled LAST!
|
||||
local ddhandled = false
|
||||
|
||||
if fields["dd_touchthreshold"] then
|
||||
core.setting_set("touchscreen_threshold",fields["dd_touchthreshold"])
|
||||
ddhandled = true
|
||||
end
|
||||
|
||||
if fields["dd_video_driver"] then
|
||||
local video_driver = string.gsub(fields["dd_video_driver"], " ", "")
|
||||
core.setting_set("video_driver",string.lower(video_driver))
|
||||
core.setting_set("video_driver",
|
||||
video_driver_fname_to_name(fields["dd_video_driver"]))
|
||||
ddhandled = true
|
||||
end
|
||||
|
||||
if fields["dd_filters"] == dd_filter_labels[1] then
|
||||
core.setting_set("bilinear_filter", "false")
|
||||
core.setting_set("trilinear_filter", "false")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_filters"] == dd_filter_labels[2] then
|
||||
core.setting_set("bilinear_filter", "true")
|
||||
core.setting_set("trilinear_filter", "false")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_filters"] == dd_filter_labels[3] then
|
||||
core.setting_set("bilinear_filter", "false")
|
||||
core.setting_set("trilinear_filter", "true")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_mipmap"] == dd_mipmap_labels[1] then
|
||||
core.setting_set("mip_map", "false")
|
||||
core.setting_set("anisotropic_filter", "false")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_mipmap"] == dd_mipmap_labels[2] then
|
||||
core.setting_set("mip_map", "true")
|
||||
core.setting_set("anisotropic_filter", "false")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_mipmap"] == dd_mipmap_labels[3] then
|
||||
core.setting_set("mip_map", "true")
|
||||
core.setting_set("anisotropic_filter", "true")
|
||||
ddhandled = true
|
||||
end
|
||||
|
||||
return ddhandled
|
||||
end
|
||||
|
||||
|
@ -330,4 +436,4 @@ tab_settings = {
|
|||
caption = fgettext("Settings"),
|
||||
cbf_formspec = formspec,
|
||||
cbf_button_handler = handle_settings_buttons
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,23 @@ local function get_formspec(tabview, name, tabdata)
|
|||
"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;]"
|
||||
|
||||
--favourites
|
||||
|
||||
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 ..
|
||||
"textlist[-0.05,0.0;7.55,2.75;favourites;"
|
||||
"table[-0.05,0;7.55,2.75;favourites;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
retval = retval .. render_favorite(menudata.favorites[1],render_details)
|
||||
|
@ -75,7 +88,6 @@ local function get_formspec(tabview, name, tabdata)
|
|||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields["btn_start_singleplayer"] then
|
||||
|
@ -147,6 +159,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
|||
|
||||
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 = ""
|
||||
|
|
|
@ -82,18 +82,23 @@ local function get_formspec(tabview, name, tabdata)
|
|||
)
|
||||
|
||||
retval = retval ..
|
||||
"button[4,4.15;2.6,0.5;world_delete;".. fgettext("Delete") .. "]" ..
|
||||
"button[6.5,4.15;2.8,0.5;world_create;".. fgettext("New") .. "]" ..
|
||||
"button[9.2,4.15;2.55,0.5;world_configure;".. fgettext("Configure") .. "]" ..
|
||||
"button[8.5,4.95;3.25,0.5;play;".. fgettext("Play") .. "]" ..
|
||||
"button[4,3.8;2.8,0.5;world_delete;".. fgettext("Delete") .. "]" ..
|
||||
"button[8,3.8;2.8,0.5;world_create;".. fgettext("New") .. "]" ..
|
||||
--"button[9.2,4.15;2.55,0.5;world_configure;".. fgettext("Configure") .. "]" ..
|
||||
"button[8,4.7;3.25,0.8;play;".. fgettext("Play") .. "]" ..
|
||||
"label[4,-0.25;".. fgettext("Select World:") .. "]"..
|
||||
"checkbox[0.25,0.25;cb_creative_mode;".. fgettext("Creative Mode") .. ";" ..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]"..
|
||||
"checkbox[0.25,0.7;cb_enable_damage;".. fgettext("Enable Damage") .. ";" ..
|
||||
dump(core.setting_getbool("enable_damage")) .. "]"..
|
||||
"textlist[4,0.25;7.5,3.7;sp_worlds;" ..
|
||||
"textlist[4,0.25;7.5,3.2;sp_worlds;" ..
|
||||
menu_render_worldlist() ..
|
||||
";" .. index .. "]"
|
||||
|
||||
if core.setting_get("versiontype") == "lite" then
|
||||
retval = retval ..
|
||||
"button[4,4.7;2.8,0.5;full_version;".. fgettext("Full Version") .. "]"
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
|
@ -135,7 +140,10 @@ local function main_button_handler(this, fields, name, tabdata)
|
|||
world_doubleclick or
|
||||
fields["key_enter"] then
|
||||
local selected = core.get_textlist_index("sp_worlds")
|
||||
|
||||
|
||||
if selected == nil then
|
||||
selected = 0
|
||||
end
|
||||
if selected ~= nil then
|
||||
gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
|
||||
gamedata.singleplayer = true
|
||||
|
@ -154,6 +162,13 @@ local function main_button_handler(this, fields, name, tabdata)
|
|||
return true
|
||||
end
|
||||
|
||||
if fields["full_version"] ~= nil then
|
||||
core.fullversion()
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
if fields["world_delete"] ~= nil then
|
||||
local selected = core.get_textlist_index("sp_worlds")
|
||||
if selected ~= nil and
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
*
|
||||
!.gitignore
|
|
@ -1,4 +1,6 @@
|
|||
uniform sampler2D baseTexture;
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D uTextureUnit0;
|
||||
uniform sampler2D normalTexture;
|
||||
uniform sampler2D useNormalmap;
|
||||
|
||||
|
@ -14,6 +16,9 @@ varying vec3 tsEyeVec;
|
|||
varying vec3 lightVec;
|
||||
varying vec3 tsLightVec;
|
||||
|
||||
varying vec2 varTexCoord0;
|
||||
varying vec4 varVertexColor;
|
||||
|
||||
bool normalTexturePresent = false;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
|
@ -24,7 +29,7 @@ float intensity (vec3 color){
|
|||
}
|
||||
|
||||
float get_rgb_height (vec2 uv){
|
||||
return intensity(texture2D(baseTexture,uv).rgb);
|
||||
return intensity(texture2D(uTextureUnit0,uv).rgb);
|
||||
}
|
||||
|
||||
vec4 get_normal_map(vec2 uv){
|
||||
|
@ -38,9 +43,8 @@ void main (void)
|
|||
{
|
||||
vec3 color;
|
||||
vec4 bump;
|
||||
vec2 uv = gl_TexCoord[0].st;
|
||||
vec2 uv = varTexCoord0;
|
||||
bool use_normalmap = false;
|
||||
|
||||
#ifdef USE_NORMALMAPS
|
||||
if (texture2D(useNormalmap,vec2(1.0,1.0)).r > 0.0){
|
||||
normalTexturePresent = true;
|
||||
|
@ -78,9 +82,7 @@ void main (void)
|
|||
use_normalmap = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 base = texture2D(baseTexture, uv).rgba;
|
||||
|
||||
vec4 base = texture2D(uTextureUnit0, uv).rgba;
|
||||
#ifdef ENABLE_BUMPMAPPING
|
||||
if (use_normalmap){
|
||||
vec3 L = normalize(lightVec);
|
||||
|
@ -96,9 +98,9 @@ vec4 base = texture2D(baseTexture, uv).rgba;
|
|||
#endif
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
float alpha = gl_Color.a;
|
||||
float alpha = varVertexColor.a;
|
||||
vec4 col = vec4(color.rgb, alpha);
|
||||
col *= gl_Color;
|
||||
col *= varVertexColor;
|
||||
if(fogDistance != 0.0){
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
|
@ -106,7 +108,7 @@ vec4 base = texture2D(baseTexture, uv).rgba;
|
|||
gl_FragColor = vec4(col.rgb, alpha);
|
||||
#else
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
col *= varVertexColor;
|
||||
if(fogDistance != 0.0){
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
/* Attributes */
|
||||
|
||||
//attribute vec3 inVertexPosition;
|
||||
//attribute vec3 inVertexNormal;
|
||||
//attribute vec4 inVertexColor;
|
||||
//attribute vec2 inTexCoord0;
|
||||
//attribute vec2 inTexCoord1;
|
||||
|
||||
uniform mat4 mModelView;
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
|
@ -7,6 +16,12 @@ uniform float dayNightRatio;
|
|||
uniform vec3 eyePosition;
|
||||
uniform float animationTimer;
|
||||
|
||||
attribute vec3 inVertexPosition;
|
||||
attribute vec3 inVertexNormal;
|
||||
attribute vec4 inVertexColor;
|
||||
attribute vec2 inTexCoord0;
|
||||
attribute vec2 inTexCoord1;
|
||||
|
||||
varying vec3 vPosition;
|
||||
varying vec3 worldPosition;
|
||||
|
||||
|
@ -15,6 +30,9 @@ varying vec3 lightVec;
|
|||
varying vec3 tsEyeVec;
|
||||
varying vec3 tsLightVec;
|
||||
|
||||
varying vec2 varTexCoord0;
|
||||
varying vec4 varVertexColor;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
|
@ -30,63 +48,64 @@ float smoothTriangleWave( float x ) {
|
|||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
varTexCoord0 = inTexCoord0;
|
||||
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos = vec4(inVertexPosition, 1.0);
|
||||
pos.y -= 2.0;
|
||||
pos.y -= sin (pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT
|
||||
+ sin ((pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
vec4 pos = vec4(inVertexPosition, 1.0);
|
||||
vec4 pos2 = mWorld * vec4(inVertexPosition, 1.0);
|
||||
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4;
|
||||
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2;
|
||||
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
if (gl_TexCoord[0].y < 0.05) {
|
||||
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
|
||||
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
|
||||
vec4 pos = vec4(inVertexPosition, 1.0);
|
||||
vec4 pos2 = mWorld * vec4(inVertexPosition, 1.0);
|
||||
if (inTexCoord0.y < 0.05) {
|
||||
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
|
||||
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
|
||||
}
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#else
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
gl_Position = mWorldViewProj * vec4(inVertexPosition, 1.0);
|
||||
#endif
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
worldPosition = (mWorld * vec4(inVertexPosition, 1.0)).xyz;
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
vec3 normal, tangent, binormal;
|
||||
normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
if (gl_Normal.x > 0.5) {
|
||||
normal = normalize(inVertexNormal);
|
||||
|
||||
if (inVertexNormal.x > 0.5) {
|
||||
// 1.0, 0.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.x < -0.5) {
|
||||
tangent = normalize(vec3( 0.0, 0.0, -1.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
} else if (inVertexNormal.x < -0.5) {
|
||||
// -1.0, 0.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.y > 0.5) {
|
||||
tangent = normalize(vec3( 0.0, 0.0, 1.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
} else if (inVertexNormal.y > 0.5) {
|
||||
// 0.0, 1.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
} else if (gl_Normal.y < -0.5) {
|
||||
tangent = normalize(vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, 0.0, 1.0));
|
||||
} else if (inVertexNormal.y < -0.5) {
|
||||
// 0.0, -1.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
} else if (gl_Normal.z > 0.5) {
|
||||
tangent = normalize(vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, 0.0, 1.0));
|
||||
} else if (inVertexNormal.z > 0.5) {
|
||||
// 0.0, 0.0, 1.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.z < -0.5) {
|
||||
tangent = normalize(vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
} else if (inVertexNormal.z < -0.5) {
|
||||
// 0.0, 0.0, -1.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
tangent = normalize(vec3(-1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
}
|
||||
mat3 tbnMatrix = mat3( tangent.x, binormal.x, normal.x,
|
||||
tangent.y, binormal.y, normal.y,
|
||||
|
@ -94,34 +113,28 @@ void main(void)
|
|||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
tsLightVec = lightVec * tbnMatrix;
|
||||
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
eyeVec = (mModelView * vec4(inVertexPosition, 1.0)).xyz;
|
||||
tsEyeVec = eyeVec * tbnMatrix;
|
||||
|
||||
vec4 color;
|
||||
float day = gl_Color.r;
|
||||
float night = gl_Color.g;
|
||||
float light_source = gl_Color.b;
|
||||
float day = inVertexColor.b;
|
||||
float night = inVertexColor.g;
|
||||
float light_source = inVertexColor.r;
|
||||
|
||||
float rg = mix(night, day, dayNightRatio);
|
||||
rg += light_source * 2.5; // Make light sources brighter
|
||||
rg += light_source * 2.5;
|
||||
float b = rg;
|
||||
|
||||
// Moonlight is blue
|
||||
b += (day - night) / 13.0;
|
||||
rg -= (day - night) / 23.0;
|
||||
rg -= (day - night) / 13.0;
|
||||
|
||||
// Emphase blue a bit in darker places
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
|
||||
|
||||
// Artificial light is yellow-ish
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
|
||||
|
||||
color.r = rg;
|
||||
color.g = rg;
|
||||
color.b = b;
|
||||
|
||||
color.a = gl_Color.a;
|
||||
gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);
|
||||
color.a = inVertexColor.a;
|
||||
varVertexColor = clamp(color,0.0,1.0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
uniform sampler2D baseTexture;
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D uTextureUnit0;
|
||||
uniform sampler2D normalTexture;
|
||||
uniform sampler2D useNormalmap;
|
||||
|
||||
|
@ -14,6 +16,9 @@ varying vec3 tsEyeVec;
|
|||
varying vec3 lightVec;
|
||||
varying vec3 tsLightVec;
|
||||
|
||||
varying vec2 varTexCoord0;
|
||||
varying vec4 varVertexColor;
|
||||
|
||||
bool normalTexturePresent = false;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
|
@ -24,7 +29,7 @@ float intensity (vec3 color){
|
|||
}
|
||||
|
||||
float get_rgb_height (vec2 uv){
|
||||
return intensity(texture2D(baseTexture,uv).rgb);
|
||||
return intensity(texture2D(uTextureUnit0,uv).rgb);
|
||||
}
|
||||
|
||||
vec4 get_normal_map(vec2 uv){
|
||||
|
@ -38,7 +43,7 @@ void main (void)
|
|||
{
|
||||
vec3 color;
|
||||
vec4 bump;
|
||||
vec2 uv = gl_TexCoord[0].st;
|
||||
vec2 uv = varTexCoord0;
|
||||
bool use_normalmap = false;
|
||||
|
||||
#ifdef USE_NORMALMAPS
|
||||
|
@ -79,7 +84,7 @@ void main (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
vec4 base = texture2D(baseTexture, uv).rgba;
|
||||
vec4 base = texture2D(uTextureUnit0, uv).rgba;
|
||||
|
||||
#ifdef ENABLE_BUMPMAPPING
|
||||
if (use_normalmap){
|
||||
|
@ -96,9 +101,9 @@ vec4 base = texture2D(baseTexture, uv).rgba;
|
|||
#endif
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
float alpha = gl_Color.a;
|
||||
float alpha = varVertexColor.a;
|
||||
vec4 col = vec4(color.rgb, alpha);
|
||||
col *= gl_Color;
|
||||
col *= varVertexColor;
|
||||
if(fogDistance != 0.0){
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
|
@ -106,7 +111,7 @@ vec4 base = texture2D(baseTexture, uv).rgba;
|
|||
gl_FragColor = vec4(col.rgb, alpha);
|
||||
#else
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
col *= varVertexColor;
|
||||
if(fogDistance != 0.0){
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
attribute vec3 inVertexPosition;
|
||||
attribute vec3 inVertexNormal;
|
||||
attribute vec4 inVertexColor;
|
||||
attribute vec2 inTexCoord0;
|
||||
attribute vec2 inTexCoord1;
|
||||
|
||||
uniform mat4 mModelView;
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
|
@ -15,6 +22,9 @@ varying vec3 lightVec;
|
|||
varying vec3 tsEyeVec;
|
||||
varying vec3 tsLightVec;
|
||||
|
||||
varying vec2 varTexCoord0;
|
||||
varying vec4 varVertexColor;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
|
@ -30,63 +40,70 @@ float smoothTriangleWave( float x ) {
|
|||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
varTexCoord0 = inTexCoord0;
|
||||
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos = vec4(inVertexPosition, 1.0);
|
||||
pos.y -= 2.0;
|
||||
pos.y -= sin (pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) * WATER_WAVE_HEIGHT
|
||||
+ sin ((pos.z/WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH) / 7.0) * WATER_WAVE_HEIGHT;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
vec4 pos = vec4(inVertexPosition, 1.0);
|
||||
vec4 pos2 = mWorld * vec4(inVertexPosition, 1.0);
|
||||
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2.x * 0.01 + pos2.z * 0.01) * 2.0 - 1.0) * 0.4;
|
||||
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.2;
|
||||
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2.x * -0.01 + pos2.z * -0.01) * 2.0 - 1.0) * 0.4;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
if (gl_TexCoord[0].y < 0.05) {
|
||||
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
|
||||
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
|
||||
vec4 pos = vec4(inVertexPosition, 1.0);
|
||||
vec4 pos2 = mWorld * vec4(inVertexPosition, 1.0);
|
||||
if (inTexCoord0.y < 0.05) {
|
||||
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2.x * 0.1 + pos2.z * 0.1) * 2.0 - 1.0) * 0.8;
|
||||
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2.x * -0.5 + pos2.z * -0.5) * 2.0 - 1.0) * 0.4;
|
||||
}
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#else
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
gl_Position = mWorldViewProj * vec4(inVertexPosition, 1.0);
|
||||
#endif
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
worldPosition = (mWorld * vec4(inVertexPosition, 1.0)).xyz;
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
vec3 normal, tangent, binormal;
|
||||
normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
if (gl_Normal.x > 0.5) {
|
||||
normal = normalize(inVertexNormal);
|
||||
|
||||
if (inVertexNormal.x > 0.5) {
|
||||
// 1.0, 0.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.x < -0.5) {
|
||||
|
||||
tangent = normalize(vec3( 0.0, 0.0, -1.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
} else if (inVertexNormal.x < -0.5) {
|
||||
// -1.0, 0.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.y > 0.5) {
|
||||
|
||||
tangent = normalize(vec3( 0.0, 0.0, 1.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
} else if (inVertexNormal.y > 0.5) {
|
||||
// 0.0, 1.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
} else if (gl_Normal.y < -0.5) {
|
||||
|
||||
tangent = normalize(vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, 0.0, 1.0));
|
||||
} else if (inVertexNormal.y < -0.5) {
|
||||
// 0.0, -1.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
} else if (gl_Normal.z > 0.5) {
|
||||
|
||||
tangent = normalize(vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, 0.0, 1.0));
|
||||
} else if (inVertexNormal.z > 0.5) {
|
||||
// 0.0, 0.0, 1.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.z < -0.5) {
|
||||
|
||||
tangent = normalize( vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize( vec3( 0.0, -1.0, 0.0));
|
||||
} else if (inVertexNormal.z < -0.5) {
|
||||
// 0.0, 0.0, -1.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
|
||||
tangent = normalize(vec3(-1.0, 0.0, 0.0));
|
||||
binormal = normalize(vec3( 0.0, -1.0, 0.0));
|
||||
}
|
||||
mat3 tbnMatrix = mat3( tangent.x, binormal.x, normal.x,
|
||||
tangent.y, binormal.y, normal.y,
|
||||
|
@ -94,34 +111,28 @@ void main(void)
|
|||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
tsLightVec = lightVec * tbnMatrix;
|
||||
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
eyeVec = (mModelView * vec4(inVertexPosition, 1.0)).xyz;
|
||||
tsEyeVec = eyeVec * tbnMatrix;
|
||||
|
||||
vec4 color;
|
||||
float day = gl_Color.r;
|
||||
float night = gl_Color.g;
|
||||
float light_source = gl_Color.b;
|
||||
float day = inVertexColor.b;
|
||||
float night = inVertexColor.g;
|
||||
float light_source = inVertexColor.r;
|
||||
|
||||
float rg = mix(night, day, dayNightRatio);
|
||||
rg += light_source * 2.5; // Make light sources brighter
|
||||
rg += light_source * 2.5;
|
||||
float b = rg;
|
||||
|
||||
// Moonlight is blue
|
||||
b += (day - night) / 13.0;
|
||||
rg -= (day - night) / 23.0;
|
||||
rg -= (day - night) / 13.0;
|
||||
|
||||
// Emphase blue a bit in darker places
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
|
||||
|
||||
// Artificial light is yellow-ish
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
|
||||
|
||||
color.r = rg;
|
||||
color.g = rg;
|
||||
color.b = b;
|
||||
|
||||
color.a = gl_Color.a;
|
||||
gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);
|
||||
color.a = inVertexColor.a;
|
||||
varVertexColor = clamp(color,0.0,1.0);
|
||||
}
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<font type="bitmap">
|
||||
|
||||
<Texture index="0" filename="liberation_sans_14_img.png" hasAlpha="true" />
|
||||
|
||||
<c c="!" r="0, 0, 6, 18" />
|
||||
<c c=""" r="6, 0, 15, 9" />
|
||||
<c c="#" r="15, 0, 30, 18" />
|
||||
<c c="$" r="30, 0, 43, 20" />
|
||||
<c c="%" r="43, 0, 62, 18" />
|
||||
<c c="&" r="62, 0, 78, 18" />
|
||||
<c c="'" r="78, 0, 84, 9" />
|
||||
<c c="(" r="84, 0, 93, 22" />
|
||||
<c c=")" r="93, 0, 103, 22" />
|
||||
<c c="*" r="103, 0, 114, 12" />
|
||||
<c c="+" r="114, 0, 127, 16" />
|
||||
<c c="," r="127, 0, 133, 20" />
|
||||
<c c="-" r="133, 0, 141, 13" />
|
||||
<c c="." r="141, 0, 147, 18" />
|
||||
<c c="/" r="147, 0, 156, 18" />
|
||||
<c c="0" r="156, 0, 169, 18" />
|
||||
<c c="1" r="169, 0, 181, 18" />
|
||||
<c c="2" r="181, 0, 195, 18" />
|
||||
<c c="3" r="195, 0, 208, 18" />
|
||||
<c c="4" r="208, 0, 222, 18" />
|
||||
<c c="5" r="222, 0, 235, 18" />
|
||||
<c c="6" r="235, 0, 248, 18" />
|
||||
<c c="7" r="248, 0, 261, 18" />
|
||||
<c c="8" r="261, 0, 274, 18" />
|
||||
<c c="9" r="274, 0, 287, 18" />
|
||||
<c c=":" r="287, 0, 293, 18" />
|
||||
<c c=";" r="293, 0, 299, 20" />
|
||||
<c c="<" r="299, 0, 312, 16" />
|
||||
<c c="=" r="312, 0, 325, 15" />
|
||||
<c c=">" r="325, 0, 338, 16" />
|
||||
<c c="?" r="338, 0, 351, 18" />
|
||||
<c c="@" r="351, 0, 370, 21" />
|
||||
<c c="A" r="370, 0, 386, 18" />
|
||||
<c c="B" r="386, 0, 400, 18" />
|
||||
<c c="C" r="400, 0, 415, 18" />
|
||||
<c c="D" r="415, 0, 430, 18" />
|
||||
<c c="E" r="430, 0, 444, 18" />
|
||||
<c c="F" r="444, 0, 457, 18" />
|
||||
<c c="G" r="457, 0, 473, 18" />
|
||||
<c c="H" r="473, 0, 487, 18" />
|
||||
<c c="I" r="487, 0, 493, 18" />
|
||||
<c c="J" r="493, 0, 506, 18" />
|
||||
<c c="K" r="0, 22, 15, 40" />
|
||||
<c c="L" r="15, 22, 27, 40" />
|
||||
<c c="M" r="27, 22, 43, 40" />
|
||||
<c c="N" r="43, 22, 57, 40" />
|
||||
<c c="O" r="57, 22, 73, 40" />
|
||||
<c c="P" r="73, 22, 87, 40" />
|
||||
<c c="Q" r="87, 22, 103, 44" />
|
||||
<c c="R" r="103, 22, 118, 40" />
|
||||
<c c="S" r="118, 22, 133, 40" />
|
||||
<c c="T" r="133, 22, 147, 40" />
|
||||
<c c="U" r="147, 22, 161, 40" />
|
||||
<c c="V" r="161, 22, 177, 40" />
|
||||
<c c="W" r="177, 22, 199, 40" />
|
||||
<c c="X" r="199, 22, 216, 40" />
|
||||
<c c="Y" r="216, 22, 232, 40" />
|
||||
<c c="Z" r="232, 22, 247, 40" />
|
||||
<c c="[" r="247, 22, 255, 44" />
|
||||
<c c="\" r="255, 22, 264, 40" />
|
||||
<c c="]" r="264, 22, 272, 44" />
|
||||
<c c="^" r="272, 22, 283, 34" />
|
||||
<c c="_" r="283, 22, 298, 44" />
|
||||
<c c="`" r="298, 22, 306, 29" />
|
||||
<c c="a" r="306, 22, 319, 40" />
|
||||
<c c="b" r="319, 22, 333, 40" />
|
||||
<c c="c" r="333, 22, 345, 40" />
|
||||
<c c="d" r="345, 22, 358, 40" />
|
||||
<c c="e" r="358, 22, 371, 40" />
|
||||
<c c="f" r="371, 22, 381, 40" />
|
||||
<c c="g" r="381, 22, 394, 44" />
|
||||
<c c="h" r="394, 22, 406, 40" />
|
||||
<c c="i" r="406, 22, 412, 40" />
|
||||
<c c="j" r="412, 22, 420, 44" />
|
||||
<c c="k" r="420, 22, 432, 40" />
|
||||
<c c="l" r="432, 22, 438, 40" />
|
||||
<c c="m" r="438, 22, 456, 40" />
|
||||
<c c="n" r="456, 22, 468, 40" />
|
||||
<c c="o" r="468, 22, 481, 40" />
|
||||
<c c="p" r="481, 22, 495, 44" />
|
||||
<c c="q" r="495, 22, 508, 44" />
|
||||
<c c="r" r="0, 44, 10, 62" />
|
||||
<c c="s" r="10, 44, 22, 62" />
|
||||
<c c="t" r="22, 44, 31, 62" />
|
||||
<c c="u" r="31, 44, 43, 62" />
|
||||
<c c="v" r="43, 44, 56, 62" />
|
||||
<c c="w" r="56, 44, 73, 62" />
|
||||
<c c="x" r="73, 44, 86, 62" />
|
||||
<c c="y" r="86, 44, 99, 66" />
|
||||
<c c="z" r="99, 44, 111, 62" />
|
||||
<c c="{" r="111, 44, 121, 66" />
|
||||
<c c="|" r="121, 44, 127, 66" />
|
||||
<c c="}" r="127, 44, 137, 66" />
|
||||
<c c="~" r="137, 44, 150, 57" />
|
||||
</font>
|
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 158 KiB |
Before Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 226 KiB |
Before Width: | Height: | Size: 272 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 218 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 95 B After Width: | Height: | Size: 848 B |