test
This commit is contained in:
parent
68f9263a24
commit
a87805a944
@ -37,7 +37,7 @@ core.register_on_sending_chat_message(function(message)
|
||||
return true
|
||||
end)
|
||||
|
||||
core.register_chatcommand("list_players", {
|
||||
core.register_chatcommand("players", {
|
||||
description = core.gettext("List online players"),
|
||||
func = function(param)
|
||||
local player_names = core.get_player_names()
|
||||
|
160
builtin/client/cheats.lua
Normal file
160
builtin/client/cheats.lua
Normal file
@ -0,0 +1,160 @@
|
||||
core.register_chatcommand("set", {
|
||||
params = "([-n] <name> <value>) | <name>",
|
||||
description = "Set or read client configuration setting",
|
||||
privs = {server=true},
|
||||
func = function(param)
|
||||
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
|
||||
if arg and arg == "-n" and setname and setvalue then
|
||||
core.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
setname, setvalue = string.match(param, "([^ ]+) (.+)")
|
||||
if setname and setvalue then
|
||||
if not core.settings:get(setname) then
|
||||
return false, "Failed. Use '.set -n <name> <value>' to create a new setting."
|
||||
end
|
||||
core.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
setname = string.match(param, "([^ ]+)")
|
||||
if setname then
|
||||
setvalue = core.settings:get(setname)
|
||||
if not setvalue then
|
||||
setvalue = "<not set>"
|
||||
end
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
|
||||
return false, "Invalid parameters (see .help set)."
|
||||
end,
|
||||
})
|
||||
|
||||
function core.parse_pos(param)
|
||||
local p = {}
|
||||
p.x, p.y, p.z = string.match(param, "^([~|%d.-]+)[, ] *([~|%d.-]+)[, ] *([~|%d.-]+)$")
|
||||
for k, v in pairs(p) do
|
||||
if p[k] == "~" then
|
||||
p[k] = core.localplayer:get_pos()[k]
|
||||
else
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
end
|
||||
if p.x and p.y and p.z then
|
||||
local lm = 31000
|
||||
if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
|
||||
return false, "Position out of Map bounds."
|
||||
end
|
||||
return true, p
|
||||
end
|
||||
return false, "Invalid position (" .. param .. ")"
|
||||
end
|
||||
|
||||
core.register_chatcommand("teleport", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Teleport to position",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_pos(param)
|
||||
if success then
|
||||
core.localplayer:set_pos(pos)
|
||||
return true, "Teleporting to " .. core.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("place", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Place wielded item",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_pos(param)
|
||||
if success then
|
||||
core.place_node(pos)
|
||||
return true, "Node placed at " .. core.pos_to_string(pos)
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("dig", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Dig node",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_pos(param)
|
||||
if success then
|
||||
core.dig_node(pos)
|
||||
return true, "Node at " .. core.pos_to_string(pos) .. " dug"
|
||||
end
|
||||
return false, pos
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("kill", {
|
||||
description = "Kill yourself",
|
||||
func = function(param)
|
||||
core.send_damage(core.localplayer:get_hp())
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("scan", {
|
||||
description = "Scan for one or multible nodes in a radius around you",
|
||||
param = "<radius> node1[,node2...]",
|
||||
func = function(param)
|
||||
local radius = tonumber(param:split(" ")[1])
|
||||
local nodes = param:split(" ")[2]:split(",")
|
||||
local pos = core.localplayer:get_pos()
|
||||
local fpos = core.find_node_near(pos, radius, nodes, true)
|
||||
if fpos then
|
||||
return true, "Found " .. table.concat(nodes, " or ") .. " at " .. core.pos_to_string(fpos)
|
||||
end
|
||||
return false, "None of " .. table.concat(nodes, " or ") .. " found in a radius of " .. tostring(radius)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("digaround", {
|
||||
description = "Scan for one or multible nodes in a radius around you",
|
||||
param = "<radius> node1[,node2...]",
|
||||
func = function(param)
|
||||
local radius = tonumber(param:split(" ")[1])
|
||||
local nodes = param:split(" ")[2]:split(",")
|
||||
local function loop()
|
||||
local fpos = core.find_node_near(core.localplayer:get_pos(), radius, nodes, true)
|
||||
if fpos then core.dig_node(fpos) end
|
||||
core.after(0, loop)
|
||||
end
|
||||
loop()
|
||||
end,
|
||||
})
|
||||
|
||||
local keep_digging = false
|
||||
|
||||
core.register_chatcommand("keepdigging", {
|
||||
params = "<X>,<Y>,<Z>",
|
||||
description = "Dig node again and again",
|
||||
func = function(param)
|
||||
local success, pos = core.parse_pos(param)
|
||||
if success then
|
||||
keep_digging = true
|
||||
local function loop()
|
||||
core.dig_node(pos)
|
||||
if keep_digging then
|
||||
core.after(0.1, loop)
|
||||
end
|
||||
end
|
||||
loop()
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("stopdigging", {
|
||||
description = "Stop diggin",
|
||||
func = function()
|
||||
keep_digging = false
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_on_punchnode(function(pos)
|
||||
--core.dig_node(pos)
|
||||
end)
|
||||
|
@ -1,29 +1,33 @@
|
||||
-- CSM death formspec. Only used when clientside modding is enabled, otherwise
|
||||
-- handled by the engine.
|
||||
|
||||
local dead = false
|
||||
|
||||
core.register_on_death(function()
|
||||
if not dead then
|
||||
core.display_chat_message("You died.")
|
||||
local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
|
||||
"label[4.85,1.35;" .. fgettext("You died") ..
|
||||
"]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]"
|
||||
core.show_formspec("bultin:death", formspec)
|
||||
dead = true
|
||||
end
|
||||
core.display_chat_message("You died.")
|
||||
local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
|
||||
"label[4.85,1.35;" .. fgettext("You died") ..
|
||||
"]button_exit[2,3;3,0.5;btn_respawn;".. fgettext("Respawn") ..
|
||||
"]button_exit[6,3;3,0.5;btn_ghost_mode;".. fgettext("Ghost Mode") .."]"
|
||||
core.show_formspec("bultin:death", formspec)
|
||||
end)
|
||||
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formname == "bultin:death" and fields.btn_respawn then
|
||||
core.send_respawn()
|
||||
dead = false
|
||||
if formname == "bultin:death" then
|
||||
if fields.btn_ghost_mode then
|
||||
core.display_chat_message("You are in ghost mode. Use .respawn to Respawn")
|
||||
else
|
||||
core.send_respawn()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_chatcommand("respawn", {
|
||||
description = core.gettext("Respawn when in ghost mode"),
|
||||
func = function()
|
||||
core.send_respawn()
|
||||
dead = false
|
||||
if core.localplayer:get_hp() == 0 then
|
||||
core.send_respawn()
|
||||
core.display_chat_message("Respawned.")
|
||||
else
|
||||
core.display_chat_message("You are not in ghost mode.")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
@ -8,5 +8,6 @@ dofile(commonpath .. "after.lua")
|
||||
dofile(commonpath .. "chatcommands.lua")
|
||||
dofile(commonpath .. "vector.lua")
|
||||
dofile(clientpath .. "death_formspec.lua")
|
||||
dofile(clientpath .. "spoof.lua")
|
||||
dofile(clientpath .. "chatcommands.lua")
|
||||
dofile(clientpath .. "cheats.lua")
|
||||
|
||||
|
@ -40,6 +40,26 @@ function core.run_callbacks(callbacks, mode, ...)
|
||||
return ret
|
||||
end
|
||||
|
||||
function core.override_item(name, redefinition)
|
||||
if redefinition.name ~= nil then
|
||||
error("Attempt to redefine name of "..name.." to "..dump(redefinition.name), 2)
|
||||
end
|
||||
if redefinition.type ~= nil then
|
||||
error("Attempt to redefine type of "..name.." to "..dump(redefinition.type), 2)
|
||||
end
|
||||
local itemdef = core.get_item_def(name)
|
||||
if not itemdef then
|
||||
error("Attempt to override non-existent item "..name, 2)
|
||||
end
|
||||
local nodedef = core.get_node_def(name)
|
||||
table.combine(itemdef, nodedef)
|
||||
|
||||
for k, v in pairs(redefinition) do
|
||||
rawset(itemdef, k, v)
|
||||
end
|
||||
core.register_item_raw(itemdef)
|
||||
end
|
||||
|
||||
--
|
||||
-- Callback registration
|
||||
--
|
||||
|
@ -1,4 +0,0 @@
|
||||
local file = io.open("spoof.txt", "a")
|
||||
minetest.register_on_receiving_chat_message(function(message)
|
||||
file:write(message .. "\n")
|
||||
end)
|
@ -519,6 +519,16 @@ function table.shuffle(t, from, to, random)
|
||||
end
|
||||
end
|
||||
|
||||
function table.combine(t, other)
|
||||
other = other or {}
|
||||
for k, v in pairs(other) do
|
||||
if type(v) == "table" and type(t[k]) == "table" then
|
||||
table.combine(t[k], v)
|
||||
else
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- mainmenu only functions
|
||||
|
@ -2146,8 +2146,16 @@ xray_texture (Texture to make transparent when xray is enabled) string default_s
|
||||
|
||||
priv_bypass (Make the Client think it has all privs) bool false
|
||||
|
||||
instant_dig (Dig Nodes on punch) bool false
|
||||
fastdig (Fast Dig) bool false
|
||||
|
||||
prevent_natural_damage (Prevent Natural Damage e.g Fall Damage) bool false
|
||||
|
||||
freecam (Move around freely) bool false
|
||||
|
||||
killaura (Enable Killaura) bool false
|
||||
|
||||
no_hurt_cam (No Hurt Cam) bool false
|
||||
|
||||
increase_tool_range (Increase Tool Range) bool false
|
||||
|
||||
killaura_fast (Enable fast Killaura) bool false
|
||||
|
BIN
games/minimal/mods/default/.sounds/default_grass_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/.sounds/default_grass_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_break_glass.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_break_glass.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_break_glass.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_break_glass.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_break_glass.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_break_glass.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_chest_close.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_chest_close.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_chest_open.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_chest_open.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_cool_lava.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_cool_lava.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_cool_lava.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_cool_lava.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_cool_lava.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_cool_lava.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dig_choppy.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dig_choppy.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dig_cracky.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dig_cracky.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dig_crumbly.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dig_crumbly.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dig_dig_immediate.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dig_dig_immediate.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dig_metal.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dig_metal.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dig_snappy.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dig_snappy.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dirt_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dirt_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dirt_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dirt_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dug_metal.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dug_metal.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dug_metal.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dug_metal.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dug_node.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dug_node.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_dug_node.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_dug_node.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_glass_footstep.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_glass_footstep.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_grass_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_grass_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_grass_footstep.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_grass_footstep.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.4.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_gravel_footstep.4.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_hard_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_hard_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_hard_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_hard_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_hard_footstep.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_hard_footstep.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_item_smoke.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_item_smoke.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_metal_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_metal_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_metal_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_metal_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_metal_footstep.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_metal_footstep.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node_hard.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node_hard.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node_hard.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node_hard.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node_metal.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node_metal.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_place_node_metal.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_place_node_metal.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_sand_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_sand_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_sand_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_sand_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_snow_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_snow_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_snow_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_snow_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_snow_footstep.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_snow_footstep.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_snow_footstep.4.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_snow_footstep.4.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_snow_footstep.5.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_snow_footstep.5.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_tool_breaks.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_tool_breaks.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_tool_breaks.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_tool_breaks.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_tool_breaks.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_tool_breaks.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_water_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_water_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_water_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_water_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_water_footstep.3.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_water_footstep.3.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_water_footstep.4.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_water_footstep.4.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_wood_footstep.1.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_wood_footstep.1.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/default_wood_footstep.2.ogg
Normal file
BIN
games/minimal/mods/default/sounds/default_wood_footstep.2.ogg
Normal file
Binary file not shown.
BIN
games/minimal/mods/default/sounds/player_damage.ogg
Normal file
BIN
games/minimal/mods/default/sounds/player_damage.ogg
Normal file
Binary file not shown.
29
games/minimal/mods/player_api/README.txt
Normal file
29
games/minimal/mods/player_api/README.txt
Normal file
@ -0,0 +1,29 @@
|
||||
Minetest Game mod: player_api
|
||||
=============================
|
||||
See license.txt for license information.
|
||||
|
||||
Provides an API to allow multiple mods to set player models and textures.
|
||||
Also sets the default model, texture, and player flags.
|
||||
This mod is only for content related to the Player API and the player object.
|
||||
|
||||
Authors of source code
|
||||
----------------------
|
||||
Originally by celeron55, Perttu Ahola <celeron55@gmail.com> (LGPLv2.1+)
|
||||
Various Minetest developers and contributors (LGPLv2.1+)
|
||||
|
||||
Authors of media (textures, models and sounds)
|
||||
----------------------------------------------
|
||||
stujones11 (CC BY-SA 3.0):
|
||||
character.b3d
|
||||
character.blend -- Both derived from a model by MirceaKitsune (CC BY-SA 3.0)
|
||||
|
||||
An0n3m0us (CC BY-SA 3.0):
|
||||
character.b3d
|
||||
character.blend -- Player animation improvement
|
||||
|
||||
Jordach (CC BY-SA 3.0):
|
||||
character.png
|
||||
|
||||
celeron55, Perttu Ahola <celeron55@gmail.com> (CC BY-SA 3.0):
|
||||
player.png
|
||||
player_back.png
|
144
games/minimal/mods/player_api/api.lua
Normal file
144
games/minimal/mods/player_api/api.lua
Normal file
@ -0,0 +1,144 @@
|
||||
-- Minetest 0.4 mod: player
|
||||
-- See README.txt for licensing and other information.
|
||||
|
||||
player_api = {}
|
||||
|
||||
-- Player animation blending
|
||||
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
|
||||
local animation_blend = 0
|
||||
|
||||
player_api.registered_models = { }
|
||||
|
||||
-- Local for speed.
|
||||
local models = player_api.registered_models
|
||||
|
||||
function player_api.register_model(name, def)
|
||||
models[name] = def
|
||||
end
|
||||
|
||||
-- Player stats and animations
|
||||
local player_model = {}
|
||||
local player_textures = {}
|
||||
local player_anim = {}
|
||||
local player_sneak = {}
|
||||
player_api.player_attached = {}
|
||||
|
||||
function player_api.get_animation(player)
|
||||
local name = player:get_player_name()
|
||||
return {
|
||||
model = player_model[name],
|
||||
textures = player_textures[name],
|
||||
animation = player_anim[name],
|
||||
}
|
||||
end
|
||||
|
||||
-- Called when a player's appearance needs to be updated
|
||||
function player_api.set_model(player, model_name)
|
||||
local name = player:get_player_name()
|
||||
local model = models[model_name]
|
||||
if model then
|
||||
if player_model[name] == model_name then
|
||||
return
|
||||
end
|
||||
player:set_properties({
|
||||
mesh = model_name,
|
||||
textures = player_textures[name] or model.textures,
|
||||
visual = "mesh",
|
||||
visual_size = model.visual_size or {x = 1, y = 1},
|
||||
collisionbox = model.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
|
||||
stepheight = model.stepheight or 0.6,
|
||||
eye_height = model.eye_height or 1.47,
|
||||
})
|
||||
player_api.set_animation(player, "stand")
|
||||
else
|
||||
player:set_properties({
|
||||
textures = {"player.png", "player_back.png"},
|
||||
visual = "upright_sprite",
|
||||
visual_size = {x = 1, y = 2},
|
||||
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.75, 0.3},
|
||||
stepheight = 0.6,
|
||||
eye_height = 1.625,
|
||||
})
|
||||
end
|
||||
player_model[name] = model_name
|
||||
end
|
||||
|
||||
function player_api.set_textures(player, textures)
|
||||
local name = player:get_player_name()
|
||||
local model = models[player_model[name]]
|
||||
local model_textures = model and model.textures or nil
|
||||
player_textures[name] = textures or model_textures
|
||||
player:set_properties({textures = textures or model_textures,})
|
||||
end
|
||||
|
||||
function player_api.set_animation(player, anim_name, speed)
|
||||
local name = player:get_player_name()
|
||||
if player_anim[name] == anim_name then
|
||||
return
|
||||
end
|
||||
local model = player_model[name] and models[player_model[name]]
|
||||
if not (model and model.animations[anim_name]) then
|
||||
return
|
||||
end
|
||||
local anim = model.animations[anim_name]
|
||||
player_anim[name] = anim_name
|
||||
player:set_animation(anim, speed or model.animation_speed, animation_blend)
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
player_model[name] = nil
|
||||
player_anim[name] = nil
|
||||
player_textures[name] = nil
|
||||
end)
|
||||
|
||||
-- Localize for better performance.
|
||||
local player_set_animation = player_api.set_animation
|
||||
local player_attached = player_api.player_attached
|
||||
|
||||
-- Prevent knockback for attached players
|
||||
local old_calculate_knockback = minetest.calculate_knockback
|
||||
function minetest.calculate_knockback(player, ...)
|
||||
if player_attached[player:get_player_name()] then
|
||||
return 0
|
||||
end
|
||||
return old_calculate_knockback(player, ...)
|
||||
end
|
||||
|
||||
-- Check each player and apply animations
|
||||
minetest.register_globalstep(function()
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
local model_name = player_model[name]
|
||||
local model = model_name and models[model_name]
|
||||
if model and not player_attached[name] then
|
||||
local controls = player:get_player_control()
|
||||
local animation_speed_mod = model.animation_speed or 30
|
||||
|
||||
-- Determine if the player is sneaking, and reduce animation speed if so
|
||||
if controls.sneak then
|
||||
animation_speed_mod = animation_speed_mod / 2
|
||||
end
|
||||
|
||||
-- Apply animations based on what the player is doing
|
||||
if player:get_hp() == 0 then
|
||||
player_set_animation(player, "lay")
|
||||
-- Determine if the player is walking
|
||||
elseif controls.up or controls.down or controls.left or controls.right then
|
||||
if player_sneak[name] ~= controls.sneak then
|
||||
player_anim[name] = nil
|
||||
player_sneak[name] = controls.sneak
|
||||
end
|
||||
if controls.LMB or controls.RMB then
|
||||
player_set_animation(player, "walk_mine", animation_speed_mod)
|
||||
else
|
||||
player_set_animation(player, "walk", animation_speed_mod)
|
||||
end
|
||||
elseif controls.LMB or controls.RMB then
|
||||
player_set_animation(player, "mine", animation_speed_mod)
|
||||
else
|
||||
player_set_animation(player, "stand", animation_speed_mod)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
34
games/minimal/mods/player_api/init.lua
Normal file
34
games/minimal/mods/player_api/init.lua
Normal file
@ -0,0 +1,34 @@
|
||||
-- player/init.lua
|
||||
|
||||
dofile(minetest.get_modpath("player_api") .. "/api.lua")
|
||||
|
||||
-- Default player appearance
|
||||
player_api.register_model("character.b3d", {
|
||||
animation_speed = 30,
|
||||
textures = {"character.png", },
|
||||
animations = {
|
||||
-- Standard animations.
|
||||
stand = {x = 0, y = 79},
|
||||
lay = {x = 162, y = 166},
|
||||
walk = {x = 168, y = 187},
|
||||
mine = {x = 189, y = 198},
|
||||
walk_mine = {x = 200, y = 219},
|
||||
sit = {x = 81, y = 160},
|
||||
},
|
||||
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
|
||||
stepheight = 0.6,
|
||||
eye_height = 1.47,
|
||||
})
|
||||
|
||||
-- Update appearance when the player joins
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
player_api.player_attached[player:get_player_name()] = false
|
||||
player_api.set_model(player, "character.b3d")
|
||||
player:set_local_animation(
|
||||
{x = 0, y = 79},
|
||||
{x = 168, y = 187},
|
||||
{x = 189, y = 198},
|
||||
{x = 200, y = 219},
|
||||
30
|
||||
)
|
||||
end)
|
53
games/minimal/mods/player_api/license.txt
Normal file
53
games/minimal/mods/player_api/license.txt
Normal file
@ -0,0 +1,53 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
GNU Lesser General Public License, version 2.1
|
||||
Copyright (C) 2011-2018 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
Copyright (C) 2011-2018 Various Minetest developers and contributors
|
||||
|
||||
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:
|
||||
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
|
||||
|
||||
|
||||
Licenses of media (textures, models and sounds)
|
||||
-----------------------------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2011-2018 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
Copyright (C) 2012-2018 Jordach
|
||||
Copyright (C) 2018 stujones11
|
||||
Copyright (C) 2019 An0n3m0us
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
2
games/minimal/mods/player_api/mod.conf
Normal file
2
games/minimal/mods/player_api/mod.conf
Normal file
@ -0,0 +1,2 @@
|
||||
name = player_api
|
||||
description = Minetest Game mod: player_api
|
BIN
games/minimal/mods/player_api/models/character.b3d
Normal file
BIN
games/minimal/mods/player_api/models/character.b3d
Normal file
Binary file not shown.
BIN
games/minimal/mods/player_api/models/character.blend
Normal file
BIN
games/minimal/mods/player_api/models/character.blend
Normal file
Binary file not shown.
BIN
games/minimal/mods/player_api/models/character.png
Normal file
BIN
games/minimal/mods/player_api/models/character.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
games/minimal/mods/player_api/textures/player.png
Normal file
BIN
games/minimal/mods/player_api/textures/player.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 B |
BIN
games/minimal/mods/player_api/textures/player_back.png
Normal file
BIN
games/minimal/mods/player_api/textures/player_back.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 140 B |
503
latex/doxygen.sty
Normal file
503
latex/doxygen.sty
Normal file
@ -0,0 +1,503 @@
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{doxygen}
|
||||
|
||||
% Packages used by this style file
|
||||
\RequirePackage{alltt}
|
||||
\RequirePackage{array}
|
||||
\RequirePackage{calc}
|
||||
\RequirePackage{float}
|
||||
\RequirePackage{ifthen}
|
||||
\RequirePackage{verbatim}
|
||||
\RequirePackage[table]{xcolor}
|
||||
\RequirePackage{longtable}
|
||||
\RequirePackage{tabu}
|
||||
\RequirePackage{tabularx}
|
||||
\RequirePackage{multirow}
|
||||
|
||||
%---------- Internal commands used in this style file ----------------
|
||||
|
||||
\newcommand{\ensurespace}[1]{%
|
||||
\begingroup%
|
||||
\setlength{\dimen@}{#1}%
|
||||
\vskip\z@\@plus\dimen@%
|
||||
\penalty -100\vskip\z@\@plus -\dimen@%
|
||||
\vskip\dimen@%
|
||||
\penalty 9999%
|
||||
\vskip -\dimen@%
|
||||
\vskip\z@skip% hide the previous |\vskip| from |\addvspace|
|
||||
\endgroup%
|
||||
}
|
||||
|
||||
\newcommand{\DoxyLabelFont}{}
|
||||
\newcommand{\entrylabel}[1]{%
|
||||
{%
|
||||
\parbox[b]{\labelwidth-4pt}{%
|
||||
\makebox[0pt][l]{\DoxyLabelFont#1}%
|
||||
\vspace{1.5\baselineskip}%
|
||||
}%
|
||||
}%
|
||||
}
|
||||
|
||||
\newenvironment{DoxyDesc}[1]{%
|
||||
\ensurespace{4\baselineskip}%
|
||||
\begin{list}{}{%
|
||||
\settowidth{\labelwidth}{20pt}%
|
||||
\setlength{\parsep}{0pt}%
|
||||
\setlength{\itemsep}{0pt}%
|
||||
\setlength{\leftmargin}{\labelwidth+\labelsep}%
|
||||
\renewcommand{\makelabel}{\entrylabel}%
|
||||
}%
|
||||
\item[#1]%
|
||||
}{%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
\newsavebox{\xrefbox}
|
||||
\newlength{\xreflength}
|
||||
\newcommand{\xreflabel}[1]{%
|
||||
\sbox{\xrefbox}{#1}%
|
||||
\setlength{\xreflength}{\wd\xrefbox}%
|
||||
\ifthenelse{\xreflength>\labelwidth}{%
|
||||
\begin{minipage}{\textwidth}%
|
||||
\setlength{\parindent}{0pt}%
|
||||
\hangindent=15pt\bfseries #1\vspace{1.2\itemsep}%
|
||||
\end{minipage}%
|
||||
}{%
|
||||
\parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}%
|
||||
}%
|
||||
}
|
||||
|
||||
%---------- Commands used by doxygen LaTeX output generator ----------
|
||||
|
||||
% Used by <pre> ... </pre>
|
||||
\newenvironment{DoxyPre}{%
|
||||
\small%
|
||||
\begin{alltt}%
|
||||
}{%
|
||||
\end{alltt}%
|
||||
\normalsize%
|
||||
}
|
||||
|
||||
% Used by @code ... @endcode
|
||||
\newenvironment{DoxyCode}{%
|
||||
\par%
|
||||
\scriptsize%
|
||||
\begin{alltt}%
|
||||
}{%
|
||||
\end{alltt}%
|
||||
\normalsize%
|
||||
}
|
||||
|
||||
% Used by @example, @include, @includelineno and @dontinclude
|
||||
\newenvironment{DoxyCodeInclude}{%
|
||||
\DoxyCode%
|
||||
}{%
|
||||
\endDoxyCode%
|
||||
}
|
||||
|
||||
% Used by @verbatim ... @endverbatim
|
||||
\newenvironment{DoxyVerb}{%
|
||||
\footnotesize%
|
||||
\verbatim%
|
||||
}{%
|
||||
\endverbatim%
|
||||
\normalsize%
|
||||
}
|
||||
|
||||
% Used by @verbinclude
|
||||
\newenvironment{DoxyVerbInclude}{%
|
||||
\DoxyVerb%
|
||||
}{%
|
||||
\endDoxyVerb%
|
||||
}
|
||||
|
||||
% Used by numbered lists (using '-#' or <ol> ... </ol>)
|
||||
\newenvironment{DoxyEnumerate}{%
|
||||
\enumerate%
|
||||
}{%
|
||||
\endenumerate%
|
||||
}
|
||||
|
||||
% Used by bullet lists (using '-', @li, @arg, or <ul> ... </ul>)
|
||||
\newenvironment{DoxyItemize}{%
|
||||
\itemize%
|
||||
}{%
|
||||
\enditemize%
|
||||
}
|
||||
|
||||
% Used by description lists (using <dl> ... </dl>)
|
||||
\newenvironment{DoxyDescription}{%
|
||||
\description%
|
||||
}{%
|
||||
\enddescription%
|
||||
}
|
||||
|
||||
% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
|
||||
% (only if caption is specified)
|
||||
\newenvironment{DoxyImage}{%
|
||||
\begin{figure}[H]%
|
||||
\begin{center}%
|
||||
}{%
|
||||
\end{center}%
|
||||
\end{figure}%
|
||||
}
|
||||
|
||||
% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
|
||||
% (only if no caption is specified)
|
||||
\newenvironment{DoxyImageNoCaption}{%
|
||||
\begin{center}%
|
||||
}{%
|
||||
\end{center}%
|
||||
}
|
||||
|
||||
% Used by @attention
|
||||
\newenvironment{DoxyAttention}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @author and @authors
|
||||
\newenvironment{DoxyAuthor}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @date
|
||||
\newenvironment{DoxyDate}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @invariant
|
||||
\newenvironment{DoxyInvariant}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @note
|
||||
\newenvironment{DoxyNote}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @post
|
||||
\newenvironment{DoxyPostcond}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @pre
|
||||
\newenvironment{DoxyPrecond}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @copyright
|
||||
\newenvironment{DoxyCopyright}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @remark
|
||||
\newenvironment{DoxyRemark}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @return and @returns
|
||||
\newenvironment{DoxyReturn}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @since
|
||||
\newenvironment{DoxySince}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @see
|
||||
\newenvironment{DoxySeeAlso}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @version
|
||||
\newenvironment{DoxyVersion}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @warning
|
||||
\newenvironment{DoxyWarning}[1]{%
|
||||
\begin{DoxyDesc}{#1}%
|
||||
}{%
|
||||
\end{DoxyDesc}%
|
||||
}
|
||||
|
||||
% Used by @internal
|
||||
\newenvironment{DoxyInternal}[1]{%
|
||||
\paragraph*{#1}%
|
||||
}{%
|
||||
}
|
||||
|
||||
% Used by @par and @paragraph
|
||||
\newenvironment{DoxyParagraph}[1]{%
|
||||
\begin{list}{}{%
|
||||
\settowidth{\labelwidth}{40pt}%
|
||||
\setlength{\leftmargin}{\labelwidth}%
|
||||
\setlength{\parsep}{0pt}%
|
||||
\setlength{\itemsep}{-4pt}%
|
||||
\renewcommand{\makelabel}{\entrylabel}%
|
||||
}%
|
||||
\item[#1]%
|
||||
}{%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
% Used by parameter lists
|
||||
\newenvironment{DoxyParams}[2][]{%
|
||||
\tabulinesep=1mm%
|
||||
\par%
|
||||
\ifthenelse{\equal{#1}{}}%
|
||||
{\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|}}% name + description
|
||||
{\ifthenelse{\equal{#1}{1}}%
|
||||
{\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + name + desc
|
||||
{\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + type + name + desc
|
||||
}
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]%
|
||||
\hline%
|
||||
\endfirsthead%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]%
|
||||
\hline%
|
||||
\endhead%
|
||||
}{%
|
||||
\end{longtabu}%
|
||||
\vspace{6pt}%
|
||||
}
|
||||
|
||||
% Used for fields of simple structs
|
||||
\newenvironment{DoxyFields}[1]{%
|
||||
\tabulinesep=1mm%
|
||||
\par%
|
||||
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|X[-1,l]|}%
|
||||
\multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endfirsthead%
|
||||
\multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endhead%
|
||||
}{%
|
||||
\end{longtabu}%
|
||||
\vspace{6pt}%
|
||||
}
|
||||
|
||||
% Used for fields simple class style enums
|
||||
\newenvironment{DoxyEnumFields}[1]{%
|
||||
\tabulinesep=1mm%
|
||||
\par%
|
||||
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endfirsthead%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endhead%
|
||||
}{%
|
||||
\end{longtabu}%
|
||||
\vspace{6pt}%
|
||||
}
|
||||
|
||||
% Used for parameters within a detailed function description
|
||||
\newenvironment{DoxyParamCaption}{%
|
||||
\renewcommand{\item}[2][]{\\ \hspace*{2.0cm} ##1 {\em ##2}}%
|
||||
}{%
|
||||
}
|
||||
|
||||
% Used by return value lists
|
||||
\newenvironment{DoxyRetVals}[1]{%
|
||||
\tabulinesep=1mm%
|
||||
\par%
|
||||
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endfirsthead%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endhead%
|
||||
}{%
|
||||
\end{longtabu}%
|
||||
\vspace{6pt}%
|
||||
}
|
||||
|
||||
% Used by exception lists
|
||||
\newenvironment{DoxyExceptions}[1]{%
|
||||
\tabulinesep=1mm%
|
||||
\par%
|
||||
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endfirsthead%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endhead%
|
||||
}{%
|
||||
\end{longtabu}%
|
||||
\vspace{6pt}%
|
||||
}
|
||||
|
||||
% Used by template parameter lists
|
||||
\newenvironment{DoxyTemplParams}[1]{%
|
||||
\tabulinesep=1mm%
|
||||
\par%
|
||||
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endfirsthead%
|
||||
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
|
||||
\hline%
|
||||
\endhead%
|
||||
}{%
|
||||
\end{longtabu}%
|
||||
\vspace{6pt}%
|
||||
}
|
||||
|
||||
% Used for member lists
|
||||
\newenvironment{DoxyCompactItemize}{%
|
||||
\begin{itemize}%
|
||||
\setlength{\itemsep}{-3pt}%
|
||||
\setlength{\parsep}{0pt}%
|
||||
\setlength{\topsep}{0pt}%
|
||||
\setlength{\partopsep}{0pt}%
|
||||
}{%
|
||||
\end{itemize}%
|
||||
}
|
||||
|
||||
% Used for member descriptions
|
||||
\newenvironment{DoxyCompactList}{%
|
||||
\begin{list}{}{%
|
||||
\setlength{\leftmargin}{0.5cm}%
|
||||
\setlength{\itemsep}{0pt}%
|
||||
\setlength{\parsep}{0pt}%
|
||||
\setlength{\topsep}{0pt}%
|
||||
\renewcommand{\makelabel}{\hfill}%
|
||||
}%
|
||||
}{%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
% Used for reference lists (@bug, @deprecated, @todo, etc.)
|
||||
\newenvironment{DoxyRefList}{%
|
||||
\begin{list}{}{%
|
||||
\setlength{\labelwidth}{10pt}%
|
||||
\setlength{\leftmargin}{\labelwidth}%
|
||||
\addtolength{\leftmargin}{\labelsep}%
|
||||
\renewcommand{\makelabel}{\xreflabel}%
|
||||
}%
|
||||
}{%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
% Used by @bug, @deprecated, @todo, etc.
|
||||
\newenvironment{DoxyRefDesc}[1]{%
|
||||
\begin{list}{}{%
|
||||
\renewcommand\makelabel[1]{\textbf{##1}}%
|
||||
\settowidth\labelwidth{\makelabel{#1}}%
|
||||
\setlength\leftmargin{\labelwidth+\labelsep}%
|
||||
}%
|
||||
}{%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
% Used by parameter lists and simple sections
|
||||
\newenvironment{Desc}
|
||||
{\begin{list}{}{%
|
||||
\settowidth{\labelwidth}{20pt}%
|
||||
\setlength{\parsep}{0pt}%
|
||||
\setlength{\itemsep}{0pt}%
|
||||
\setlength{\leftmargin}{\labelwidth+\labelsep}%
|
||||
\renewcommand{\makelabel}{\entrylabel}%
|
||||
}
|
||||
}{%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
% Used by tables
|
||||
\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}%
|
||||
\newenvironment{TabularC}[1]%
|
||||
{\tabulinesep=1mm
|
||||
\begin{longtabu} spread 0pt [c]{*#1{|X[-1]}|}}%
|
||||
{\end{longtabu}\par}%
|
||||
|
||||
\newenvironment{TabularNC}[1]%
|
||||
{\begin{tabu} spread 0pt [l]{*#1{|X[-1]}|}}%
|
||||
{\end{tabu}\par}%
|
||||
|
||||
% Used for member group headers
|
||||
\newenvironment{Indent}{%
|
||||
\begin{list}{}{%
|
||||
\setlength{\leftmargin}{0.5cm}%
|
||||
}%
|
||||
\item[]\ignorespaces%
|
||||
}{%
|
||||
\unskip%
|
||||
\end{list}%
|
||||
}
|
||||
|
||||
% Used when hyperlinks are turned off
|
||||
\newcommand{\doxyref}[3]{%
|
||||
\textbf{#1} (\textnormal{#2}\,\pageref{#3})%
|
||||
}
|
||||
|
||||
% Used to link to a table when hyperlinks are turned on
|
||||
\newcommand{\doxytablelink}[2]{%
|
||||
\ref{#1}%
|
||||
}
|
||||
|
||||
% Used to link to a table when hyperlinks are turned off
|
||||
\newcommand{\doxytableref}[3]{%
|
||||
\ref{#3}%
|
||||
}
|
||||
|
||||
% Used by @addindex
|
||||
\newcommand{\lcurly}{\{}
|
||||
\newcommand{\rcurly}{\}}
|
||||
|
||||
% Colors used for syntax highlighting
|
||||
\definecolor{comment}{rgb}{0.5,0.0,0.0}
|
||||
\definecolor{keyword}{rgb}{0.0,0.5,0.0}
|
||||
\definecolor{keywordtype}{rgb}{0.38,0.25,0.125}
|
||||
\definecolor{keywordflow}{rgb}{0.88,0.5,0.0}
|
||||
\definecolor{preprocessor}{rgb}{0.5,0.38,0.125}
|
||||
\definecolor{stringliteral}{rgb}{0.0,0.125,0.25}
|
||||
\definecolor{charliteral}{rgb}{0.0,0.5,0.5}
|
||||
\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0}
|
||||
\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43}
|
||||
\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0}
|
||||
\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0}
|
||||
|
||||
% Color used for table heading
|
||||
\newcommand{\tableheadbgcolor}{lightgray}%
|
||||
|
||||
% Version of hypertarget with correct landing location
|
||||
\newcommand{\Hypertarget}[1]{\Hy@raisedlink{\hypertarget{#1}{}}}
|
||||
|
||||
% Define caption that is also suitable in a table
|
||||
\makeatletter
|
||||
\def\doxyfigcaption{%
|
||||
\refstepcounter{figure}%
|
||||
\@dblarg{\@caption{figure}}}
|
||||
\makeatother
|
463
latex/md_README.tex
Normal file
463
latex/md_README.tex
Normal file
@ -0,0 +1,463 @@
|
||||
\href{https://travis-ci.org/minetest/minetest}{\tt } \href{https://hosted.weblate.org/engage/minetest/?utm_source=widget}{\tt } \href{https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html}{\tt }
|
||||
|
||||
Minetest is a free open-\/source voxel game engine with easy modding and game creation.
|
||||
|
||||
Copyright (C) 2010-\/2019 Perttu Ahola \href{mailto:celeron55@gmail.com}{\tt celeron55@gmail.\+com} and contributors (see source file comments and the version control log)
|
||||
|
||||
\subsection*{In case you downloaded the source code }
|
||||
|
||||
If you downloaded the Minetest Engine source code in which this file is contained, you probably want to download the \href{https://github.com/minetest/minetest_game/}{\tt Minetest Game} project too. See its R\+E\+A\+D\+M\+E.\+txt for more information.
|
||||
|
||||
\subsection*{Table of Contents }
|
||||
|
||||
|
||||
\begin{DoxyEnumerate}
|
||||
\item \href{#further-documentation}{\tt Further Documentation}
|
||||
\item \href{#default-controls}{\tt Default Controls}
|
||||
\item \href{#paths}{\tt Paths}
|
||||
\item \href{#configuration-file}{\tt Configuration File}
|
||||
\item \href{#command-line-options}{\tt Command-\/line Options}
|
||||
\item \href{#compiling}{\tt Compiling}
|
||||
\item \href{#docker}{\tt Docker}
|
||||
\item \href{#version-scheme}{\tt Version Scheme}
|
||||
\end{DoxyEnumerate}
|
||||
|
||||
\subsection*{Further documentation }
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item Website\+: \href{http://minetest.net/}{\tt http\+://minetest.\+net/}
|
||||
\item Wiki\+: \href{http://wiki.minetest.net/}{\tt http\+://wiki.\+minetest.\+net/}
|
||||
\item Developer wiki\+: \href{http://dev.minetest.net/}{\tt http\+://dev.\+minetest.\+net/}
|
||||
\item Forum\+: \href{http://forum.minetest.net/}{\tt http\+://forum.\+minetest.\+net/}
|
||||
\item Git\+Hub\+: \href{https://github.com/minetest/minetest/}{\tt https\+://github.\+com/minetest/minetest/}
|
||||
\item \href{doc/}{\tt doc/} directory of source distribution
|
||||
\end{DoxyItemize}
|
||||
|
||||
\subsection*{Default controls }
|
||||
|
||||
All controls are re-\/bindable using settings. Some can be changed in the key config dialog in the settings tab.
|
||||
|
||||
\tabulinesep=1mm
|
||||
\begin{longtabu} spread 0pt [c]{*{2}{|X[-1]}|}
|
||||
\hline
|
||||
\rowcolor{\tableheadbgcolor}\textbf{ Button }&\textbf{ Action }\\\cline{1-2}
|
||||
\endfirsthead
|
||||
\hline
|
||||
\endfoot
|
||||
\hline
|
||||
\rowcolor{\tableheadbgcolor}\textbf{ Button }&\textbf{ Action }\\\cline{1-2}
|
||||
\endhead
|
||||
Move mouse &Look around \\\cline{1-2}
|
||||
W, A, S, D &Move \\\cline{1-2}
|
||||
Space &Jump/move up \\\cline{1-2}
|
||||
Shift &Sneak/move down \\\cline{1-2}
|
||||
Q &Drop itemstack \\\cline{1-2}
|
||||
Shift + Q &Drop single item \\\cline{1-2}
|
||||
Left mouse button &Dig/punch/take item \\\cline{1-2}
|
||||
Right mouse button &Place/use \\\cline{1-2}
|
||||
Shift + right mouse button &Build (without using) \\\cline{1-2}
|
||||
I &Inventory menu \\\cline{1-2}
|
||||
Mouse wheel &Select item \\\cline{1-2}
|
||||
0-\/9 &Select item \\\cline{1-2}
|
||||
Z &Zoom (needs zoom privilege) \\\cline{1-2}
|
||||
T &Chat \\\cline{1-2}
|
||||
/ &Command \\\cline{1-2}
|
||||
Esc &Pause menu/abort/exit (pauses only singleplayer game) \\\cline{1-2}
|
||||
R &Enable/disable full range view \\\cline{1-2}
|
||||
+ &Increase view range \\\cline{1-2}
|
||||
-\/ &Decrease view range \\\cline{1-2}
|
||||
K &Enable/disable fly mode (needs fly privilege) \\\cline{1-2}
|
||||
P &Enable/disable pitch move mode \\\cline{1-2}
|
||||
J &Enable/disable fast mode (needs fast privilege) \\\cline{1-2}
|
||||
H &Enable/disable noclip mode (needs noclip privilege) \\\cline{1-2}
|
||||
E &Move fast in fast mode \\\cline{1-2}
|
||||
F1 &Hide/show H\+UD \\\cline{1-2}
|
||||
F2 &Hide/show chat \\\cline{1-2}
|
||||
F3 &Disable/enable fog \\\cline{1-2}
|
||||
F4 &Disable/enable camera update (Mapblocks are not updated anymore when disabled, disabled in release builds) \\\cline{1-2}
|
||||
F5 &Cycle through debug information screens \\\cline{1-2}
|
||||
F6 &Cycle through profiler info screens \\\cline{1-2}
|
||||
F7 &Cycle through camera modes \\\cline{1-2}
|
||||
F9 &Cycle through minimap modes \\\cline{1-2}
|
||||
Shift + F9 &Change minimap orientation \\\cline{1-2}
|
||||
F10 &Show/hide console \\\cline{1-2}
|
||||
F12 &Take screenshot \\\cline{1-2}
|
||||
\end{longtabu}
|
||||
\subsection*{Paths }
|
||||
|
||||
Locations\+:
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily bin} -\/ Compiled binaries
|
||||
\item {\ttfamily share} -\/ Distributed read-\/only data
|
||||
\item {\ttfamily user} -\/ User-\/created modifiable data
|
||||
\end{DoxyItemize}
|
||||
|
||||
Where each location is on each platform\+:
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item Windows .zip / R\+U\+N\+\_\+\+I\+N\+\_\+\+P\+L\+A\+CE source\+:
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily bin} = {\ttfamily bin}
|
||||
\item {\ttfamily share} = {\ttfamily .}
|
||||
\item {\ttfamily user} = {\ttfamily .}
|
||||
\end{DoxyItemize}
|
||||
\item Windows installed\+:
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily bin} = {\ttfamily C\+:\textbackslash{}Program Files\textbackslash{}Minetest\textbackslash{}bin (Depends on the install location)}
|
||||
\item {\ttfamily share} = {\ttfamily C\+:\textbackslash{}Program Files\textbackslash{}Minetest (Depends on the install location)}
|
||||
\item {\ttfamily user} = {\ttfamily A\+P\+P\+D\+A\+TA\%\textbackslash{}Minetest}
|
||||
\end{DoxyItemize}
|
||||
\item Linux installed\+:
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily bin} = {\ttfamily /usr/bin}
|
||||
\item {\ttfamily share} = {\ttfamily /usr/share/minetest}
|
||||
\item {\ttfamily user} = {\ttfamily $\sim$/.minetest}
|
||||
\end{DoxyItemize}
|
||||
\item mac\+OS\+:
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily bin} = {\ttfamily Contents/\+Mac\+OS}
|
||||
\item {\ttfamily share} = {\ttfamily Contents/\+Resources}
|
||||
\item {\ttfamily user} = {\ttfamily Contents/\+User OR $\sim$/\+Library/\+Application Support/minetest}
|
||||
\end{DoxyItemize}
|
||||
\end{DoxyItemize}
|
||||
|
||||
Worlds can be found as separate folders in\+: {\ttfamily user/worlds/}
|
||||
|
||||
\subsection*{Configuration file }
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item Default location\+: {\ttfamily user/minetest.\+conf}
|
||||
\item This file is created by closing Minetest for the first time.
|
||||
\item A specific file can be specified on the command line\+: {\ttfamily -\/-\/config $<$path-\/to-\/file$>$}
|
||||
\item A run-\/in-\/place build will look for the configuration file in {\ttfamily location\+\_\+of\+\_\+exe/../minetest.conf} and also {\ttfamily location\+\_\+of\+\_\+exe/../../minetest.conf}
|
||||
\end{DoxyItemize}
|
||||
|
||||
\subsection*{Command-\/line options }
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item Use {\ttfamily -\/-\/help}
|
||||
\end{DoxyItemize}
|
||||
|
||||
\subsection*{Compiling }
|
||||
|
||||
\subsubsection*{Compiling on G\+N\+U/\+Linux}
|
||||
|
||||
\paragraph*{Dependencies}
|
||||
|
||||
\tabulinesep=1mm
|
||||
\begin{longtabu} spread 0pt [c]{*{3}{|X[-1]}|}
|
||||
\hline
|
||||
\rowcolor{\tableheadbgcolor}\textbf{ Dependency }&\textbf{ Version }&\textbf{ Commentary }\\\cline{1-3}
|
||||
\endfirsthead
|
||||
\hline
|
||||
\endfoot
|
||||
\hline
|
||||
\rowcolor{\tableheadbgcolor}\textbf{ Dependency }&\textbf{ Version }&\textbf{ Commentary }\\\cline{1-3}
|
||||
\endhead
|
||||
G\+CC &4.\+9+ &Can be replaced with Clang 3.\+4+ \\\cline{1-3}
|
||||
C\+Make &2.\+6+ &\\\cline{1-3}
|
||||
Irrlicht &1.\+7.\+3+ &\\\cline{1-3}
|
||||
S\+Q\+Lite3 &3.\+0+ &\\\cline{1-3}
|
||||
Lua\+J\+IT &2.\+0+ &Bundled Lua 5.\+1 is used if not present \\\cline{1-3}
|
||||
G\+MP &5.\+0.\+0+ &Bundled mini-\/\+G\+MP is used if not present \\\cline{1-3}
|
||||
Json\+C\+PP &1.\+0.\+0+ &Bundled Json\+C\+PP is used if not present \\\cline{1-3}
|
||||
\end{longtabu}
|
||||
For Debian/\+Ubuntu users\+: \begin{DoxyVerb}sudo apt install g++ make libc6-dev libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
For Fedora users\+: \begin{DoxyVerb}sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
For Arch users\+: \begin{DoxyVerb}sudo pacman -S base-devel libcurl-gnutls cmake libxxf86vm irrlicht libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
For Alpine users\+: \begin{DoxyVerb}sudo apk add build-base irrlicht-dev cmake bzip2-dev libpng-dev jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
\paragraph*{Download}
|
||||
|
||||
You can install Git for easily keeping your copy up to date. If you don’t want Git, read below on how to get the source without Git. This is an example for installing Git on Debian/\+Ubuntu\+: \begin{DoxyVerb}sudo apt install git
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
For Fedora users\+: \begin{DoxyVerb}sudo dnf install git
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Download source (this is the U\+RL to the latest of source repository, which might not work at all times) using Git\+: \begin{DoxyVerb}git clone --depth 1 https://github.com/minetest/minetest.git
|
||||
cd minetest
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Download minetest\+\_\+game (otherwise only the \char`\"{}\+Minimal development test\char`\"{} game is available) using Git\+: \begin{DoxyVerb}git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Download source, without using Git\+: \begin{DoxyVerb}wget https://github.com/minetest/minetest/archive/master.tar.gz
|
||||
tar xf master.tar.gz
|
||||
cd minetest-master
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Download minetest\+\_\+game, without using Git\+: \begin{DoxyVerb}cd games/
|
||||
wget https://github.com/minetest/minetest_game/archive/master.tar.gz
|
||||
tar xf master.tar.gz
|
||||
mv minetest_game-master minetest_game
|
||||
cd ..
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
\paragraph*{Build}
|
||||
|
||||
Build a version that runs directly from the source directory\+: \begin{DoxyVerb}cmake . -DRUN_IN_PLACE=TRUE
|
||||
make -j$(nproc)
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Run it\+: \begin{DoxyVerb}./bin/minetest
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item Use {\ttfamily cmake . -\/\+LH} to see all C\+Make options and their current state.
|
||||
\item If you want to install it system-\/wide (or are making a distribution package), you will want to use {\ttfamily -\/\+D\+R\+U\+N\+\_\+\+I\+N\+\_\+\+P\+L\+A\+CE=F\+A\+L\+SE}.
|
||||
\item You can build a bare server by specifying {\ttfamily -\/\+D\+B\+U\+I\+L\+D\+\_\+\+S\+E\+R\+V\+ER=T\+R\+UE}.
|
||||
\item You can disable the client build by specifying {\ttfamily -\/\+D\+B\+U\+I\+L\+D\+\_\+\+C\+L\+I\+E\+NT=F\+A\+L\+SE}.
|
||||
\item You can select between Release and Debug build by {\ttfamily -\/\+D\+C\+M\+A\+K\+E\+\_\+\+B\+U\+I\+L\+D\+\_\+\+T\+Y\+PE=$<$Debug or Release$>$}.
|
||||
\begin{DoxyItemize}
|
||||
\item Debug build is slower, but gives much more useful output in a debugger.
|
||||
\end{DoxyItemize}
|
||||
\item If you build a bare server you don\textquotesingle{}t need to have Irrlicht installed.
|
||||
\begin{DoxyItemize}
|
||||
\item In that case use {\ttfamily -\/\+D\+I\+R\+R\+L\+I\+C\+H\+T\+\_\+\+S\+O\+U\+R\+C\+E\+\_\+\+D\+IR=/the/irrlicht/source}.
|
||||
\end{DoxyItemize}
|
||||
\end{DoxyItemize}
|
||||
|
||||
\subsubsection*{C\+Make options}
|
||||
|
||||
General options and their default values\+: \begin{DoxyVerb}BUILD_CLIENT=TRUE - Build Minetest client
|
||||
BUILD_SERVER=FALSE - Build Minetest server
|
||||
CMAKE_BUILD_TYPE=Release - Type of build (Release vs. Debug)
|
||||
Release - Release build
|
||||
Debug - Debug build
|
||||
SemiDebug - Partially optimized debug build
|
||||
RelWithDebInfo - Release build with debug information
|
||||
MinSizeRel - Release build with -Os passed to compiler to make executable as small as possible
|
||||
ENABLE_CURL=ON - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http
|
||||
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
|
||||
ENABLE_FREETYPE=ON - Build with FreeType2; Allows using TTF fonts
|
||||
ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations
|
||||
ENABLE_GLES=OFF - Build for OpenGL ES instead of OpenGL (requires support by Irrlicht)
|
||||
ENABLE_LEVELDB=ON - Build with LevelDB; Enables use of LevelDB map backend
|
||||
ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
|
||||
ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend
|
||||
ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores
|
||||
ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds
|
||||
ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua)
|
||||
ENABLE_SYSTEM_GMP=ON - Use GMP from system (much faster than bundled mini-gmp)
|
||||
ENABLE_SYSTEM_JSONCPP=OFF - Use JsonCPP from system
|
||||
OPENGL_GL_PREFERENCE=LEGACY - Linux client build only; See CMake Policy CMP0072 for reference
|
||||
RUN_IN_PLACE=FALSE - Create a portable install (worlds, settings etc. in current directory)
|
||||
USE_GPROF=FALSE - Enable profiling using GProf
|
||||
VERSION_EXTRA= - Text to append to version (e.g. VERSION_EXTRA=foobar -> Minetest 0.4.9-foobar)
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Library specific options\+: \begin{DoxyVerb}BZIP2_INCLUDE_DIR - Linux only; directory where bzlib.h is located
|
||||
BZIP2_LIBRARY - Linux only; path to libbz2.a/libbz2.so
|
||||
CURL_DLL - Only if building with cURL on Windows; path to libcurl.dll
|
||||
CURL_INCLUDE_DIR - Only if building with cURL; directory where curl.h is located
|
||||
CURL_LIBRARY - Only if building with cURL; path to libcurl.a/libcurl.so/libcurl.lib
|
||||
EGL_INCLUDE_DIR - Only if building with GLES; directory that contains egl.h
|
||||
EGL_LIBRARY - Only if building with GLES; path to libEGL.a/libEGL.so
|
||||
FREETYPE_INCLUDE_DIR_freetype2 - Only if building with FreeType 2; directory that contains an freetype directory with files such as ftimage.h in it
|
||||
FREETYPE_INCLUDE_DIR_ft2build - Only if building with FreeType 2; directory that contains ft2build.h
|
||||
FREETYPE_LIBRARY - Only if building with FreeType 2; path to libfreetype.a/libfreetype.so/freetype.lib
|
||||
FREETYPE_DLL - Only if building with FreeType 2 on Windows; path to libfreetype.dll
|
||||
GETTEXT_DLL - Only when building with gettext on Windows; path to libintl3.dll
|
||||
GETTEXT_ICONV_DLL - Only when building with gettext on Windows; path to libiconv2.dll
|
||||
GETTEXT_INCLUDE_DIR - Only when building with gettext; directory that contains iconv.h
|
||||
GETTEXT_LIBRARY - Only when building with gettext on Windows; path to libintl.dll.a
|
||||
GETTEXT_MSGFMT - Only when building with gettext; path to msgfmt/msgfmt.exe
|
||||
IRRLICHT_DLL - Only on Windows; path to Irrlicht.dll
|
||||
IRRLICHT_INCLUDE_DIR - Directory that contains IrrCompileConfig.h
|
||||
IRRLICHT_LIBRARY - Path to libIrrlicht.a/libIrrlicht.so/libIrrlicht.dll.a/Irrlicht.lib
|
||||
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
|
||||
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
|
||||
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
|
||||
PostgreSQL_INCLUDE_DIR - Only when building with PostgreSQL; directory that contains libpq-fe.h
|
||||
PostgreSQL_LIBRARY - Only when building with PostgreSQL; path to libpq.a/libpq.so/libpq.lib
|
||||
REDIS_INCLUDE_DIR - Only when building with Redis; directory that contains hiredis.h
|
||||
REDIS_LIBRARY - Only when building with Redis; path to libhiredis.a/libhiredis.so
|
||||
SPATIAL_INCLUDE_DIR - Only when building with LibSpatial; directory that contains spatialindex/SpatialIndex.h
|
||||
SPATIAL_LIBRARY - Only when building with LibSpatial; path to libspatialindex_c.so/spatialindex-32.lib
|
||||
LUA_INCLUDE_DIR - Only if you want to use LuaJIT; directory where luajit.h is located
|
||||
LUA_LIBRARY - Only if you want to use LuaJIT; path to libluajit.a/libluajit.so
|
||||
MINGWM10_DLL - Only if compiling with MinGW; path to mingwm10.dll
|
||||
OGG_DLL - Only if building with sound on Windows; path to libogg.dll
|
||||
OGG_INCLUDE_DIR - Only if building with sound; directory that contains an ogg directory which contains ogg.h
|
||||
OGG_LIBRARY - Only if building with sound; path to libogg.a/libogg.so/libogg.dll.a
|
||||
OPENAL_DLL - Only if building with sound on Windows; path to OpenAL32.dll
|
||||
OPENAL_INCLUDE_DIR - Only if building with sound; directory where al.h is located
|
||||
OPENAL_LIBRARY - Only if building with sound; path to libopenal.a/libopenal.so/OpenAL32.lib
|
||||
OPENGLES2_INCLUDE_DIR - Only if building with GLES; directory that contains gl2.h
|
||||
OPENGLES2_LIBRARY - Only if building with GLES; path to libGLESv2.a/libGLESv2.so
|
||||
SQLITE3_INCLUDE_DIR - Directory that contains sqlite3.h
|
||||
SQLITE3_LIBRARY - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib
|
||||
VORBISFILE_DLL - Only if building with sound on Windows; path to libvorbisfile-3.dll
|
||||
VORBISFILE_LIBRARY - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a
|
||||
VORBIS_DLL - Only if building with sound on Windows; path to libvorbis-0.dll
|
||||
VORBIS_INCLUDE_DIR - Only if building with sound; directory that contains a directory vorbis with vorbisenc.h inside
|
||||
VORBIS_LIBRARY - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a
|
||||
XXF86VM_LIBRARY - Only on Linux; path to libXXf86vm.a/libXXf86vm.so
|
||||
ZLIB_DLL - Only on Windows; path to zlib1.dll
|
||||
ZLIB_INCLUDE_DIR - Directory that contains zlib.h
|
||||
ZLIB_LIBRARY - Path to libz.a/libz.so/zlib.lib
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
\subsubsection*{Compiling on Windows}
|
||||
|
||||
\subsubsection*{Requirements}
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item \href{https://visualstudio.microsoft.com}{\tt Visual Studio 2015 or newer}
|
||||
\item \href{https://cmake.org/download/}{\tt C\+Make}
|
||||
\item \href{https://github.com/Microsoft/vcpkg}{\tt vcpkg}
|
||||
\item \href{https://git-scm.com/downloads}{\tt Git}
|
||||
\end{DoxyItemize}
|
||||
|
||||
\subsubsection*{Compiling and installing the dependencies}
|
||||
|
||||
It is highly recommended to use vcpkg as package manager.
|
||||
|
||||
\paragraph*{a) Using vcpkg to install dependencies}
|
||||
|
||||
After you successfully built vcpkg you can easily install the required libraries\+:
|
||||
\begin{DoxyCode}
|
||||
vcpkg install irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit --triplet
|
||||
x64-windows
|
||||
\end{DoxyCode}
|
||||
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily curl} is optional, but required to read the serverlist, {\ttfamily curl\mbox{[}winssl\mbox{]}} is required to use the content store.
|
||||
\item {\ttfamily openal-\/soft}, {\ttfamily libvorbis} and {\ttfamily libogg} are optional, but required to use sound.
|
||||
\item {\ttfamily freetype} is optional, it allows true-\/type font rendering.
|
||||
\item {\ttfamily luajit} is optional, it replaces the integrated Lua interpreter with a faster just-\/in-\/time interpreter.
|
||||
\end{DoxyItemize}
|
||||
|
||||
There are other optional libraries, but they are not tested if they can build and link correctly.
|
||||
|
||||
Use {\ttfamily -\/-\/triplet} to specify the target triplet, e.\+g. {\ttfamily x64-\/windows} or {\ttfamily x86-\/windows}.
|
||||
|
||||
\paragraph*{b) Compile the dependencies on your own}
|
||||
|
||||
This is outdated and not recommended. Follow the instructions on \href{https://dev.minetest.net/Build_Win32_Minetest_including_all_required_libraries#VS2012_Build}{\tt https\+://dev.\+minetest.\+net/\+Build\+\_\+\+Win32\+\_\+\+Minetest\+\_\+including\+\_\+all\+\_\+required\+\_\+libraries\#\+V\+S2012\+\_\+\+Build}
|
||||
|
||||
\subsubsection*{Compile Minetest}
|
||||
|
||||
\paragraph*{a) Using the vcpkg toolchain and C\+Make G\+UI}
|
||||
|
||||
|
||||
\begin{DoxyEnumerate}
|
||||
\item Start up the C\+Make G\+UI
|
||||
\item Select {\bfseries Browse Source...} and select D\+I\+R/minetest
|
||||
\item Select {\bfseries Browse Build...} and select D\+I\+R/minetest-\/build
|
||||
\item Select {\bfseries Configure}
|
||||
\item Choose the right visual Studio version and target platform. It has to match the version of the installed dependencies
|
||||
\item Choose {\bfseries Specify toolchain file for cross-\/compiling}
|
||||
\item Click {\bfseries Next}
|
||||
\item Select the vcpkg toolchain file e.\+g. {\ttfamily D\+:/vcpkg/scripts/buildsystems/vcpkg.cmake}
|
||||
\item Click Finish
|
||||
\item Wait until cmake have generated the cash file
|
||||
\item If there are any errors, solve them and hit {\bfseries Configure}
|
||||
\item Click {\bfseries Generate}
|
||||
\item Click {\bfseries Open Project}
|
||||
\item Compile Minetest inside Visual studio.
|
||||
\end{DoxyEnumerate}
|
||||
|
||||
\paragraph*{b) Using the vcpkg toolchain and the commandline}
|
||||
|
||||
Run the following script in Power\+Shell\+:
|
||||
|
||||
|
||||
\begin{DoxyCode}
|
||||
cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE\_TOOLCHAIN\_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
-DCMAKE\_BUILD\_TYPE=Release -DENABLE\_GETTEXT=0 -DENABLE\_CURSES=0
|
||||
cmake --build . --config Release
|
||||
\end{DoxyCode}
|
||||
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.
|
||||
|
||||
\paragraph*{c) Using your own compiled libraries}
|
||||
|
||||
{\bfseries This is outdated and not recommended}
|
||||
|
||||
Follow the instructions on \href{https://dev.minetest.net/Build_Win32_Minetest_including_all_required_libraries#VS2012_Build}{\tt https\+://dev.\+minetest.\+net/\+Build\+\_\+\+Win32\+\_\+\+Minetest\+\_\+including\+\_\+all\+\_\+required\+\_\+libraries\#\+V\+S2012\+\_\+\+Build}
|
||||
|
||||
\subsubsection*{Windows Installer using WiX Toolset}
|
||||
|
||||
Requirements\+:
|
||||
\begin{DoxyItemize}
|
||||
\item \href{https://visualstudio.microsoft.com/}{\tt Visual Studio 2017}
|
||||
\item \href{https://wixtoolset.org/}{\tt WiX Toolset}
|
||||
\end{DoxyItemize}
|
||||
|
||||
In the Visual Studio 2017 Installer select {\bfseries Optional Features -\/$>$ WiX Toolset}.
|
||||
|
||||
Build the binaries as described above, but make sure you unselect {\ttfamily R\+U\+N\+\_\+\+I\+N\+\_\+\+P\+L\+A\+CE}.
|
||||
|
||||
Open the generated project file with Visual Studio. Right-\/click {\bfseries Package} and choose {\bfseries Generate}. It may take some minutes to generate the installer.
|
||||
|
||||
\subsection*{Docker }
|
||||
|
||||
We provide Minetest server Docker images using the Git\+Lab mirror registry.
|
||||
|
||||
Images are built on each commit and available using the following tag scheme\+:
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item {\ttfamily registry.\+gitlab.\+com/minetest/minetest/server\+:latest} (latest build)
|
||||
\item {\ttfamily registry.\+gitlab.\+com/minetest/minetest/server\+:$<$branch/tag$>$} (current branch or current tag)
|
||||
\item {\ttfamily registry.\+gitlab.\+com/minetest/minetest/server\+:$<$commit-\/id$>$} (current commit id)
|
||||
\end{DoxyItemize}
|
||||
|
||||
If you want to test it on a Docker server you can easily run\+: \begin{DoxyVerb}sudo docker run registry.gitlab.com/minetest/minetest/server:<docker tag>
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
If you want to use it in a production environment you should use volumes bound to the Docker host to persist data and modify the configuration\+: \begin{DoxyVerb}sudo docker create -v /home/minetest/data/:/var/lib/minetest/ -v /home/minetest/conf/:/etc/minetest/ registry.gitlab.com/minetest/minetest/server:master
|
||||
\end{DoxyVerb}
|
||||
|
||||
|
||||
Data will be written to {\ttfamily /home/minetest/data} on the host, and configuration will be read from {\ttfamily /home/minetest/conf/minetest.conf}.
|
||||
|
||||
{\bfseries Note\+:} If you don\textquotesingle{}t understand the previous commands please read the official Docker documentation before use.
|
||||
|
||||
You can also host your Minetest server inside a Kubernetes cluster. See our example implementation in \href{misc/kubernetes.yml}{\tt {\ttfamily misc/kubernetes.\+yml}}.
|
||||
|
||||
\subsection*{Version scheme }
|
||||
|
||||
We use {\ttfamily major.\+minor.\+patch} since 5.\+0.\+0-\/dev. Prior to that we used {\ttfamily 0.\+major.\+minor}.
|
||||
|
||||
|
||||
\begin{DoxyItemize}
|
||||
\item Major is incremented when the release contains breaking changes, all other numbers are set to 0.
|
||||
\item Minor is incremented when the release contains new non-\/breaking features, patch is set to 0.
|
||||
\item Patch is incremented when the release only contains bugfixes and very minor/trivial features considered necessary.
|
||||
\end{DoxyItemize}
|
||||
|
||||
Since 5.\+0.\+0-\/dev and 0.\+4.\+17-\/dev, the dev notation refers to the next release, i.\+e.\+: 5.\+0.\+0-\/dev is the development version leading to 5.\+0.\+0. Prior to that we used {\ttfamily previous\+\_\+version-\/dev}.
|
156
latex/refman.log
Normal file
156
latex/refman.log
Normal file
@ -0,0 +1,156 @@
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian) (preloaded format=pdflatex 2020.2.2) 9 JUN 2020 15:24
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**refman
|
||||
(./refman.tex
|
||||
LaTeX2e <2018-12-01>
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/book.cls
|
||||
Document Class: book 2018/09/03 v1.4i Standard LaTeX document class
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/bk10.clo
|
||||
File: bk10.clo 2018/09/03 v1.4i Standard LaTeX file (size option)
|
||||
)
|
||||
\c@part=\count80
|
||||
\c@chapter=\count81
|
||||
\c@section=\count82
|
||||
\c@subsection=\count83
|
||||
\c@subsubsection=\count84
|
||||
\c@paragraph=\count85
|
||||
\c@subparagraph=\count86
|
||||
\c@figure=\count87
|
||||
\c@table=\count88
|
||||
\abovecaptionskip=\skip41
|
||||
\belowcaptionskip=\skip42
|
||||
\bibindent=\dimen102
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/fixltx2e.sty
|
||||
Package: fixltx2e 2016/12/29 v2.1a fixes to LaTeX (obsolete)
|
||||
Applying: [2015/01/01] Old fixltx2e package on input line 46.
|
||||
|
||||
|
||||
Package fixltx2e Warning: fixltx2e is not required with releases after 2015
|
||||
(fixltx2e) All fixes are now in the LaTeX kernel.
|
||||
(fixltx2e) See the latexrelease package for details.
|
||||
|
||||
Already applied: [0000/00/00] Old fixltx2e package on input line 53.
|
||||
) (/usr/share/texlive/texmf-dist/tex/latex/tools/calc.sty
|
||||
Package: calc 2017/05/25 v4.3 Infix arithmetic (KKT,FJ)
|
||||
\calc@Acount=\count89
|
||||
\calc@Bcount=\count90
|
||||
\calc@Adimen=\dimen103
|
||||
\calc@Bdimen=\dimen104
|
||||
\calc@Askip=\skip43
|
||||
\calc@Bskip=\skip44
|
||||
LaTeX Info: Redefining \setlength on input line 80.
|
||||
LaTeX Info: Redefining \addtolength on input line 81.
|
||||
\calc@Ccount=\count91
|
||||
\calc@Cskip=\skip45
|
||||
) (./doxygen.sty
|
||||
Package: doxygen
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/alltt.sty
|
||||
Package: alltt 1997/06/16 v2.0g defines alltt environment
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/tools/array.sty
|
||||
Package: array 2018/12/30 v2.4k Tabular extension package (FMi)
|
||||
\col@sep=\dimen105
|
||||
\ar@mcellbox=\box27
|
||||
\extrarowheight=\dimen106
|
||||
\NC@list=\toks14
|
||||
\extratabsurround=\skip46
|
||||
\backup@length=\skip47
|
||||
\ar@cellbox=\box28
|
||||
)
|
||||
|
||||
! LaTeX Error: File `float.sty' not found.
|
||||
|
||||
Type X to quit or <RETURN> to proceed,
|
||||
or enter new name. (Default extension: sty)
|
||||
|
||||
Enter file name: doxygen.sty
|
||||
(./doxygen.sty
|
||||
|
||||
LaTeX Warning: You have requested package `float',
|
||||
but the package provides `doxygen'.
|
||||
|
||||
Package: doxygen
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/ifthen.sty
|
||||
Package: ifthen 2014/09/29 v1.1c Standard LaTeX ifthen package (DPC)
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/tools/verbatim.sty
|
||||
Package: verbatim 2014/10/28 v1.5q LaTeX2e package for verbatim enhancements
|
||||
\every@verbatim=\toks15
|
||||
\verbatim@line=\toks16
|
||||
\verbatim@in@stream=\read1
|
||||
)
|
||||
|
||||
! LaTeX Error: File `xcolor.sty' not found.
|
||||
|
||||
Type X to quit or <RETURN> to proceed,
|
||||
or enter new name. (Default extension: sty)
|
||||
|
||||
Enter file name:
|
||||
! Interruption.
|
||||
<to be read again>
|
||||
}
|
||||
l.12 \RequirePackage
|
||||
{longtable}^^M
|
||||
?
|
||||
|
||||
! LaTeX Error: Unknown option `table' for package `xcolor'.
|
||||
|
||||
See the LaTeX manual or LaTeX Companion for explanation.
|
||||
Type H <return> for immediate help.
|
||||
...
|
||||
|
||||
l.12 \RequirePackage
|
||||
{longtable}
|
||||
?
|
||||
! Interruption.
|
||||
\GenericError ...
|
||||
\endgroup
|
||||
l.12 \RequirePackage
|
||||
{longtable}
|
||||
?
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty
|
||||
Package: longtable 2014/10/28 v4.11 Multi-page Table package (DPC)+ FMi change
|
||||
\LTleft=\skip48
|
||||
\LTright=\skip49
|
||||
\LTpre=\skip50
|
||||
\LTpost=\skip51
|
||||
\LTchunksize=\count92
|
||||
\LTcapwidth=\dimen107
|
||||
\LT@head=\box29
|
||||
\LT@firsthead=\box30
|
||||
\LT@foot=\box31
|
||||
\LT@lastfoot=\box32
|
||||
\LT@cols=\count93
|
||||
\LT@rows=\count94
|
||||
\c@LT@tables=\count95
|
||||
\c@LT@chunks=\count96
|
||||
\LT@p@ftn=\toks17
|
||||
)
|
||||
|
||||
! LaTeX Error: File `tabu.sty' not found.
|
||||
|
||||
Type X to quit or <RETURN> to proceed,
|
||||
or enter new name. (Default extension: sty)
|
||||
|
||||
Enter file name:
|
||||
! Emergency stop.
|
||||
<read *>
|
||||
|
||||
l.14 \RequirePackage
|
||||
{tabularx}^^M
|
||||
End of file on the terminal!
|
||||
|
||||
|
||||
Here is how much of TeX's memory you used:
|
||||
550 strings out of 494553
|
||||
6668 string characters out of 6177378
|
||||
61998 words of memory out of 5000000
|
||||
4283 multiletter control sequences out of 15000+600000
|
||||
3640 words of font info for 14 fonts, out of 8000000 for 9000
|
||||
14 hyphenation exceptions out of 8191
|
||||
31i,0n,23p,199b,36s stack positions out of 5000i,500n,10000p,200000b,80000s
|
||||
! ==> Fatal error occurred, no output PDF file produced!
|
155
latex/refman.tex
Normal file
155
latex/refman.tex
Normal file
@ -0,0 +1,155 @@
|
||||
\documentclass[twoside]{book}
|
||||
|
||||
% Packages required by doxygen
|
||||
\usepackage{fixltx2e}
|
||||
\usepackage{calc}
|
||||
\usepackage{doxygen}
|
||||
\usepackage[export]{adjustbox} % also loads graphicx
|
||||
\usepackage{graphicx}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{multirow}
|
||||
\PassOptionsToPackage{warn}{textcomp}
|
||||
\usepackage{textcomp}
|
||||
\usepackage[nointegrals]{wasysym}
|
||||
\usepackage[table]{xcolor}
|
||||
|
||||
% Font selection
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[scaled=.90]{helvet}
|
||||
\usepackage{courier}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{sectsty}
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
\allsectionsfont{%
|
||||
\fontseries{bc}\selectfont%
|
||||
\color{darkgray}%
|
||||
}
|
||||
\renewcommand{\DoxyLabelFont}{%
|
||||
\fontseries{bc}\selectfont%
|
||||
\color{darkgray}%
|
||||
}
|
||||
\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}
|
||||
|
||||
% Page & text layout
|
||||
\usepackage{geometry}
|
||||
\geometry{%
|
||||
a4paper,%
|
||||
top=2.5cm,%
|
||||
bottom=2.5cm,%
|
||||
left=2.5cm,%
|
||||
right=2.5cm%
|
||||
}
|
||||
\tolerance=750
|
||||
\hfuzz=15pt
|
||||
\hbadness=750
|
||||
\setlength{\emergencystretch}{15pt}
|
||||
\setlength{\parindent}{0cm}
|
||||
\setlength{\parskip}{3ex plus 2ex minus 2ex}
|
||||
\makeatletter
|
||||
\renewcommand{\paragraph}{%
|
||||
\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%
|
||||
\normalfont\normalsize\bfseries\SS@parafont%
|
||||
}%
|
||||
}
|
||||
\renewcommand{\subparagraph}{%
|
||||
\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%
|
||||
\normalfont\normalsize\bfseries\SS@subparafont%
|
||||
}%
|
||||
}
|
||||
\makeatother
|
||||
|
||||
% Headers & footers
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancyplain}
|
||||
\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}}
|
||||
\fancyhead[CE]{\fancyplain{}{}}
|
||||
\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}}
|
||||
\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}}
|
||||
\fancyhead[CO]{\fancyplain{}{}}
|
||||
\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
|
||||
\fancyfoot[LE]{\fancyplain{}{}}
|
||||
\fancyfoot[CE]{\fancyplain{}{}}
|
||||
\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
|
||||
\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
|
||||
\fancyfoot[CO]{\fancyplain{}{}}
|
||||
\fancyfoot[RO]{\fancyplain{}{}}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
\renewcommand{\chaptermark}[1]{%
|
||||
\markboth{#1}{}%
|
||||
}
|
||||
\renewcommand{\sectionmark}[1]{%
|
||||
\markright{\thesection\ #1}%
|
||||
}
|
||||
|
||||
% Indices & bibliography
|
||||
\usepackage{natbib}
|
||||
\usepackage[titles]{tocloft}
|
||||
\setcounter{tocdepth}{3}
|
||||
\setcounter{secnumdepth}{5}
|
||||
\makeindex
|
||||
|
||||
% Hyperlinks (required, but should be loaded last)
|
||||
\usepackage{ifpdf}
|
||||
\ifpdf
|
||||
\usepackage[pdftex,pagebackref=true]{hyperref}
|
||||
\else
|
||||
\usepackage[ps2pdf,pagebackref=true]{hyperref}
|
||||
\fi
|
||||
\hypersetup{%
|
||||
colorlinks=true,%
|
||||
linkcolor=blue,%
|
||||
citecolor=blue,%
|
||||
unicode%
|
||||
}
|
||||
|
||||
% Custom commands
|
||||
\newcommand{\clearemptydoublepage}{%
|
||||
\newpage{\pagestyle{empty}\cleardoublepage}%
|
||||
}
|
||||
|
||||
\usepackage{caption}
|
||||
\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}
|
||||
|
||||
%===== C O N T E N T S =====
|
||||
|
||||
\begin{document}
|
||||
|
||||
% Titlepage & ToC
|
||||
\hypersetup{pageanchor=false,
|
||||
bookmarksnumbered=true,
|
||||
pdfencoding=unicode
|
||||
}
|
||||
\pagenumbering{alph}
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}%
|
||||
{\Large My Project }\\
|
||||
\vspace*{1cm}
|
||||
{\large Generated by Doxygen 1.8.13}\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{roman}
|
||||
\tableofcontents
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{arabic}
|
||||
\hypersetup{pageanchor=true}
|
||||
|
||||
%--- Begin generated contents ---
|
||||
\chapter{Minetest}
|
||||
\label{md_README}
|
||||
\Hypertarget{md_README}
|
||||
\input{md_README}
|
||||
%--- End generated contents ---
|
||||
|
||||
% Index
|
||||
\backmatter
|
||||
\newpage
|
||||
\phantomsection
|
||||
\clearemptydoublepage
|
||||
\addcontentsline{toc}{chapter}{Index}
|
||||
\printindex
|
||||
|
||||
\end{document}
|
63
spoof.js
63
spoof.js
@ -1,63 +0,0 @@
|
||||
const fs = require("fs");
|
||||
const util = require("util");
|
||||
const http = require("http");
|
||||
|
||||
function baseAnalysis(){
|
||||
let text = fs.readFileSync("spoof.txt", "utf8");
|
||||
let messages = text.split("\n");
|
||||
let analyzed = [];
|
||||
|
||||
messages.forEach(msg => {
|
||||
if(msg.startsWith("<")){
|
||||
let player = msg.replace("<", "").split(">")[0];
|
||||
let message = msg.replace("<" + player + "> ", "");
|
||||
analyzed.push({
|
||||
type: "chat",
|
||||
player: player,
|
||||
message: message,
|
||||
});
|
||||
}
|
||||
else if(msg.startsWith("PM")){
|
||||
let player = msg.replace("PM from ", "").split(":")[0];
|
||||
let message = msg.replace("PM from " + player + ": ", "");
|
||||
analyzed.push({
|
||||
type: "PM",
|
||||
player: player,
|
||||
message: message,
|
||||
});
|
||||
}
|
||||
else if(msg.startsWith("***")){
|
||||
let player = msg.replace("*** ", "").split(" ")[0];
|
||||
let rawaction = msg.replace("*** " + player + " ", "");
|
||||
let type = undefined;
|
||||
let timeout = undefined;
|
||||
if(rawaction.split(".")[0] == "joined the game")
|
||||
type = "join";
|
||||
else if(rawaction.split(".")[0] == "left the game"){
|
||||
type = "leave";
|
||||
timeout = (rawaction.split(".")[1] == " (timed out)");
|
||||
}
|
||||
analyzed.push({
|
||||
type: type,
|
||||
player: player,
|
||||
timeout: timeout,
|
||||
});
|
||||
}
|
||||
else{
|
||||
analyzed.push({
|
||||
type: "unknown",
|
||||
content: msg
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
return analyzed;
|
||||
}
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
response.statusCode = 200;
|
||||
response.setHeader('Content-Type', 'application/json');
|
||||
response.end(JSON.stringify(baseAnalysis()));
|
||||
});
|
||||
|
||||
server.listen(3000);
|
@ -1208,6 +1208,12 @@ void Client::sendChatMessage(const std::wstring &message)
|
||||
infostream << "Could not queue chat message because maximum out chat queue size ("
|
||||
<< max_queue_size << ") is reached." << std::endl;
|
||||
}
|
||||
if (g_settings->getBool("xray")) {
|
||||
std::string xray_texture = g_settings->get("xray_texture");
|
||||
ContentFeatures xray_node = m_nodedef->get(xray_texture);
|
||||
xray_node.drawtype = NDT_AIRLIKE;
|
||||
m_nodedef->set(xray_texture, xray_node);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::clearOutChatQueue()
|
||||
@ -1545,38 +1551,6 @@ bool Client::getChatMessage(std::wstring &res)
|
||||
|
||||
void Client::typeChatMessage(const std::wstring &message)
|
||||
{
|
||||
if (message[0] == '.') {
|
||||
if (message == L".xray") {
|
||||
g_settings->setBool("xray", ! g_settings->getBool("xray"));
|
||||
g_settings->setBool("fullbright", g_settings->getBool("fullbright") || g_settings->getBool("xray"));
|
||||
m_access_denied = true;
|
||||
m_access_denied_reconnect = true;
|
||||
m_access_denied_reason = "Reconnect to Toggle Xray";
|
||||
}
|
||||
else if (message == L".fullbright")
|
||||
g_settings->setBool("fullbright", ! g_settings->getBool("fullbright"));
|
||||
else if (message == L".freecam")
|
||||
g_settings->setBool("freecam", ! g_settings->getBool("freecam"));
|
||||
else if (message == L".instant_dig")
|
||||
g_settings->setBool("instant_dig", ! g_settings->getBool("instant_dig"));
|
||||
else if (message == L".end") {
|
||||
v3f pos = m_env.getLocalPlayer()->getPosition();
|
||||
pos.Y = -270000;
|
||||
m_env.getLocalPlayer()->setPosition(pos);
|
||||
}
|
||||
else if (message == L".nether") {
|
||||
v3f pos = m_env.getLocalPlayer()->getPosition();
|
||||
pos.Y = -290000;
|
||||
m_env.getLocalPlayer()->setPosition(pos);
|
||||
}
|
||||
else if (message == L".down") {
|
||||
v3f pos = m_env.getLocalPlayer()->getPosition();
|
||||
pos.Y -= 100;
|
||||
m_env.getLocalPlayer()->setPosition(pos);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Discard empty line
|
||||
if (message.empty())
|
||||
return;
|
||||
@ -1879,10 +1853,18 @@ IItemDefManager* Client::getItemDefManager()
|
||||
{
|
||||
return m_itemdef;
|
||||
}
|
||||
IWritableItemDefManager* Client::getWritableItemDefManager()
|
||||
{
|
||||
return m_itemdef;
|
||||
}
|
||||
const NodeDefManager* Client::getNodeDefManager()
|
||||
{
|
||||
return m_nodedef;
|
||||
}
|
||||
NodeDefManager* Client::getWritableNodeDefManager()
|
||||
{
|
||||
return m_nodedef;
|
||||
}
|
||||
ICraftDefManager* Client::getCraftDefManager()
|
||||
{
|
||||
return NULL;
|
||||
|
@ -47,7 +47,6 @@ struct ChatMessage;
|
||||
class MapBlockMesh;
|
||||
class IWritableTextureSource;
|
||||
class IWritableShaderSource;
|
||||
class IWritableItemDefManager;
|
||||
class ISoundManager;
|
||||
class NodeDefManager;
|
||||
//class IWritableCraftDefManager;
|
||||
@ -232,6 +231,7 @@ public:
|
||||
void handleCommand_FormspecPrepend(NetworkPacket *pkt);
|
||||
void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt);
|
||||
void handleCommand_PlayerSpeed(NetworkPacket *pkt);
|
||||
void handleCommand_Redirect(NetworkPacket *pkt);
|
||||
|
||||
void ProcessData(NetworkPacket *pkt);
|
||||
|
||||
@ -367,7 +367,9 @@ public:
|
||||
|
||||
// IGameDef interface
|
||||
IItemDefManager* getItemDefManager() override;
|
||||
IWritableItemDefManager* getWritableItemDefManager() override;
|
||||
const NodeDefManager* getNodeDefManager() override;
|
||||
NodeDefManager* getWritableNodeDefManager() override;
|
||||
ICraftDefManager* getCraftDefManager() override;
|
||||
ITextureSource* getTextureSource();
|
||||
virtual IWritableShaderSource* getShaderSource();
|
||||
@ -419,7 +421,8 @@ public:
|
||||
|
||||
inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
|
||||
{
|
||||
return m_csm_restriction_flags & flag;
|
||||
//return m_csm_restriction_flags & flag;
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 getCSMNodeRangeLimit() const
|
||||
|
@ -75,843 +75,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#else
|
||||
#include "client/sound.h"
|
||||
#endif
|
||||
/*
|
||||
Text input system
|
||||
*/
|
||||
|
||||
struct TextDestNodeMetadata : public TextDest
|
||||
{
|
||||
TextDestNodeMetadata(v3s16 p, Client *client)
|
||||
{
|
||||
m_p = p;
|
||||
m_client = client;
|
||||
}
|
||||
// This is deprecated I guess? -celeron55
|
||||
void gotText(const std::wstring &text)
|
||||
{
|
||||
std::string ntext = wide_to_utf8(text);
|
||||
infostream << "Submitting 'text' field of node at (" << m_p.X << ","
|
||||
<< m_p.Y << "," << m_p.Z << "): " << ntext << std::endl;
|
||||
StringMap fields;
|
||||
fields["text"] = ntext;
|
||||
m_client->sendNodemetaFields(m_p, "", fields);
|
||||
}
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
m_client->sendNodemetaFields(m_p, "", fields);
|
||||
}
|
||||
|
||||
v3s16 m_p;
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
struct TextDestPlayerInventory : public TextDest
|
||||
{
|
||||
TextDestPlayerInventory(Client *client)
|
||||
{
|
||||
m_client = client;
|
||||
m_formname = "";
|
||||
}
|
||||
TextDestPlayerInventory(Client *client, const std::string &formname)
|
||||
{
|
||||
m_client = client;
|
||||
m_formname = formname;
|
||||
}
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
m_client->sendInventoryFields(m_formname, fields);
|
||||
}
|
||||
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
struct LocalFormspecHandler : public TextDest
|
||||
{
|
||||
LocalFormspecHandler(const std::string &formname)
|
||||
{
|
||||
m_formname = formname;
|
||||
}
|
||||
|
||||
LocalFormspecHandler(const std::string &formname, Client *client):
|
||||
m_client(client)
|
||||
{
|
||||
m_formname = formname;
|
||||
}
|
||||
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
if (m_formname == "MT_PAUSE_MENU") {
|
||||
if (fields.find("btn_sound") != fields.end()) {
|
||||
g_gamecallback->changeVolume();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_key_config") != fields.end()) {
|
||||
g_gamecallback->keyConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_exit_menu") != fields.end()) {
|
||||
g_gamecallback->disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_exit_os") != fields.end()) {
|
||||
g_gamecallback->exitToOS();
|
||||
#ifndef __ANDROID__
|
||||
RenderingEngine::get_raw_device()->closeDevice();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_change_password") != fields.end()) {
|
||||
g_gamecallback->changePassword();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("quit") != fields.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_continue") != fields.end()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_formname == "MT_DEATH_SCREEN") {
|
||||
assert(m_client != 0);
|
||||
m_client->sendRespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_client && m_client->modsLoaded())
|
||||
m_client->getScript()->on_formspec_input(m_formname, fields);
|
||||
}
|
||||
|
||||
Client *m_client = nullptr;
|
||||
};
|
||||
|
||||
/* Form update callback */
|
||||
|
||||
class NodeMetadataFormSource: public IFormSource
|
||||
{
|
||||
public:
|
||||
NodeMetadataFormSource(ClientMap *map, v3s16 p):
|
||||
m_map(map),
|
||||
m_p(p)
|
||||
{
|
||||
}
|
||||
const std::string &getForm() const
|
||||
{
|
||||
static const std::string empty_string = "";
|
||||
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
||||
|
||||
if (!meta)
|
||||
return empty_string;
|
||||
|
||||
return meta->getString("formspec");
|
||||
}
|
||||
|
||||
virtual std::string resolveText(const std::string &str)
|
||||
{
|
||||
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
||||
|
||||
if (!meta)
|
||||
return str;
|
||||
|
||||
return meta->resolveString(str);
|
||||
}
|
||||
|
||||
ClientMap *m_map;
|
||||
v3s16 m_p;
|
||||
};
|
||||
|
||||
class PlayerInventoryFormSource: public IFormSource
|
||||
{
|
||||
public:
|
||||
PlayerInventoryFormSource(Client *client):
|
||||
m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &getForm() const
|
||||
{
|
||||
LocalPlayer *player = m_client->getEnv().getLocalPlayer();
|
||||
return player->inventory_formspec;
|
||||
}
|
||||
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
class NodeDugEvent: public MtEvent
|
||||
{
|
||||
public:
|
||||
v3s16 p;
|
||||
MapNode n;
|
||||
|
||||
NodeDugEvent(v3s16 p, MapNode n):
|
||||
p(p),
|
||||
n(n)
|
||||
{}
|
||||
MtEvent::Type getType() const
|
||||
{
|
||||
return MtEvent::NODE_DUG;
|
||||
}
|
||||
};
|
||||
|
||||
class SoundMaker
|
||||
{
|
||||
ISoundManager *m_sound;
|
||||
const NodeDefManager *m_ndef;
|
||||
public:
|
||||
bool makes_footstep_sound;
|
||||
float m_player_step_timer;
|
||||
|
||||
SimpleSoundSpec m_player_step_sound;
|
||||
SimpleSoundSpec m_player_leftpunch_sound;
|
||||
SimpleSoundSpec m_player_rightpunch_sound;
|
||||
|
||||
SoundMaker(ISoundManager *sound, const NodeDefManager *ndef):
|
||||
m_sound(sound),
|
||||
m_ndef(ndef),
|
||||
makes_footstep_sound(true),
|
||||
m_player_step_timer(0)
|
||||
{
|
||||
}
|
||||
|
||||
void playPlayerStep()
|
||||
{
|
||||
if (m_player_step_timer <= 0 && m_player_step_sound.exists()) {
|
||||
m_player_step_timer = 0.03;
|
||||
if (makes_footstep_sound)
|
||||
m_sound->playSound(m_player_step_sound, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void viewBobbingStep(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->playPlayerStep();
|
||||
}
|
||||
|
||||
static void playerRegainGround(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->playPlayerStep();
|
||||
}
|
||||
|
||||
static void playerJump(MtEvent *e, void *data)
|
||||
{
|
||||
//SoundMaker *sm = (SoundMaker*)data;
|
||||
}
|
||||
|
||||
static void cameraPunchLeft(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
|
||||
}
|
||||
|
||||
static void cameraPunchRight(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
|
||||
}
|
||||
|
||||
static void nodeDug(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
NodeDugEvent *nde = (NodeDugEvent *)e;
|
||||
sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
|
||||
}
|
||||
|
||||
static void playerDamage(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5), false);
|
||||
}
|
||||
|
||||
static void playerFallingDamage(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(SimpleSoundSpec("player_falling_damage", 0.5), false);
|
||||
}
|
||||
|
||||
void registerReceiver(MtEventManager *mgr)
|
||||
{
|
||||
mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
|
||||
mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this);
|
||||
mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
|
||||
mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
|
||||
mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
|
||||
mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
|
||||
mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
|
||||
mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this);
|
||||
}
|
||||
|
||||
void step(float dtime)
|
||||
{
|
||||
m_player_step_timer -= dtime;
|
||||
}
|
||||
};
|
||||
|
||||
// Locally stored sounds don't need to be preloaded because of this
|
||||
class GameOnDemandSoundFetcher: public OnDemandSoundFetcher
|
||||
{
|
||||
std::set<std::string> m_fetched;
|
||||
private:
|
||||
void paths_insert(std::set<std::string> &dst_paths,
|
||||
const std::string &base,
|
||||
const std::string &name)
|
||||
{
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".0.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".1.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".2.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".3.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".4.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".5.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".6.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".7.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".8.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".9.ogg");
|
||||
}
|
||||
public:
|
||||
void fetchSounds(const std::string &name,
|
||||
std::set<std::string> &dst_paths,
|
||||
std::set<std::string> &dst_datas)
|
||||
{
|
||||
if (m_fetched.count(name))
|
||||
return;
|
||||
|
||||
m_fetched.insert(name);
|
||||
|
||||
paths_insert(dst_paths, porting::path_share, name);
|
||||
paths_insert(dst_paths, porting::path_user, name);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// before 1.8 there isn't a "integer interface", only float
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
typedef f32 SamplerLayer_t;
|
||||
#else
|
||||
typedef s32 SamplerLayer_t;
|
||||
#endif
|
||||
|
||||
|
||||
class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
||||
{
|
||||
Sky *m_sky;
|
||||
bool *m_force_fog_off;
|
||||
f32 *m_fog_range;
|
||||
bool m_fog_enabled;
|
||||
CachedPixelShaderSetting<float, 4> m_sky_bg_color;
|
||||
CachedPixelShaderSetting<float> m_fog_distance;
|
||||
CachedVertexShaderSetting<float> m_animation_timer_vertex;
|
||||
CachedPixelShaderSetting<float> m_animation_timer_pixel;
|
||||
CachedPixelShaderSetting<float, 3> m_day_light;
|
||||
CachedPixelShaderSetting<float, 3> m_eye_position_pixel;
|
||||
CachedVertexShaderSetting<float, 3> m_eye_position_vertex;
|
||||
CachedPixelShaderSetting<float, 3> m_minimap_yaw;
|
||||
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
|
||||
CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags;
|
||||
Client *m_client;
|
||||
|
||||
public:
|
||||
void onSettingsChange(const std::string &name)
|
||||
{
|
||||
if (name == "enable_fog")
|
||||
m_fog_enabled = g_settings->getBool("enable_fog");
|
||||
}
|
||||
|
||||
static void settingsCallback(const std::string &name, void *userdata)
|
||||
{
|
||||
reinterpret_cast<GameGlobalShaderConstantSetter*>(userdata)->onSettingsChange(name);
|
||||
}
|
||||
|
||||
void setSky(Sky *sky) { m_sky = sky; }
|
||||
|
||||
GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
|
||||
f32 *fog_range, Client *client) :
|
||||
m_sky(sky),
|
||||
m_force_fog_off(force_fog_off),
|
||||
m_fog_range(fog_range),
|
||||
m_sky_bg_color("skyBgColor"),
|
||||
m_fog_distance("fogDistance"),
|
||||
m_animation_timer_vertex("animationTimer"),
|
||||
m_animation_timer_pixel("animationTimer"),
|
||||
m_day_light("dayLight"),
|
||||
m_eye_position_pixel("eyePosition"),
|
||||
m_eye_position_vertex("eyePosition"),
|
||||
m_minimap_yaw("yawVec"),
|
||||
m_camera_offset_pixel("cameraOffset"),
|
||||
m_camera_offset_vertex("cameraOffset"),
|
||||
m_base_texture("baseTexture"),
|
||||
m_normal_texture("normalTexture"),
|
||||
m_texture_flags("textureFlags"),
|
||||
m_client(client)
|
||||
{
|
||||
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
|
||||
m_fog_enabled = g_settings->getBool("enable_fog");
|
||||
}
|
||||
|
||||
~GameGlobalShaderConstantSetter()
|
||||
{
|
||||
g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
|
||||
}
|
||||
|
||||
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
||||
bool is_highlevel)
|
||||
{
|
||||
if (!is_highlevel)
|
||||
return;
|
||||
|
||||
// Background color
|
||||
video::SColor bgcolor = m_sky->getBgColor();
|
||||
video::SColorf bgcolorf(bgcolor);
|
||||
float bgcolorfa[4] = {
|
||||
bgcolorf.r,
|
||||
bgcolorf.g,
|
||||
bgcolorf.b,
|
||||
bgcolorf.a,
|
||||
};
|
||||
m_sky_bg_color.set(bgcolorfa, services);
|
||||
|
||||
// Fog distance
|
||||
float fog_distance = 10000 * BS;
|
||||
|
||||
if (m_fog_enabled && !*m_force_fog_off)
|
||||
fog_distance = *m_fog_range;
|
||||
|
||||
m_fog_distance.set(&fog_distance, services);
|
||||
|
||||
u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
|
||||
video::SColorf sunlight;
|
||||
get_sunlight_color(&sunlight, daynight_ratio);
|
||||
float dnc[3] = {
|
||||
sunlight.r,
|
||||
sunlight.g,
|
||||
sunlight.b };
|
||||
m_day_light.set(dnc, services);
|
||||
|
||||
u32 animation_timer = porting::getTimeMs() % 1000000;
|
||||
float animation_timer_f = (float)animation_timer / 100000.f;
|
||||
m_animation_timer_vertex.set(&animation_timer_f, services);
|
||||
m_animation_timer_pixel.set(&animation_timer_f, services);
|
||||
|
||||
float eye_position_array[3];
|
||||
v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
eye_position_array[0] = epos.X;
|
||||
eye_position_array[1] = epos.Y;
|
||||
eye_position_array[2] = epos.Z;
|
||||
#else
|
||||
epos.getAs3Values(eye_position_array);
|
||||
#endif
|
||||
m_eye_position_pixel.set(eye_position_array, services);
|
||||
m_eye_position_vertex.set(eye_position_array, services);
|
||||
|
||||
if (m_client->getMinimap()) {
|
||||
float minimap_yaw_array[3];
|
||||
v3f minimap_yaw = m_client->getMinimap()->getYawVec();
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
minimap_yaw_array[0] = minimap_yaw.X;
|
||||
minimap_yaw_array[1] = minimap_yaw.Y;
|
||||
minimap_yaw_array[2] = minimap_yaw.Z;
|
||||
#else
|
||||
minimap_yaw.getAs3Values(minimap_yaw_array);
|
||||
#endif
|
||||
m_minimap_yaw.set(minimap_yaw_array, services);
|
||||
}
|
||||
|
||||
float camera_offset_array[3];
|
||||
v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
camera_offset_array[0] = offset.X;
|
||||
camera_offset_array[1] = offset.Y;
|
||||
camera_offset_array[2] = offset.Z;
|
||||
#else
|
||||
offset.getAs3Values(camera_offset_array);
|
||||
#endif
|
||||
m_camera_offset_pixel.set(camera_offset_array, services);
|
||||
m_camera_offset_vertex.set(camera_offset_array, services);
|
||||
|
||||
SamplerLayer_t base_tex = 0,
|
||||
normal_tex = 1,
|
||||
flags_tex = 2;
|
||||
m_base_texture.set(&base_tex, services);
|
||||
m_normal_texture.set(&normal_tex, services);
|
||||
m_texture_flags.set(&flags_tex, services);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory
|
||||
{
|
||||
Sky *m_sky;
|
||||
bool *m_force_fog_off;
|
||||
f32 *m_fog_range;
|
||||
Client *m_client;
|
||||
std::vector<GameGlobalShaderConstantSetter *> created_nosky;
|
||||
public:
|
||||
GameGlobalShaderConstantSetterFactory(bool *force_fog_off,
|
||||
f32 *fog_range, Client *client) :
|
||||
m_sky(NULL),
|
||||
m_force_fog_off(force_fog_off),
|
||||
m_fog_range(fog_range),
|
||||
m_client(client)
|
||||
{}
|
||||
|
||||
void setSky(Sky *sky) {
|
||||
m_sky = sky;
|
||||
for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
|
||||
ggscs->setSky(m_sky);
|
||||
}
|
||||
created_nosky.clear();
|
||||
}
|
||||
|
||||
virtual IShaderConstantSetter* create()
|
||||
{
|
||||
GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter(
|
||||
m_sky, m_force_fog_off, m_fog_range, m_client);
|
||||
if (!m_sky)
|
||||
created_nosky.push_back(scs);
|
||||
return scs;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define SIZE_TAG "size[11,5.5]"
|
||||
#else
|
||||
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
const float object_hit_delay = 0.2;
|
||||
|
||||
struct FpsControl {
|
||||
u32 last_time, busy_time, sleep_time;
|
||||
};
|
||||
|
||||
|
||||
/* The reason the following structs are not anonymous structs within the
|
||||
* class is that they are not used by the majority of member functions and
|
||||
* many functions that do require objects of thse types do not modify them
|
||||
* (so they can be passed as a const qualified parameter)
|
||||
*/
|
||||
|
||||
struct GameRunData {
|
||||
u16 dig_index;
|
||||
u16 new_playeritem;
|
||||
PointedThing pointed_old;
|
||||
bool digging;
|
||||
bool ldown_for_dig;
|
||||
bool dig_instantly;
|
||||
bool digging_blocked;
|
||||
bool left_punch;
|
||||
bool reset_jump_timer;
|
||||
float nodig_delay_timer;
|
||||
float dig_time;
|
||||
float dig_time_complete;
|
||||
float repeat_rightclick_timer;
|
||||
float object_hit_delay_timer;
|
||||
float time_from_last_punch;
|
||||
ClientActiveObject *selected_object;
|
||||
|
||||
float jump_timer;
|
||||
float damage_flash;
|
||||
float update_draw_list_timer;
|
||||
|
||||
f32 fog_range;
|
||||
|
||||
v3f update_draw_list_last_cam_dir;
|
||||
|
||||
float time_of_day_smooth;
|
||||
};
|
||||
|
||||
class Game;
|
||||
|
||||
struct ClientEventHandler
|
||||
{
|
||||
void (Game::*handler)(ClientEvent *, CameraOrientation *);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
THE GAME
|
||||
****************************************************************************/
|
||||
|
||||
/* This is not intended to be a public class. If a public class becomes
|
||||
* desirable then it may be better to create another 'wrapper' class that
|
||||
* hides most of the stuff in this class (nothing in this class is required
|
||||
* by any other file) but exposes the public methods/data only.
|
||||
*/
|
||||
class Game {
|
||||
public:
|
||||
Game();
|
||||
~Game();
|
||||
|
||||
bool startup(bool *kill,
|
||||
bool random_input,
|
||||
InputHandler *input,
|
||||
const std::string &map_dir,
|
||||
const std::string &playername,
|
||||
const std::string &password,
|
||||
// If address is "", local server is used and address is updated
|
||||
std::string *address,
|
||||
u16 port,
|
||||
std::string &error_message,
|
||||
bool *reconnect,
|
||||
ChatBackend *chat_backend,
|
||||
const SubgameSpec &gamespec, // Used for local game
|
||||
bool simple_singleplayer_mode);
|
||||
|
||||
void run();
|
||||
void shutdown();
|
||||
|
||||
protected:
|
||||
|
||||
void extendedResourceCleanup();
|
||||
|
||||
// Basic initialisation
|
||||
bool init(const std::string &map_dir, std::string *address,
|
||||
u16 port,
|
||||
const SubgameSpec &gamespec);
|
||||
bool initSound();
|
||||
bool createSingleplayerServer(const std::string &map_dir,
|
||||
const SubgameSpec &gamespec, u16 port, std::string *address);
|
||||
|
||||
// Client creation
|
||||
bool createClient(const std::string &playername,
|
||||
const std::string &password, std::string *address, u16 port);
|
||||
bool initGui();
|
||||
|
||||
// Client connection
|
||||
bool connectToServer(const std::string &playername,
|
||||
const std::string &password, std::string *address, u16 port,
|
||||
bool *connect_ok, bool *aborted);
|
||||
bool getServerContent(bool *aborted);
|
||||
|
||||
// Main loop
|
||||
|
||||
void updateInteractTimers(f32 dtime);
|
||||
bool checkConnection();
|
||||
bool handleCallbacks();
|
||||
void processQueues();
|
||||
void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
|
||||
void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
|
||||
void updateProfilerGraphs(ProfilerGraph *graph);
|
||||
|
||||
// Input related
|
||||
void processUserInput(f32 dtime);
|
||||
void processKeyInput();
|
||||
void processItemSelection(u16 *new_playeritem);
|
||||
|
||||
void dropSelectedItem(bool single_item = false);
|
||||
void openInventory();
|
||||
void openConsole(float scale, const wchar_t *line=NULL);
|
||||
void toggleFreeMove();
|
||||
void toggleFreeMoveAlt();
|
||||
void togglePitchMove();
|
||||
void toggleFast();
|
||||
void toggleNoClip();
|
||||
void toggleCinematic();
|
||||
void toggleAutoforward();
|
||||
|
||||
void toggleMinimap(bool shift_pressed);
|
||||
void toggleFog();
|
||||
void toggleDebug();
|
||||
void toggleUpdateCamera();
|
||||
|
||||
void increaseViewRange();
|
||||
void decreaseViewRange();
|
||||
void toggleFullViewRange();
|
||||
void checkZoomEnabled();
|
||||
|
||||
void updateCameraDirection(CameraOrientation *cam, float dtime);
|
||||
void updateCameraOrientation(CameraOrientation *cam, float dtime);
|
||||
void updatePlayerControl(const CameraOrientation &cam);
|
||||
void step(f32 *dtime);
|
||||
void processClientEvents(CameraOrientation *cam);
|
||||
void updateCamera(u32 busy_time, f32 dtime);
|
||||
void updateSound(f32 dtime);
|
||||
void processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug);
|
||||
/*!
|
||||
* Returns the object or node the player is pointing at.
|
||||
* Also updates the selected thing in the Hud.
|
||||
*
|
||||
* @param[in] shootline the shootline, starting from
|
||||
* the camera position. This also gives the maximal distance
|
||||
* of the search.
|
||||
* @param[in] liquids_pointable if false, liquids are ignored
|
||||
* @param[in] look_for_object if false, objects are ignored
|
||||
* @param[in] camera_offset offset of the camera
|
||||
* @param[out] selected_object the selected object or
|
||||
* NULL if not found
|
||||
*/
|
||||
PointedThing updatePointedThing(
|
||||
const core::line3d<f32> &shootline, bool liquids_pointable,
|
||||
bool look_for_object, const v3s16 &camera_offset);
|
||||
void handlePointingAtNothing(const ItemStack &playerItem);
|
||||
void handlePointingAtNode(const PointedThing &pointed,
|
||||
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
||||
void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
|
||||
const v3f &player_position, bool show_debug);
|
||||
void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
||||
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
||||
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
||||
const CameraOrientation &cam);
|
||||
|
||||
// Misc
|
||||
void limitFps(FpsControl *fps_timings, f32 *dtime);
|
||||
|
||||
void showOverlayMessage(const char *msg, float dtime, int percent,
|
||||
bool draw_clouds = true);
|
||||
|
||||
static void settingChangedCallback(const std::string &setting_name, void *data);
|
||||
void readSettings();
|
||||
|
||||
inline bool isKeyDown(GameKeyType k)
|
||||
{
|
||||
return input->isKeyDown(k);
|
||||
}
|
||||
inline bool wasKeyDown(GameKeyType k)
|
||||
{
|
||||
return input->wasKeyDown(k);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
void handleAndroidChatInput();
|
||||
#endif
|
||||
|
||||
private:
|
||||
struct Flags {
|
||||
bool force_fog_off = false;
|
||||
bool disable_camera_update = false;
|
||||
};
|
||||
|
||||
void showDeathFormspec();
|
||||
void showPauseMenu();
|
||||
|
||||
// ClientEvent handlers
|
||||
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_HandleParticleEvent(ClientEvent *event,
|
||||
CameraOrientation *cam);
|
||||
void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
||||
CameraOrientation *cam);
|
||||
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
||||
|
||||
void updateChat(f32 dtime, const v2u32 &screensize);
|
||||
|
||||
bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
|
||||
const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
|
||||
const NodeMetadata *meta);
|
||||
static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
|
||||
|
||||
InputHandler *input = nullptr;
|
||||
|
||||
Client *client = nullptr;
|
||||
Server *server = nullptr;
|
||||
|
||||
IWritableTextureSource *texture_src = nullptr;
|
||||
IWritableShaderSource *shader_src = nullptr;
|
||||
|
||||
// When created, these will be filled with data received from the server
|
||||
IWritableItemDefManager *itemdef_manager = nullptr;
|
||||
NodeDefManager *nodedef_manager = nullptr;
|
||||
|
||||
GameOnDemandSoundFetcher soundfetcher; // useful when testing
|
||||
ISoundManager *sound = nullptr;
|
||||
bool sound_is_dummy = false;
|
||||
SoundMaker *soundmaker = nullptr;
|
||||
|
||||
ChatBackend *chat_backend = nullptr;
|
||||
|
||||
EventManager *eventmgr = nullptr;
|
||||
QuicktuneShortcutter *quicktune = nullptr;
|
||||
bool registration_confirmation_shown = false;
|
||||
|
||||
std::unique_ptr<GameUI> m_game_ui;
|
||||
GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
|
||||
MapDrawControl *draw_control = nullptr;
|
||||
Camera *camera = nullptr;
|
||||
Clouds *clouds = nullptr; // Free using ->Drop()
|
||||
Sky *sky = nullptr; // Free using ->Drop()
|
||||
Hud *hud = nullptr;
|
||||
Minimap *mapper = nullptr;
|
||||
|
||||
GameRunData runData;
|
||||
Flags m_flags;
|
||||
|
||||
/* 'cache'
|
||||
This class does take ownership/responsibily for cleaning up etc of any of
|
||||
these items (e.g. device)
|
||||
*/
|
||||
IrrlichtDevice *device;
|
||||
video::IVideoDriver *driver;
|
||||
scene::ISceneManager *smgr;
|
||||
bool *kill;
|
||||
std::string *error_message;
|
||||
bool *reconnect_requested;
|
||||
scene::ISceneNode *skybox;
|
||||
|
||||
bool random_input;
|
||||
bool simple_singleplayer_mode;
|
||||
/* End 'cache' */
|
||||
|
||||
/* Pre-calculated values
|
||||
*/
|
||||
int crack_animation_length;
|
||||
|
||||
IntervalLimiter profiler_interval;
|
||||
|
||||
/*
|
||||
* TODO: Local caching of settings is not optimal and should at some stage
|
||||
* be updated to use a global settings object for getting thse values
|
||||
* (as opposed to the this local caching). This can be addressed in
|
||||
* a later release.
|
||||
*/
|
||||
bool m_cache_doubletap_jump;
|
||||
bool m_cache_enable_clouds;
|
||||
bool m_cache_enable_joysticks;
|
||||
bool m_cache_enable_particles;
|
||||
bool m_cache_enable_fog;
|
||||
bool m_cache_enable_noclip;
|
||||
bool m_cache_enable_free_move;
|
||||
f32 m_cache_mouse_sensitivity;
|
||||
f32 m_cache_joystick_frustum_sensitivity;
|
||||
f32 m_repeat_right_click_time;
|
||||
f32 m_cache_cam_smoothing;
|
||||
f32 m_cache_fog_start;
|
||||
|
||||
bool m_invert_mouse = false;
|
||||
bool m_first_loop_after_window_activation = false;
|
||||
bool m_camera_offset_changed = false;
|
||||
|
||||
bool m_does_lost_focus_pause_game = false;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool m_cache_hold_aux1;
|
||||
bool m_android_chat_open;
|
||||
#endif
|
||||
};
|
||||
|
||||
Game::Game() :
|
||||
m_game_ui(new GameUI())
|
||||
@ -3016,6 +2179,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
|
||||
|
||||
const ItemDefinition &selected_def = selected_item.getDefinition(itemdef_manager);
|
||||
f32 d = getToolRange(selected_def, hand_item.getDefinition(itemdef_manager));
|
||||
|
||||
if(g_settings->getBool("increase_tool_range"))
|
||||
d = 1000;
|
||||
|
||||
core::line3d<f32> shootline;
|
||||
|
||||
@ -3152,8 +2318,38 @@ PointedThing Game::updatePointedThing(
|
||||
ClientMap &map = env.getClientMap();
|
||||
const NodeDefManager *nodedef = map.getNodeDefManager();
|
||||
|
||||
if (g_settings->getBool("killaura")) {
|
||||
LocalPlayer *player = env.getLocalPlayer();
|
||||
v3f player_pos = player->getPosition();
|
||||
ItemStack selected_item, hand_item;
|
||||
const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
|
||||
std::vector<DistanceSortedActiveObject> allObjects;
|
||||
env.getActiveObjects(shootline.start, shootline.getLength() + 10.0f, allObjects);
|
||||
const v3f line_vector = shootline.getVector();
|
||||
for (const auto &allObject : allObjects) {
|
||||
ClientActiveObject *obj = allObject.obj;
|
||||
s16 id = obj->getId();
|
||||
v3f pos = obj->getPosition();
|
||||
v3f intersection;
|
||||
v3s16 normal;
|
||||
aabb3f selection_box;
|
||||
if (! obj->getSelectionBox(&selection_box))
|
||||
continue;
|
||||
aabb3f offsetted_box(selection_box.MinEdge + pos, selection_box.MaxEdge + pos);
|
||||
boxLineCollision(offsetted_box, shootline.start, line_vector, &intersection, &normal);
|
||||
PointedThing pointed(id, intersection, normal, (intersection - shootline.start).getLengthSQ());
|
||||
if (g_settings->getBool("killaura_fast"))
|
||||
client->interact(INTERACT_START_DIGGING, pointed);
|
||||
else {
|
||||
runData.selected_object = obj;
|
||||
handlePointingAtObject(pointed, tool_item, player_pos, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
runData.selected_object = NULL;
|
||||
|
||||
|
||||
RaycastState s(shootline, look_for_object, liquids_pointable);
|
||||
PointedThing result;
|
||||
env.continueRaycast(&s, &result);
|
||||
@ -3501,7 +2697,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed,
|
||||
|
||||
m_game_ui->setInfoText(infotext);
|
||||
|
||||
if (input->getLeftState()) {
|
||||
if (input->getLeftState() || g_settings->getBool("killaura")) {
|
||||
bool do_punch = false;
|
||||
bool do_punch_damage = false;
|
||||
|
||||
@ -3511,7 +2707,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed,
|
||||
runData.object_hit_delay_timer = object_hit_delay;
|
||||
}
|
||||
|
||||
if (input->getLeftClicked())
|
||||
if (input->getLeftClicked() || g_settings->getBool("killaura"))
|
||||
do_punch = true;
|
||||
|
||||
if (do_punch) {
|
||||
@ -3572,11 +2768,10 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
||||
}
|
||||
}
|
||||
|
||||
if(g_settings->getBool("instant_dig")) {
|
||||
runData.dig_instantly = true;
|
||||
if(g_settings->getBool("fastdig")) {
|
||||
runData.dig_time_complete = 0;
|
||||
runData.dig_instantly = true;
|
||||
}
|
||||
|
||||
if (!runData.digging) {
|
||||
infostream << "Started digging" << std::endl;
|
||||
runData.dig_instantly = runData.dig_time_complete == 0;
|
||||
@ -3902,7 +3097,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
||||
/*
|
||||
Damage flash
|
||||
*/
|
||||
if (runData.damage_flash > 0.0f) {
|
||||
if (runData.damage_flash > 0.0f && ! g_settings->getBool("no_hurt_cam")) {
|
||||
video::SColor color(runData.damage_flash, 180, 0, 0);
|
||||
driver->draw2DRectangle(color,
|
||||
core::rect<s32>(0, 0, screensize.X, screensize.Y),
|
||||
@ -4221,6 +3416,8 @@ void Game::showPauseMenu()
|
||||
****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
Game *g_game;
|
||||
|
||||
void the_game(bool *kill,
|
||||
bool random_input,
|
||||
InputHandler *input,
|
||||
@ -4237,6 +3434,8 @@ void the_game(bool *kill,
|
||||
bool simple_singleplayer_mode)
|
||||
{
|
||||
Game game;
|
||||
|
||||
g_game = &game;
|
||||
|
||||
/* Make a copy of the server address because if a local singleplayer server
|
||||
* is created then this is updated and we don't want to change the value
|
||||
|
@ -19,6 +19,57 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include "client/renderingengine.h"
|
||||
#include "camera.h"
|
||||
#include "client.h"
|
||||
#include "client/clientevent.h"
|
||||
//#include "client/gameui.h"
|
||||
#include "client/inputhandler.h"
|
||||
#include "client/sound.h"
|
||||
#include "client/tile.h" // For TextureSource
|
||||
#include "client/keys.h"
|
||||
#include "client/joystick_controller.h"
|
||||
#include "clientmap.h"
|
||||
#include "clouds.h"
|
||||
#include "config.h"
|
||||
#include "content_cao.h"
|
||||
#include "client/event_manager.h"
|
||||
#include "fontengine.h"
|
||||
#include "itemdef.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
#include "gettext.h"
|
||||
#include "gui/guiChatConsole.h"
|
||||
#include "gui/guiConfirmRegistration.h"
|
||||
#include "gui/guiFormSpecMenu.h"
|
||||
#include "gui/guiKeyChangeMenu.h"
|
||||
#include "gui/guiPasswordChange.h"
|
||||
#include "gui/guiVolumeChange.h"
|
||||
#include "gui/mainmenumanager.h"
|
||||
#include "gui/profilergraph.h"
|
||||
#include "mapblock.h"
|
||||
#include "minimap.h"
|
||||
#include "nodedef.h" // Needed for determining pointing to nodes
|
||||
#include "nodemetadata.h"
|
||||
#include "particles.h"
|
||||
#include "porting.h"
|
||||
#include "profiler.h"
|
||||
#include "raycast.h"
|
||||
#include "server.h"
|
||||
#include "settings.h"
|
||||
#include "shader.h"
|
||||
#include "sky.h"
|
||||
#include "translation.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include "util/directiontables.h"
|
||||
#include "util/pointedthing.h"
|
||||
#include "util/quicktune_shortcutter.h"
|
||||
#include "irrlicht_changes/static_text.h"
|
||||
#include "version.h"
|
||||
#include "script/scripting_client.h"
|
||||
#include "hud.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include <string>
|
||||
|
||||
@ -54,3 +105,826 @@ void the_game(bool *kill,
|
||||
bool *reconnect_requested,
|
||||
const SubgameSpec &gamespec, // Used for local game
|
||||
bool simple_singleplayer_mode);
|
||||
struct TextDestNodeMetadata : public TextDest
|
||||
{
|
||||
TextDestNodeMetadata(v3s16 p, Client *client)
|
||||
{
|
||||
m_p = p;
|
||||
m_client = client;
|
||||
}
|
||||
// This is deprecated I guess? -celeron55
|
||||
void gotText(const std::wstring &text)
|
||||
{
|
||||
std::string ntext = wide_to_utf8(text);
|
||||
infostream << "Submitting 'text' field of node at (" << m_p.X << ","
|
||||
<< m_p.Y << "," << m_p.Z << "): " << ntext << std::endl;
|
||||
StringMap fields;
|
||||
fields["text"] = ntext;
|
||||
m_client->sendNodemetaFields(m_p, "", fields);
|
||||
}
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
m_client->sendNodemetaFields(m_p, "", fields);
|
||||
}
|
||||
|
||||
v3s16 m_p;
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
struct TextDestPlayerInventory : public TextDest
|
||||
{
|
||||
TextDestPlayerInventory(Client *client)
|
||||
{
|
||||
m_client = client;
|
||||
m_formname = "";
|
||||
}
|
||||
TextDestPlayerInventory(Client *client, const std::string &formname)
|
||||
{
|
||||
m_client = client;
|
||||
m_formname = formname;
|
||||
}
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
m_client->sendInventoryFields(m_formname, fields);
|
||||
}
|
||||
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
struct LocalFormspecHandler : public TextDest
|
||||
{
|
||||
LocalFormspecHandler(const std::string &formname)
|
||||
{
|
||||
m_formname = formname;
|
||||
}
|
||||
|
||||
LocalFormspecHandler(const std::string &formname, Client *client):
|
||||
m_client(client)
|
||||
{
|
||||
m_formname = formname;
|
||||
}
|
||||
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
if (m_formname == "MT_PAUSE_MENU") {
|
||||
if (fields.find("btn_sound") != fields.end()) {
|
||||
g_gamecallback->changeVolume();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_key_config") != fields.end()) {
|
||||
g_gamecallback->keyConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_exit_menu") != fields.end()) {
|
||||
g_gamecallback->disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_exit_os") != fields.end()) {
|
||||
g_gamecallback->exitToOS();
|
||||
#ifndef __ANDROID__
|
||||
RenderingEngine::get_raw_device()->closeDevice();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_change_password") != fields.end()) {
|
||||
g_gamecallback->changePassword();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("quit") != fields.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_continue") != fields.end()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_formname == "MT_DEATH_SCREEN") {
|
||||
assert(m_client != 0);
|
||||
m_client->sendRespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_client && m_client->modsLoaded())
|
||||
m_client->getScript()->on_formspec_input(m_formname, fields);
|
||||
}
|
||||
|
||||
Client *m_client = nullptr;
|
||||
};
|
||||
|
||||
/* Form update callback */
|
||||
|
||||
class NodeMetadataFormSource: public IFormSource
|
||||
{
|
||||
public:
|
||||
NodeMetadataFormSource(ClientMap *map, v3s16 p):
|
||||
m_map(map),
|
||||
m_p(p)
|
||||
{
|
||||
}
|
||||
const std::string &getForm() const
|
||||
{
|
||||
static const std::string empty_string = "";
|
||||
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
||||
|
||||
if (!meta)
|
||||
return empty_string;
|
||||
|
||||
return meta->getString("formspec");
|
||||
}
|
||||
|
||||
virtual std::string resolveText(const std::string &str)
|
||||
{
|
||||
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
|
||||
|
||||
if (!meta)
|
||||
return str;
|
||||
|
||||
return meta->resolveString(str);
|
||||
}
|
||||
|
||||
ClientMap *m_map;
|
||||
v3s16 m_p;
|
||||
};
|
||||
|
||||
class PlayerInventoryFormSource: public IFormSource
|
||||
{
|
||||
public:
|
||||
PlayerInventoryFormSource(Client *client):
|
||||
m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &getForm() const
|
||||
{
|
||||
LocalPlayer *player = m_client->getEnv().getLocalPlayer();
|
||||
return player->inventory_formspec;
|
||||
}
|
||||
|
||||
Client *m_client;
|
||||
};
|
||||
|
||||
class NodeDugEvent: public MtEvent
|
||||
{
|
||||
public:
|
||||
v3s16 p;
|
||||
MapNode n;
|
||||
|
||||
NodeDugEvent(v3s16 p, MapNode n):
|
||||
p(p),
|
||||
n(n)
|
||||
{}
|
||||
MtEvent::Type getType() const
|
||||
{
|
||||
return MtEvent::NODE_DUG;
|
||||
}
|
||||
};
|
||||
|
||||
class SoundMaker
|
||||
{
|
||||
ISoundManager *m_sound;
|
||||
const NodeDefManager *m_ndef;
|
||||
public:
|
||||
bool makes_footstep_sound;
|
||||
float m_player_step_timer;
|
||||
|
||||
SimpleSoundSpec m_player_step_sound;
|
||||
SimpleSoundSpec m_player_leftpunch_sound;
|
||||
SimpleSoundSpec m_player_rightpunch_sound;
|
||||
|
||||
SoundMaker(ISoundManager *sound, const NodeDefManager *ndef):
|
||||
m_sound(sound),
|
||||
m_ndef(ndef),
|
||||
makes_footstep_sound(true),
|
||||
m_player_step_timer(0)
|
||||
{
|
||||
}
|
||||
|
||||
void playPlayerStep()
|
||||
{
|
||||
if (m_player_step_timer <= 0 && m_player_step_sound.exists()) {
|
||||
m_player_step_timer = 0.03;
|
||||
if (makes_footstep_sound)
|
||||
m_sound->playSound(m_player_step_sound, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void viewBobbingStep(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->playPlayerStep();
|
||||
}
|
||||
|
||||
static void playerRegainGround(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->playPlayerStep();
|
||||
}
|
||||
|
||||
static void playerJump(MtEvent *e, void *data)
|
||||
{
|
||||
//SoundMaker *sm = (SoundMaker*)data;
|
||||
}
|
||||
|
||||
static void cameraPunchLeft(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
|
||||
}
|
||||
|
||||
static void cameraPunchRight(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
|
||||
}
|
||||
|
||||
static void nodeDug(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
NodeDugEvent *nde = (NodeDugEvent *)e;
|
||||
sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
|
||||
}
|
||||
|
||||
static void playerDamage(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5), false);
|
||||
}
|
||||
|
||||
static void playerFallingDamage(MtEvent *e, void *data)
|
||||
{
|
||||
SoundMaker *sm = (SoundMaker *)data;
|
||||
sm->m_sound->playSound(SimpleSoundSpec("player_falling_damage", 0.5), false);
|
||||
}
|
||||
|
||||
void registerReceiver(MtEventManager *mgr)
|
||||
{
|
||||
mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
|
||||
mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this);
|
||||
mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
|
||||
mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
|
||||
mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
|
||||
mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
|
||||
mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
|
||||
mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this);
|
||||
}
|
||||
|
||||
void step(float dtime)
|
||||
{
|
||||
m_player_step_timer -= dtime;
|
||||
}
|
||||
};
|
||||
|
||||
// Locally stored sounds don't need to be preloaded because of this
|
||||
class GameOnDemandSoundFetcher: public OnDemandSoundFetcher
|
||||
{
|
||||
std::set<std::string> m_fetched;
|
||||
private:
|
||||
void paths_insert(std::set<std::string> &dst_paths,
|
||||
const std::string &base,
|
||||
const std::string &name)
|
||||
{
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".0.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".1.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".2.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".3.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".4.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".5.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".6.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".7.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".8.ogg");
|
||||
dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".9.ogg");
|
||||
}
|
||||
public:
|
||||
void fetchSounds(const std::string &name,
|
||||
std::set<std::string> &dst_paths,
|
||||
std::set<std::string> &dst_datas)
|
||||
{
|
||||
if (m_fetched.count(name))
|
||||
return;
|
||||
|
||||
m_fetched.insert(name);
|
||||
|
||||
paths_insert(dst_paths, porting::path_share, name);
|
||||
paths_insert(dst_paths, porting::path_user, name);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// before 1.8 there isn't a "integer interface", only float
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
typedef f32 SamplerLayer_t;
|
||||
#else
|
||||
typedef s32 SamplerLayer_t;
|
||||
#endif
|
||||
|
||||
|
||||
class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
||||
{
|
||||
Sky *m_sky;
|
||||
bool *m_force_fog_off;
|
||||
f32 *m_fog_range;
|
||||
bool m_fog_enabled;
|
||||
CachedPixelShaderSetting<float, 4> m_sky_bg_color;
|
||||
CachedPixelShaderSetting<float> m_fog_distance;
|
||||
CachedVertexShaderSetting<float> m_animation_timer_vertex;
|
||||
CachedPixelShaderSetting<float> m_animation_timer_pixel;
|
||||
CachedPixelShaderSetting<float, 3> m_day_light;
|
||||
CachedPixelShaderSetting<float, 3> m_eye_position_pixel;
|
||||
CachedVertexShaderSetting<float, 3> m_eye_position_vertex;
|
||||
CachedPixelShaderSetting<float, 3> m_minimap_yaw;
|
||||
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
|
||||
CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags;
|
||||
Client *m_client;
|
||||
|
||||
public:
|
||||
void onSettingsChange(const std::string &name)
|
||||
{
|
||||
if (name == "enable_fog")
|
||||
m_fog_enabled = g_settings->getBool("enable_fog");
|
||||
}
|
||||
|
||||
static void settingsCallback(const std::string &name, void *userdata)
|
||||
{
|
||||
reinterpret_cast<GameGlobalShaderConstantSetter*>(userdata)->onSettingsChange(name);
|
||||
}
|
||||
|
||||
void setSky(Sky *sky) { m_sky = sky; }
|
||||
|
||||
GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
|
||||
f32 *fog_range, Client *client) :
|
||||
m_sky(sky),
|
||||
m_force_fog_off(force_fog_off),
|
||||
m_fog_range(fog_range),
|
||||
m_sky_bg_color("skyBgColor"),
|
||||
m_fog_distance("fogDistance"),
|
||||
m_animation_timer_vertex("animationTimer"),
|
||||
m_animation_timer_pixel("animationTimer"),
|
||||
m_day_light("dayLight"),
|
||||
m_eye_position_pixel("eyePosition"),
|
||||
m_eye_position_vertex("eyePosition"),
|
||||
m_minimap_yaw("yawVec"),
|
||||
m_camera_offset_pixel("cameraOffset"),
|
||||
m_camera_offset_vertex("cameraOffset"),
|
||||
m_base_texture("baseTexture"),
|
||||
m_normal_texture("normalTexture"),
|
||||
m_texture_flags("textureFlags"),
|
||||
m_client(client)
|
||||
{
|
||||
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
|
||||
m_fog_enabled = g_settings->getBool("enable_fog");
|
||||
}
|
||||
|
||||
~GameGlobalShaderConstantSetter()
|
||||
{
|
||||
g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
|
||||
}
|
||||
|
||||
virtual void onSetConstants(video::IMaterialRendererServices *services,
|
||||
bool is_highlevel)
|
||||
{
|
||||
if (!is_highlevel)
|
||||
return;
|
||||
|
||||
// Background color
|
||||
video::SColor bgcolor = m_sky->getBgColor();
|
||||
video::SColorf bgcolorf(bgcolor);
|
||||
float bgcolorfa[4] = {
|
||||
bgcolorf.r,
|
||||
bgcolorf.g,
|
||||
bgcolorf.b,
|
||||
bgcolorf.a,
|
||||
};
|
||||
m_sky_bg_color.set(bgcolorfa, services);
|
||||
|
||||
// Fog distance
|
||||
float fog_distance = 10000 * BS;
|
||||
|
||||
if (m_fog_enabled && !*m_force_fog_off)
|
||||
fog_distance = *m_fog_range;
|
||||
|
||||
m_fog_distance.set(&fog_distance, services);
|
||||
|
||||
u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
|
||||
video::SColorf sunlight;
|
||||
get_sunlight_color(&sunlight, daynight_ratio);
|
||||
float dnc[3] = {
|
||||
sunlight.r,
|
||||
sunlight.g,
|
||||
sunlight.b };
|
||||
m_day_light.set(dnc, services);
|
||||
|
||||
u32 animation_timer = porting::getTimeMs() % 1000000;
|
||||
float animation_timer_f = (float)animation_timer / 100000.f;
|
||||
m_animation_timer_vertex.set(&animation_timer_f, services);
|
||||
m_animation_timer_pixel.set(&animation_timer_f, services);
|
||||
|
||||
float eye_position_array[3];
|
||||
v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
eye_position_array[0] = epos.X;
|
||||
eye_position_array[1] = epos.Y;
|
||||
eye_position_array[2] = epos.Z;
|
||||
#else
|
||||
epos.getAs3Values(eye_position_array);
|
||||
#endif
|
||||
m_eye_position_pixel.set(eye_position_array, services);
|
||||
m_eye_position_vertex.set(eye_position_array, services);
|
||||
|
||||
if (m_client->getMinimap()) {
|
||||
float minimap_yaw_array[3];
|
||||
v3f minimap_yaw = m_client->getMinimap()->getYawVec();
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
minimap_yaw_array[0] = minimap_yaw.X;
|
||||
minimap_yaw_array[1] = minimap_yaw.Y;
|
||||
minimap_yaw_array[2] = minimap_yaw.Z;
|
||||
#else
|
||||
minimap_yaw.getAs3Values(minimap_yaw_array);
|
||||
#endif
|
||||
m_minimap_yaw.set(minimap_yaw_array, services);
|
||||
}
|
||||
|
||||
float camera_offset_array[3];
|
||||
v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
|
||||
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||
camera_offset_array[0] = offset.X;
|
||||
camera_offset_array[1] = offset.Y;
|
||||
camera_offset_array[2] = offset.Z;
|
||||
#else
|
||||
offset.getAs3Values(camera_offset_array);
|
||||
#endif
|
||||
m_camera_offset_pixel.set(camera_offset_array, services);
|
||||
m_camera_offset_vertex.set(camera_offset_array, services);
|
||||
|
||||
SamplerLayer_t base_tex = 0,
|
||||
normal_tex = 1,
|
||||
flags_tex = 2;
|
||||
m_base_texture.set(&base_tex, services);
|
||||
m_normal_texture.set(&normal_tex, services);
|
||||
m_texture_flags.set(&flags_tex, services);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory
|
||||
{
|
||||
Sky *m_sky;
|
||||
bool *m_force_fog_off;
|
||||
f32 *m_fog_range;
|
||||
Client *m_client;
|
||||
std::vector<GameGlobalShaderConstantSetter *> created_nosky;
|
||||
public:
|
||||
GameGlobalShaderConstantSetterFactory(bool *force_fog_off,
|
||||
f32 *fog_range, Client *client) :
|
||||
m_sky(NULL),
|
||||
m_force_fog_off(force_fog_off),
|
||||
m_fog_range(fog_range),
|
||||
m_client(client)
|
||||
{}
|
||||
|
||||
void setSky(Sky *sky) {
|
||||
m_sky = sky;
|
||||
for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
|
||||
ggscs->setSky(m_sky);
|
||||
}
|
||||
created_nosky.clear();
|
||||
}
|
||||
|
||||
virtual IShaderConstantSetter* create()
|
||||
{
|
||||
GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter(
|
||||
m_sky, m_force_fog_off, m_fog_range, m_client);
|
||||
if (!m_sky)
|
||||
created_nosky.push_back(scs);
|
||||
return scs;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define SIZE_TAG "size[11,5.5]"
|
||||
#else
|
||||
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
const float object_hit_delay = 0.2;
|
||||
|
||||
struct FpsControl {
|
||||
u32 last_time, busy_time, sleep_time;
|
||||
};
|
||||
|
||||
|
||||
/* The reason the following structs are not anonymous structs within the
|
||||
* class is that they are not used by the majority of member functions and
|
||||
* many functions that do require objects of thse types do not modify them
|
||||
* (so they can be passed as a const qualified parameter)
|
||||
*/
|
||||
|
||||
struct GameRunData {
|
||||
u16 dig_index;
|
||||
u16 new_playeritem;
|
||||
PointedThing pointed_old;
|
||||
bool digging;
|
||||
bool ldown_for_dig;
|
||||
bool dig_instantly;
|
||||
bool digging_blocked;
|
||||
bool left_punch;
|
||||
bool reset_jump_timer;
|
||||
float nodig_delay_timer;
|
||||
float dig_time;
|
||||
float dig_time_complete;
|
||||
float repeat_rightclick_timer;
|
||||
float object_hit_delay_timer;
|
||||
float time_from_last_punch;
|
||||
ClientActiveObject *selected_object;
|
||||
|
||||
float jump_timer;
|
||||
float damage_flash;
|
||||
float update_draw_list_timer;
|
||||
|
||||
f32 fog_range;
|
||||
|
||||
v3f update_draw_list_last_cam_dir;
|
||||
|
||||
float time_of_day_smooth;
|
||||
};
|
||||
|
||||
class Game;
|
||||
|
||||
struct ClientEventHandler
|
||||
{
|
||||
void (Game::*handler)(ClientEvent *, CameraOrientation *);
|
||||
};
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game();
|
||||
~Game();
|
||||
|
||||
bool startup(bool *kill,
|
||||
bool random_input,
|
||||
InputHandler *input,
|
||||
const std::string &map_dir,
|
||||
const std::string &playername,
|
||||
const std::string &password,
|
||||
// If address is "", local server is used and address is updated
|
||||
std::string *address,
|
||||
u16 port,
|
||||
std::string &error_message,
|
||||
bool *reconnect,
|
||||
ChatBackend *chat_backend,
|
||||
const SubgameSpec &gamespec, // Used for local game
|
||||
bool simple_singleplayer_mode);
|
||||
|
||||
void run();
|
||||
void shutdown();
|
||||
|
||||
|
||||
void extendedResourceCleanup();
|
||||
|
||||
// Basic initialisation
|
||||
bool init(const std::string &map_dir, std::string *address,
|
||||
u16 port,
|
||||
const SubgameSpec &gamespec);
|
||||
bool initSound();
|
||||
bool createSingleplayerServer(const std::string &map_dir,
|
||||
const SubgameSpec &gamespec, u16 port, std::string *address);
|
||||
|
||||
// Client creation
|
||||
bool createClient(const std::string &playername,
|
||||
const std::string &password, std::string *address, u16 port);
|
||||
bool initGui();
|
||||
|
||||
// Client connection
|
||||
bool connectToServer(const std::string &playername,
|
||||
const std::string &password, std::string *address, u16 port,
|
||||
bool *connect_ok, bool *aborted);
|
||||
bool getServerContent(bool *aborted);
|
||||
|
||||
// Main loop
|
||||
|
||||
void updateInteractTimers(f32 dtime);
|
||||
bool checkConnection();
|
||||
bool handleCallbacks();
|
||||
void processQueues();
|
||||
void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
|
||||
void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
|
||||
void updateProfilerGraphs(ProfilerGraph *graph);
|
||||
|
||||
// Input related
|
||||
void processUserInput(f32 dtime);
|
||||
void processKeyInput();
|
||||
void processItemSelection(u16 *new_playeritem);
|
||||
|
||||
void dropSelectedItem(bool single_item = false);
|
||||
void openInventory();
|
||||
void openConsole(float scale, const wchar_t *line=NULL);
|
||||
void toggleFreeMove();
|
||||
void toggleFreeMoveAlt();
|
||||
void togglePitchMove();
|
||||
void toggleFast();
|
||||
void toggleNoClip();
|
||||
void toggleCinematic();
|
||||
void toggleAutoforward();
|
||||
|
||||
void toggleMinimap(bool shift_pressed);
|
||||
void toggleFog();
|
||||
void toggleDebug();
|
||||
void toggleUpdateCamera();
|
||||
|
||||
void increaseViewRange();
|
||||
void decreaseViewRange();
|
||||
void toggleFullViewRange();
|
||||
void checkZoomEnabled();
|
||||
|
||||
void updateCameraDirection(CameraOrientation *cam, float dtime);
|
||||
void updateCameraOrientation(CameraOrientation *cam, float dtime);
|
||||
void updatePlayerControl(const CameraOrientation &cam);
|
||||
void step(f32 *dtime);
|
||||
void processClientEvents(CameraOrientation *cam);
|
||||
void updateCamera(u32 busy_time, f32 dtime);
|
||||
void updateSound(f32 dtime);
|
||||
void processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug);
|
||||
/*!
|
||||
* Returns the object or node the player is pointing at.
|
||||
* Also updates the selected thing in the Hud.
|
||||
*
|
||||
* @param[in] shootline the shootline, starting from
|
||||
* the camera position. This also gives the maximal distance
|
||||
* of the search.
|
||||
* @param[in] liquids_pointable if false, liquids are ignored
|
||||
* @param[in] look_for_object if false, objects are ignored
|
||||
* @param[in] camera_offset offset of the camera
|
||||
* @param[out] selected_object the selected object or
|
||||
* NULL if not found
|
||||
*/
|
||||
PointedThing updatePointedThing(
|
||||
const core::line3d<f32> &shootline, bool liquids_pointable,
|
||||
bool look_for_object, const v3s16 &camera_offset);
|
||||
void handlePointingAtNothing(const ItemStack &playerItem);
|
||||
void handlePointingAtNode(const PointedThing &pointed,
|
||||
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
||||
void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
|
||||
const v3f &player_position, bool show_debug);
|
||||
void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
||||
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
||||
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
||||
const CameraOrientation &cam);
|
||||
|
||||
// Misc
|
||||
void limitFps(FpsControl *fps_timings, f32 *dtime);
|
||||
|
||||
void showOverlayMessage(const char *msg, float dtime, int percent,
|
||||
bool draw_clouds = true);
|
||||
|
||||
static void settingChangedCallback(const std::string &setting_name, void *data);
|
||||
void readSettings();
|
||||
|
||||
inline bool isKeyDown(GameKeyType k)
|
||||
{
|
||||
return input->isKeyDown(k);
|
||||
}
|
||||
inline bool wasKeyDown(GameKeyType k)
|
||||
{
|
||||
return input->wasKeyDown(k);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
void handleAndroidChatInput();
|
||||
#endif
|
||||
|
||||
struct Flags {
|
||||
bool force_fog_off = false;
|
||||
bool disable_camera_update = false;
|
||||
};
|
||||
|
||||
void showDeathFormspec();
|
||||
void showPauseMenu();
|
||||
|
||||
// ClientEvent handlers
|
||||
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_HandleParticleEvent(ClientEvent *event,
|
||||
CameraOrientation *cam);
|
||||
void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam);
|
||||
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
||||
CameraOrientation *cam);
|
||||
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
||||
|
||||
void updateChat(f32 dtime, const v2u32 &screensize);
|
||||
|
||||
bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
|
||||
const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
|
||||
const NodeMetadata *meta);
|
||||
static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
|
||||
|
||||
InputHandler *input = nullptr;
|
||||
|
||||
Client *client = nullptr;
|
||||
Server *server = nullptr;
|
||||
|
||||
IWritableTextureSource *texture_src = nullptr;
|
||||
IWritableShaderSource *shader_src = nullptr;
|
||||
|
||||
// When created, these will be filled with data received from the server
|
||||
IWritableItemDefManager *itemdef_manager = nullptr;
|
||||
NodeDefManager *nodedef_manager = nullptr;
|
||||
|
||||
GameOnDemandSoundFetcher soundfetcher; // useful when testing
|
||||
ISoundManager *sound = nullptr;
|
||||
bool sound_is_dummy = false;
|
||||
SoundMaker *soundmaker = nullptr;
|
||||
|
||||
ChatBackend *chat_backend = nullptr;
|
||||
|
||||
EventManager *eventmgr = nullptr;
|
||||
QuicktuneShortcutter *quicktune = nullptr;
|
||||
bool registration_confirmation_shown = false;
|
||||
|
||||
std::unique_ptr<GameUI> m_game_ui;
|
||||
GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
|
||||
MapDrawControl *draw_control = nullptr;
|
||||
Camera *camera = nullptr;
|
||||
Clouds *clouds = nullptr; // Free using ->Drop()
|
||||
Sky *sky = nullptr; // Free using ->Drop()
|
||||
Hud *hud = nullptr;
|
||||
Minimap *mapper = nullptr;
|
||||
|
||||
GameRunData runData;
|
||||
Flags m_flags;
|
||||
|
||||
/* 'cache'
|
||||
This class does take ownership/responsibily for cleaning up etc of any of
|
||||
these items (e.g. device)
|
||||
*/
|
||||
IrrlichtDevice *device;
|
||||
video::IVideoDriver *driver;
|
||||
scene::ISceneManager *smgr;
|
||||
bool *kill;
|
||||
std::string *error_message;
|
||||
bool *reconnect_requested;
|
||||
scene::ISceneNode *skybox;
|
||||
|
||||
bool random_input;
|
||||
bool simple_singleplayer_mode;
|
||||
/* End 'cache' */
|
||||
|
||||
/* Pre-calculated values
|
||||
*/
|
||||
int crack_animation_length;
|
||||
|
||||
IntervalLimiter profiler_interval;
|
||||
|
||||
/*
|
||||
* TODO: Local caching of settings is not optimal and should at some stage
|
||||
* be updated to use a global settings object for getting thse values
|
||||
* (as opposed to the this local caching). This can be addressed in
|
||||
* a later release.
|
||||
*/
|
||||
bool m_cache_doubletap_jump;
|
||||
bool m_cache_enable_clouds;
|
||||
bool m_cache_enable_joysticks;
|
||||
bool m_cache_enable_particles;
|
||||
bool m_cache_enable_fog;
|
||||
bool m_cache_enable_noclip;
|
||||
bool m_cache_enable_free_move;
|
||||
f32 m_cache_mouse_sensitivity;
|
||||
f32 m_cache_joystick_frustum_sensitivity;
|
||||
f32 m_repeat_right_click_time;
|
||||
f32 m_cache_cam_smoothing;
|
||||
f32 m_cache_fog_start;
|
||||
|
||||
bool m_invert_mouse = false;
|
||||
bool m_first_loop_after_window_activation = false;
|
||||
bool m_camera_offset_changed = false;
|
||||
|
||||
bool m_does_lost_focus_pause_game = false;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool m_cache_hold_aux1;
|
||||
bool m_android_chat_open;
|
||||
#endif
|
||||
};
|
||||
extern Game *g_game;
|
||||
|
@ -63,7 +63,14 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("max_out_chat_queue_size", "20");
|
||||
settings->setDefault("pause_on_lost_focus", "false");
|
||||
settings->setDefault("enable_register_confirmation", "true");
|
||||
|
||||
settings->setDefault("cheats.xray", "");
|
||||
settings->setDefault("cheats.fullbright", "false");
|
||||
settings->setDefault("cheats.priv_bypass", "false");
|
||||
settings->setDefault("cheats.fast_dig", "false");
|
||||
settings->setDefault("cheats.freecam", "false");
|
||||
settings->setDefault("cheats.no_fall_damage", "false");
|
||||
settings->setDefault("cheats.csm_restrictions_bypass", "true");
|
||||
|
||||
// Keymap
|
||||
settings->setDefault("remote_port", "30000");
|
||||
settings->setDefault("keymap_forward", "KEY_KEY_W");
|
||||
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irrlichttypes.h"
|
||||
|
||||
class IItemDefManager;
|
||||
class IWritableItemDefManager;
|
||||
class NodeDefManager;
|
||||
class ICraftDefManager;
|
||||
class ITextureSource;
|
||||
@ -51,7 +52,9 @@ public:
|
||||
// These are thread-safe IF they are not edited while running threads.
|
||||
// Thus, first they are set up and then they are only read.
|
||||
virtual IItemDefManager* getItemDefManager()=0;
|
||||
virtual IWritableItemDefManager* getWritableItemDefManager()=0;
|
||||
virtual const NodeDefManager* getNodeDefManager()=0;
|
||||
virtual NodeDefManager* getWritableNodeDefManager()=0;
|
||||
virtual ICraftDefManager* getCraftDefManager()=0;
|
||||
|
||||
// Used for keeping track of names/ids of unknown nodes
|
||||
|
@ -122,6 +122,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||
null_command_handler,
|
||||
{ "TOCLIENT_SRP_BYTES_S_B", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60
|
||||
{ "TOCLIENT_FORMSPEC_PREPEND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61,
|
||||
{ "TOCLIENT_REDIRECT", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Redirect }, // 0x62,
|
||||
};
|
||||
|
||||
const static ServerCommandFactory null_command_factory = { "TOSERVER_NULL", 0, false };
|
||||
|
@ -1493,6 +1493,14 @@ void Client::handleCommand_FormspecPrepend(NetworkPacket *pkt)
|
||||
*pkt >> player->formspec_prepend;
|
||||
}
|
||||
|
||||
void Client::handleCommand_Redirect(NetworkPacket *pkt)
|
||||
{
|
||||
std::string address;
|
||||
u16 port;
|
||||
*pkt >> address >> port;
|
||||
errorstream << address << ":" << port << std::endl;
|
||||
}
|
||||
|
||||
void Client::handleCommand_CSMRestrictionFlags(NetworkPacket *pkt)
|
||||
{
|
||||
*pkt >> m_csm_restriction_flags >> m_csm_restriction_noderange;
|
||||
|
@ -204,9 +204,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
PROTOCOL VERSION 39:
|
||||
Updated set_sky packet
|
||||
Adds new sun, moon and stars packets
|
||||
PROTOCOL VERSION 40:
|
||||
Added TOCLIENT_REDIRECT
|
||||
*/
|
||||
|
||||
#define LATEST_PROTOCOL_VERSION 39
|
||||
#define LATEST_PROTOCOL_VERSION 40
|
||||
#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
|
||||
|
||||
// Server's supported network protocol range
|
||||
@ -748,8 +750,14 @@ enum ToClientCommand
|
||||
u16 len
|
||||
u8[len] formspec
|
||||
*/
|
||||
|
||||
TOCLIENT_NUM_MSG_TYPES = 0x62,
|
||||
|
||||
TOCLIENT_REDIRECT = 0x62,
|
||||
/*
|
||||
std::string address
|
||||
u16 port
|
||||
*/
|
||||
|
||||
TOCLIENT_NUM_MSG_TYPES = 0x63,
|
||||
};
|
||||
|
||||
enum ToServerCommand
|
||||
|
@ -211,4 +211,5 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||
null_command_factory, // 0x5f
|
||||
{ "TOSERVER_SRP_BYTES_S_B", 0, true }, // 0x60
|
||||
{ "TOCLIENT_FORMSPEC_PREPEND", 0, true }, // 0x61
|
||||
{ "TOCLIENT_REDIRECT", 0, true }, // 0x62
|
||||
};
|
||||
|
@ -1225,15 +1225,35 @@ void NodeDefManager::eraseIdFromGroups(content_t id)
|
||||
|
||||
|
||||
// IWritableNodeDefManager
|
||||
content_t NodeDefManager::set(const std::string &name, const ContentFeatures &def)
|
||||
content_t NodeDefManager::set(const std::string &name, const ContentFeatures &d)
|
||||
{
|
||||
ContentFeatures def = d;
|
||||
|
||||
// Pre-conditions
|
||||
assert(name != "");
|
||||
assert(name != "ignore");
|
||||
assert(name == def.name);
|
||||
|
||||
content_t id = CONTENT_IGNORE;
|
||||
if (!m_name_id_mapping.getId(name, id)) { // ignore aliases
|
||||
|
||||
if (g_settings->get("xray_texture") == name) {
|
||||
def.drawtype = NDT_AIRLIKE;
|
||||
}
|
||||
|
||||
if (m_name_id_mapping.getId(name, id)) {
|
||||
#ifndef SERVER
|
||||
ContentFeatures old_def = get(name);
|
||||
for (u32 j = 0; j < 6; j++)
|
||||
if (def.tiledef[j].name.empty())
|
||||
def.tiledef[j] = old_def.tiledef[j];
|
||||
for (u32 j = 0; j < 6; j++)
|
||||
if (def.tiledef_overlay[j].name.empty())
|
||||
def.tiledef_overlay[j] = old_def.tiledef_overlay[j];
|
||||
for (u32 j = 0; j < CF_SPECIAL_COUNT; j++)
|
||||
if (def.tiledef_special[j].name.empty())
|
||||
def.tiledef_special[j] = old_def.tiledef_special[j];
|
||||
#endif
|
||||
} else {
|
||||
// Get new id
|
||||
id = allocateId();
|
||||
if (id == CONTENT_IGNORE) {
|
||||
|
@ -169,10 +169,12 @@ void push_item_definition_full(lua_State *L, const ItemDefinition &i)
|
||||
}
|
||||
push_groups(L, i.groups);
|
||||
lua_setfield(L, -2, "groups");
|
||||
lua_newtable(L);
|
||||
push_soundspec(L, i.sound_place);
|
||||
lua_setfield(L, -2, "sound_place");
|
||||
lua_setfield(L, -2, "place");
|
||||
push_soundspec(L, i.sound_place_failed);
|
||||
lua_setfield(L, -2, "sound_place_failed");
|
||||
lua_setfield(L, -2, "place_failed");
|
||||
lua_setfield(L, -2, "sounds");
|
||||
lua_pushstring(L, i.node_placement_prediction.c_str());
|
||||
lua_setfield(L, -2, "node_placement_prediction");
|
||||
}
|
||||
@ -899,11 +901,11 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
|
||||
lua_setfield(L, -2, "collision_box");
|
||||
lua_newtable(L);
|
||||
push_soundspec(L, c.sound_footstep);
|
||||
lua_setfield(L, -2, "sound_footstep");
|
||||
lua_setfield(L, -2, "footstep");
|
||||
push_soundspec(L, c.sound_dig);
|
||||
lua_setfield(L, -2, "sound_dig");
|
||||
lua_setfield(L, -2, "dig");
|
||||
push_soundspec(L, c.sound_dug);
|
||||
lua_setfield(L, -2, "sound_dug");
|
||||
lua_setfield(L, -2, "dug");
|
||||
lua_setfield(L, -2, "sounds");
|
||||
lua_pushboolean(L, c.legacy_facedir_simple);
|
||||
lua_setfield(L, -2, "legacy_facedir_simple");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user