aboutsummaryrefslogtreecommitdiff
path: root/doc
Commit message (Collapse)AuthorAge
* Use the nodebox as selection box if it's not set manuallyDiego Martínez2013-04-05
|
* Allow modifying movement speed, jump height and gravity per-player via the ↵MirceaKitsune2013-04-05
| | | | Lua API.
* Update doc/lua-api.txtPilzAdam2013-04-03
|
* Add Ore generation flags, implement ore absolute heightkwolekr2013-03-31
|
* Add different place sound for nodesPilzAdam2013-03-29
|
* New damage system, add damageGroups to ToolCapabilities, bump protocol versionPilzAdam2013-03-29
|
* Fix parameter list of obj:set_attach() and obj:set_bone_position()PilzAdam2013-03-28
|
* Vary ore sheet y position by noisekwolekr2013-03-24
|
* Fix indentation of lua_api.txtPerttu Ahola2013-03-24
|
* Update lua_api.txtkwolekr2013-03-24
|
* Allow spawning particles from the server, from luaJeija2013-03-23
| | | | | | | | | Spawn single particles or make use of ParticleSpawner for many randomly spawned particles. Accessible in Lua using minetest.spawn_particle and minetest.add_particlespawner. Increase Protocol Version to 17. Conflicts: src/clientserver.h
* 6d facedirRealBadAngel2013-03-23
|
* Support game-specific minetest.confPerttu Ahola2013-03-21
|
* lua_api.txt: Document paths, games and common mod loadingPerttu Ahola2013-03-21
|
* lua methods set_look_pitch and set_look_yawRealBadAngel2013-03-17
|
* Allow minetest.after to take a variable number of argumentsJeija2013-03-17
|
* Added method to get all registered recipes for item(node)RealBadAngel2013-03-05
|
* Allow any character in formspec strings with escape charkwolekr2013-03-05
|
* Add python script to doc/protocol.txtsfan52013-02-28
|
* Change Minetest-c55 to MinetestPilzAdam2013-02-24
|
* Add seed parameter for default and L-system treesRealBadAngel2013-02-24
|
* Fix to on_rightclick not able to change wielded_itemRealBadAngel2013-02-13
|
* Treegen update. Some new symbols. Speed up code a bit.RealBadAngel2013-01-23
|
* add support for saving settings by lua command (server doesn't autosave on exit)sapier2013-01-21
|
* Fix buttons not working for Lua-triggered formspecssapier2013-01-07
|
* L-Systems treegen update.RealBadAngel2013-01-07
|
* Implement textarea in formspec, a multiline input fieldJeija2013-01-04
|
* Add on_rightclick(pos, node, clicker) callback for nodesPilzAdam2013-01-04
|
* Add InvRef:get_location()Perttu Ahola2013-01-02
|
* Add TOCLIENT_SHOW_FORMSPEC to display formspecs at client from luasapier2013-01-02
|
* L-System treegenRealBadAngel2012-12-30
|
* Add ability to change the itemstack in placenode callbacksPilzAdam2012-12-17
|
* Fix hypen used as minus sign (manpages), fix spelling error (server.cpp)Ilya Zhuravlev2012-12-17
|
* New elements in formspec, item_image and item_image_button.RealBadAngel2012-12-01
| | | | Fixed also game bug drawing dragged item behind fields, buttons etc.
* Add the group attached_nodePilzAdam2012-12-01
| | | | Nodes in this group will be dropped as items if the node under them or the node in the wallmounted direction is not walkable.
* Add shutdown hook interface to Lua APIMatthew I2012-11-30
| | | | | | | | | | Scripts can call minetest.register_on_shutdown() to register a shutdown hook. Document that minetest.register_on_shutdown() callbacks may not be run If the server crashes, it is unlikely that callbacks registered using minetest.register_on_shutdown() will be called.
* Bump version to 0.4.4 as this isn't compatible with 0.4.3Perttu Ahola2012-11-26
|
* RealBadAngel's patch which allows the lua api to read pressed player keys. ↵MirceaKitsune2012-11-25
| | | | | | | | | | This should make it possible to change the player's animation based on what he is doing Correct lua api version number Always update animations and attachments after the entity is added to scene client side. Fixes animations not being applied in client initialization for some reason. Attachments should be re-tested now just to be safe. Fix a segmentation fault caused by reaching materials that didn't exist in a loop for setting texture
* A bunch of fixesMirceaKitsune2012-11-25
| | | | | | | | | | | | No longer hide players who are dead. With models, a death animation should be used instead Some changes requested by celeron55 Rename a lot of things in the code, and use better lua api function names Minor code corrections Bump protocol version up, since the models / animations / attachments code creates new client<->server messages
* Update attachments at the ending of the addToScene function for parents. And ↵MirceaKitsune2012-11-25
| | | | | | | | | | | | | | | | | | | | with this... *drum roll* Client-side attachments are at last functional and stick visibly. Fix the last segmentation fault (apparently). So far attachments seem to be fully functional, although removing the parent causes children to go to origin 0,0,0 and possibly still cause such a fault (though this should already be addressed) Fix a bug in falling code where entities get stuck Also check if the parent has been removed server-side, and detach the child if so. Fixes children going to origin 0,0,0 when their parent is removed. Unset all attachment properties when permanently detaching (on both the client and server). Also store less data we don't need Create a separate function for detaching, and also update lua api documentation When a child is detached, update its position from the server to clients. This WILL cause it to get positioned slightly differently client side, as the server attachment system only copies parent origin and knows not about mesh / bone transformation. This prevents different clients seeing the object detached in different spots which is most correct Update the position of attached players to clients. An attached player will see himself move, but this is currently VERY ugly and laggy as it is done by the server (it probably must stay this way too) Use a different approach for locally attached players. This allows for smooth positio transitions to work, as well at the player turning around freely. Still buggy however
* Framework for the attachment system, new object property which allows ↵MirceaKitsune2012-11-25
| | | | | | | | | | | | | | changing the color and alpha of mesh materials New object property which allows changing the color and alpha of mesh materials. Due to the current lighting systems it doesn't work yet, but the full implementation is there Framework for the attachment system, with no actual functionality yet Send bone and player object to the setAttachment function in content_sao.cpp, but we need a way to translate it there and send it to the client I will also want position and rotation offsets to be possible to apply to attachments Network object ID from server to client. This will be used to identify the parent client-side and know what to attach to
* Get the new animation framework properly workingMirceaKitsune2012-11-25
| | | | | | Store start and end frames as v2f Also move bone animations to their own function instead of object properties
* Joint positioning and rotation code, and fix a problem related to their lua APIMirceaKitsune2012-11-25
| | | | Attempt to move the animation system to a more correct implementation, rather than using object properties. Incomplete and breaks functionality
* Allow the LUA API to set animations to meshes as well as the animation ↵MirceaKitsune2012-11-25
| | | | | | | | | | | | speed. Also update animations only when needed. Support for animation blending, though for some reason it doesn't work. Don't enable animation transitions by default for many reaosons Object property to store individual bone positions. LUA can specify a bone name followed by a bone position. No functionality yet. Bone rotation to be added in the following commit Same system for bone rotation, plus a few other things I missed
* Get the mesh working through the memory cache properly. Most credit goes to ↵MirceaKitsune2012-11-25
| | | | | | | | | | celeron55 for the help on this code Get the texture from memory as well Add .x to the list of supported formats Update LUA API documentation
* Adding background to FormspecRealBadAngel2012-11-08
|
* Merge pull request #243 from xyzz/liquid_renewablePilzAdam2012-11-03
|\ | | | | Add liquid_renewable property, allow non-renewable liquids.
| * Add liquid_renewable property.Ilya Zhuravlev2012-09-07
| |
* | Add falling_node to special groups in lua-api.txtPilzAdam2012-11-01
| |
* | Add nodedef.on_blast() to lua_api.txt in order to support chained explosions ↵Perttu Ahola2012-09-09
| | | | | | | | of any explosives
span class="hl opt">[str] then return false end return true end -------------------------------------------------------------------------------- -- Dumps values in a line-per-value format. -- For example, {test = {"Testing..."}} becomes: -- _["test"] = {} -- _["test"][1] = "Testing..." -- This handles tables as keys and circular references properly. -- It also handles multiple references well, writing the table only once. -- The dumped argument is internal-only. function dump2(o, name, dumped) name = name or "_" -- "dumped" is used to keep track of serialized tables to handle -- multiple references and circular tables properly. -- It only contains tables as keys. The value is the name that -- the table has in the dump, eg: -- {x = {"y"}} -> dumped[{"y"}] = '_["x"]' dumped = dumped or {} if type(o) ~= "table" then return string.format("%s = %s\n", name, basic_dump(o)) end if dumped[o] then return string.format("%s = %s\n", name, dumped[o]) end dumped[o] = name -- This contains a list of strings to be concatenated later (because -- Lua is slow at individual concatenation). local t = {} for k, v in pairs(o) do local keyStr if type(k) == "table" then if dumped[k] then keyStr = dumped[k] else -- Key tables don't have a name, so use one of -- the form _G["table: 0xFFFFFFF"] keyStr = string.format("_G[%q]", tostring(k)) -- Dump key table t[#t + 1] = dump2(k, keyStr, dumped) end else keyStr = basic_dump(k) end local vname = string.format("%s[%s]", name, keyStr) t[#t + 1] = dump2(v, vname, dumped) end return string.format("%s = {}\n%s", name, table.concat(t)) end -------------------------------------------------------------------------------- -- This dumps values in a one-statement format. -- For example, {test = {"Testing..."}} becomes: -- [[{ -- test = { -- "Testing..." -- } -- }]] -- This supports tables as keys, but not circular references. -- It performs poorly with multiple references as it writes out the full -- table each time. -- The indent field specifies a indentation string, it defaults to a tab. -- Use the empty string to disable indentation. -- The dumped and level arguments are internal-only. function dump(o, indent, nested, level) if type(o) ~= "table" then return basic_dump(o) end -- Contains table -> true/nil of currently nested tables nested = nested or {} if nested[o] then return "<circular reference>" end nested[o] = true indent = indent or "\t" level = level or 1 local t = {} local dumped_indexes = {} for i, v in ipairs(o) do t[#t + 1] = dump(v, indent, nested, level + 1) dumped_indexes[i] = true end for k, v in pairs(o) do if not dumped_indexes[k] then if type(k) ~= "string" or not is_valid_identifier(k) then k = "["..dump(k, indent, nested, level + 1).."]" end v = dump(v, indent, nested, level + 1) t[#t + 1] = k.." = "..v end end nested[o] = nil if indent ~= "" then local indent_str = "\n"..string.rep(indent, level) local end_indent_str = "\n"..string.rep(indent, level - 1) return string.format("{%s%s%s}", indent_str, table.concat(t, ","..indent_str), end_indent_str) end return "{"..table.concat(t, ", ").."}" end -------------------------------------------------------------------------------- function string.split(str, delim, include_empty, max_splits, sep_is_pattern) delim = delim or "," max_splits = max_splits or -1 local items = {} local pos, len, seplen = 1, #str, #delim local plain = not sep_is_pattern max_splits = max_splits + 1 repeat local np, npe = string_find(str, delim, pos, plain) np, npe = (np or (len+1)), (npe or (len+1)) if (not np) or (max_splits == 1) then np = len + 1 npe = np end local s = string_sub(str, pos, np - 1) if include_empty or (s ~= "") then max_splits = max_splits - 1 items[#items + 1] = s end pos = npe + 1 until (max_splits == 0) or (pos > (len + 1)) return items end -------------------------------------------------------------------------------- function table.indexof(list, val) for i, v in ipairs(list) do if v == val then return i end end return -1 end assert(table.indexof({"foo", "bar"}, "foo") == 1) assert(table.indexof({"foo", "bar"}, "baz") == -1) -------------------------------------------------------------------------------- if INIT ~= "client" then function file_exists(filename) local f = io.open(filename, "r") if f == nil then return false else f:close() return true end end end -------------------------------------------------------------------------------- function string:trim() return (self:gsub("^%s*(.-)%s*$", "%1")) end assert(string.trim("\n \t\tfoo bar\t ") == "foo bar") -------------------------------------------------------------------------------- function math.hypot(x, y) local t x = math.abs(x) y = math.abs(y) t = math.min(x, y) x = math.max(x, y) if x == 0 then return 0 end t = t / x return x * math.sqrt(1 + t * t) end -------------------------------------------------------------------------------- function math.sign(x, tolerance) tolerance = tolerance or 0 if x > tolerance then return 1 elseif x < -tolerance then return -1 end return 0 end -------------------------------------------------------------------------------- function get_last_folder(text,count) local parts = text:split(DIR_DELIM) if count == nil then return parts[#parts] end local retval = "" for i=1,count,1 do retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM end return retval end -------------------------------------------------------------------------------- function cleanup_path(temppath) local parts = temppath:split("-") temppath = "" for i=1,#parts,1 do if temppath ~= "" then temppath = temppath .. "_" end temppath = temppath .. parts[i] end parts = temppath:split(".") temppath = "" for i=1,#parts,1 do if temppath ~= "" then temppath = temppath .. "_" end temppath = temppath .. parts[i] end parts = temppath:split("'") temppath = "" for i=1,#parts,1 do if temppath ~= "" then temppath = temppath .. "" end temppath = temppath .. parts[i] end parts = temppath:split(" ") temppath = "" for i=1,#parts,1 do if temppath ~= "" then temppath = temppath end temppath = temppath .. parts[i] end return temppath end function core.formspec_escape(text) if text ~= nil then text = string.gsub(text,"\\","\\\\") text = string.gsub(text,"%]","\\]") text = string.gsub(text,"%[","\\[") text = string.gsub(text,";","\\;") text = string.gsub(text,",","\\,") end return text end function core.wrap_text(text, charlimit) local retval = {} local current_idx = 1 local start,stop = string_find(text, " ", current_idx) local nl_start,nl_stop = string_find(text, "\n", current_idx) local gotnewline = false if nl_start ~= nil and (start == nil or nl_start < start) then start = nl_start stop = nl_stop gotnewline = true end local last_line = "" while start ~= nil do if string.len(last_line) + (stop-start) > charlimit then retval[#retval + 1] = last_line last_line = "" end if last_line ~= "" then last_line = last_line .. " " end last_line = last_line .. string_sub(text, current_idx, stop - 1) if gotnewline then retval[#retval + 1] = last_line last_line = "" gotnewline = false end current_idx = stop+1 start,stop = string_find(text, " ", current_idx) nl_start,nl_stop = string_find(text, "\n", current_idx) if nl_start ~= nil and (start == nil or nl_start < start) then start = nl_start stop = nl_stop gotnewline = true end end --add last part of text if string.len(last_line) + (string.len(text) - current_idx) > charlimit then retval[#retval + 1] = last_line retval[#retval + 1] = string_sub(text, current_idx) else last_line = last_line .. " " .. string_sub(text, current_idx) retval[#retval + 1] = last_line end return retval end -------------------------------------------------------------------------------- if INIT == "game" then local dirs1 = {9, 18, 7, 12} local dirs2 = {20, 23, 22, 21} function core.rotate_and_place(itemstack, placer, pointed_thing, infinitestacks, orient_flags) orient_flags = orient_flags or {} local unode = core.get_node_or_nil(pointed_thing.under) if not unode then return end local undef = core.registered_nodes[unode.name] if undef and undef.on_rightclick then undef.on_rightclick(pointed_thing.under, unode, placer, itemstack, pointed_thing) return end local fdir = core.dir_to_facedir(placer:get_look_dir()) local wield_name = itemstack:get_name() local above = pointed_thing.above local under = pointed_thing.under local iswall = (above.y == under.y) local isceiling = not iswall and (above.y < under.y) local anode = core.get_node_or_nil(above) if not anode then return end local pos = pointed_thing.above local node = anode if undef and undef.buildable_to then pos = pointed_thing.under node = unode iswall = false end if core.is_protected(pos, placer:get_player_name()) then core.record_protection_violation(pos, placer:get_player_name()) return end local ndef = core.registered_nodes[node.name] if not ndef or not ndef.buildable_to then return end if orient_flags.force_floor then iswall = false isceiling = false elseif orient_flags.force_ceiling then iswall = false isceiling = true elseif orient_flags.force_wall then iswall = true isceiling = false elseif orient_flags.invert_wall then iswall = not iswall end if iswall then core.set_node(pos, {name = wield_name, param2 = dirs1[fdir + 1]}) elseif isceiling then if orient_flags.force_facedir then core.set_node(pos, {name = wield_name, param2 = 20}) else core.set_node(pos, {name = wield_name, param2 = dirs2[fdir + 1]}) end else -- place right side up if orient_flags.force_facedir then core.set_node(pos, {name = wield_name, param2 = 0}) else core.set_node(pos, {name = wield_name, param2 = fdir}) end end if not infinitestacks then itemstack:take_item() return itemstack end end -------------------------------------------------------------------------------- --Wrapper for rotate_and_place() to check for sneak and assume Creative mode --implies infinite stacks when performing a 6d rotation. -------------------------------------------------------------------------------- core.rotate_node = function(itemstack, placer, pointed_thing) core.rotate_and_place(itemstack, placer, pointed_thing, core.settings:get_bool("creative_mode"), {invert_wall = placer:get_player_control().sneak}) return itemstack end end -------------------------------------------------------------------------------- function core.explode_table_event(evt) if evt ~= nil then local parts = evt:split(":") if #parts == 3 then local t = parts[1]:trim() local r = tonumber(parts[2]:trim()) local c = tonumber(parts[3]:trim()) if type(r) == "number" and type(c) == "number" and t ~= "INV" then return {type=t, row=r, column=c} end end end return {type="INV", row=0, column=0} end -------------------------------------------------------------------------------- function core.explode_textlist_event(evt) if evt ~= nil then local parts = evt:split(":") if #parts == 2 then local t = parts[1]:trim() local r = tonumber(parts[2]:trim()) if type(r) == "number" and t ~= "INV" then return {type=t, index=r} end end end return {type="INV", index=0} end -------------------------------------------------------------------------------- function core.explode_scrollbar_event(evt) local retval = core.explode_textlist_event(evt) retval.value = retval.index retval.index = nil return retval end -------------------------------------------------------------------------------- function core.pos_to_string(pos, decimal_places) local x = pos.x local y = pos.y local z = pos.z if decimal_places ~= nil then x = string.format("%." .. decimal_places .. "f", x) y = string.format("%." .. decimal_places .. "f", y) z = string.format("%." .. decimal_places .. "f", z) end return "(" .. x .. "," .. y .. "," .. z .. ")" end -------------------------------------------------------------------------------- function core.string_to_pos(value) if value == nil then return nil end local p = {} p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$") if p.x and p.y and p.z then p.x = tonumber(p.x) p.y = tonumber(p.y) p.z = tonumber(p.z) return p end local p = {} p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$") if p.x and p.y and p.z then p.x = tonumber(p.x) p.y = tonumber(p.y) p.z = tonumber(p.z) return p end return nil end assert(core.string_to_pos("10.0, 5, -2").x == 10) assert(core.string_to_pos("( 10.0, 5, -2)").z == -2) assert(core.string_to_pos("asd, 5, -2)") == nil) -------------------------------------------------------------------------------- function core.string_to_area(value) local p1, p2 = unpack(value:split(") (")) if p1 == nil or p2 == nil then return nil end p1 = core.string_to_pos(p1 .. ")") p2 = core.string_to_pos("(" .. p2) if p1 == nil or p2 == nil then return nil end return p1, p2 end local function test_string_to_area() local p1, p2 = core.string_to_area("(10.0, 5, -2) ( 30.2, 4, -12.53)") assert(p1.x == 10.0 and p1.y == 5 and p1.z == -2) assert(p2.x == 30.2 and p2.y == 4 and p2.z == -12.53) p1, p2 = core.string_to_area("(10.0, 5, -2 30.2, 4, -12.53") assert(p1 == nil and p2 == nil) p1, p2 = core.string_to_area("(10.0, 5,) -2 fgdf2, 4, -12.53") assert(p1 == nil and p2 == nil) end test_string_to_area() -------------------------------------------------------------------------------- function table.copy(t, seen) local n = {} seen = seen or {} seen[t] = n for k, v in pairs(t) do n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] = (type(v) == "table" and (seen[v] or table.copy(v, seen))) or v end return n end -------------------------------------------------------------------------------- -- mainmenu only functions -------------------------------------------------------------------------------- if INIT == "mainmenu" then function core.get_game(index) local games = game.get_games() if index > 0 and index <= #games then return games[index] end return nil end end if INIT == "client" or INIT == "mainmenu" then function fgettext_ne(text, ...) text = core.gettext(text) local arg = {n=select('#', ...), ...} if arg.n >= 1 then -- Insert positional parameters ($1, $2, ...) local result = '' local pos = 1 while pos <= text:len() do local newpos = text:find('[$]', pos) if newpos == nil then result = result .. text:sub(pos) pos = text:len() + 1 else local paramindex = tonumber(text:sub(newpos+1, newpos+1)) result = result .. text:sub(pos, newpos-1) .. tostring(arg[paramindex]) pos = newpos + 2 end end text = result end return text end function fgettext(text, ...) return core.formspec_escape(fgettext_ne(text, ...)) end end local ESCAPE_CHAR = string.char(0x1b) function core.get_color_escape_sequence(color) return ESCAPE_CHAR .. "(c@" .. color .. ")" end function core.get_background_escape_sequence(color) return ESCAPE_CHAR .. "(b@" .. color .. ")" end function core.colorize(color, message) local lines = tostring(message):split("\n", true) local color_code = core.get_color_escape_sequence(color) for i, line in ipairs(lines) do lines[i] = color_code .. line end return table.concat(lines, "\n") .. core.get_color_escape_sequence("#ffffff") end function core.strip_foreground_colors(str) return (str:gsub(ESCAPE_CHAR .. "%(c@[^)]+%)", "")) end function core.strip_background_colors(str) return (str:gsub(ESCAPE_CHAR .. "%(b@[^)]+%)", "")) end function core.strip_colors(str) return (str:gsub(ESCAPE_CHAR .. "%([bc]@[^)]+%)", "")) end -------------------------------------------------------------------------------- -- Returns the exact coordinate of a pointed surface -------------------------------------------------------------------------------- function core.pointed_thing_to_face_pos(placer, pointed_thing) local eye_offset_first = placer:get_eye_offset() local node_pos = pointed_thing.under local camera_pos = placer:get_pos() local pos_off = vector.multiply( vector.subtract(pointed_thing.above, node_pos), 0.5) local look_dir = placer:get_look_dir() local offset, nc local oc = {} for c, v in pairs(pos_off) do if nc or v == 0 then oc[#oc + 1] = c else offset = v nc = c end end local fine_pos = {[nc] = node_pos[nc] + offset} camera_pos.y = camera_pos.y + 1.625 + eye_offset_first.y / 10 local f = (node_pos[nc] + offset - camera_pos[nc]) / look_dir[nc] for i = 1, #oc do fine_pos[oc[i]] = camera_pos[oc[i]] + look_dir[oc[i]] * f end return fine_pos end