Compare commits

...

209 Commits

Author SHA1 Message Date
Perttu Ahola
a8eb68142e Call this 0.4.dev-20120606 2012-06-07 00:40:04 +03:00
Perttu Ahola
81554fbf72 Add minetest.serialize() and minetest.deserialize() 2012-06-07 00:05:00 +03:00
Perttu Ahola
a435cfcd82 Allow groups in crafting recipes 2012-06-06 23:39:17 +03:00
Perttu Ahola
7631918a12 Remove obsolete "footprints" default setting from defaultsettings.cpp 2012-06-06 20:04:05 +03:00
Kahrl
e070f1e525 Allow replacements in cooking and fuel recipes 2012-06-06 00:22:34 +03:00
Perttu Ahola
430d6e1cca Fix small errors in lua_api.txt 2012-06-06 00:15:33 +03:00
Perttu Ahola
3a0562bebc Add after_destruct and cache the existence of on_construct, on_destruct and after_destruct for quick skipping when a node does not have them 2012-06-05 23:51:37 +03:00
Perttu Ahola
c3658e7c79 place_node, dig_node and punch_node; an in-game tester tool; remove old code 2012-06-05 23:10:07 +03:00
Perttu Ahola
b0f81c3253 Fix NDT_RAILLIKE tweakings 2012-06-05 21:51:01 +03:00
darkrose
31c171fc1e Shadily clean up NDT_RAILLIKE to surely differ from the few leftover non-LGPLv2 parts from the standpoint of copyright law. 2012-06-05 19:47:19 +03:00
Perttu Ahola
e9c123b1b9 Clean and optimize clouds.cpp enough to not really contain any of the small amount of non-LGPLv2/later code left 2012-06-05 18:54:42 +03:00
Perttu Ahola
037b259197 Switch the license to be LGPLv2/later, with small parts still remaining as GPLv2/later, by agreement of major contributors 2012-06-05 18:54:07 +03:00
Perttu Ahola
a569961e0f Update translation template po/minetest.pot 2012-06-04 23:29:14 +03:00
Perttu Ahola
7eabde6aee Use gettext for more basic user interface strings 2012-06-04 23:24:31 +03:00
Perttu Ahola
ed772da0cc Remove misdesigned exception from ReliablePacketBuffer 2012-06-04 22:43:33 +03:00
Perttu Ahola
f48882213e Add ignore_world_load_errors configuration option and provide better error messages 2012-06-04 22:34:40 +03:00
Perttu Ahola
1cd2076d42 Improve GUIMessageMenu (move and resize elements based on size of text) 2012-06-04 22:33:47 +03:00
Perttu Ahola
816b9c8d71 Fix loading of old signs 2012-06-04 18:19:23 +03:00
Perttu Ahola
3bea1a944e Call this 0.4.dev-20120603 2012-06-04 00:37:51 +03:00
darkrose
3e419ffb38 Add InvRef:is_empty(listname) and make chests/furnaces not diggable if not empty in minimal game 2012-06-03 22:31:02 +03:00
darkrose
a149c6ecde Add can_dig callback 2012-06-03 22:31:02 +03:00
darkrose
3f18e9a2da fix locked chest to not destroy denied items (minimal game) 2012-06-03 22:31:02 +03:00
Perttu Ahola
4b0494062e Add fire visualization to minimal furnace menu 2012-06-03 22:31:02 +03:00
Perttu Ahola
a09d86dd3c Update inventory menu from formspec on-the-fly 2012-06-03 22:31:02 +03:00
Perttu Ahola
3ccb0f691b Add texture modification [lowpart:percent:filename 2012-06-03 22:31:02 +03:00
Perttu Ahola
1709fd854a Implement image[<X>,<Y>;<W>,<H>;<texture name>] and allow floating-point values in formspec 2012-06-03 22:31:02 +03:00
Perttu Ahola
7bf446f671 Reshape inventory menu code 2012-06-03 22:31:02 +03:00
Perttu Ahola
e4bc76f55c Add a bit of unit test for inventory 2012-06-03 22:31:02 +03:00
Perttu Ahola
81c5e5200b Fix loading of legacy chests 2012-06-03 22:31:01 +03:00
Perttu Ahola
9c3830dd35 Use proper furnace cook time 2012-06-03 22:31:01 +03:00
Perttu Ahola
bf8cfce50e Add ObjRef:is_player() and modify ObjRef:get_player_name() to always return a string to aid better inter-object compatibility of code that assumes objects to be players 2012-06-03 22:31:01 +03:00
Perttu Ahola
b235e4d290 Make GUIinventoryMenu::drawList more robust with invalid data 2012-06-03 22:31:01 +03:00
darkrose
b8cf6dee3e Lua implementation of furnace with visible active state 2012-06-03 22:31:01 +03:00
Perttu Ahola
35df1ee253 Implement locked chest; add after_place_node and after_dig_node node callbacks 2012-06-03 22:31:01 +03:00
Perttu Ahola
353f9fd43c minetest.get_craft_result 2012-06-03 22:31:01 +03:00
Perttu Ahola
3899f83da8 NodeMetaRef:{to,from}_table and lua_api.txt additions 2012-06-03 22:31:01 +03:00
Perttu Ahola
5f3c70061d Properly handle dropping of items from nodes, and disallow moving items directly between nodes 2012-06-03 22:31:01 +03:00
Perttu Ahola
aba7134301 on_metadata_inventory_{move,offer,take} 2012-06-03 22:31:01 +03:00
Perttu Ahola
d7447cdf9e Implement sign using form field protocol 2012-06-03 22:31:01 +03:00
Perttu Ahola
ff8d2bbc36 Convert legacy chest inventory list "0" to "main" 2012-06-03 22:31:00 +03:00
Perttu Ahola
70c98c9972 Properly create metadata inventories in minimal 2012-06-03 22:31:00 +03:00
Perttu Ahola
45f32838b9 Improve GUIInventoryMenu error messages more 2012-06-03 22:31:00 +03:00
Perttu Ahola
7d6e80a423 Add proper error messages to GUIInventoryMenu when inventory lists are invalid 2012-06-03 22:31:00 +03:00
Perttu Ahola
f3ec1452cd Random node metadata things 2012-06-03 22:31:00 +03:00
Perttu Ahola
29f03756bd Attempt to begin to implement chests and furnace in Lua (with problems) 2012-06-03 22:31:00 +03:00
Perttu Ahola
fe8c5546f0 Add node on_construct, on_destruct callbacks and update lua_api.txt 2012-06-03 22:31:00 +03:00
darkrose
c4315a7afa Strip unneeded variables from NodeMetadata 2012-06-03 22:31:00 +03:00
Kahrl
704782c95b WIP node metadata, node timers 2012-06-03 22:31:00 +03:00
Perttu Ahola
67059e1932 Catch VersionMismatchException while loading world data 2012-06-03 20:42:49 +03:00
Perttu Ahola
e2ea711136 Check password hash validity 2012-06-03 20:32:44 +03:00
Perttu Ahola
74aa598769 Fix MSVC build (pow type overload stuff) 2012-05-31 20:22:37 +03:00
Perttu Ahola
747ff7daf8 Add support for putting modpacks directly into mod directories 2012-05-21 19:49:35 +03:00
Perttu Ahola
1f670fc688 Add better trace peudo-loglevel support 2012-05-20 18:30:30 +03:00
Perttu Ahola
388906ac70 Allow using --worldname for local game too 2012-05-20 17:41:40 +03:00
Perttu Ahola
49d9745dc4 Comment out unnecessary debug output in Settings 2012-05-20 17:19:48 +03:00
Perttu Ahola
7c15d793ac --world list 2012-05-20 17:09:46 +03:00
Perttu Ahola
d90cb3511c Better description of static_spawnpoint in minetest.conf.example 2012-05-20 16:59:13 +03:00
Perttu Ahola
5100272dc3 Update minetest.conf.example a bit 2012-05-20 14:54:02 +03:00
Perttu Ahola
afda9810f1 Tune smooth lighting a bit 2012-05-20 14:12:17 +03:00
Perttu Ahola
22df8b81b3 Log more stuff in Client::afterContentReceived() 2012-05-19 17:11:41 +03:00
Perttu Ahola
7a427c9070 Take out the "Privileges of foo are hidden from you." response of /privs 2012-05-19 12:42:55 +03:00
Perttu Ahola
a35e4bdbda Add a hack to get rid of the rare "ERROR: StaticObjectList::insert(): id already exists" failure 2012-04-15 14:37:35 +03:00
Perttu Ahola
0aeb5adb8f Fix continuing to process TOSERVER_INIT2 even if player doesn't exist 2012-04-14 18:46:10 +03:00
Perttu Ahola
9c5cc217bf Add "Registered definitions of stuff" to doc/lua_api.txt 2012-04-14 11:24:18 +03:00
Perttu Ahola
24603d7ad3 Fix executing register_chatcommand-defined commands even in the middle of a chat line 2012-04-13 17:20:48 +03:00
Perttu Ahola
1eac6ff8ff Fix unhandled InvalidPositionException 2012-04-10 18:16:03 +03:00
Perttu Ahola
8742b3dab2 basic_privs to allow granting/revoking interact_extra too 2012-04-10 00:41:28 +03:00
Perttu Ahola
93cdc9b9dc Support static_spawnpoint setting 2012-04-09 23:32:13 +03:00
Perttu Ahola
8ed74a3429 Fix ABM handling on block activation 2012-04-09 23:06:24 +03:00
Perttu Ahola
07a5e59ae7 Allow redefining minetest.item_place and the like 2012-04-09 21:14:16 +03:00
Perttu Ahola
f8c2f1cf54 Make client know about reverted disallowed diggings 2012-04-09 21:13:22 +03:00
Perttu Ahola
b1f043d010 Add basic_privs privilege 2012-04-09 18:57:41 +03:00
Perttu Ahola
251c0c8508 Improve doc/lua_api.txt and add minetest.get_item_group(name, group) 2012-04-09 12:36:25 +03:00
Perttu Ahola
3214daca4c Fix unable to join server first time with a password 2012-04-09 11:24:35 +03:00
Perttu Ahola
e4485f5412 Call this 0.4.dev-20120408 2012-04-08 23:55:17 +03:00
Perttu Ahola
4eaaa0ec53 Add minimal documentation about the $world/game/ addition 2012-04-08 23:32:53 +03:00
Perttu Ahola
42323014ea Support placing a minetest game inside $world/game to allow creating proper adventure maps
Pro-tip: You can open a world in minetest by opening the world.mt file using minetest.
2012-04-08 23:17:02 +03:00
Perttu Ahola
c59d139eeb Fix crash after 'LuaEntity name "particles:smoke" not defined' and similar errors 2012-04-08 23:16:15 +03:00
Perttu Ahola
2b4d21160f minetest.get_node_group(name, group) 2012-04-08 18:39:55 +03:00
Perttu Ahola
e29a5b11e4 EnvRef:find_nodes_in_area(minp, maxp, nodenames) 2012-04-08 14:37:12 +03:00
Perttu Ahola
b58ee690a3 Allow looping of local and positional sounds 2012-04-08 14:35:57 +03:00
Perttu Ahola
d8edd3d0c8 Make lava brighter by showing light sources at their full emitted light level 2012-04-08 04:01:12 +03:00
Perttu Ahola
1b078efd5f Improve texture atlas generation 2012-04-07 23:37:12 +03:00
q66
e8e73d37fb Fullscreen, vsync, fullscreen_bpp and fsaa options in the config; fsaa is experimental atm, causes visible spaces between blocks. 2012-04-07 23:23:00 +03:00
Perttu Ahola
2eec788544 Improve doc/lua_api.txt 2012-04-07 19:59:03 +03:00
Perttu Ahola
dca28b9e12 Tune mapgen 2012-04-07 19:57:26 +03:00
Perttu Ahola
e879c92596 Fix collision code getting stuck if speed is 0 2012-04-07 19:19:36 +03:00
Perttu Ahola
7281c68b27 Fix segfault when setting privileges of a non-connected player 2012-04-07 18:46:10 +03:00
Perttu Ahola
d228f1b658 Fix fabs() brainfart 2012-04-07 18:05:06 +03:00
Perttu Ahola
2e60593c5b Tune desert beaches 2012-04-07 17:59:24 +03:00
Perttu Ahola
531fe10f51 Fix MSVC ambiguous fabs() call errors 2012-04-07 16:47:45 +03:00
Perttu Ahola
454b07455a Add deserts to map generator 2012-04-07 15:36:51 +03:00
Perttu Ahola
a4dc6f2c76 Tune mapgen a bit 2012-04-07 14:08:49 +03:00
Sergey Gilfanov
5608f12f9b PerlinNoise for Lua. 2012-04-07 13:39:01 +03:00
Perttu Ahola
18d8e3acec Support custom textures installed as /textures/all/*.png 2012-04-07 10:43:06 +03:00
Perttu Ahola
578fc5bb44 Add EnvRef:find_node_near(pos, radius, nodenames) 2012-04-06 22:44:42 +03:00
Perttu Ahola
e8660cfd8e Add missing mapgen.lua to games/minimal 2012-04-06 21:09:23 +03:00
Perttu Ahola
6a57eabb14 Handle failing openal init properly, add enable_sound and sound_volume settings 2012-04-06 15:30:36 +03:00
Perttu Ahola
a67540807a Add #include <unistd.h> to filesys.cpp 2012-04-06 14:56:14 +03:00
Perttu Ahola
20c377ca65 experimental:soundblock dig_immediate=3 2012-04-06 11:20:51 +03:00
Perttu Ahola
5436f1c7d5 Attempt to fix sound left-right channels 2012-04-06 00:39:37 +03:00
Perttu Ahola
4107390337 Make the minimal development test somewhat playable by adding ore generation and removing the player visual switch test 2012-04-05 21:42:33 +03:00
Perttu Ahola
e74da72b82 Fix crash when inputting only / in chat 2012-04-05 21:18:42 +03:00
Perttu Ahola
24953ba974 Fix super-small size of regular item entities 2012-04-04 22:57:29 +03:00
Perttu Ahola
22a5a1fa43 Show reported map seed on debug info (F5) 2012-04-04 22:43:54 +03:00
Perttu Ahola
7bac62ee7f Minimally update compiling on Windows in README.txt 2012-04-04 21:30:54 +03:00
Perttu Ahola
fcda11c6b0 Add to README.txt's example dependencies on Linux: libogg-dev libvorbis-dev libopenal-dev 2012-04-04 21:13:03 +03:00
Perttu Ahola
66e1cb324c Fix visual='cube' size 2012-04-04 18:10:10 +03:00
Perttu Ahola
a869d23451 Fix sound direction and add experimental:soundblock alias sb in minimal for testing 2012-04-04 13:32:08 +03:00
Perttu Ahola
41f4941b74 Remove debug output 2012-04-04 13:20:56 +03:00
Perttu Ahola
b22168d3da Fix dropped nodeitem visuals 2012-04-04 13:16:09 +03:00
Perttu Ahola
b9b56bac6b Fix buildbot 2012-04-03 08:55:13 +03:00
Perttu Ahola
fa670fa4b5 Add util/buildbot 2012-04-03 08:48:44 +03:00
Perttu Ahola
b131a0cf0c Add optional MINGWM10_DLL to cmake install 2012-04-03 01:03:31 +03:00
Perttu Ahola
d7cef8d762 Add multiplayer test script 2012-04-03 00:32:08 +03:00
Perttu Ahola
4483fc7df3 Fix installation path of minetest_game/mods (// in place of / doesn't work on virtualbox network drives) 2012-04-02 22:50:46 +03:00
Perttu Ahola
2cd5addc0c Fix things for cross-compiling using mingw 2012-04-02 21:14:30 +03:00
Perttu Ahola
5bf06efb2a Tune cave generation 2012-04-02 08:51:05 +03:00
Perttu Ahola
5196e309b8 Improve caves more 2012-04-02 02:49:21 +03:00
Perttu Ahola
bee1adc651 Some completely crapshit coding to make caves more varied 2012-04-01 20:54:36 +03:00
Perttu Ahola
f0e7da8a63 Implement dropped items as LuaEntities; leave the old ones as is for compatibility 2012-04-01 16:06:01 +03:00
Perttu Ahola
5bd32eca0f Fix disabling of player movement cheat detection in singleplayer 2012-04-01 13:37:07 +03:00
Perttu Ahola
491287c0af Don't apply player movement cheat detection in singleplayer 2012-04-01 13:19:50 +03:00
Perttu Ahola
8ecfd88d92 Remplement and improve /setting in Lua, now called /set 2012-04-01 13:08:52 +03:00
Perttu Ahola
b54178bbbd Don't allow /granting unknown privileges 2012-04-01 12:45:38 +03:00
Perttu Ahola
67547f74fc Split builtin.lua to multiple files 2012-04-01 12:38:19 +03:00
Perttu Ahola
56ba193c77 Allow getting the path of builtin.lua using minetest.get_modpath("__builtin") 2012-04-01 12:38:14 +03:00
Perttu Ahola
d5594e431c granting and revoking of all privileges at once 2012-04-01 01:10:29 +03:00
Perttu Ahola
7bfa2d4da6 Add license of Lua in README.txt 2012-03-31 19:30:17 +03:00
Perttu Ahola
4cf00f5698 Change default privileges from "build, shout" to "interact, shout" 2012-03-31 17:48:46 +03:00
Perttu Ahola
a18326e97a Fix authentication handler reporting failed password change while it isn't 2012-03-31 17:41:04 +03:00
Perttu Ahola
36c9463467 Improve /grant and /revoke output, add /auth_reload 2012-03-31 17:26:44 +03:00
Perttu Ahola
13159c1a48 Add server-side enforcement of the 'fast' privilege; also fix client checking 'fly' instead of 'fast' 2012-03-31 17:08:39 +03:00
Perttu Ahola
0fbef74f31 Fix client.h getting included on the server build 2012-03-31 16:32:00 +03:00
Perttu Ahola
52122c342d Add 'fly' and 'fast' privileges and the underlying privileges-to-client system 2012-03-31 16:25:02 +03:00
Perttu Ahola
96ee73f790 Fix doc/lua_api.txt 2012-03-31 14:27:04 +03:00
Perttu Ahola
dc70f50b59 initial_properties field in entity definition 2012-03-31 13:50:25 +03:00
Perttu Ahola
e297c73913 More documentation in doc/lua_api.txt 2012-03-31 13:08:17 +03:00
Perttu Ahola
280e1a2512 Allow group:groupname in ABM definition and implement minetest.hash_node_position() 2012-03-31 12:30:11 +03:00
Jonathan Neuschäfer
1518b8f753 cmake: lua: use COMMON_CFLAGS
This fixes LUA_USE_DLOPEN having no effect.
2012-03-31 01:31:17 +03:00
Perttu Ahola
5403b1cf6d Install minetest_game without .git and other unnecessary things 2012-03-31 00:05:01 +03:00
Perttu Ahola
29110d5428 Fix handling of missing auth.txt in the new handler 2012-03-30 23:12:01 +03:00
Perttu Ahola
462003363f Make server ignore media files with unknown filename extensions 2012-03-30 22:49:44 +03:00
Perttu Ahola
b494324ec3 Fix admin password handling in minetest.builtin_auth_handler.get_auth 2012-03-30 21:25:54 +03:00
Perttu Ahola
4cee9a86ac Improved teleport command 2012-03-30 20:54:57 +03:00
Perttu Ahola
7cad0a2dcd Reimplement authentication handler in Lua; now we have 1) infinite privilege names, 2) minetest.register_authentication_handler() 2012-03-30 18:42:18 +03:00
Perttu Ahola
ed1ff06867 Fix the position of LuaEntityCAOs not getting updated at all 2012-03-30 13:55:08 +03:00
Perttu Ahola
80a64341f0 Add minetest.get_connected_players() 2012-03-30 13:45:51 +03:00
Perttu Ahola
bbf3eebb1a Fix object visuals flashing brightly or disappearing when switching them at night 2012-03-30 13:44:48 +03:00
Perttu Ahola
6b20ea0752 Fix walking sound of other players (and other objects) 2012-03-30 13:34:25 +03:00
Perttu Ahola
3241ad3ae8 ObjectRef:set_armor_groups() and ObjectRef:set_properties() - works on players too! 2012-03-30 13:34:21 +03:00
Perttu Ahola
9e7ccedba4 ObjectProperties 2012-03-30 12:51:51 +03:00
Perttu Ahola
b9ffb5f30d minetest.register_chatcommand(cmd, def) 2012-03-30 01:45:23 +03:00
Perttu Ahola
9d456ca87a Raise the player fall damage threshold to a much more fun level 2012-03-29 23:32:56 +03:00
Perttu Ahola
18350ad37f Improve the look of fences 2012-03-29 22:59:43 +03:00
Kahrl
0983f65da7 [transformN image modifier 2012-03-29 22:58:01 +03:00
Perttu Ahola
42bbd5c9ae Simple fix for camera blinking black when jumping into ceiling with current smaller collision box 2012-03-29 21:21:34 +03:00
Perttu Ahola
92ae11bd3b Use GenericCAO in place of LuaEntityCAO and PlayerCAO 2012-03-29 19:42:42 +03:00
Perttu Ahola
443f45eca1 Add GenericCAO and player armor groups, but don't use them yet 2012-03-29 16:10:11 +03:00
Kahrl
a9ddbb4beb on_joinplayer + on_leaveplayer + scriptapi_run_callbacks + bugfix
Add minetest.register_on_joinplayer and minetest.register_on_leaveplayer,
make adding new callbacks to scriptapi.cpp easier by adding
scriptapi_run_callbacks, also fix a minor bug with PlayerSAO <->
singleplayer mode interaction
2012-03-29 14:27:09 +03:00
Kahrl
f8c3743991 added PlayerSAO and RemotePlayer, removed ServerRemotePlayer 2012-03-29 14:05:45 +03:00
Perttu Ahola
072c265c30 Modify minimal/give_initial_stuff to always give stuff 2012-03-29 13:39:18 +03:00
Perttu Ahola
440e9cdbef Rework tool_capabilities a bit (maxwear->uses, scale dig time according to leveldiff) 2012-03-29 13:35:20 +03:00
Perttu Ahola
ace005bf7c Try a default day+night length of 20 minutes instead of 15 2012-03-29 11:41:41 +03:00
Perttu Ahola
75821c6889 Generate beaches 2012-03-29 03:44:37 +03:00
Perttu Ahola
d376148ca1 Generate blobs of dirt and gravel in stone 2012-03-29 02:23:59 +03:00
Perttu Ahola
582ca33507 Remove unnecessary debug output 2012-03-29 01:38:13 +03:00
Perttu Ahola
a6ca7eb29d Area-based MapEditEvent ignore and that put to use for on_generate too 2012-03-29 01:22:08 +03:00
Perttu Ahola
02c035c548 Reduce EnvRef:set_node() time tenfold by postponing the dayNightDiff update until it is actually needed 2012-03-29 00:28:48 +03:00
Perttu Ahola
418041d906 Fix on_generate minp/maxp (was broken due to chunkymapgen) 2012-03-28 23:11:28 +03:00
Perttu Ahola
a3a400992e Add EnvRef:set_node() 2012-03-28 22:50:08 +03:00
Perttu Ahola
68625b047f Add range option to PseudoRandom:next() 2012-03-28 22:01:23 +03:00
Perttu Ahola
9a1df7bf38 Add blockseed to on_generated 2012-03-28 22:01:21 +03:00
Perttu Ahola
81b9cfdfa4 Default to having fancy trees and 3d clouds turned on 2012-03-28 14:10:54 +03:00
Perttu Ahola
ae7aa65069 Add minetest.is_singleplayer() 2012-03-28 13:22:48 +03:00
Perttu Ahola
9e0f969b8b doc/lua_api.txt: minetest.get_worldpath(modname) -> minetest.get_worldpath() 2012-03-28 13:01:35 +03:00
Perttu Ahola
14a8fa4d68 Correctly lock mutexes when the server sends MapEditEvents (could cause memory corruption) 2012-03-28 12:51:47 +03:00
Perttu Ahola
07e5c9bd5f No occlusion culling when free_move is on and camera is inside ground 2012-03-28 12:19:25 +03:00
Perttu Ahola
49c2ca0216 Make mapgen use mapgen_* node aliases rather than the LEGN macro 2012-03-28 01:26:15 +03:00
Perttu Ahola
04172e3dd0 Add PseudoRandom in Lua API 2012-03-28 00:38:20 +03:00
Perttu Ahola
2c56a9f588 Tune skybox 2012-03-27 23:30:41 +03:00
Perttu Ahola
20e025b3d8 Try to make background/fog/sky color selection work better 2012-03-27 22:41:07 +03:00
Perttu Ahola
10591d2080 Set default minimum viewing range of 35 nodes 2012-03-27 19:57:24 +03:00
Perttu Ahola
af29c0ade5 Unrelated, but anyway: tune light levels again 2012-03-27 19:25:25 +03:00
Perttu Ahola
4c876ac62e Tune caves 2012-03-27 19:09:08 +03:00
Perttu Ahola
66bf7b0b01 Fix deep ground cave generation a bit 2012-03-27 19:09:08 +03:00
Perttu Ahola
17d51a1609 Fix mapgen block_is_underground heuristic 2012-03-27 19:09:07 +03:00
Perttu Ahola
0a59605e05 Tune mapgen 2012-03-27 19:09:07 +03:00
Perttu Ahola
202658678d Set default maximum viewing range to a bit more than default server send range to make fog work well 2012-03-27 19:09:07 +03:00
Perttu Ahola
4f01db256f Re-implement and re-tune mapgen v2 2012-03-27 19:05:59 +03:00
Perttu Ahola
c04f4a7d73 Tune generation responsiveness and cheat inhibition on server 2012-03-27 19:05:59 +03:00
Perttu Ahola
f5e46ba7fc Increase maximum generate distance now that generation might actually keep up with it 2012-03-27 19:04:59 +03:00
Perttu Ahola
8609af54fc Remove usage of mapgen::add_random_objects(block) 2012-03-27 19:01:52 +03:00
Perttu Ahola
9a4ef87859 Remove no-op mapgen::add_random_objects 2012-03-27 19:01:52 +03:00
Perttu Ahola
a57f4c23d8 Fix inexistent_top_provides_sunlight heuristic in make_block and remove clitch-causing optimization 2012-03-27 19:01:52 +03:00
Perttu Ahola
d629f4d2fb Remove some debug output 2012-03-27 19:01:52 +03:00
Perttu Ahola
6f20a73782 Tune block fetching to clients on server 2012-03-27 19:01:52 +03:00
Perttu Ahola
8cb7badd63 Do post-mapgen lighting using the VoxelManipulator-based functions (causes glitches currently) 2012-03-27 19:01:51 +03:00
Perttu Ahola
0f3c2f6541 voxalgo::clearLightAndCollectSources 2012-03-27 19:01:51 +03:00
Perttu Ahola
56496ad5d8 Implement propagateSunlight for VoxelManipulator 2012-03-27 19:01:50 +03:00
Perttu Ahola
e15dca2a9f Fix tree generation density for different mapgen chunk sizes 2012-03-27 18:52:36 +03:00
Perttu Ahola
a32706bc26 Post-mapgen lighting optimization 2012-03-27 18:52:36 +03:00
Perttu Ahola
bdcca4767c Make mapgen generate stuff in chunks of 3^3 mapblocks 2012-03-27 18:52:36 +03:00
Perttu Ahola
38f4dbfb51 Update minetest.conf.example and defaultsettings.cpp 2012-03-27 18:51:21 +03:00
Perttu Ahola
a374b1a6a3 Increase vertical FOV on lower aspect ratios (<16:10) 2012-03-27 18:39:21 +03:00
Perttu Ahola
0ff94978f5 Fix minetest_game installation and don't fail if it doesn't exist 2012-03-27 17:33:51 +03:00
Perttu Ahola
fa24e6b995 Fix and extend minetest.after(time, func, param) 2012-03-27 08:17:42 +03:00
Perttu Ahola
37b64ff616 Add minetest.after(time, func) 2012-03-27 00:37:31 +03:00
Perttu Ahola
a2fd8d1db1 Add default_grass_footstep.1.ogg as a test sound in minimal 2012-03-27 00:36:31 +03:00
222 changed files with 12693 additions and 8181 deletions

View File

@@ -7,10 +7,15 @@ endif(${CMAKE_VERSION} STREQUAL "2.8.2")
# This can be read from ${PROJECT_NAME} after project() is called
project(minetest)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
set(VERSION_MAJOR 0)
set(VERSION_MINOR 4)
set(VERSION_PATCH dev-20120326)
set(VERSION_PATCH dev-20120606)
if(VERSION_EXTRA)
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
endif()
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
MESSAGE(STATUS "*** Will build version ${VERSION_STRING} ***")
@@ -85,13 +90,20 @@ elseif(UNIX) # Linux, BSD etc
endif()
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest" DESTINATION "${SHAREDIR}/games")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games")
set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game")
if(EXISTS ${MINETEST_GAME_SOURCE} AND IS_DIRECTORY ${MINETEST_GAME_SOURCE})
install(FILES ${MINETEST_GAME_SOURCE}/game.conf DESTINATION "${SHAREDIR}/games/minetest_game/")
install(FILES ${MINETEST_GAME_SOURCE}/README.txt DESTINATION "${SHAREDIR}/games/minetest_game/")
install(DIRECTORY ${MINETEST_GAME_SOURCE}/mods DESTINATION "${SHAREDIR}/games/minetest_game")
endif()
if(BUILD_CLIENT)
#install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/sounds/base/pack" DESTINATION "${SHAREDIR}/sounds/base")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base")
endif()
if(RUN_IN_PLACE)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/mods/minetest/mods_here.txt" DESTINATION "${SHAREDIR}/mods/minetest")
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/textures/all/textures_here.txt" DESTINATION "${SHAREDIR}/textures/all")
endif()
install(FILES "README.txt" DESTINATION "${DOCDIR}")

View File

@@ -79,13 +79,20 @@ Compiling on GNU/Linux:
-----------------------
Install dependencies. Here's an example for Debian/Ubuntu:
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
$ wget https://github.com/celeron55/minetest/tarball/master -O master.tar.gz
$ tar xf master.tar.gz
$ cd celeron55-minetest-286edd4 (or similar)
Download minetest_game (otherwise only the "Minimal development test" game is available)
$ cd games/
$ wget https://github.com/celeron55/minetest_game/tarball/master -O master.tar.gz
$ tar xf master.tar.gz
$ mv celeron55-minetest_game-* minetest_game
$ cd ..
Build a version that runs directly from the source directory:
$ cmake . -DRUN_IN_PLACE=1
$ make -j2
@@ -102,6 +109,9 @@ $ ./minetest
Compiling on Windows:
---------------------
- This section is outdated. In addition to what is described here:
- In addition to minetest, you need to download minetest_game.
- If you wish to have sound support, you need libogg, libvorbis and libopenal
- You need:
* CMake:
@@ -250,8 +260,8 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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,
@@ -259,7 +269,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@@ -315,6 +325,34 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
Lua
---------------
Lua is licensed under the terms of the MIT license reproduced below.
This means that Lua is free software and can be used for both academic
and commercial purposes at absolutely no cost.
For details and rationale, see http://www.lua.org/license.html .
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Fonts
---------------

188
builtin/auth.lua Normal file
View File

@@ -0,0 +1,188 @@
-- Minetest: builtin/auth.lua
--
-- Authentication handler
--
function minetest.string_to_privs(str, delim)
assert(type(str) == "string")
delim = delim or ','
privs = {}
for _, priv in pairs(string.split(str, delim)) do
privs[priv:trim()] = true
end
return privs
end
function minetest.privs_to_string(privs, delim)
assert(type(privs) == "table")
delim = delim or ','
list = {}
for priv, bool in pairs(privs) do
if bool then
table.insert(list, priv)
end
end
return table.concat(list, delim)
end
assert(minetest.string_to_privs("a,b").b == true)
assert(minetest.privs_to_string({a=true,b=true}) == "a,b")
minetest.auth_file_path = minetest.get_worldpath().."/auth.txt"
minetest.auth_table = {}
local function read_auth_file()
local newtable = {}
local file, errmsg = io.open(minetest.auth_file_path, 'rb')
if not file then
minetest.log("info", minetest.auth_file_path.." could not be opened for reading ("..errmsg.."); assuming new world")
return
end
for line in file:lines() do
if line ~= "" then
local name, password, privilegestring = string.match(line, "([^:]*):([^:]*):([^:]*)")
if not name or not password or not privilegestring then
error("Invalid line in auth.txt: "..dump(line))
end
local privileges = minetest.string_to_privs(privilegestring)
newtable[name] = {password=password, privileges=privileges}
end
end
io.close(file)
minetest.auth_table = newtable
minetest.notify_authentication_modified()
end
local function save_auth_file()
local newtable = {}
-- Check table for validness before attempting to save
for name, stuff in pairs(minetest.auth_table) do
assert(type(name) == "string")
assert(name ~= "")
assert(type(stuff) == "table")
assert(type(stuff.password) == "string")
assert(type(stuff.privileges) == "table")
end
local file, errmsg = io.open(minetest.auth_file_path, 'w+b')
if not file then
error(minetest.auth_file_path.." could not be opened for writing: "..errmsg)
end
for name, stuff in pairs(minetest.auth_table) do
local privstring = minetest.privs_to_string(stuff.privileges)
file:write(name..":"..stuff.password..":"..privstring..'\n')
end
io.close(file)
end
read_auth_file()
minetest.builtin_auth_handler = {
get_auth = function(name)
assert(type(name) == "string")
-- Figure out what password to use for a new player (singleplayer
-- always has an empty password, otherwise use default, which is
-- usually empty too)
local new_password_hash = ""
-- If not in authentication table, return nil
if not minetest.auth_table[name] then
return nil
end
-- Figure out what privileges the player should have.
-- Take a copy of the privilege table
local privileges = {}
for priv, _ in pairs(minetest.auth_table[name].privileges) do
privileges[priv] = true
end
-- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
if minetest.is_singleplayer() then
for priv, def in pairs(minetest.registered_privileges) do
if def.give_to_singleplayer then
privileges[priv] = true
end
end
-- For the admin, give everything
elseif name == minetest.setting_get("name") then
for priv, def in pairs(minetest.registered_privileges) do
privileges[priv] = true
end
end
-- All done
return {
password = minetest.auth_table[name].password,
privileges = privileges,
}
end,
create_auth = function(name, password)
assert(type(name) == "string")
assert(type(password) == "string")
minetest.log('info', "Built-in authentication handler adding player '"..name.."'")
minetest.auth_table[name] = {
password = password,
privileges = minetest.string_to_privs(minetest.setting_get("default_privs")),
}
save_auth_file()
end,
set_password = function(name, password)
assert(type(name) == "string")
assert(type(password) == "string")
if not minetest.auth_table[name] then
minetest.builtin_auth_handler.create_auth(name, password)
else
minetest.log('info', "Built-in authentication handler setting password of player '"..name.."'")
minetest.auth_table[name].password = password
save_auth_file()
end
return true
end,
set_privileges = function(name, privileges)
assert(type(name) == "string")
assert(type(privileges) == "table")
if not minetest.auth_table[name] then
minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
end
minetest.auth_table[name].privileges = privileges
minetest.notify_authentication_modified(name)
save_auth_file()
end,
reload = function()
read_auth_file()
return true
end,
}
function minetest.register_authentication_handler(handler)
if minetest.registered_auth_handler then
error("Add-on authentication handler already registered by "..minetest.registered_auth_handler_modname)
end
minetest.registered_auth_handler = handler
minetest.registered_auth_handler_modname = minetest.get_current_modname()
end
function minetest.get_auth_handler()
if minetest.registered_auth_handler then
return minetest.registered_auth_handler
end
return minetest.builtin_auth_handler
end
function minetest.set_player_password(name, password)
if minetest.get_auth_handler().set_password then
minetest.get_auth_handler().set_password(name, password)
end
end
function minetest.set_player_privs(name, privs)
if minetest.get_auth_handler().set_privileges then
minetest.get_auth_handler().set_privileges(name, privs)
end
end
function minetest.auth_reload()
if minetest.get_auth_handler().reload then
return minetest.get_auth_handler().reload()
end
return false
end

View File

@@ -5,800 +5,20 @@
-- before loading and running any mods.
--
--
-- Override some Lua library functions
--
-- Initialize some very basic things
print = minetest.debug
--
--
--
function basic_dump2(o)
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
elseif type(o) == "boolean" then
return tostring(o)
elseif type(o) == "function" then
return "<function>"
elseif type(o) == "userdata" then
return "<userdata>"
elseif type(o) == "nil" then
return "nil"
else
error("cannot dump a " .. type(o))
return nil
end
end
function dump2(o, name, dumped)
name = name or "_"
dumped = dumped or {}
io.write(name, " = ")
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
or type(o) == "function" or type(o) == "nil"
or type(o) == "userdata" then
io.write(basic_dump2(o), "\n")
elseif type(o) == "table" then
if dumped[o] then
io.write(dumped[o], "\n")
else
dumped[o] = name
io.write("{}\n") -- new table
for k,v in pairs(o) do
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
dump2(v, fieldname, dumped)
end
end
else
error("cannot dump a " .. type(o))
return nil
end
end
function dump(o, dumped)
dumped = dumped or {}
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
elseif type(o) == "table" then
if dumped[o] then
return "<circular reference>"
end
dumped[o] = true
local t = {}
for k,v in pairs(o) do
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
end
return "{" .. table.concat(t, ", ") .. "}"
elseif type(o) == "boolean" then
return tostring(o)
elseif type(o) == "function" then
return "<function>"
elseif type(o) == "userdata" then
return "<userdata>"
elseif type(o) == "nil" then
return "nil"
else
error("cannot dump a " .. type(o))
return nil
end
end
--
-- Item definition helpers
--
function minetest.inventorycube(img1, img2, img3)
img2 = img2 or img1
img3 = img3 or img1
return "[inventorycube"
.. "{" .. img1:gsub("%^", "&")
.. "{" .. img2:gsub("%^", "&")
.. "{" .. img3:gsub("%^", "&")
end
function minetest.pos_to_string(pos)
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
end
function minetest.get_pointed_thing_position(pointed_thing, above)
if pointed_thing.type == "node" then
if above then
-- The position where a node would be placed
return pointed_thing.above
else
-- The position where a node would be dug
return pointed_thing.under
end
elseif pointed_thing.type == "object" then
obj = pointed_thing.ref
if obj ~= nil then
return obj:getpos()
else
return nil
end
else
return nil
end
end
function minetest.dir_to_facedir(dir)
if math.abs(dir.x) > math.abs(dir.z) then
if dir.x < 0 then
return 3
else
return 1
end
else
if dir.z < 0 then
return 2
else
return 0
end
end
end
function minetest.dir_to_wallmounted(dir)
if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
if dir.y < 0 then
return 1
else
return 0
end
elseif math.abs(dir.x) > math.abs(dir.z) then
if dir.x < 0 then
return 3
else
return 2
end
else
if dir.z < 0 then
return 5
else
return 4
end
end
end
function minetest.get_node_drops(nodename, toolname)
local drop = ItemStack({name=nodename}):get_definition().drop
if drop == nil then
-- default drop
return {ItemStack({name=nodename})}
elseif type(drop) == "string" then
-- itemstring drop
return {ItemStack(drop)}
elseif drop.items == nil then
-- drop = {} to disable default drop
return {}
end
-- Extended drop table
local got_items = {}
local got_count = 0
local _, item, tool
for _, item in ipairs(drop.items) do
local good_rarity = true
local good_tool = true
if item.rarity ~= nil then
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
end
if item.tools ~= nil then
good_tool = false
for _, tool in ipairs(item.tools) do
if tool:sub(1, 1) == '~' then
good_tool = toolname:find(tool:sub(2)) ~= nil
else
good_tool = toolname == tool
end
if good_tool then
break
end
end
end
if good_rarity and good_tool then
got_count = got_count + 1
for _, add_item in ipairs(item.items) do
got_items[#got_items+1] = add_item
end
if drop.max_items ~= nil and got_count == drop.max_items then
break
end
end
end
return got_items
end
function minetest.item_place_node(itemstack, placer, pointed_thing)
local item = itemstack:peek_item()
local def = itemstack:get_definition()
if def.type == "node" and pointed_thing.type == "node" then
local pos = pointed_thing.above
local oldnode = minetest.env:get_node(pos)
local olddef = ItemStack({name=oldnode.name}):get_definition()
if not olddef.buildable_to then
minetest.log("info", placer:get_player_name() .. " tried to place"
.. " node in invalid position " .. minetest.pos_to_string(pos)
.. ", replacing " .. oldnode.name)
return
end
minetest.log("action", placer:get_player_name() .. " places node "
.. def.name .. " at " .. minetest.pos_to_string(pos))
local newnode = {name = def.name, param1 = 0, param2 = 0}
-- Calculate direction for wall mounted stuff like torches and signs
if def.paramtype2 == 'wallmounted' then
local under = pointed_thing.under
local above = pointed_thing.above
local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
newnode.param2 = minetest.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
elseif def.paramtype2 == 'facedir' then
local playerpos = placer:getpos()
local dir = {x = pos.x - playerpos.x, y = pos.y - playerpos.y, z = pos.z - playerpos.z}
newnode.param2 = minetest.dir_to_facedir(dir)
minetest.log("action", "facedir: " .. newnode.param2)
end
-- Add node and update
minetest.env:add_node(pos, newnode)
-- Set metadata owner
if def.metadata_name ~= "" then
minetest.env:get_meta(pos):set_owner(placer:get_player_name())
end
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_placenodes) do
callback(pos, newnode, placer)
end
itemstack:take_item()
end
return itemstack
end
function minetest.item_place_object(itemstack, placer, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
if pos ~= nil then
local item = itemstack:take_item()
minetest.env:add_item(pos, item)
end
return itemstack
end
function minetest.item_place(itemstack, placer, pointed_thing)
if itemstack:get_definition().type == "node" then
return minetest.item_place_node(itemstack, placer, pointed_thing)
else
return minetest.item_place_object(itemstack, placer, pointed_thing)
end
end
function minetest.item_drop(itemstack, dropper, pos)
minetest.env:add_item(pos, itemstack)
return ""
end
function minetest.item_eat(hp_change, replace_with_item)
return function(itemstack, user, pointed_thing) -- closure
if itemstack:take_item() ~= nil then
user:set_hp(user:get_hp() + hp_change)
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
end
return itemstack
end
end
function minetest.node_punch(pos, node, puncher)
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_punchnodes) do
callback(pos, node, puncher)
end
end
function minetest.node_dig(pos, node, digger)
minetest.debug("node_dig")
local def = ItemStack({name=node.name}):get_definition()
if not def.diggable then
minetest.debug("not diggable")
minetest.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. " which is not diggable "
.. minetest.pos_to_string(pos))
return
end
local meta = minetest.env:get_meta(pos)
if meta ~= nil and not meta:get_allow_removal() then
minetest.debug("dig prevented by metadata")
minetest.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. ", but removal is disabled by metadata "
.. minetest.pos_to_string(pos))
return
end
minetest.log('action', digger:get_player_name() .. " digs "
.. node.name .. " at " .. minetest.pos_to_string(pos))
if not minetest.setting_getbool("creative_mode") then
local wielded = digger:get_wielded_item()
local drops = minetest.get_node_drops(node.name, wielded:get_name())
-- Wear out tool
tp = wielded:get_tool_capabilities()
dp = minetest.get_dig_params(def.groups, tp)
wielded:add_wear(dp.wear)
digger:set_wielded_item(wielded)
-- Add dropped items
local _, dropped_item
for _, dropped_item in ipairs(drops) do
digger:get_inventory():add_item("main", dropped_item)
end
end
-- Remove node and update
minetest.env:remove_node(pos)
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_dignodes) do
callback(pos, node, digger)
end
end
--
-- Item definition defaults
--
minetest.nodedef_default = {
-- Item properties
type="node",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
usable = false,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = minetest.item_place,
on_drop = minetest.item_drop,
on_use = nil,
on_punch = minetest.node_punch,
on_dig = minetest.node_dig,
-- Node properties
drawtype = "normal",
visual_scale = 1.0,
tile_images = {""},
special_materials = {
{image="", backface_culling=true},
{image="", backface_culling=true},
},
alpha = 255,
post_effect_color = {a=0, r=0, g=0, b=0},
paramtype = "none",
paramtype2 = "none",
is_ground_content = false,
sunlight_propagates = false,
walkable = true,
pointable = true,
diggable = true,
climbable = false,
buildable_to = false,
metadata_name = "",
liquidtype = "none",
liquid_alternative_flowing = "",
liquid_alternative_source = "",
liquid_viscosity = 0,
light_source = 0,
damage_per_second = 0,
selection_box = {type="regular"},
legacy_facedir_simple = false,
legacy_wallmounted = false,
}
minetest.craftitemdef_default = {
type="craft",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = minetest.item_place,
on_drop = minetest.item_drop,
on_use = nil,
}
minetest.tooldef_default = {
type="tool",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 1,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = minetest.item_place,
on_drop = minetest.item_drop,
on_use = nil,
}
minetest.noneitemdef_default = { -- This is used for the hand and unknown items
type="none",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = nil,
on_drop = nil,
on_use = nil,
}
--
-- Make raw registration functions inaccessible to anyone except builtin.lua
--
local register_item_raw = minetest.register_item_raw
minetest.register_item_raw = nil
local register_alias_raw = minetest.register_alias_raw
minetest.register_item_raw = nil
--
-- Item / entity / ABM registration functions
--
minetest.registered_abms = {}
minetest.registered_entities = {}
minetest.registered_items = {}
minetest.registered_nodes = {}
minetest.registered_craftitems = {}
minetest.registered_tools = {}
minetest.registered_aliases = {}
-- For tables that are indexed by item name:
-- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
local function set_alias_metatable(table)
setmetatable(table, {
__index = function(name)
return rawget(table, minetest.registered_aliases[name])
end
})
end
set_alias_metatable(minetest.registered_items)
set_alias_metatable(minetest.registered_nodes)
set_alias_metatable(minetest.registered_craftitems)
set_alias_metatable(minetest.registered_tools)
-- These item names may not be used because they would interfere
-- with legacy itemstrings
local forbidden_item_names = {
MaterialItem = true,
MaterialItem2 = true,
MaterialItem3 = true,
NodeItem = true,
node = true,
CraftItem = true,
craft = true,
MBOItem = true,
ToolItem = true,
tool = true,
}
local function check_modname_prefix(name)
if name:sub(1,1) == ":" then
-- Escape the modname prefix enforcement mechanism
return name:sub(2)
else
-- Modname prefix enforcement
local expected_prefix = minetest.get_current_modname() .. ":"
if name:sub(1, #expected_prefix) ~= expected_prefix then
error("Name " .. name .. " does not follow naming conventions: " ..
"\"modname:\" or \":\" prefix required")
end
local subname = name:sub(#expected_prefix+1)
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
error("Name " .. name .. " does not follow naming conventions: " ..
"contains unallowed characters")
end
return name
end
end
function minetest.register_abm(spec)
-- Add to minetest.registered_abms
minetest.registered_abms[#minetest.registered_abms+1] = spec
end
function minetest.register_entity(name, prototype)
-- Check name
if name == nil then
error("Unable to register entity: Name is nil")
end
name = check_modname_prefix(tostring(name))
prototype.name = name
prototype.__index = prototype -- so that it can be used as a metatable
-- Add to minetest.registered_entities
minetest.registered_entities[name] = prototype
end
function minetest.register_item(name, itemdef)
-- Check name
if name == nil then
error("Unable to register item: Name is nil")
end
name = check_modname_prefix(tostring(name))
if forbidden_item_names[name] then
error("Unable to register item: Name is forbidden: " .. name)
end
itemdef.name = name
-- Apply defaults and add to registered_* table
if itemdef.type == "node" then
setmetatable(itemdef, {__index = minetest.nodedef_default})
minetest.registered_nodes[itemdef.name] = itemdef
elseif itemdef.type == "craft" then
setmetatable(itemdef, {__index = minetest.craftitemdef_default})
minetest.registered_craftitems[itemdef.name] = itemdef
elseif itemdef.type == "tool" then
setmetatable(itemdef, {__index = minetest.tooldef_default})
minetest.registered_tools[itemdef.name] = itemdef
elseif itemdef.type == "none" then
setmetatable(itemdef, {__index = minetest.noneitemdef_default})
else
error("Unable to register item: Type is invalid: " .. dump(itemdef))
end
-- Flowing liquid uses param2
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
itemdef.paramtype2 = "flowingliquid"
end
-- BEGIN Legacy stuff
if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
minetest.register_craft({
type="cooking",
output=itemdef.cookresult_itemstring,
recipe=itemdef.name,
cooktime=itemdef.furnace_cooktime
})
end
if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
minetest.register_craft({
type="fuel",
recipe=itemdef.name,
burntime=itemdef.furnace_burntime
})
end
-- END Legacy stuff
-- Disable all further modifications
getmetatable(itemdef).__newindex = {}
--minetest.log("Registering item: " .. itemdef.name)
minetest.registered_items[itemdef.name] = itemdef
minetest.registered_aliases[itemdef.name] = nil
register_item_raw(itemdef)
end
function minetest.register_node(name, nodedef)
nodedef.type = "node"
minetest.register_item(name, nodedef)
end
function minetest.register_craftitem(name, craftitemdef)
craftitemdef.type = "craft"
-- BEGIN Legacy stuff
if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
craftitemdef.inventory_image = craftitemdef.image
end
-- END Legacy stuff
minetest.register_item(name, craftitemdef)
end
function minetest.register_tool(name, tooldef)
tooldef.type = "tool"
tooldef.stack_max = 1
-- BEGIN Legacy stuff
if tooldef.inventory_image == nil and tooldef.image ~= nil then
tooldef.inventory_image = tooldef.image
end
if tooldef.tool_capabilities == nil and
(tooldef.full_punch_interval ~= nil or
tooldef.basetime ~= nil or
tooldef.dt_weight ~= nil or
tooldef.dt_crackiness ~= nil or
tooldef.dt_crumbliness ~= nil or
tooldef.dt_cuttability ~= nil or
tooldef.basedurability ~= nil or
tooldef.dd_weight ~= nil or
tooldef.dd_crackiness ~= nil or
tooldef.dd_crumbliness ~= nil or
tooldef.dd_cuttability ~= nil) then
tooldef.tool_capabilities = {
full_punch_interval = tooldef.full_punch_interval,
basetime = tooldef.basetime,
dt_weight = tooldef.dt_weight,
dt_crackiness = tooldef.dt_crackiness,
dt_crumbliness = tooldef.dt_crumbliness,
dt_cuttability = tooldef.dt_cuttability,
basedurability = tooldef.basedurability,
dd_weight = tooldef.dd_weight,
dd_crackiness = tooldef.dd_crackiness,
dd_crumbliness = tooldef.dd_crumbliness,
dd_cuttability = tooldef.dd_cuttability,
}
end
-- END Legacy stuff
minetest.register_item(name, tooldef)
end
function minetest.register_alias(name, convert_to)
if forbidden_item_names[name] then
error("Unable to register alias: Name is forbidden: " .. name)
end
if minetest.registered_items[name] ~= nil then
minetest.log("WARNING: Not registering alias, item with same name" ..
" is already defined: " .. name .. " -> " .. convert_to)
else
--minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
minetest.registered_aliases[name] = convert_to
register_alias_raw(name, convert_to)
end
end
-- Alias the forbidden item names to "" so they can't be
-- created via itemstrings (e.g. /give)
local name
for name in pairs(forbidden_item_names) do
minetest.registered_aliases[name] = ""
register_alias_raw(name, "")
end
-- Deprecated:
-- Aliases for minetest.register_alias (how ironic...)
--minetest.alias_node = minetest.register_alias
--minetest.alias_tool = minetest.register_alias
--minetest.alias_craftitem = minetest.register_alias
--
-- Built-in node definitions. Also defined in C.
--
minetest.register_item(":unknown", {
type = "none",
description = "Unknown Item",
inventory_image = "unknown_item.png",
on_place = minetest.item_place,
on_drop = minetest.item_drop,
})
minetest.register_node(":air", {
description = "Air (you hacker you!)",
inventory_image = "unknown_block.png",
wield_image = "unknown_block.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
air_equivalent = true,
})
minetest.register_node(":ignore", {
description = "Ignore (you hacker you!)",
inventory_image = "unknown_block.png",
wield_image = "unknown_block.png",
drawtype = "airlike",
paramtype = "none",
sunlight_propagates = false,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true, -- A way to remove accidentally placed ignores
air_equivalent = true,
})
-- The hand (bare definition)
minetest.register_item(":", {
type = "none",
})
--
-- Default material types
--
function digprop_err()
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: The minetest.digprop_* functions are obsolete and need to be replaced by item groups.")
end
minetest.digprop_constanttime = digprop_err
minetest.digprop_stonelike = digprop_err
minetest.digprop_dirtlike = digprop_err
minetest.digprop_gravellike = digprop_err
minetest.digprop_woodlike = digprop_err
minetest.digprop_leaveslike = digprop_err
minetest.digprop_glasslike = digprop_err
--
-- Creative inventory
--
minetest.creative_inventory = {}
minetest.add_to_creative_inventory = function(itemstring)
table.insert(minetest.creative_inventory, itemstring)
end
--
-- Callback registration
--
local function make_registration()
local t = {}
local registerfunc = function(func) table.insert(t, func) end
return t, registerfunc
end
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
--
-- Set random seed
--
math.randomseed(os.time())
-- END
-- Load other files
dofile(minetest.get_modpath("__builtin").."/serialize.lua")
dofile(minetest.get_modpath("__builtin").."/misc_helpers.lua")
dofile(minetest.get_modpath("__builtin").."/item.lua")
dofile(minetest.get_modpath("__builtin").."/misc_register.lua")
dofile(minetest.get_modpath("__builtin").."/item_entity.lua")
dofile(minetest.get_modpath("__builtin").."/deprecated.lua")
dofile(minetest.get_modpath("__builtin").."/misc.lua")
dofile(minetest.get_modpath("__builtin").."/privileges.lua")
dofile(minetest.get_modpath("__builtin").."/auth.lua")
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")

353
builtin/chatcommands.lua Normal file
View File

@@ -0,0 +1,353 @@
-- Minetest: builtin/chatcommands.lua
--
-- Chat command handler
--
minetest.chatcommands = {}
function minetest.register_chatcommand(cmd, def)
def = def or {}
def.params = def.params or ""
def.description = def.description or ""
def.privs = def.privs or {}
minetest.chatcommands[cmd] = def
end
minetest.register_on_chat_message(function(name, message)
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
if not param then
param = ""
end
local cmd_def = minetest.chatcommands[cmd]
if cmd_def then
if not cmd_def.func then
-- This is a C++ command
return false
else
local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs)
if has_privs then
cmd_def.func(name, param)
else
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
end
return true -- handled chat message
end
end
return false
end)
--
-- Chat commands
--
-- Register C++ commands without functions
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)"})
minetest.register_chatcommand("status", {description = "print server status line"})
minetest.register_chatcommand("shutdown", {params = "", description = "shutdown server", privs = {server=true}})
minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}})
minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}})
minetest.register_chatcommand("ban", {params = "<name>", description = "ban IP of player", privs = {ban=true}})
minetest.register_chatcommand("unban", {params = "<name/ip>", description = "remove IP ban", privs = {ban=true}})
-- Register other commands
minetest.register_chatcommand("help", {
privs = {},
params = "(nothing)/all/privs/<cmd>",
description = "Get help for commands or list privileges",
func = function(name, param)
local format_help_line = function(cmd, def)
local msg = "/"..cmd
if def.params and def.params ~= "" then msg = msg .. " " .. def.params end
if def.description and def.description ~= "" then msg = msg .. ": " .. def.description end
return msg
end
if param == "" then
local msg = ""
cmds = {}
for cmd, def in pairs(minetest.chatcommands) do
if minetest.check_player_privs(name, def.privs) then
table.insert(cmds, cmd)
end
end
minetest.chat_send_player(name, "Available commands: "..table.concat(cmds, " "))
minetest.chat_send_player(name, "Use '/help <cmd>' to get more information, or '/help all' to list everything.")
elseif param == "all" then
minetest.chat_send_player(name, "Available commands:")
for cmd, def in pairs(minetest.chatcommands) do
if minetest.check_player_privs(name, def.privs) then
minetest.chat_send_player(name, format_help_line(cmd, def))
end
end
elseif param == "privs" then
minetest.chat_send_player(name, "Available privileges:")
for priv, def in pairs(minetest.registered_privileges) do
minetest.chat_send_player(name, priv..": "..def.description)
end
else
local cmd = param
def = minetest.chatcommands[cmd]
if not def then
minetest.chat_send_player(name, "Command not available: "..cmd)
else
minetest.chat_send_player(name, format_help_line(cmd, def))
end
end
end,
})
minetest.register_chatcommand("privs", {
params = "<name>",
description = "print out privileges of player",
func = function(name, param)
if param == "" then
param = name
else
--[[if not minetest.check_player_privs(name, {privs=true}) then
minetest.chat_send_player(name, "Privileges of "..param.." are hidden from you.")
return
end]]
end
minetest.chat_send_player(name, "Privileges of "..param..": "..minetest.privs_to_string(minetest.get_player_privs(param), ' '))
end,
})
minetest.register_chatcommand("grant", {
params = "<name> <privilege>|all",
description = "Give privilege to player",
privs = {},
func = function(name, param)
if not minetest.check_player_privs(name, {privs=true}) and
not minetest.check_player_privs(name, {basic_privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
if not grantname or not grantprivstr then
minetest.chat_send_player(name, "Invalid parameters (see /help grant)")
return
end
local grantprivs = minetest.string_to_privs(grantprivstr)
if grantprivstr == "all" then
grantprivs = minetest.registered_privileges
end
local privs = minetest.get_player_privs(grantname)
local privs_known = true
for priv, _ in pairs(grantprivs) do
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
if not minetest.registered_privileges[priv] then
minetest.chat_send_player(name, "Unknown privilege: "..priv)
privs_known = false
end
privs[priv] = true
end
if not privs_known then
return
end
minetest.set_player_privs(grantname, privs)
minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
if grantname ~= name then
minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
end
end,
})
minetest.register_chatcommand("revoke", {
params = "<name> <privilege>|all",
description = "Remove privilege from player",
privs = {},
func = function(name, param)
if not minetest.check_player_privs(name, {privs=true}) and
not minetest.check_player_privs(name, {basic_privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
if not revokename or not revokeprivstr then
minetest.chat_send_player(name, "Invalid parameters (see /help revoke)")
return
end
local revokeprivs = minetest.string_to_privs(revokeprivstr)
local privs = minetest.get_player_privs(revokename)
for priv, _ in pairs(revokeprivs) do
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
minetest.chat_send_player(name, "Your privileges are insufficient.")
return
end
end
if revokeprivstr == "all" then
privs = {}
else
for priv, _ in pairs(revokeprivs) do
privs[priv] = nil
end
end
minetest.set_player_privs(revokename, privs)
minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
if revokename ~= name then
minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
end
end,
})
minetest.register_chatcommand("setpassword", {
params = "<name> <password>",
description = "set given password",
privs = {password=true},
func = function(name, param)
if param == "" then
minetest.chat_send_player(name, "Password field required")
return
end
minetest.set_player_password(name, param)
minetest.chat_send_player(name, "Password set")
end,
})
minetest.register_chatcommand("clearpassword", {
params = "<name>",
description = "set empty password",
privs = {password=true},
func = function(name, param)
minetest.set_player_password(name, '')
minetest.chat_send_player(name, "Password cleared")
end,
})
minetest.register_chatcommand("auth_reload", {
params = "",
description = "reload authentication data",
privs = {server=true},
func = function(name, param)
local done = minetest.auth_reload()
if done then
minetest.chat_send_player(name, "Done.")
else
minetest.chat_send_player(name, "Failed.")
end
end,
})
minetest.register_chatcommand("teleport", {
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
description = "teleport to given position",
privs = {teleport=true},
func = function(name, param)
-- Returns (pos, true) if found, otherwise (pos, false)
local function find_free_position_near(pos)
local tries = {
{x=1,y=0,z=0},
{x=-1,y=0,z=0},
{x=0,y=0,z=1},
{x=0,y=0,z=-1},
}
for _, d in ipairs(tries) do
local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z}
local n = minetest.env:get_node(p)
if not minetest.registered_nodes[n.name].walkable then
return p, true
end
end
return pos, false
end
local teleportee = nil
local p = {}
p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
teleportee = minetest.env:get_player_by_name(name)
if teleportee and p.x and p.y and p.z then
minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
local teleportee = nil
local p = nil
local target_name = nil
target_name = string.match(param, "^([^ ]+)$")
teleportee = minetest.env:get_player_by_name(name)
if target_name then
local target = minetest.env:get_player_by_name(target_name)
if target then
p = target:getpos()
end
end
if teleportee and p then
p = find_free_position_near(p)
minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
if minetest.check_player_privs(name, {bring=true}) then
local teleportee = nil
local p = {}
local teleportee_name = nil
teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
if teleportee_name then
teleportee = minetest.env:get_player_by_name(teleportee_name)
end
if teleportee and p.x and p.y and p.z then
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
local teleportee = nil
local p = nil
local teleportee_name = nil
local target_name = nil
teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
if teleportee_name then
teleportee = minetest.env:get_player_by_name(teleportee_name)
end
if target_name then
local target = minetest.env:get_player_by_name(target_name)
if target then
p = target:getpos()
end
end
if teleportee and p then
p = find_free_position_near(p)
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
teleportee:setpos(p)
return
end
end
minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)")
return
end,
})
minetest.register_chatcommand("set", {
params = "[-n] <name> <value> | <name>",
description = "set or read server configuration setting",
privs = {server=true},
func = function(name, param)
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
if arg and arg == "-n" and setname and setvalue then
minetest.setting_set(setname, setvalue)
minetest.chat_send_player(name, setname.." = "..setvalue)
return
end
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
if setname and setvalue then
if not minetest.setting_get(setname) then
minetest.chat_send_player(name, "Failed. Use '/set -n <name> <value>' to create a new setting.")
return
end
minetest.setting_set(setname, setvalue)
minetest.chat_send_player(name, setname.." = "..setvalue)
return
end
local setname = string.match(param, "([^ ]+)")
if setname then
local setvalue = minetest.setting_get(setname)
if not setvalue then
setvalue = "<not set>"
end
minetest.chat_send_player(name, setname.." = "..setvalue)
return
end
minetest.chat_send_player(name, "Invalid parameters (see /help set)")
end,
})

19
builtin/deprecated.lua Normal file
View File

@@ -0,0 +1,19 @@
-- Minetest: builtin/deprecated.lua
--
-- Default material types
--
function digprop_err()
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: The minetest.digprop_* functions are obsolete and need to be replaced by item groups.")
end
minetest.digprop_constanttime = digprop_err
minetest.digprop_stonelike = digprop_err
minetest.digprop_dirtlike = digprop_err
minetest.digprop_gravellike = digprop_err
minetest.digprop_woodlike = digprop_err
minetest.digprop_leaveslike = digprop_err
minetest.digprop_glasslike = digprop_err

444
builtin/item.lua Normal file
View File

@@ -0,0 +1,444 @@
-- Minetest: builtin/item.lua
--
-- Item definition helpers
--
function minetest.inventorycube(img1, img2, img3)
img2 = img2 or img1
img3 = img3 or img1
return "[inventorycube"
.. "{" .. img1:gsub("%^", "&")
.. "{" .. img2:gsub("%^", "&")
.. "{" .. img3:gsub("%^", "&")
end
function minetest.get_pointed_thing_position(pointed_thing, above)
if pointed_thing.type == "node" then
if above then
-- The position where a node would be placed
return pointed_thing.above
else
-- The position where a node would be dug
return pointed_thing.under
end
elseif pointed_thing.type == "object" then
obj = pointed_thing.ref
if obj ~= nil then
return obj:getpos()
else
return nil
end
else
return nil
end
end
function minetest.dir_to_facedir(dir)
if math.abs(dir.x) > math.abs(dir.z) then
if dir.x < 0 then
return 3
else
return 1
end
else
if dir.z < 0 then
return 2
else
return 0
end
end
end
function minetest.dir_to_wallmounted(dir)
if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
if dir.y < 0 then
return 1
else
return 0
end
elseif math.abs(dir.x) > math.abs(dir.z) then
if dir.x < 0 then
return 3
else
return 2
end
else
if dir.z < 0 then
return 5
else
return 4
end
end
end
function minetest.get_node_drops(nodename, toolname)
local drop = ItemStack({name=nodename}):get_definition().drop
if drop == nil then
-- default drop
return {ItemStack({name=nodename})}
elseif type(drop) == "string" then
-- itemstring drop
return {ItemStack(drop)}
elseif drop.items == nil then
-- drop = {} to disable default drop
return {}
end
-- Extended drop table
local got_items = {}
local got_count = 0
local _, item, tool
for _, item in ipairs(drop.items) do
local good_rarity = true
local good_tool = true
if item.rarity ~= nil then
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
end
if item.tools ~= nil then
good_tool = false
for _, tool in ipairs(item.tools) do
if tool:sub(1, 1) == '~' then
good_tool = toolname:find(tool:sub(2)) ~= nil
else
good_tool = toolname == tool
end
if good_tool then
break
end
end
end
if good_rarity and good_tool then
got_count = got_count + 1
for _, add_item in ipairs(item.items) do
got_items[#got_items+1] = add_item
end
if drop.max_items ~= nil and got_count == drop.max_items then
break
end
end
end
return got_items
end
function minetest.item_place_node(itemstack, placer, pointed_thing)
local item = itemstack:peek_item()
local def = itemstack:get_definition()
if def.type == "node" and pointed_thing.type == "node" then
local pos = pointed_thing.above
local oldnode = minetest.env:get_node(pos)
local olddef = ItemStack({name=oldnode.name}):get_definition()
if not olddef.buildable_to then
minetest.log("info", placer:get_player_name() .. " tried to place"
.. " node in invalid position " .. minetest.pos_to_string(pos)
.. ", replacing " .. oldnode.name)
return
end
minetest.log("action", placer:get_player_name() .. " places node "
.. def.name .. " at " .. minetest.pos_to_string(pos))
local newnode = {name = def.name, param1 = 0, param2 = 0}
-- Calculate direction for wall mounted stuff like torches and signs
if def.paramtype2 == 'wallmounted' then
local under = pointed_thing.under
local above = pointed_thing.above
local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
newnode.param2 = minetest.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
elseif def.paramtype2 == 'facedir' then
local playerpos = placer:getpos()
local dir = {x = pos.x - playerpos.x, y = pos.y - playerpos.y, z = pos.z - playerpos.z}
newnode.param2 = minetest.dir_to_facedir(dir)
minetest.log("action", "facedir: " .. newnode.param2)
end
-- Add node and update
minetest.env:add_node(pos, newnode)
-- Run callback
if def.after_place_node then
def.after_place_node(pos, placer)
end
-- Run script hook (deprecated)
local _, callback
for _, callback in ipairs(minetest.registered_on_placenodes) do
callback(pos, newnode, placer)
end
itemstack:take_item()
end
return itemstack
end
function minetest.item_place_object(itemstack, placer, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
if pos ~= nil then
local item = itemstack:take_item()
minetest.env:add_item(pos, item)
end
return itemstack
end
function minetest.item_place(itemstack, placer, pointed_thing)
if itemstack:get_definition().type == "node" then
return minetest.item_place_node(itemstack, placer, pointed_thing)
else
return minetest.item_place_object(itemstack, placer, pointed_thing)
end
end
function minetest.item_drop(itemstack, dropper, pos)
if dropper.get_player_name then
local v = dropper:get_look_dir()
local p = {x=pos.x+v.x, y=pos.y+1.5+v.y, z=pos.z+v.z}
local obj = minetest.env:add_item(p, itemstack)
v.x = v.x*2
v.y = v.y*2 + 1
v.z = v.z*2
obj:setvelocity(v)
else
minetest.env:add_item(pos, itemstack)
end
return ""
end
function minetest.item_eat(hp_change, replace_with_item)
return function(itemstack, user, pointed_thing) -- closure
if itemstack:take_item() ~= nil then
user:set_hp(user:get_hp() + hp_change)
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
end
return itemstack
end
end
function minetest.node_punch(pos, node, puncher)
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_punchnodes) do
callback(pos, node, puncher)
end
end
function minetest.node_dig(pos, node, digger)
minetest.debug("node_dig")
local def = ItemStack({name=node.name}):get_definition()
if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then
minetest.debug("not diggable")
minetest.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. " which is not diggable "
.. minetest.pos_to_string(pos))
return
end
minetest.log('action', digger:get_player_name() .. " digs "
.. node.name .. " at " .. minetest.pos_to_string(pos))
if not minetest.setting_getbool("creative_mode") then
local wielded = digger:get_wielded_item()
local drops = minetest.get_node_drops(node.name, wielded:get_name())
-- Wear out tool
tp = wielded:get_tool_capabilities()
dp = minetest.get_dig_params(def.groups, tp)
wielded:add_wear(dp.wear)
digger:set_wielded_item(wielded)
-- Add dropped items to object's inventory
if digger:get_inventory() then
local _, dropped_item
for _, dropped_item in ipairs(drops) do
digger:get_inventory():add_item("main", dropped_item)
end
end
end
local oldnode = nil
local oldmetadata = nil
if def.after_dig_node then
oldnode = node;
oldmetadata = minetest.env:get_meta(pos):to_table()
end
-- Remove node and update
minetest.env:remove_node(pos)
-- Run callback
if def.after_dig_node then
def.after_dig_node(pos, oldnode, oldmetadata, digger)
end
-- Run script hook (deprecated)
local _, callback
for _, callback in ipairs(minetest.registered_on_dignodes) do
callback(pos, node, digger)
end
end
function minetest.node_metadata_inventory_move_allow_all(pos, from_list,
from_index, to_list, to_index, count, player)
minetest.log("verbose", "node_metadata_inventory_move_allow_all")
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
local from_stack = inv:get_stack(from_list, from_index)
local taken_items = from_stack:take_item(count)
inv:set_stack(from_list, from_index, from_stack)
local to_stack = inv:get_stack(to_list, to_index)
to_stack:add_item(taken_items)
inv:set_stack(to_list, to_index, to_stack)
end
function minetest.node_metadata_inventory_offer_allow_all(pos, listname, index, stack, player)
minetest.log("verbose", "node_metadata_inventory_offer_allow_all")
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
local the_stack = inv:get_stack(listname, index)
the_stack:add_item(stack)
inv:set_stack(listname, index, the_stack)
return ItemStack("")
end
function minetest.node_metadata_inventory_take_allow_all(pos, listname, index, count, player)
minetest.log("verbose", "node_metadata_inventory_take_allow_all")
local meta = minetest.env:get_meta(pos)
local inv = meta:get_inventory()
local the_stack = inv:get_stack(listname, index)
local taken_items = the_stack:take_item(count)
inv:set_stack(listname, index, the_stack)
return taken_items
end
-- This is used to allow mods to redefine minetest.item_place and so on
-- NOTE: This is not the preferred way. Preferred way is to provide enough
-- callbacks to not require redefining global functions. -celeron55
local function redef_wrapper(table, name)
return function(...)
return table[name](...)
end
end
--
-- Item definition defaults
--
minetest.nodedef_default = {
-- Item properties
type="node",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
usable = false,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
on_use = nil,
can_dig = nil,
on_punch = redef_wrapper(minetest, 'node_punch'), -- minetest.node_punch
on_dig = redef_wrapper(minetest, 'node_dig'), -- minetest.node_dig
on_receive_fields = nil,
on_metadata_inventory_move = minetest.node_metadata_inventory_move_allow_all,
on_metadata_inventory_offer = minetest.node_metadata_inventory_offer_allow_all,
on_metadata_inventory_take = minetest.node_metadata_inventory_take_allow_all,
-- Node properties
drawtype = "normal",
visual_scale = 1.0,
tile_images = {""},
special_materials = {
{image="", backface_culling=true},
{image="", backface_culling=true},
},
alpha = 255,
post_effect_color = {a=0, r=0, g=0, b=0},
paramtype = "none",
paramtype2 = "none",
is_ground_content = false,
sunlight_propagates = false,
walkable = true,
pointable = true,
diggable = true,
climbable = false,
buildable_to = false,
liquidtype = "none",
liquid_alternative_flowing = "",
liquid_alternative_source = "",
liquid_viscosity = 0,
light_source = 0,
damage_per_second = 0,
selection_box = {type="regular"},
legacy_facedir_simple = false,
legacy_wallmounted = false,
}
minetest.craftitemdef_default = {
type="craft",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
on_use = nil,
}
minetest.tooldef_default = {
type="tool",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 1,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
on_use = nil,
}
minetest.noneitemdef_default = { -- This is used for the hand and unknown items
type="none",
-- name intentionally not defined here
description = "",
groups = {},
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
liquids_pointable = false,
tool_capabilities = nil,
-- Interaction callbacks
on_place = nil,
on_drop = nil,
on_use = nil,
}

103
builtin/item_entity.lua Normal file
View File

@@ -0,0 +1,103 @@
-- Minetest: builtin/item_entity.lua
function minetest.spawn_item(pos, item)
-- Take item in any format
local stack = ItemStack(item)
local obj = minetest.env:add_entity(pos, "__builtin:item")
obj:get_luaentity():set_item(stack:to_string())
return obj
end
minetest.register_entity("__builtin:item", {
initial_properties = {
hp_max = 1,
physical = true,
collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
visual = "sprite",
visual_size = {x=0.5, y=0.5},
textures = {""},
spritediv = {x=1, y=1},
initial_sprite_basepos = {x=0, y=0},
is_visible = false,
},
itemstring = '',
physical_state = true,
set_item = function(self, itemstring)
self.itemstring = itemstring
local stack = ItemStack(itemstring)
local itemtable = stack:to_table()
local itemname = nil
if itemtable then
itemname = stack:to_table().name
end
local item_texture = nil
local item_type = ""
if minetest.registered_items[itemname] then
item_texture = minetest.registered_items[itemname].inventory_image
item_type = minetest.registered_items[itemname].type
end
prop = {
is_visible = true,
visual = "sprite",
textures = {"unknown_item.png"}
}
if item_texture and item_texture ~= "" then
prop.visual = "sprite"
prop.textures = {item_texture}
prop.visual_size = {x=0.50, y=0.50}
else
prop.visual = "wielditem"
prop.textures = {itemname}
prop.visual_size = {x=0.20, y=0.20}
prop.automatic_rotate = math.pi * 0.25
end
self.object:set_properties(prop)
end,
get_staticdata = function(self)
return self.itemstring
end,
on_activate = function(self, staticdata)
self.itemstring = staticdata
self.object:set_armor_groups({immortal=1})
self.object:setvelocity({x=0, y=2, z=0})
self.object:setacceleration({x=0, y=-10, z=0})
self:set_item(self.itemstring)
end,
on_step = function(self, dtime)
local p = self.object:getpos()
p.y = p.y - 0.3
local nn = minetest.env:get_node(p).name
if minetest.registered_nodes[nn].walkable then
if self.physical_state then
self.object:setvelocity({x=0,y=0,z=0})
self.object:setacceleration({x=0, y=0, z=0})
self.physical_state = false
self.object:set_properties({
physical = false
})
end
else
if not self.physical_state then
self.object:setvelocity({x=0,y=0,z=0})
self.object:setacceleration({x=0, y=-10, z=0})
self.physical_state = true
self.object:set_properties({
physical = true
})
end
end
end,
on_punch = function(self, hitter)
if self.itemstring ~= '' then
hitter:get_inventory():add_item("main", self.itemstring)
end
self.object:remove()
end,
})

101
builtin/misc.lua Normal file
View File

@@ -0,0 +1,101 @@
-- Minetest: builtin/misc.lua
--
-- Misc. API functions
--
minetest.timers_to_add = {}
minetest.timers = {}
minetest.register_globalstep(function(dtime)
for _, timer in ipairs(minetest.timers_to_add) do
table.insert(minetest.timers, timer)
end
minetest.timers_to_add = {}
for index, timer in ipairs(minetest.timers) do
timer.time = timer.time - dtime
if timer.time <= 0 then
timer.func(timer.param)
table.remove(minetest.timers,index)
end
end
end)
function minetest.after(time, func, param)
table.insert(minetest.timers_to_add, {time=time, func=func, param=param})
end
function minetest.check_player_privs(name, privs)
local player_privs = minetest.get_player_privs(name)
local missing_privileges = {}
for priv, val in pairs(privs) do
if val then
if not player_privs[priv] then
table.insert(missing_privileges, priv)
end
end
end
if #missing_privileges > 0 then
return false, missing_privileges
end
return true, ""
end
function minetest.get_connected_players()
-- This could be optimized a bit, but leave that for later
local list = {}
for _, obj in pairs(minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 1000000)) do
if obj:is_player() then
table.insert(list, obj)
end
end
return list
end
function minetest.hash_node_position(pos)
return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
end
function minetest.get_item_group(name, group)
if not minetest.registered_items[name] or not
minetest.registered_items[name].groups[group] then
return 0
end
return minetest.registered_items[name].groups[group]
end
function minetest.get_node_group(name, group)
return minetest.get_item_group(name, group)
end
function minetest.string_to_pos(value)
local p = {}
p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
if p.x and p.y and p.z then
p.x = tonumber(p.x)
p.y = tonumber(p.y)
p.z = tonumber(p.z)
return p
end
local p = {}
p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
if p.x and p.y and p.z then
p.x = tonumber(p.x)
p.y = tonumber(p.y)
p.z = tonumber(p.z)
return p
end
return nil
end
assert(minetest.string_to_pos("10.0, 5, -2").x == 10)
assert(minetest.string_to_pos("( 10.0, 5, -2)").z == -2)
assert(minetest.string_to_pos("asd, 5, -2)") == nil)
function minetest.setting_get_pos(name)
local value = minetest.setting_get(name)
if not value then
return nil
end
return minetest.string_to_pos(value)
end

94
builtin/misc_helpers.lua Normal file
View File

@@ -0,0 +1,94 @@
-- Minetest: builtin/misc_helpers.lua
function basic_dump2(o)
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
elseif type(o) == "boolean" then
return tostring(o)
elseif type(o) == "function" then
return "<function>"
elseif type(o) == "userdata" then
return "<userdata>"
elseif type(o) == "nil" then
return "nil"
else
error("cannot dump a " .. type(o))
return nil
end
end
function dump2(o, name, dumped)
name = name or "_"
dumped = dumped or {}
io.write(name, " = ")
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
or type(o) == "function" or type(o) == "nil"
or type(o) == "userdata" then
io.write(basic_dump2(o), "\n")
elseif type(o) == "table" then
if dumped[o] then
io.write(dumped[o], "\n")
else
dumped[o] = name
io.write("{}\n") -- new table
for k,v in pairs(o) do
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
dump2(v, fieldname, dumped)
end
end
else
error("cannot dump a " .. type(o))
return nil
end
end
function dump(o, dumped)
dumped = dumped or {}
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
elseif type(o) == "table" then
if dumped[o] then
return "<circular reference>"
end
dumped[o] = true
local t = {}
for k,v in pairs(o) do
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
end
return "{" .. table.concat(t, ", ") .. "}"
elseif type(o) == "boolean" then
return tostring(o)
elseif type(o) == "function" then
return "<function>"
elseif type(o) == "userdata" then
return "<userdata>"
elseif type(o) == "nil" then
return "nil"
else
error("cannot dump a " .. type(o))
return nil
end
end
function string:split(sep)
local sep, fields = sep or ",", {}
local pattern = string.format("([^%s]+)", sep)
self:gsub(pattern, function(c) fields[#fields+1] = c end)
return fields
end
function string:trim()
return (self:gsub("^%s*(.-)%s*$", "%1"))
end
assert(string.trim("\n \t\tfoo bar\t ") == "foo bar")
function minetest.pos_to_string(pos)
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
end

324
builtin/misc_register.lua Normal file
View File

@@ -0,0 +1,324 @@
-- Minetest: builtin/misc_register.lua
--
-- Make raw registration functions inaccessible to anyone except this file
--
local register_item_raw = minetest.register_item_raw
minetest.register_item_raw = nil
local register_alias_raw = minetest.register_alias_raw
minetest.register_item_raw = nil
--
-- Item / entity / ABM registration functions
--
minetest.registered_abms = {}
minetest.registered_entities = {}
minetest.registered_items = {}
minetest.registered_nodes = {}
minetest.registered_craftitems = {}
minetest.registered_tools = {}
minetest.registered_aliases = {}
-- For tables that are indexed by item name:
-- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
local function set_alias_metatable(table)
setmetatable(table, {
__index = function(name)
return rawget(table, minetest.registered_aliases[name])
end
})
end
set_alias_metatable(minetest.registered_items)
set_alias_metatable(minetest.registered_nodes)
set_alias_metatable(minetest.registered_craftitems)
set_alias_metatable(minetest.registered_tools)
-- These item names may not be used because they would interfere
-- with legacy itemstrings
local forbidden_item_names = {
MaterialItem = true,
MaterialItem2 = true,
MaterialItem3 = true,
NodeItem = true,
node = true,
CraftItem = true,
craft = true,
MBOItem = true,
ToolItem = true,
tool = true,
}
local function check_modname_prefix(name)
if name:sub(1,1) == ":" then
-- Escape the modname prefix enforcement mechanism
return name:sub(2)
else
-- Modname prefix enforcement
local expected_prefix = minetest.get_current_modname() .. ":"
if name:sub(1, #expected_prefix) ~= expected_prefix then
error("Name " .. name .. " does not follow naming conventions: " ..
"\"modname:\" or \":\" prefix required")
end
local subname = name:sub(#expected_prefix+1)
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
error("Name " .. name .. " does not follow naming conventions: " ..
"contains unallowed characters")
end
return name
end
end
function minetest.register_abm(spec)
-- Add to minetest.registered_abms
minetest.registered_abms[#minetest.registered_abms+1] = spec
end
function minetest.register_entity(name, prototype)
-- Check name
if name == nil then
error("Unable to register entity: Name is nil")
end
name = check_modname_prefix(tostring(name))
prototype.name = name
prototype.__index = prototype -- so that it can be used as a metatable
-- Add to minetest.registered_entities
minetest.registered_entities[name] = prototype
end
function minetest.register_item(name, itemdef)
-- Check name
if name == nil then
error("Unable to register item: Name is nil")
end
name = check_modname_prefix(tostring(name))
if forbidden_item_names[name] then
error("Unable to register item: Name is forbidden: " .. name)
end
itemdef.name = name
-- Apply defaults and add to registered_* table
if itemdef.type == "node" then
setmetatable(itemdef, {__index = minetest.nodedef_default})
minetest.registered_nodes[itemdef.name] = itemdef
elseif itemdef.type == "craft" then
setmetatable(itemdef, {__index = minetest.craftitemdef_default})
minetest.registered_craftitems[itemdef.name] = itemdef
elseif itemdef.type == "tool" then
setmetatable(itemdef, {__index = minetest.tooldef_default})
minetest.registered_tools[itemdef.name] = itemdef
elseif itemdef.type == "none" then
setmetatable(itemdef, {__index = minetest.noneitemdef_default})
else
error("Unable to register item: Type is invalid: " .. dump(itemdef))
end
-- Flowing liquid uses param2
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
itemdef.paramtype2 = "flowingliquid"
end
-- BEGIN Legacy stuff
if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
minetest.register_craft({
type="cooking",
output=itemdef.cookresult_itemstring,
recipe=itemdef.name,
cooktime=itemdef.furnace_cooktime
})
end
if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
minetest.register_craft({
type="fuel",
recipe=itemdef.name,
burntime=itemdef.furnace_burntime
})
end
-- END Legacy stuff
-- Disable all further modifications
getmetatable(itemdef).__newindex = {}
--minetest.log("Registering item: " .. itemdef.name)
minetest.registered_items[itemdef.name] = itemdef
minetest.registered_aliases[itemdef.name] = nil
register_item_raw(itemdef)
end
function minetest.register_node(name, nodedef)
nodedef.type = "node"
minetest.register_item(name, nodedef)
end
function minetest.register_craftitem(name, craftitemdef)
craftitemdef.type = "craft"
-- BEGIN Legacy stuff
if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
craftitemdef.inventory_image = craftitemdef.image
end
-- END Legacy stuff
minetest.register_item(name, craftitemdef)
end
function minetest.register_tool(name, tooldef)
tooldef.type = "tool"
tooldef.stack_max = 1
-- BEGIN Legacy stuff
if tooldef.inventory_image == nil and tooldef.image ~= nil then
tooldef.inventory_image = tooldef.image
end
if tooldef.tool_capabilities == nil and
(tooldef.full_punch_interval ~= nil or
tooldef.basetime ~= nil or
tooldef.dt_weight ~= nil or
tooldef.dt_crackiness ~= nil or
tooldef.dt_crumbliness ~= nil or
tooldef.dt_cuttability ~= nil or
tooldef.basedurability ~= nil or
tooldef.dd_weight ~= nil or
tooldef.dd_crackiness ~= nil or
tooldef.dd_crumbliness ~= nil or
tooldef.dd_cuttability ~= nil) then
tooldef.tool_capabilities = {
full_punch_interval = tooldef.full_punch_interval,
basetime = tooldef.basetime,
dt_weight = tooldef.dt_weight,
dt_crackiness = tooldef.dt_crackiness,
dt_crumbliness = tooldef.dt_crumbliness,
dt_cuttability = tooldef.dt_cuttability,
basedurability = tooldef.basedurability,
dd_weight = tooldef.dd_weight,
dd_crackiness = tooldef.dd_crackiness,
dd_crumbliness = tooldef.dd_crumbliness,
dd_cuttability = tooldef.dd_cuttability,
}
end
-- END Legacy stuff
minetest.register_item(name, tooldef)
end
function minetest.register_alias(name, convert_to)
if forbidden_item_names[name] then
error("Unable to register alias: Name is forbidden: " .. name)
end
if minetest.registered_items[name] ~= nil then
minetest.log("WARNING: Not registering alias, item with same name" ..
" is already defined: " .. name .. " -> " .. convert_to)
else
--minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
minetest.registered_aliases[name] = convert_to
register_alias_raw(name, convert_to)
end
end
-- Alias the forbidden item names to "" so they can't be
-- created via itemstrings (e.g. /give)
local name
for name in pairs(forbidden_item_names) do
minetest.registered_aliases[name] = ""
register_alias_raw(name, "")
end
-- Deprecated:
-- Aliases for minetest.register_alias (how ironic...)
--minetest.alias_node = minetest.register_alias
--minetest.alias_tool = minetest.register_alias
--minetest.alias_craftitem = minetest.register_alias
--
-- Built-in node definitions. Also defined in C.
--
minetest.register_item(":unknown", {
type = "none",
description = "Unknown Item",
inventory_image = "unknown_item.png",
on_place = minetest.item_place,
on_drop = minetest.item_drop,
})
minetest.register_node(":air", {
description = "Air (you hacker you!)",
inventory_image = "unknown_block.png",
wield_image = "unknown_block.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
air_equivalent = true,
})
minetest.register_node(":ignore", {
description = "Ignore (you hacker you!)",
inventory_image = "unknown_block.png",
wield_image = "unknown_block.png",
drawtype = "airlike",
paramtype = "none",
sunlight_propagates = false,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true, -- A way to remove accidentally placed ignores
air_equivalent = true,
})
-- The hand (bare definition)
minetest.register_item(":", {
type = "none",
})
--
-- Creative inventory
--
minetest.creative_inventory = {}
minetest.add_to_creative_inventory = function(itemstring)
table.insert(minetest.creative_inventory, itemstring)
end
--
-- Callback registration
--
local function make_registration()
local t = {}
local registerfunc = function(func) table.insert(t, func) end
return t, registerfunc
end
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_registration()
minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()
minetest.registered_on_placenodes = {}
minetest.register_on_placenode = function(callback)
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: minetest.register_on_placenode is deprecated. Use on_construct or after_place_node in node definition instead.")
table.insert(minetest.registered_on_placenodes, callback)
end
minetest.registered_on_dignodes = {}
minetest.register_on_dignode = function(callback)
minetest.log("info", debug.traceback())
minetest.log("info", "WARNING: minetest.register_on_dignode is deprecated. Use on_destruct or after_dig_node in node definition instead.")
table.insert(minetest.registered_on_dignodes, callback)
end

48
builtin/privileges.lua Normal file
View File

@@ -0,0 +1,48 @@
-- Minetest: builtin/privileges.lua
--
-- Privileges
--
minetest.registered_privileges = {}
function minetest.register_privilege(name, param)
local function fill_defaults(def)
if def.give_to_singleplayer == nil then
def.give_to_singleplayer = true
end
if def.description == nil then
def.description = "(no description)"
end
end
local def = {}
if type(param) == "table" then
def = param
else
def = {description = param}
end
fill_defaults(def)
minetest.registered_privileges[name] = def
end
minetest.register_privilege("interact", "Can interact with things and modify the world")
minetest.register_privilege("teleport", "Can use /teleport command")
minetest.register_privilege("bring", "Can teleport other players")
minetest.register_privilege("settime", "Can use /time")
minetest.register_privilege("privs", "Can modify privileges")
minetest.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
minetest.register_privilege("server", "Can do server maintenance stuff")
minetest.register_privilege("shout", "Can speak in chat")
minetest.register_privilege("ban", "Can ban and unban players")
minetest.register_privilege("give", "Can use /give and /giveme")
minetest.register_privilege("password", "Can use /setpassword and /clearpassword")
minetest.register_privilege("fly", {
description = "Can fly using the free_move mode",
give_to_singleplayer = false,
})
minetest.register_privilege("fast", {
description = "Can walk fast using the fast_move mode",
give_to_singleplayer = false,
})

207
builtin/serialize.lua Normal file
View File

@@ -0,0 +1,207 @@
-- Minetest: builtin/serialize.lua
-- https://github.com/fab13n/metalua/blob/no-dll/src/lib/serialize.lua
-- Copyright (c) 2006-2997 Fabien Fleutot <metalua@gmail.com>
-- License: MIT
--------------------------------------------------------------------------------
-- Serialize an object into a source code string. This string, when passed as
-- an argument to deserialize(), returns an object structurally identical
-- to the original one. The following are currently supported:
-- * strings, numbers, booleans, nil
-- * tables thereof. Tables can have shared part, but can't be recursive yet.
-- Caveat: metatables and environments aren't saved.
--------------------------------------------------------------------------------
local no_identity = { number=1, boolean=1, string=1, ['nil']=1 }
function minetest.serialize(x)
local gensym_max = 0 -- index of the gensym() symbol generator
local seen_once = { } -- element->true set of elements seen exactly once in the table
local multiple = { } -- element->varname set of elements seen more than once
local nested = { } -- transient, set of elements currently being traversed
local nest_points = { }
local nest_patches = { }
local function gensym()
gensym_max = gensym_max + 1 ; return gensym_max
end
-----------------------------------------------------------------------------
-- nest_points are places where a table appears within itself, directly or not.
-- for instance, all of these chunks create nest points in table x:
-- "x = { }; x[x] = 1", "x = { }; x[1] = x", "x = { }; x[1] = { y = { x } }".
-- To handle those, two tables are created by mark_nest_point:
-- * nest_points [parent] associates all keys and values in table parent which
-- create a nest_point with boolean `true'
-- * nest_patches contain a list of { parent, key, value } tuples creating
-- a nest point. They're all dumped after all the other table operations
-- have been performed.
--
-- mark_nest_point (p, k, v) fills tables nest_points and nest_patches with
-- informations required to remember that key/value (k,v) create a nest point
-- in table parent. It also marks `parent' as occuring multiple times, since
-- several references to it will be required in order to patch the nest
-- points.
-----------------------------------------------------------------------------
local function mark_nest_point (parent, k, v)
local nk, nv = nested[k], nested[v]
assert (not nk or seen_once[k] or multiple[k])
assert (not nv or seen_once[v] or multiple[v])
local mode = (nk and nv and "kv") or (nk and "k") or ("v")
local parent_np = nest_points [parent]
local pair = { k, v }
if not parent_np then parent_np = { }; nest_points [parent] = parent_np end
parent_np [k], parent_np [v] = nk, nv
table.insert (nest_patches, { parent, k, v })
seen_once [parent], multiple [parent] = nil, true
end
-----------------------------------------------------------------------------
-- First pass, list the tables and functions which appear more than once in x
-----------------------------------------------------------------------------
local function mark_multiple_occurences (x)
if no_identity [type(x)] then return end
if seen_once [x] then seen_once [x], multiple [x] = nil, true
elseif multiple [x] then -- pass
else seen_once [x] = true end
if type (x) == 'table' then
nested [x] = true
for k, v in pairs (x) do
if nested[k] or nested[v] then mark_nest_point (x, k, v) else
mark_multiple_occurences (k)
mark_multiple_occurences (v)
end
end
nested [x] = nil
end
end
local dumped = { } -- multiply occuring values already dumped in localdefs
local localdefs = { } -- already dumped local definitions as source code lines
-- mutually recursive functions:
local dump_val, dump_or_ref_val
--------------------------------------------------------------------
-- if x occurs multiple times, dump the local var rather than the
-- value. If it's the first time it's dumped, also dump the content
-- in localdefs.
--------------------------------------------------------------------
function dump_or_ref_val (x)
if nested[x] then return 'false' end -- placeholder for recursive reference
if not multiple[x] then return dump_val (x) end
local var = dumped [x]
if var then return "_[" .. var .. "]" end -- already referenced
local val = dump_val(x) -- first occurence, create and register reference
var = gensym()
table.insert(localdefs, "_["..var.."]="..val)
dumped [x] = var
return "_[" .. var .. "]"
end
-----------------------------------------------------------------------------
-- Second pass, dump the object; subparts occuring multiple times are dumped
-- in local variables which can be referenced multiple times;
-- care is taken to dump locla vars in asensible order.
-----------------------------------------------------------------------------
function dump_val(x)
local t = type(x)
if x==nil then return 'nil'
elseif t=="number" then return tostring(x)
elseif t=="string" then return string.format("%q", x)
elseif t=="boolean" then return x and "true" or "false"
elseif t=="table" then
local acc = { }
local idx_dumped = { }
local np = nest_points [x]
for i, v in ipairs(x) do
if np and np[v] then
table.insert (acc, 'false') -- placeholder
else
table.insert (acc, dump_or_ref_val(v))
end
idx_dumped[i] = true
end
for k, v in pairs(x) do
if np and (np[k] or np[v]) then
--check_multiple(k); check_multiple(v) -- force dumps in localdefs
elseif not idx_dumped[k] then
table.insert (acc, "[" .. dump_or_ref_val(k) .. "] = " .. dump_or_ref_val(v))
end
end
return "{ "..table.concat(acc,", ").." }"
else
error ("Can't serialize data of type "..t)
end
end
local function dump_nest_patches()
for _, entry in ipairs(nest_patches) do
local p, k, v = unpack (entry)
assert (multiple[p])
local set = dump_or_ref_val (p) .. "[" .. dump_or_ref_val (k) .. "] = " ..
dump_or_ref_val (v) .. " -- rec "
table.insert (localdefs, set)
end
end
mark_multiple_occurences (x)
local toplevel = dump_or_ref_val (x)
dump_nest_patches()
if next (localdefs) then
return "local _={ }\n" ..
table.concat (localdefs, "\n") ..
"\nreturn " .. toplevel
else
return "return " .. toplevel
end
end
-- Deserialization.
-- http://stackoverflow.com/questions/5958818/loading-serialized-data-into-a-table
--
local function stringtotable(sdata)
if sdata:byte(1) == 27 then return nil, "binary bytecode prohibited" end
local f, message = assert(loadstring(sdata))
if not f then return nil, message end
setfenv(f, table)
return f()
end
function minetest.deserialize(sdata)
local table = {}
local okay,results = pcall(stringtotable, sdata)
if okay then
return results
end
print('error:'.. results)
return nil
end
-- Run some unit tests
local function unit_test()
function unitTest(name, success)
if not success then
error(name .. ': failed')
end
end
unittest_input = {cat={sound="nyan", speed=400}, dog={sound="woof"}}
unittest_output = minetest.deserialize(minetest.serialize(unittest_input))
unitTest("test 1a", unittest_input.cat.sound == unittest_output.cat.sound)
unitTest("test 1b", unittest_input.cat.speed == unittest_output.cat.speed)
unitTest("test 1c", unittest_input.dog.sound == unittest_output.dog.sound)
unittest_input = {escapechars="\n\r\t\v\\\"\'\[\]", noneuropean="θשׁ٩∂"}
unittest_output = minetest.deserialize(minetest.serialize(unittest_input))
unitTest("test 3a", unittest_input.escapechars == unittest_output.escapechars)
unitTest("test 3b", unittest_input.noneuropean == unittest_output.noneuropean)
end
unit_test() -- Run it
unit_test = nil -- Hide it

33
builtin/static_spawn.lua Normal file
View File

@@ -0,0 +1,33 @@
-- Minetest: builtin/static_spawn.lua
local function warn_invalid_static_spawnpoint()
if minetest.setting_get("static_spawnpoint") and
not minetest.setting_get_pos("static_spawnpoint") then
minetest.log('error', "The static_spawnpoint setting is invalid: \""..
minetest.setting_get("static_spawnpoint").."\"")
end
end
warn_invalid_static_spawnpoint()
local function put_player_in_spawn(obj)
warn_invalid_static_spawnpoint()
local static_spawnpoint = minetest.setting_get_pos("static_spawnpoint")
if not static_spawnpoint then
return false
end
minetest.log('action', "Moving "..obj:get_player_name()..
" to static spawnpoint at "..
minetest.pos_to_string(static_spawnpoint))
obj:setpos(static_spawnpoint)
return true
end
minetest.register_on_newplayer(function(obj)
put_player_in_spawn(obj)
end)
minetest.register_on_respawnplayer(function(obj)
return put_player_in_spawn(obj)
end)

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,9 @@ LIGHT_MAX = 14
-- Definitions made by this mod that other mods can use too
default = {}
-- Load other files
dofile(minetest.get_modpath("default").."/mapgen.lua")
--
-- Tool definition
--
@@ -24,10 +27,10 @@ minetest.register_item(":", {
full_punch_interval = 1.0,
max_drop_level = 0,
groupcaps = {
fleshy = {times={[2]=2.00, [3]=1.00}, maxwear=0, maxlevel=1},
crumbly = {times={[3]=0.70}, maxwear=0, maxlevel=1},
snappy = {times={[3]=0.40}, maxwear=0, maxlevel=1},
oddly_breakable_by_hand = {times={[1]=3.50,[2]=2.00,[3]=0.70}, maxwear=0, maxlevel=3},
fleshy = {times={[2]=2.00, [3]=1.00}, uses=0, maxlevel=1},
crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1},
snappy = {times={[3]=0.40}, uses=0, maxlevel=1},
oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=1.40}, uses=0, maxlevel=3},
}
}
})
@@ -38,7 +41,7 @@ minetest.register_tool("default:pick_wood", {
tool_capabilities = {
max_drop_level=0,
groupcaps={
cracky={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1}
cracky={times={[2]=2.00, [3]=1.20}, uses=10, maxlevel=1}
}
},
})
@@ -48,7 +51,7 @@ minetest.register_tool("default:pick_stone", {
tool_capabilities = {
max_drop_level=0,
groupcaps={
cracky={times={[1]=1.50, [2]=0.80, [3]=0.60}, maxwear=0.05, maxlevel=1}
cracky={times={[1]=2.00, [2]=1.20, [3]=0.80}, uses=20, maxlevel=1}
}
},
})
@@ -58,7 +61,7 @@ minetest.register_tool("default:pick_steel", {
tool_capabilities = {
max_drop_level=1,
groupcaps={
cracky={times={[1]=1.00, [2]=0.60, [3]=0.40}, maxwear=0.1, maxlevel=2}
cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2}
}
},
})
@@ -69,9 +72,9 @@ minetest.register_tool("default:pick_mese", {
full_punch_interval = 1.0,
max_drop_level=3,
groupcaps={
cracky={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3},
crumbly={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3},
snappy={times={[1]=0.2, [2]=0.2, [3]=0.2}, maxwear=0.05, maxlevel=3}
cracky={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3}
}
},
})
@@ -81,7 +84,7 @@ minetest.register_tool("default:shovel_wood", {
tool_capabilities = {
max_drop_level=0,
groupcaps={
crumbly={times={[1]=1.50, [2]=0.80, [3]=0.50}, maxwear=0.1, maxlevel=1}
crumbly={times={[1]=2.00, [2]=0.80, [3]=0.50}, uses=10, maxlevel=1}
}
},
})
@@ -91,7 +94,7 @@ minetest.register_tool("default:shovel_stone", {
tool_capabilities = {
max_drop_level=0,
groupcaps={
crumbly={times={[1]=0.80, [2]=0.50, [3]=0.30}, maxwear=0.05, maxlevel=1}
crumbly={times={[1]=1.20, [2]=0.50, [3]=0.30}, uses=20, maxlevel=1}
}
},
})
@@ -101,7 +104,7 @@ minetest.register_tool("default:shovel_steel", {
tool_capabilities = {
max_drop_level=1,
groupcaps={
crumbly={times={[1]=0.50, [2]=0.35, [3]=0.30}, maxwear=0.1, maxlevel=2}
crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=10, maxlevel=2}
}
},
})
@@ -111,8 +114,8 @@ minetest.register_tool("default:axe_wood", {
tool_capabilities = {
max_drop_level=0,
groupcaps={
choppy={times={[2]=1.40, [3]=0.80}, maxwear=0.1, maxlevel=1},
fleshy={times={[2]=1.50, [3]=0.80}, maxwear=0.1, maxlevel=1}
choppy={times={[2]=1.40, [3]=0.80}, uses=10, maxlevel=1},
fleshy={times={[2]=1.50, [3]=0.80}, uses=10, maxlevel=1}
}
},
})
@@ -122,8 +125,8 @@ minetest.register_tool("default:axe_stone", {
tool_capabilities = {
max_drop_level=0,
groupcaps={
choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, maxwear=0.05, maxlevel=1},
fleshy={times={[2]=1.30, [3]=0.70}, maxwear=0.05, maxlevel=1}
choppy={times={[1]=1.50, [2]=1.00, [3]=0.60}, uses=20, maxlevel=1},
fleshy={times={[2]=1.30, [3]=0.70}, uses=20, maxlevel=1}
}
},
})
@@ -133,8 +136,8 @@ minetest.register_tool("default:axe_steel", {
tool_capabilities = {
max_drop_level=1,
groupcaps={
choppy={times={[1]=1.00, [2]=0.80, [3]=0.50}, maxwear=0.1, maxlevel=2},
fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.03, maxlevel=1}
choppy={times={[1]=2.00, [2]=1.60, [3]=1.00}, uses=10, maxlevel=2},
fleshy={times={[2]=1.10, [3]=0.60}, uses=40, maxlevel=1}
}
},
})
@@ -145,9 +148,9 @@ minetest.register_tool("default:sword_wood", {
full_punch_interval = 1.0,
max_drop_level=0,
groupcaps={
fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.1, maxlevel=1},
snappy={times={[2]=1.00, [3]=0.50}, maxwear=0.1, maxlevel=1},
choppy={times={[3]=1.00}, maxwear=0.05, maxlevel=0}
fleshy={times={[2]=1.10, [3]=0.60}, uses=10, maxlevel=1},
snappy={times={[2]=1.00, [3]=0.50}, uses=10, maxlevel=1},
choppy={times={[3]=1.00}, uses=20, maxlevel=0}
}
}
})
@@ -158,9 +161,9 @@ minetest.register_tool("default:sword_stone", {
full_punch_interval = 1.0,
max_drop_level=0,
groupcaps={
fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
snappy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0}
fleshy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
snappy={times={[2]=0.80, [3]=0.40}, uses=20, maxlevel=1},
choppy={times={[3]=0.90}, uses=20, maxlevel=0}
}
}
})
@@ -171,9 +174,9 @@ minetest.register_tool("default:sword_steel", {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
fleshy={times={[1]=1.00, [2]=0.40, [3]=0.20}, maxwear=0.1, maxlevel=2},
snappy={times={[2]=0.70, [3]=0.30}, maxwear=0.03, maxlevel=1},
choppy={times={[3]=0.70}, maxwear=0.03, maxlevel=0}
fleshy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=10, maxlevel=2},
snappy={times={[2]=0.70, [3]=0.30}, uses=40, maxlevel=1},
choppy={times={[3]=0.70}, uses=40, maxlevel=0}
}
}
})
@@ -962,7 +965,7 @@ minetest.register_node("default:mese", {
description = "Mese",
tile_images = {"default_mese.png"},
is_ground_content = true,
groups = {cracky=1},
groups = {cracky=1,level=2},
sounds = default.node_sound_defaults(),
})
@@ -1109,6 +1112,21 @@ minetest.register_node("default:sign_wall", {
groups = {choppy=2,dig_immediate=2},
legacy_wallmounted = true,
sounds = default.node_sound_defaults(),
on_construct = function(pos)
--local n = minetest.env:get_node(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", "hack:sign_text_input")
meta:set_string("infotext", "\"\"")
end,
on_receive_fields = function(pos, formname, fields, sender)
--print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
local meta = minetest.env:get_meta(pos)
fields.text = fields.text or ""
print((sender:get_player_name() or "").." wrote \""..fields.text..
"\" to sign at "..minetest.pos_to_string(pos))
meta:set_string("text", fields.text)
meta:set_string("infotext", '"'..fields.text..'"')
end,
})
minetest.register_node("default:chest", {
@@ -1116,32 +1134,312 @@ minetest.register_node("default:chest", {
tile_images = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
"default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
paramtype2 = "facedir",
metadata_name = "chest",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"list[current_name;main;0,0;8,4;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", "Chest")
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
on_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
minetest.log("action", player:get_player_name()..
" moves stuff in chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_move_allow_all(
pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_offer = function(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name()..
" moves stuff to chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_offer_allow_all(
pos, listname, index, stack, player)
end,
on_metadata_inventory_take = function(pos, listname, index, count, player)
minetest.log("action", player:get_player_name()..
" takes stuff from chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_take_allow_all(
pos, listname, index, count, player)
end,
})
local function has_locked_chest_privilege(meta, player)
if player:get_player_name() ~= meta:get_string("owner") then
return false
end
return true
end
minetest.register_node("default:chest_locked", {
description = "Locked Chest",
tile_images = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
"default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
paramtype2 = "facedir",
metadata_name = "locked_chest",
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
legacy_facedir_simple = true,
sounds = default.node_sound_wood_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.env:get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
meta:set_string("infotext", "Locked Chest (owned by "..
meta:get_string("owner")..")")
end,
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec",
"invsize[8,9;]"..
"list[current_name;main;0,0;8,4;]"..
"list[current_player;main;0,5;8,4;]")
meta:set_string("infotext", "Locked Chest")
meta:set_string("owner", "")
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
on_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return
end
minetest.log("action", player:get_player_name()..
" moves stuff in locked chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_move_allow_all(
pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_offer = function(pos, listname, index, stack, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return stack
end
minetest.log("action", player:get_player_name()..
" moves stuff to locked chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_offer_allow_all(
pos, listname, index, stack, player)
end,
on_metadata_inventory_take = function(pos, listname, index, count, player)
local meta = minetest.env:get_meta(pos)
if not has_locked_chest_privilege(meta, player) then
minetest.log("action", player:get_player_name()..
" tried to access a locked chest belonging to "..
meta:get_string("owner").." at "..
minetest.pos_to_string(pos))
return
end
minetest.log("action", player:get_player_name()..
" takes stuff from locked chest at "..minetest.pos_to_string(pos))
return minetest.node_metadata_inventory_take_allow_all(
pos, listname, index, count, player)
end,
})
default.furnace_inactive_formspec =
"invsize[8,9;]"..
"image[2,2;1,1;default_furnace_fire_bg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;1,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]"
minetest.register_node("default:furnace", {
description = "Furnace",
tile_images = {"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"},
paramtype2 = "facedir",
metadata_name = "furnace",
groups = {cracky=2},
legacy_facedir_simple = true,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", default.furnace_inactive_formspec)
meta:set_string("infotext", "Furnace")
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("fuel") then
return false
elseif not inv:is_empty("dst") then
return false
elseif not inv:is_empty("src") then
return false
end
return true
end,
})
minetest.register_node("default:furnace_active", {
description = "Furnace",
tile_images = {"default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"},
paramtype2 = "facedir",
light_source = 8,
drop = "default:furnace",
groups = {cracky=2},
legacy_facedir_simple = true,
sounds = default.node_sound_stone_defaults(),
on_construct = function(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", default.furnace_inactive_formspec)
meta:set_string("infotext", "Furnace");
local inv = meta:get_inventory()
inv:set_size("fuel", 1)
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
can_dig = function(pos,player)
local meta = minetest.env:get_meta(pos);
local inv = meta:get_inventory()
if not inv:is_empty("fuel") then
return false
elseif not inv:is_empty("dst") then
return false
elseif not inv:is_empty("src") then
return false
end
return true
end,
})
function hacky_swap_node(pos,name)
local node = minetest.env:get_node(pos)
local meta = minetest.env:get_meta(pos)
local meta0 = meta:to_table()
if node.name == name then
return
end
node.name = name
local meta0 = meta:to_table()
minetest.env:set_node(pos,node)
meta = minetest.env:get_meta(pos)
meta:from_table(meta0)
end
minetest.register_abm({
nodenames = {"default:furnace","default:furnace_active"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.env:get_meta(pos)
for i, name in ipairs({
"fuel_totaltime",
"fuel_time",
"src_totaltime",
"src_time"
}) do
if meta:get_string(name) == "" then
meta:set_float(name, 0.0)
end
end
local inv = meta:get_inventory()
local srclist = inv:get_list("src")
local cooked = nil
if srclist then
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
local was_active = false
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
was_active = true
meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
meta:set_float("src_time", meta:get_float("src_time") + 1)
if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
-- check if there's room for output in "dst" list
if inv:room_for_item("dst",cooked.item) then
-- Put result in "dst" list
inv:add_item("dst", cooked.item)
-- take stuff from "src" list
srcstack = inv:get_stack("src", 1)
srcstack:take_item()
inv:set_stack("src", 1, srcstack)
else
print("Could not insert '"..cooked.item.."'")
end
meta:set_string("src_time", 0)
end
end
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
local percent = math.floor(meta:get_float("fuel_time") /
meta:get_float("fuel_totaltime") * 100)
meta:set_string("infotext","Furnace active: "..percent.."%")
hacky_swap_node(pos,"default:furnace_active")
meta:set_string("formspec",
"invsize[8,9;]"..
"image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-percent)..":default_furnace_fire_fg.png]"..
"list[current_name;fuel;2,3;1,1;]"..
"list[current_name;src;2,1;1,1;]"..
"list[current_name;dst;5,1;2,2;]"..
"list[current_player;main;0,5;8,4;]")
return
end
local fuel = nil
local cooked = nil
local fuellist = inv:get_list("fuel")
local srclist = inv:get_list("src")
if srclist then
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
end
if fuellist then
fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
end
if fuel.time <= 0 then
meta:set_string("infotext","Furnace out of fuel")
hacky_swap_node(pos,"default:furnace")
meta:set_string("formspec", default.furnace_inactive_formspec)
return
end
if cooked.item:is_empty() then
if was_active then
meta:set_string("infotext","Furnace is empty")
hacky_swap_node(pos,"default:furnace")
meta:set_string("formspec", default.furnace_inactive_formspec)
end
return
end
meta:set_string("fuel_totaltime", fuel.time)
meta:set_string("fuel_time", 0)
local stack = inv:get_stack("fuel", 1)
stack:take_item()
inv:set_stack("fuel", 1, stack)
end,
})
minetest.register_node("default:cobble", {
@@ -1298,6 +1596,29 @@ minetest.add_to_creative_inventory('default:water_source')
minetest.add_to_creative_inventory('default:lava_source')
minetest.add_to_creative_inventory('default:ladder')
--
-- Aliases for the current map generator outputs
--
minetest.register_alias("mapgen_air", "air")
minetest.register_alias("mapgen_stone", "default:stone")
minetest.register_alias("mapgen_tree", "default:tree")
minetest.register_alias("mapgen_leaves", "default:leaves")
minetest.register_alias("mapgen_apple", "default:apple")
minetest.register_alias("mapgen_water_source", "default:water_source")
minetest.register_alias("mapgen_dirt", "default:dirt")
minetest.register_alias("mapgen_sand", "default:sand")
minetest.register_alias("mapgen_gravel", "default:gravel")
minetest.register_alias("mapgen_clay", "default:clay")
minetest.register_alias("mapgen_lava_source", "default:lava_source")
minetest.register_alias("mapgen_cobble", "default:cobble")
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
minetest.register_alias("mapgen_mese", "default:mese")
--
-- Some common functions
--
@@ -1500,6 +1821,57 @@ minetest.register_on_chat_message(function(name, message)
end
end)
--
-- Test some things
--
local function test_get_craft_result()
print("test_get_craft_result()")
-- normal
local input = {
method = "normal",
width = 2,
items = {"", "default:coal_lump", "", "default:stick"}
}
print("torch crafting input: "..dump(input))
local output, decremented_input = minetest.get_craft_result(input)
print("torch crafting output: "..dump(output))
print("torch crafting decremented input: "..dump(decremented_input))
assert(output.item)
print("torch crafting output.item:to_table(): "..dump(output.item:to_table()))
assert(output.item:get_name() == "default:torch")
assert(output.item:get_count() == 4)
-- fuel
local input = {
method = "fuel",
width = 1,
items = {"default:coal_lump"}
}
print("coal fuel input: "..dump(input))
local output, decremented_input = minetest.get_craft_result(input)
print("coal fuel output: "..dump(output))
print("coal fuel decremented input: "..dump(decremented_input))
assert(output.time)
assert(output.time > 0)
-- cook
local input = {
method = "cooking",
width = 1,
items = {"default:cobble"}
}
print("cobble cooking input: "..dump(output))
local output, decremented_input = minetest.get_craft_result(input)
print("cobble cooking output: "..dump(output))
print("cobble cooking decremented input: "..dump(decremented_input))
assert(output.time)
assert(output.time > 0)
assert(output.item)
print("cobble cooking output.item:to_table(): "..dump(output.item:to_table()))
assert(output.item:get_name() == "default:stone")
assert(output.item:get_count() == 1)
end
test_get_craft_result()
--
-- Done, print some random stuff
--

View File

@@ -0,0 +1,114 @@
-- minetest/default/mapgen.lua
--
-- Aliases for map generator outputs
--
minetest.register_alias("mapgen_air", "air")
minetest.register_alias("mapgen_stone", "default:stone")
minetest.register_alias("mapgen_tree", "default:tree")
minetest.register_alias("mapgen_leaves", "default:leaves")
minetest.register_alias("mapgen_apple", "default:apple")
minetest.register_alias("mapgen_water_source", "default:water_source")
minetest.register_alias("mapgen_dirt", "default:dirt")
minetest.register_alias("mapgen_sand", "default:sand")
minetest.register_alias("mapgen_gravel", "default:gravel")
minetest.register_alias("mapgen_clay", "default:clay")
minetest.register_alias("mapgen_lava_source", "default:lava_source")
minetest.register_alias("mapgen_cobble", "default:cobble")
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
minetest.register_alias("mapgen_mese", "default:mese")
--
-- Ore generation
--
local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, ore_per_chunk, height_min, height_max)
if maxp.y < height_min or minp.y > height_max then
return
end
local y_min = math.max(minp.y, height_min)
local y_max = math.min(maxp.y, height_max)
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
local pr = PseudoRandom(seed)
local num_chunks = math.floor(chunks_per_volume * volume)
local chunk_size = 3
if ore_per_chunk <= 4 then
chunk_size = 2
end
local inverse_chance = math.floor(chunk_size*chunk_size*chunk_size / ore_per_chunk)
--print("generate_ore num_chunks: "..dump(num_chunks))
for i=1,num_chunks do
local y0 = pr:next(y_min, y_max-chunk_size+1)
if y0 >= height_min and y0 <= height_max then
local x0 = pr:next(minp.x, maxp.x-chunk_size+1)
local z0 = pr:next(minp.z, maxp.z-chunk_size+1)
local p0 = {x=x0, y=y0, z=z0}
for x1=0,chunk_size-1 do
for y1=0,chunk_size-1 do
for z1=0,chunk_size-1 do
if pr:next(1,inverse_chance) == 1 then
local x2 = x0+x1
local y2 = y0+y1
local z2 = z0+z1
local p2 = {x=x2, y=y2, z=z2}
if minetest.env:get_node(p2).name == wherein then
minetest.env:set_node(p2, {name=name})
end
end
end
end
end
end
end
--print("generate_ore done")
end
minetest.register_on_generated(function(minp, maxp, seed)
generate_ore("default:stone_with_coal", "default:stone", minp, maxp, seed, 1/8/8/8, 5, -31000, 64)
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+1, 1/16/16/16, 5, -5, 7)
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+2, 1/12/12/12, 5, -16, -5)
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+3, 1/9/9/9, 5, -31000, -17)
-- Generate clay
if maxp.y >= 2 and minp.y <= 0 then
-- Assume X and Z lengths are equal
local divlen = 4
local divs = (maxp.x-minp.x)/divlen+1;
for divx=0+1,divs-1-1 do
for divz=0+1,divs-1-1 do
local cx = minp.x + math.floor((divx+0.5)*divlen)
local cz = minp.z + math.floor((divz+0.5)*divlen)
if minetest.env:get_node({x=cx,y=1,z=cz}).name == "default:water_source" and
minetest.env:get_node({x=cx,y=0,z=cz}).name == "default:sand" then
local is_shallow = true
local num_water_around = 0
if minetest.env:get_node({x=cx-divlen*2,y=1,z=cz+0}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if minetest.env:get_node({x=cx+divlen*2,y=1,z=cz+0}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if minetest.env:get_node({x=cx+0,y=1,z=cz-divlen*2}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if minetest.env:get_node({x=cx+0,y=1,z=cz+divlen*2}).name == "default:water_source" then
num_water_around = num_water_around + 1 end
if num_water_around >= 2 then
is_shallow = false
end
if is_shallow then
for x1=-divlen,divlen do
for z1=-divlen,divlen do
if minetest.env:get_node({x=cx+x1,y=0,z=cz+z1}).name == "default:sand" then
minetest.env:set_node({x=cx+x1,y=0,z=cz+z1}, {name="default:clay"})
end
end
end
end
end
end
end
end
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

View File

@@ -6,38 +6,59 @@
experimental = {}
timers_to_add = {}
timers = {}
minetest.register_globalstep(function(dtime)
for indes, timer in ipairs(timers_to_add) do
table.insert(timers, timer)
end
timers_to_add = {}
for index, timer in ipairs(timers) do
timer.time = timer.time - dtime
if timer.time <= 0 then
timer.func()
timers[index] = nil
end
end
end)
after = function(time, func)
table.insert(timers_to_add, {time=time, func=func})
function experimental.print_to_everything(msg)
minetest.log("action", msg)
minetest.chat_send_all(msg)
end
--[[
experimental.player_visual_index = 0
function switch_player_visual()
for _, obj in pairs(minetest.get_connected_players()) do
if experimental.player_visual_index == 0 then
obj:set_properties({visual="upright_sprite"})
else
obj:set_properties({visual="cube"})
end
end
experimental.player_visual_index = (experimental.player_visual_index + 1) % 2
minetest.after(1.0, switch_player_visual)
end
minetest.after(1.0, switch_player_visual)
]]
minetest.register_node("experimental:soundblock", {
tile_images = {"unknown_block.png", "default_tnt_bottom.png",
"default_tnt_side.png", "default_tnt_side.png",
"default_tnt_side.png", "default_tnt_side.png"},
inventory_image = minetest.inventorycube("unknown_block.png",
"default_tnt_side.png", "default_tnt_side.png"),
groups = {dig_immediate=3},
})
minetest.register_alias("sb", "experimental:soundblock")
minetest.register_abm({
nodenames = {"experimental:soundblock"},
interval = 1,
chance = 1,
action = function(p0, node, _, _)
minetest.sound_play("default_grass_footstep", {pos=p0, gain=0.5})
end,
})
--[[
stepsound = -1
function test_sound()
print("test_sound")
stepsound = minetest.sound_play("default_grass_footstep", {gain=1.0})
after(2.0, test_sound)
--after(0.1, test_sound_stop)
minetest.after(2.0, test_sound)
--minetest.after(0.1, test_sound_stop)
end
function test_sound_stop()
print("test_sound_stop")
minetest.sound_stop(stepsound)
after(2.0, test_sound)
minetest.after(2.0, test_sound)
end
test_sound()
--]]
@@ -81,235 +102,10 @@ function on_step(dtime)
end
minetest.register_globalstep(on_step)
-- An example furnace-thing implemented in Lua
--[[
minetest.register_node("experimental:luafurnace", {
tile_images = {"default_lava.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front.png"},
--inventory_image = "furnace_front.png",
inventory_image = minetest.inventorycube("default_furnace_front.png"),
paramtype = "facedir_simple",
metadata_name = "generic",
material = minetest.digprop_stonelike(3.0),
})
minetest.register_on_placenode(function(pos, newnode, placer)
if newnode.name == "experimental:luafurnace" then
local meta = minetest.env:get_meta(pos)
meta:inventory_set_list("fuel", {""})
meta:inventory_set_list("src", {""})
meta:inventory_set_list("dst", {"","","",""})
meta:set_inventory_draw_spec(
"invsize[8,9;]"
.."list[current_name;fuel;2,3;1,1;]"
.."list[current_name;src;2,1;1,1;]"
.."list[current_name;dst;5,1;2,2;]"
.."list[current_player;main;0,5;8,4;]"
)
local total_cooked = 0;
meta:set_string("total_cooked", total_cooked)
meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
end
end)
minetest.register_abm({
nodenames = {"experimental:luafurnace"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.env:get_meta(pos)
for i, name in ipairs({
"fuel_totaltime",
"fuel_time",
"src_totaltime",
"src_time"
}) do
if not meta:get_string(name) then
meta:set_string(name, 0)
end
end
local inv = meta:get_inventory()
local fuelitem = inv:get_stack("fuel", 1):peek_item()
local srcitem = inv:get_stack("src", 1):peek_item()
--print("fuelitem="..dump(fuelitem))
--print("srcitem="..dump(srcitem))
local was_active = false
local src_cooktime = -1
local result_stackstring = nil
if srcitem then
local prop = get_item_definition(srcitem)
if prop and prop.cookresult_itemstring ~= "" then
result_stackstring = prop.cookresult_itemstring
src_cooktime = prop.furnace_cooktime or 3
end
end
print("src_cooktime="..dump(src_cooktime))
print("result_stackstring="..dump(result_stackstring))
if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
was_active = true
meta:set_string("fuel_time", tonumber(meta:get_string("fuel_time")) + 1)
meta:set_string("src_time", tonumber(meta:get_string("src_time")) + 1)
--print("result_stackstring="..dump(result_stackstring))
--print('tonumber(meta:get_string("src_time"))='..dump(tonumber(meta:get_string("src_time"))))
--print("src_cooktime="..dump(src_cooktime))
if result_stackstring and tonumber(meta:get_string("src_time")) >= src_cooktime and src_cooktime >= 0 then
-- Put result in "dst" list
success = inv:autoinsert_stackstring("dst", result_stackstring)
if not success then
print("Could not autoinsert '"..result_stackstring.."'")
end
-- If succeeded, take stuff from "src" list
if success then
srcstack = inv:get_stack("src", 1)
srcstack:take_item()
inv:set_stack("src", 1, srcstack)
end
meta:set_string("src_time", 0)
end
end
if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
meta:set_infotext("Furnace active: "..(tonumber(meta:get_string("fuel_time"))/tonumber(meta:get_string("fuel_totaltime"))*100).."%")
return
end
local srcitem = inv:get_stack("src", 1):peek_item()
local src_cooktime = 0
local result_stackstring = nil
if srcitem then
local prop = get_item_definition(srcitem)
if prop and prop.cookresult_itemstring ~= "" then
result_stackstring = prop.cookresult_itemstring
src_cooktime = prop.furnace_cooktime or 3
end
end
local fuelitem = inv:get_stack("fuel", 1):peek_item()
if not result_stackstring or not fuelitem then
if was_active then
meta:set_infotext("Furnace is empty")
end
return
end
local burntime = -1
if fuelitem then
local prop = get_item_definition(fuelitem)
if prop then
burntime = prop.furnace_burntime or -1
end
end
if burntime <= 0 then
meta:set_infotext("Furnace out of fuel")
return
end
meta:set_string("fuel_totaltime", burntime)
meta:set_string("fuel_time", 0)
local stack = inv:get_stack("fuel", 1)
stack:take_item()
inv:set_stack("fuel", 1, stack)
end,
})
minetest.register_abm({
nodenames = {"experimental:luafurnace"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.env:get_meta(pos)
local fuellist = meta:inventory_get_list("fuel")
local srclist = meta:inventory_get_list("src")
local dstlist = meta:inventory_get_list("dst")
if fuellist == nil or srclist == nil or dstlist == nil then
return
end
_, srcitem = stackstring_take_item(srclist[1])
_, fuelitem = stackstring_take_item(fuellist[1])
if not srcitem or not fuelitem then return end
if fuelitem.type == "node" then
local prop = minetest.registered_nodes[fuelitem.name]
if prop == nil then return end
if prop.furnace_burntime < 0 then return end
else
return
end
local resultstack = nil
if srcitem.type == "node" then
local prop = minetest.registered_nodes[srcitem.name]
if prop == nil then return end
if prop.cookresult_item == "" then return end
resultstack = prop.cookresult_item
else
return
end
if resultstack == nil then
return
end
dstlist[1], success = stackstring_put_stackstring(dstlist[1], resultstack)
if not success then
return
end
fuellist[1], _ = stackstring_take_item(fuellist[1])
srclist[1], _ = stackstring_take_item(srclist[1])
meta:inventory_set_list("fuel", fuellist)
meta:inventory_set_list("src", srclist)
meta:inventory_set_list("dst", dstlist)
local total_cooked = meta:get_string("total_cooked")
total_cooked = tonumber(total_cooked) + 1
meta:set_string("total_cooked", total_cooked)
meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
end,
})
minetest.register_craft({
output = 'node "experimental:luafurnace" 1',
recipe = {
{'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
{'node "default:cobble"', 'node "default:steel_ingot"', 'node "default:cobble"'},
{'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
}
})
--]]
--
-- Random stuff
--
--[[
minetest.register_tool("experimental:horribletool", {
image = "default_lava.png",
basetime = 2.0
dt_weight = 0.2
dt_crackiness = 0.2
dt_crumbliness = 0.2
dt_cuttability = 0.2
basedurability = 50
dd_weight = -5
dd_crackiness = -5
dd_crumbliness = -5
dd_cuttability = -5
})
--]]
--
-- TNT (not functional)
--
@@ -415,16 +211,17 @@ minetest.register_alias("TNT", "experimental:tnt")
--
minetest.register_entity("experimental:dummyball", {
-- Static definition
hp_max = 20,
physical = false,
collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
visual = "sprite",
visual_size = {x=1, y=1},
textures = {"experimental_dummyball.png"},
spritediv = {x=1, y=3},
initial_sprite_basepos = {x=0, y=0},
-- Dynamic variables
initial_properties = {
hp_max = 20,
physical = false,
collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
visual = "sprite",
visual_size = {x=1, y=1},
textures = {"experimental_dummyball.png"},
spritediv = {x=1, y=3},
initial_sprite_basepos = {x=0, y=0},
},
phase = 0,
phasetimer = 0,
@@ -645,6 +442,68 @@ minetest.register_abm({
end,
})--]]
minetest.register_node("experimental:tester_node_1", {
description = "Tester Node 1",
tile_images = {"wieldhand.png"},
groups = {oddly_breakable_by_hand=2},
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
experimental.print_to_everything("experimental:tester_node_1:on_construct("..minetest.pos_to_string(pos)..")")
local meta = minetest.env:get_meta(pos)
meta:set_string("mine", "test")
end,
after_place_node = function(pos, placer)
experimental.print_to_everything("experimental:tester_node_1:after_place_node("..minetest.pos_to_string(pos)..")")
local meta = minetest.env:get_meta(pos)
if meta:get_string("mine") == "test" then
experimental.print_to_everything("correct metadata found")
else
experimental.print_to_everything("incorrect metadata found")
end
end,
on_destruct = function(pos)
experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")")
end,
after_destruct = function(pos)
experimental.print_to_everything("experimental:tester_node_1:after_destruct("..minetest.pos_to_string(pos)..")")
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")")
end,
})
minetest.register_craftitem("experimental:tester_tool_1", {
description = "Tester Tool 1",
inventory_image = "experimental_tester_tool_1.png",
on_use = function(itemstack, user, pointed_thing)
--print(dump(pointed_thing))
if pointed_thing.type == "node" then
if minetest.env:get_node(pointed_thing.under).name == "experimental:tester_node_1" then
local p = pointed_thing.under
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
minetest.env:dig_node(p)
else
local p = pointed_thing.above
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
minetest.env:place_node(p, {name="experimental:tester_node_1"})
end
end
end,
})
minetest.register_craft({
output = 'experimental:tester_tool_1',
recipe = {
{'group:crumbly'},
{'group:crumbly'},
}
})
minetest.log("experimental modname="..dump(minetest.get_current_modname()))
minetest.log("experimental modpath="..dump(minetest.get_modpath("experimental")))
minetest.log("experimental worldpath="..dump(minetest.get_worldpath()))

View File

@@ -1,12 +1,16 @@
minetest.register_on_newplayer(function(player)
print("on_newplayer")
if minetest.setting_getbool("give_initial_stuff") then
print("giving give_initial_stuff to player")
player:get_inventory():add_item('main', 'default:pick_steel')
player:get_inventory():add_item('main', 'default:torch 99')
player:get_inventory():add_item('main', 'default:axe_steel')
player:get_inventory():add_item('main', 'default:shovel_steel')
player:get_inventory():add_item('main', 'default:cobble 99')
end
print("[minimal] giving initial stuff to player")
player:get_inventory():add_item('main', 'default:pick_stone')
player:get_inventory():add_item('main', 'default:torch 99')
player:get_inventory():add_item('main', 'default:cobble 99')
player:get_inventory():add_item('main', 'default:wood 99')
player:get_inventory():add_item('main', 'default:axe_steel')
player:get_inventory():add_item('main', 'default:shovel_steel')
player:get_inventory():add_item('main', 'default:pick_wood')
player:get_inventory():add_item('main', 'default:pick_steel')
player:get_inventory():add_item('main', 'default:pick_mese')
player:get_inventory():add_item('main', 'default:mese 99')
player:get_inventory():add_item('main', 'default:water_source 99')
player:get_inventory():add_item('main', 'experimental:tester_tool_1')
end)

View File

@@ -0,0 +1,11 @@
--
-- Minimal Development Test
-- Mod: test
--
-- Try out PseudoRandom
pseudo = PseudoRandom(13)
assert(pseudo:next() == 22290)
assert(pseudo:next() == 13854)

View File

@@ -8,7 +8,7 @@
# Uncomment settings by removing the preceding #.
#
# Further documentation:
# http://celeron.55.lt/~celeron55/minetest/wiki/doku.php
# http://c55.me/minetest/wiki/doku.php
#
# NOTE: This file might not be up-to-date, refer to the
# defaultsettings.cpp file for an up-to-date list:
@@ -16,6 +16,7 @@
#
# A vim command to convert most of defaultsettings.cpp to conf file format:
# :'<,'>s/\tg_settings\.setDefault("\([^"]*\)", "\([^"]*\)");.*/#\1 = \2/g
# Note: Some of the settings are implemented in Lua
#
# Client and server
@@ -47,7 +48,6 @@
#keymap_rangeselect = KEY_KEY_R
#keymap_freemove = KEY_KEY_K
#keymap_fastmove = KEY_KEY_J
#keymap_frametime_graph = KEY_F1
#keymap_screenshot = KEY_F12
# Some (temporary) keys for debugging
#keymap_print_debug_stacks = KEY_KEY_P
@@ -58,11 +58,17 @@
# (to not waste CPU power for no benefit)
#fps_max = 60
# The allowed adjustment range for the automatic rendering range adjustment
#viewing_range_nodes_max = 300
#viewing_range_nodes_min = 25
#viewing_range_nodes_max = 160
#viewing_range_nodes_min = 35
# Initial window size
#screenW = 800
#screenH = 600
#fullscreen = false
#fullscreen_bpp = 24
# Experimental option, might cause visible spaces between blocks
# when set to higher number than 0
#fsaa = 0
#vsync = false
# Address to connect to (#blank = start local server)
#address =
# Enable random user input, for testing
@@ -78,8 +84,6 @@
# Enable smooth lighting with simple ambient occlusion;
# disable for speed or for different looks.
#smooth_lighting = true
# Whether to draw a frametime graph (for debugging frametime)
#frametime_graph = false
# Enable combining mainly used textures to a bigger one for improved speed
# disable if it causes graphics glitches.
#enable_texture_atlas = true
@@ -110,19 +114,22 @@
#console_color = (0,0,0)
# In-game chat console background alpha (opaqueness, between 0 and 255)
#console_alpha = 200
# Sound settings
#enable_sound = true
#sound_volume = 0.7
#
# Server stuff
#
# Default game (default when creating a new world)
#default_game = mesetint
# Map directory (everything in the world is stored here)
#map-dir = /custom/map
#default_game = minetest
# World directory (everything in the world is stored here)
#map-dir = /custom/world
# Message of the Day
#motd = Welcome to this awesome Minetest server!
# Maximum number of players connected simultaneously
#max_users = 20
#max_users = 100
# Set to false to allow old clients to connect
#strict_protocol_version_checking = true
# Set to true to enable creative mode (unlimited inventory)
@@ -139,10 +146,12 @@
#default_password =
# Available privileges: build, teleport, settime, privs, shout
#default_privs = build, shout
# Whether players are transferred to client without any range limit
# Whether players are shown to clients without any range limit
#unlimited_player_transfer_distance = true
# Whether to enable players killing each other
#enable_pvp = true
# If this is set, players will always (re)spawn at the given position
#static_spawnpoint = 0, 10, 0
# Profiler data print interval. #0 = disable.
#profiler_print_interval = 0
@@ -155,17 +164,21 @@
#max_simultaneous_block_sends_per_client = 2
# how many blocks are flying in the wire simultaneously per server
#max_simultaneous_block_sends_server_total = 8
#max_block_send_distance = 7
#max_block_generate_distance = 5
#time_send_interval = 20
# From how far blocks are sent to clients (value * 16 nodes)
#max_block_send_distance = 10
# From how far blocks are generated for clients (value * 16 nodes)
#max_block_generate_distance = 6
# Interval of sending time of day to clients
#time_send_interval = 5
# Length of day/night cycle. 72=20min, 360=4min, 1=24hour, 0=day/night/whatever stays unchanged
#time_speed = 72
#time_speed = 96
#server_unload_unused_data_timeout = 29
# Interval of saving important changes in the world
#server_map_save_interval = 5.3
# To reduce lag, block transfers are slowed down when a player is building something.
# This determines how long they are slowed down after placing or removing a node.
#full_block_send_enable_min_time_from_building = 2.0
# Set to true to enable experimental features or stuff that is tested
# (varies from version to version, usually not useful at all)
#enable_experimental = false
# Length of a server tick in dedicated server
#dedicated_server_step = 0.05
# Can be set to true to disable shutting down on invalid world data
#ignore_world_load_errors = false

5
misc/winresource.rc Normal file
View File

@@ -0,0 +1,5 @@
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
LANGUAGE 0, SUBLANG_NEUTRAL
130 ICON "minetest-icon.ico"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: minetest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-08-02 12:36+0200\n"
"POT-Creation-Date: 2012-06-04 23:25+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,461 +17,278 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
#: src/guiConfirmMenu.cpp:120
msgid "Yes"
msgstr ""
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
#: src/guiConfirmMenu.cpp:126
msgid "No"
msgstr ""
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
#: src/guiCreateWorld.cpp:116
msgid "World name"
msgstr ""
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
#: src/guiCreateWorld.cpp:135
msgid "Game"
msgstr ""
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
#: src/guiCreateWorld.cpp:159
msgid "Create"
msgstr ""
#: src/guiKeyChangeMenu.cpp:158
msgid "Use"
msgstr ""
#: src/guiKeyChangeMenu.cpp:173
msgid "Sneak"
msgstr ""
#: src/guiKeyChangeMenu.cpp:189
msgid "Jump"
msgstr ""
#: src/guiKeyChangeMenu.cpp:204
msgid "Inventory"
msgstr ""
#: src/guiKeyChangeMenu.cpp:220
msgid "Chat"
msgstr ""
#: src/guiKeyChangeMenu.cpp:236
msgid "Toggle fly"
msgstr ""
#: src/guiKeyChangeMenu.cpp:251
msgid "Toggle fast"
msgstr ""
#: src/guiKeyChangeMenu.cpp:266
msgid "Range select"
msgstr ""
#: src/guiKeyChangeMenu.cpp:283
msgid "Print stacks"
msgstr ""
#: src/guiKeyChangeMenu.cpp:298
msgid "Save"
msgstr ""
#: src/guiKeyChangeMenu.cpp:304 src/guiKeyChangeMenu.h:33
#: src/guiCreateWorld.cpp:165 src/guiKeyChangeMenu.cpp:374 src/keycode.cpp:221
msgid "Cancel"
msgstr ""
#: src/guiKeyChangeMenu.cpp:537 src/guiKeyChangeMenu.cpp:542
#: src/guiKeyChangeMenu.cpp:547 src/guiKeyChangeMenu.cpp:552
#: src/guiKeyChangeMenu.cpp:557 src/guiKeyChangeMenu.cpp:562
#: src/guiKeyChangeMenu.cpp:567 src/guiKeyChangeMenu.cpp:572
#: src/guiKeyChangeMenu.cpp:577 src/guiKeyChangeMenu.cpp:582
#: src/guiKeyChangeMenu.cpp:587 src/guiKeyChangeMenu.cpp:592
#: src/guiKeyChangeMenu.cpp:597
#: src/guiDeathScreen.cpp:96
msgid "You died."
msgstr ""
#: src/guiDeathScreen.cpp:104
msgid "Respawn"
msgstr ""
#: src/guiKeyChangeMenu.cpp:111
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
msgstr ""
#: src/guiKeyChangeMenu.cpp:121
msgid "Forward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:138
msgid "Backward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:154 src/keycode.cpp:226
msgid "Left"
msgstr ""
#: src/guiKeyChangeMenu.cpp:169 src/keycode.cpp:226
msgid "Right"
msgstr ""
#: src/guiKeyChangeMenu.cpp:185
msgid "Use"
msgstr ""
#: src/guiKeyChangeMenu.cpp:200
msgid "Sneak"
msgstr ""
#: src/guiKeyChangeMenu.cpp:216
msgid "Jump"
msgstr ""
#: src/guiKeyChangeMenu.cpp:231
msgid "Drop"
msgstr ""
#: src/guiKeyChangeMenu.cpp:246
msgid "Inventory"
msgstr ""
#: src/guiKeyChangeMenu.cpp:262
msgid "Chat"
msgstr ""
#: src/guiKeyChangeMenu.cpp:276
msgid "Command"
msgstr ""
#: src/guiKeyChangeMenu.cpp:290
msgid "Console"
msgstr ""
#: src/guiKeyChangeMenu.cpp:306
msgid "Toggle fly"
msgstr ""
#: src/guiKeyChangeMenu.cpp:321
msgid "Toggle fast"
msgstr ""
#: src/guiKeyChangeMenu.cpp:336
msgid "Range select"
msgstr ""
#: src/guiKeyChangeMenu.cpp:353
msgid "Print stacks"
msgstr ""
#: src/guiKeyChangeMenu.cpp:368
msgid "Save"
msgstr ""
#: src/guiKeyChangeMenu.cpp:626 src/guiKeyChangeMenu.cpp:631
#: src/guiKeyChangeMenu.cpp:636 src/guiKeyChangeMenu.cpp:641
#: src/guiKeyChangeMenu.cpp:646 src/guiKeyChangeMenu.cpp:651
#: src/guiKeyChangeMenu.cpp:656 src/guiKeyChangeMenu.cpp:661
#: src/guiKeyChangeMenu.cpp:666 src/guiKeyChangeMenu.cpp:671
#: src/guiKeyChangeMenu.cpp:676 src/guiKeyChangeMenu.cpp:681
#: src/guiKeyChangeMenu.cpp:686 src/guiKeyChangeMenu.cpp:691
#: src/guiKeyChangeMenu.cpp:696 src/guiKeyChangeMenu.cpp:701
msgid "press Key"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
#: src/guiMainMenu.cpp:217
msgid "Singleplayer"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
#: src/guiMainMenu.cpp:218
msgid "Multiplayer"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
#: src/guiMainMenu.cpp:219
msgid "Advanced"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
#: src/guiMainMenu.cpp:220
msgid "Settings"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
#: src/guiMainMenu.cpp:221
msgid "Credits"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
#: src/guiMainMenu.cpp:252
msgid "Select World:"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Return"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Tab"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "X Button 2"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Capital"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Control"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Kana"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Menu"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Pause"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Shift"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Convert"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Escape"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Final"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Junja"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Kanji"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Nonconvert"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Accept"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "End"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Home"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Mode Change"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Next"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Priot"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Space"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Down"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Execute"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Print"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Select"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Up"
msgstr ""
#: src/guiKeyChangeMenu.h:39
#: src/guiMainMenu.cpp:274 src/keycode.cpp:227
msgid "Delete"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Help"
#: src/guiMainMenu.cpp:281
msgid "New"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
#: src/guiMainMenu.cpp:289
msgid "Configure"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Snapshot"
msgstr ""
#: src/guiKeyChangeMenu.h:42
msgid "Left Windows"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Apps"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Numpad 0"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Numpad 1"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Right Windows"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Sleep"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 2"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 3"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 4"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 5"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 6"
msgstr ""
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 7"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad *"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad +"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad -"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad /"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad 8"
msgstr ""
#: src/guiKeyChangeMenu.h:45
msgid "Numpad 9"
msgstr ""
#: src/guiKeyChangeMenu.h:49
msgid "Num Lock"
msgstr ""
#: src/guiKeyChangeMenu.h:49
msgid "Scroll Lock"
msgstr ""
#: src/guiKeyChangeMenu.h:50
msgid "Left Shift"
msgstr ""
#: src/guiKeyChangeMenu.h:50
msgid "Right Shight"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Left Control"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Left Menu"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Right Control"
msgstr ""
#: src/guiKeyChangeMenu.h:51
msgid "Right Menu"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Comma"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Minus"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Period"
msgstr ""
#: src/guiKeyChangeMenu.h:53
msgid "Plus"
msgstr ""
#: src/guiKeyChangeMenu.h:57
msgid "Attn"
msgstr ""
#: src/guiKeyChangeMenu.h:57
msgid "CrSel"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "Erase OEF"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "ExSel"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "OEM Clear"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "PA1"
msgstr ""
#: src/guiKeyChangeMenu.h:58
#: src/guiMainMenu.cpp:304 src/keycode.cpp:246
msgid "Play"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "Zoom"
msgstr ""
#: src/guiMainMenu.cpp:181
msgid "Name/Password"
msgstr ""
#: src/guiMainMenu.cpp:206
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:228
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:235
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:241
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:249
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:258
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:281
#: src/guiMainMenu.cpp:315 src/guiMainMenu.cpp:492
msgid "Creative Mode"
msgstr ""
#: src/guiMainMenu.cpp:287
#: src/guiMainMenu.cpp:321 src/guiMainMenu.cpp:498
msgid "Enable Damage"
msgstr ""
#: src/guiMainMenu.cpp:295
msgid "Delete map"
#: src/guiMainMenu.cpp:341 src/guiMainMenu.cpp:414
msgid "Name/Password"
msgstr ""
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
#: src/guiMainMenu.cpp:368 src/guiMainMenu.cpp:441
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:394 src/guiMainMenu.cpp:473
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:464
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:505 src/guiMainMenu.cpp:833
msgid "Delete world"
msgstr ""
#: src/guiMainMenu.cpp:512
msgid "Create world"
msgstr ""
#: src/guiMainMenu.cpp:546
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:552
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:558
msgid "3D Clouds"
msgstr ""
#: src/guiMainMenu.cpp:564
msgid "Opaque water"
msgstr ""
#: src/guiMainMenu.cpp:573
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:804
msgid "Address required."
msgstr ""
#: src/guiMainMenu.cpp:822
msgid "Cannot delete world: Nothing selected"
msgstr ""
#: src/guiMainMenu.cpp:837
msgid "Files to be deleted"
msgstr ""
#: src/guiMainMenu.cpp:853
msgid "Cannot create world: No games found"
msgstr ""
#: src/guiMainMenu.cpp:866
msgid "Nothing here"
msgstr ""
#: src/guiMainMenu.cpp:915
msgid "Failed to delete all world files"
msgstr ""
#: src/guiMessageMenu.cpp:109 src/guiTextInputMenu.cpp:123
msgid "Proceed"
msgstr ""
#: src/guiPasswordChange.cpp:103
#: src/guiPasswordChange.cpp:108
msgid "Old Password"
msgstr ""
#: src/guiPasswordChange.cpp:120
#: src/guiPasswordChange.cpp:125
msgid "New Password"
msgstr ""
#: src/guiPasswordChange.cpp:136
#: src/guiPasswordChange.cpp:141
msgid "Confirm Password"
msgstr ""
#: src/guiPasswordChange.cpp:153
#: src/guiPasswordChange.cpp:158
msgid "Change"
msgstr ""
#: src/guiPasswordChange.cpp:162
#: src/guiPasswordChange.cpp:167
msgid "Passwords do not match!"
msgstr ""
#: src/guiPauseMenu.cpp:111
#: src/guiPauseMenu.cpp:118
msgid "Continue"
msgstr ""
#: src/guiPauseMenu.cpp:118
#: src/guiPauseMenu.cpp:127
msgid "Change Password"
msgstr ""
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
#: src/guiPauseMenu.cpp:135
msgid "Exit to Menu"
msgstr ""
#: src/guiPauseMenu.cpp:132
#: src/guiPauseMenu.cpp:142
msgid "Exit to OS"
msgstr ""
#: src/guiPauseMenu.cpp:139
#: src/guiPauseMenu.cpp:149
msgid ""
"Default Controls:\n"
"- WASD: Walk\n"
@@ -485,3 +302,325 @@ msgid ""
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""
#: src/keycode.cpp:221
msgid "Left Button"
msgstr ""
#: src/keycode.cpp:221
msgid "Middle Button"
msgstr ""
#: src/keycode.cpp:221
msgid "Right Button"
msgstr ""
#: src/keycode.cpp:221
msgid "X Button 1"
msgstr ""
#: src/keycode.cpp:222
msgid "Back"
msgstr ""
#: src/keycode.cpp:222
msgid "Clear"
msgstr ""
#: src/keycode.cpp:222
msgid "Return"
msgstr ""
#: src/keycode.cpp:222
msgid "Tab"
msgstr ""
#: src/keycode.cpp:222
msgid "X Button 2"
msgstr ""
#: src/keycode.cpp:223
msgid "Capital"
msgstr ""
#: src/keycode.cpp:223
msgid "Control"
msgstr ""
#: src/keycode.cpp:223
msgid "Kana"
msgstr ""
#: src/keycode.cpp:223
msgid "Menu"
msgstr ""
#: src/keycode.cpp:223
msgid "Pause"
msgstr ""
#: src/keycode.cpp:223
msgid "Shift"
msgstr ""
#: src/keycode.cpp:224
msgid "Convert"
msgstr ""
#: src/keycode.cpp:224
msgid "Escape"
msgstr ""
#: src/keycode.cpp:224
msgid "Final"
msgstr ""
#: src/keycode.cpp:224
msgid "Junja"
msgstr ""
#: src/keycode.cpp:224
msgid "Kanji"
msgstr ""
#: src/keycode.cpp:224
msgid "Nonconvert"
msgstr ""
#: src/keycode.cpp:225
msgid "Accept"
msgstr ""
#: src/keycode.cpp:225
msgid "End"
msgstr ""
#: src/keycode.cpp:225
msgid "Home"
msgstr ""
#: src/keycode.cpp:225
msgid "Mode Change"
msgstr ""
#: src/keycode.cpp:225
msgid "Next"
msgstr ""
#: src/keycode.cpp:225
msgid "Prior"
msgstr ""
#: src/keycode.cpp:225
msgid "Space"
msgstr ""
#: src/keycode.cpp:226
msgid "Down"
msgstr ""
#: src/keycode.cpp:226
msgid "Execute"
msgstr ""
#: src/keycode.cpp:226
msgid "Print"
msgstr ""
#: src/keycode.cpp:226
msgid "Select"
msgstr ""
#: src/keycode.cpp:226
msgid "Up"
msgstr ""
#: src/keycode.cpp:227
msgid "Help"
msgstr ""
#: src/keycode.cpp:227
msgid "Insert"
msgstr ""
#: src/keycode.cpp:227
msgid "Snapshot"
msgstr ""
#: src/keycode.cpp:230
msgid "Left Windows"
msgstr ""
#: src/keycode.cpp:231
msgid "Apps"
msgstr ""
#: src/keycode.cpp:231
msgid "Numpad 0"
msgstr ""
#: src/keycode.cpp:231
msgid "Numpad 1"
msgstr ""
#: src/keycode.cpp:231
msgid "Right Windows"
msgstr ""
#: src/keycode.cpp:231
msgid "Sleep"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 2"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 3"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 4"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 5"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 6"
msgstr ""
#: src/keycode.cpp:232
msgid "Numpad 7"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad *"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad +"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad -"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad /"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad 8"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad 9"
msgstr ""
#: src/keycode.cpp:237
msgid "Num Lock"
msgstr ""
#: src/keycode.cpp:237
msgid "Scroll Lock"
msgstr ""
#: src/keycode.cpp:238
msgid "Left Shift"
msgstr ""
#: src/keycode.cpp:238
msgid "Right Shift"
msgstr ""
#: src/keycode.cpp:239
msgid "Left Control"
msgstr ""
#: src/keycode.cpp:239
msgid "Left Menu"
msgstr ""
#: src/keycode.cpp:239
msgid "Right Control"
msgstr ""
#: src/keycode.cpp:239
msgid "Right Menu"
msgstr ""
#: src/keycode.cpp:241
msgid "Comma"
msgstr ""
#: src/keycode.cpp:241
msgid "Minus"
msgstr ""
#: src/keycode.cpp:241
msgid "Period"
msgstr ""
#: src/keycode.cpp:241
msgid "Plus"
msgstr ""
#: src/keycode.cpp:245
msgid "Attn"
msgstr ""
#: src/keycode.cpp:245
msgid "CrSel"
msgstr ""
#: src/keycode.cpp:246
msgid "Erase OEF"
msgstr ""
#: src/keycode.cpp:246
msgid "ExSel"
msgstr ""
#: src/keycode.cpp:246
msgid "OEM Clear"
msgstr ""
#: src/keycode.cpp:246
msgid "PA1"
msgstr ""
#: src/keycode.cpp:246
msgid "Zoom"
msgstr ""
#: src/main.cpp:1379
msgid "Main Menu"
msgstr ""
#: src/main.cpp:1601
msgid "Failed to initialize world"
msgstr ""
#: src/main.cpp:1613
msgid "No world selected and no address provided. Nothing to do."
msgstr ""
#: src/main.cpp:1621
msgid "Could not find or load game \""
msgstr ""
#: src/main.cpp:1635
msgid "Invalid gamespec."
msgstr ""
#: src/main.cpp:1675
msgid "Connection error (timed out?)"
msgstr ""
#: src/main.cpp:1686
msgid ""
"\n"
"Check debug.txt for details."
msgstr ""

View File

@@ -67,7 +67,7 @@ endif(ENABLE_SOUND AND BUILD_CLIENT)
if(SOUND_PROBLEM)
message(FATAL_ERROR "Sound enabled, but cannot be used.\n"
"To continue, either fill in the required paths or disable sound.")
"To continue, either fill in the required paths or disable sound. (-DENABLE_SOUND=0)")
endif()
if(USE_SOUND)
set(sound_SRCS sound_openal.cpp)
@@ -106,6 +106,8 @@ if(WIN32)
CACHE FILEPATH "Path to zlibwapi.dll (for installation)")
set(IRRLICHT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../../irrlicht-1.7.2"
CACHE PATH "irrlicht dir")
set(MINGWM10_DLL ""
CACHE FILEPATH "Path to mingwm10.dll (for installation)")
if(ENABLE_SOUND)
set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)")
set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)")
@@ -153,18 +155,19 @@ configure_file(
)
set(common_SRCS
genericobject.cpp
voxelalgorithms.cpp
sound.cpp
quicktune.cpp
subgame.cpp
inventorymanager.cpp
mods.cpp
serverremoteplayer.cpp
content_abm.cpp
craftdef.cpp
nameidmapping.cpp
itemdef.cpp
nodedef.cpp
luaentity_common.cpp
object_properties.cpp
scriptapi.cpp
script.cpp
log.cpp
@@ -172,9 +175,9 @@ set(common_SRCS
mapgen.cpp
content_nodemeta.cpp
content_mapnode.cpp
auth.cpp
collision.cpp
nodemetadata.cpp
nodetimer.cpp
serverobject.cpp
noise.cpp
porting.cpp
@@ -205,14 +208,19 @@ set(common_SRCS
# This gives us the icon
if(WIN32)
set(WINRESOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../misc/winresource.rc)
if(MINGW)
if(NOT CMAKE_RC_COMPILER)
set(CMAKE_RC_COMPILER "windres.exe")
endif()
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
COMMAND windres.exe -I${CMAKE_CURRENT_SOURCE_DIR}
-i${CMAKE_CURRENT_SOURCE_DIR}/winresource.rc
-o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR}
-i${WINRESOURCE_FILE}
-o ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
SET(common_SRCS ${common_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
else(MINGW) # Probably MSVC
set(common_SRCS ${common_SRCS} winresource.rc)
set(common_SRCS ${common_SRCS} ${WINRESOURCE_FILE})
endif(MINGW)
endif()
@@ -220,6 +228,7 @@ endif()
set(minetest_SRCS
${common_SRCS}
${sound_SRCS}
localplayer.cpp
sky.cpp
clientmap.cpp
content_cso.cpp
@@ -347,14 +356,18 @@ else()
set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-but-set-variable")
endif(HAS_UNUSED_BUT_SET_VARIABLE_WARNING)
endif()
if(MINGW)
set(OTHER_FLAGS "-mthreads -fexceptions")
endif()
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES i386 CACHE STRING "do not build for 64-bit" FORCE)
set(ARCH i386)
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall ${WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} ${OTHER_FLAGS} -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O1 -Wall ${WARNING_FLAGS} ${OTHER_FLAGS}")
if(USE_GPROF)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
@@ -374,6 +387,9 @@ endif()
# Installation
#
if(WIN32)
if(MINGWM10_DLL)
install(FILES ${MINGWM10_DLL} DESTINATION ${BINDIR})
endif()
if(DEFINED ZLIB_DLL)
install(FILES ${ZLIB_DLL} DESTINATION ${BINDIR})
endif()

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -1,300 +0,0 @@
/*
Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "auth.h"
#include <fstream>
#include <jmutexautolock.h>
//#include "main.h" // for g_settings
#include <sstream>
#include "strfnd.h"
#include "log.h"
std::set<std::string> privsToSet(u64 privs)
{
std::set<std::string> s;
if(privs & PRIV_INTERACT)
s.insert("interact");
if(privs & PRIV_TELEPORT)
s.insert("teleport");
if(privs & PRIV_SETTIME)
s.insert("settime");
if(privs & PRIV_PRIVS)
s.insert("privs");
if(privs & PRIV_SHOUT)
s.insert("shout");
if(privs & PRIV_BAN)
s.insert("ban");
if(privs & PRIV_GIVE)
s.insert("give");
if(privs & PRIV_PASSWORD)
s.insert("password");
return s;
}
// Convert a privileges value into a human-readable string,
// with each component separated by a comma.
std::string privsToString(u64 privs)
{
std::ostringstream os(std::ios_base::binary);
if(privs & PRIV_INTERACT)
os<<"interact,";
if(privs & PRIV_TELEPORT)
os<<"teleport,";
if(privs & PRIV_SETTIME)
os<<"settime,";
if(privs & PRIV_PRIVS)
os<<"privs,";
if(privs & PRIV_SHOUT)
os<<"shout,";
if(privs & PRIV_BAN)
os<<"ban,";
if(privs & PRIV_GIVE)
os<<"give,";
if(privs & PRIV_PASSWORD)
os<<"password,";
if(os.tellp())
{
// Drop the trailing comma. (Why on earth can't
// you truncate a C++ stream anyway???)
std::string tmp = os.str();
return tmp.substr(0, tmp.length() -1);
}
return os.str();
}
// Converts a comma-seperated list of privilege values into a
// privileges value. The reverse of privsToString(). Returns
// PRIV_INVALID if there is anything wrong with the input.
u64 stringToPrivs(std::string str)
{
u64 privs=0;
Strfnd f(str);
while(f.atend() == false)
{
std::string s = trim(f.next(","));
if(s == "build")
privs |= PRIV_INTERACT;
else if(s == "interact")
privs |= PRIV_INTERACT;
else if(s == "teleport")
privs |= PRIV_TELEPORT;
else if(s == "settime")
privs |= PRIV_SETTIME;
else if(s == "privs")
privs |= PRIV_PRIVS;
else if(s == "shout")
privs |= PRIV_SHOUT;
else if(s == "ban")
privs |= PRIV_BAN;
else if(s == "give")
privs |= PRIV_GIVE;
else if(s == "password")
privs |= PRIV_PASSWORD;
else
return PRIV_INVALID;
}
return privs;
}
AuthManager::AuthManager(const std::string &authfilepath):
m_authfilepath(authfilepath),
m_modified(false)
{
m_mutex.Init();
try{
load();
}
catch(SerializationError &e)
{
infostream<<"WARNING: AuthManager: creating "
<<m_authfilepath<<std::endl;
}
}
AuthManager::~AuthManager()
{
save();
}
void AuthManager::load()
{
JMutexAutoLock lock(m_mutex);
infostream<<"AuthManager: loading from "<<m_authfilepath<<std::endl;
std::ifstream is(m_authfilepath.c_str(), std::ios::binary);
if(is.good() == false)
{
infostream<<"AuthManager: failed loading from "<<m_authfilepath<<std::endl;
throw SerializationError("AuthManager::load(): Couldn't open file");
}
for(;;)
{
if(is.eof() || is.good() == false)
break;
// Read a line
std::string line;
std::getline(is, line, '\n');
std::istringstream iss(line);
// Read name
std::string name;
std::getline(iss, name, ':');
// Read password
std::string pwd;
std::getline(iss, pwd, ':');
// Read privileges
std::string stringprivs;
std::getline(iss, stringprivs, ':');
u64 privs = stringToPrivs(stringprivs);
// Store it
AuthData ad;
ad.pwd = pwd;
ad.privs = privs;
m_authdata[name] = ad;
}
m_modified = false;
}
void AuthManager::save()
{
JMutexAutoLock lock(m_mutex);
infostream<<"AuthManager: saving to "<<m_authfilepath<<std::endl;
std::ofstream os(m_authfilepath.c_str(), std::ios::binary);
if(os.good() == false)
{
infostream<<"AuthManager: failed saving to "<<m_authfilepath<<std::endl;
throw SerializationError("AuthManager::save(): Couldn't open file");
}
for(core::map<std::string, AuthData>::Iterator
i = m_authdata.getIterator();
i.atEnd()==false; i++)
{
std::string name = i.getNode()->getKey();
if(name == "")
continue;
AuthData ad = i.getNode()->getValue();
os<<name<<":"<<ad.pwd<<":"<<privsToString(ad.privs)<<"\n";
}
m_modified = false;
}
bool AuthManager::exists(const std::string &username)
{
JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username);
if(n == NULL)
return false;
return true;
}
void AuthManager::set(const std::string &username, AuthData ad)
{
JMutexAutoLock lock(m_mutex);
m_authdata[username] = ad;
m_modified = true;
}
void AuthManager::add(const std::string &username)
{
JMutexAutoLock lock(m_mutex);
m_authdata[username] = AuthData();
m_modified = true;
}
std::string AuthManager::getPassword(const std::string &username)
{
JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username);
if(n == NULL)
throw AuthNotFoundException("");
return n->getValue().pwd;
}
void AuthManager::setPassword(const std::string &username,
const std::string &password)
{
JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username);
if(n == NULL)
throw AuthNotFoundException("");
AuthData ad = n->getValue();
ad.pwd = password;
n->setValue(ad);
m_modified = true;
}
u64 AuthManager::getPrivs(const std::string &username)
{
JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username);
if(n == NULL)
throw AuthNotFoundException("");
return n->getValue().privs;
}
void AuthManager::setPrivs(const std::string &username, u64 privs)
{
JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username);
if(n == NULL)
throw AuthNotFoundException("");
AuthData ad = n->getValue();
ad.privs = privs;
n->setValue(ad);
m_modified = true;
}
bool AuthManager::isModified()
{
JMutexAutoLock lock(m_mutex);
return m_modified;
}

View File

@@ -1,107 +0,0 @@
/*
Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef AUTH_HEADER
#define AUTH_HEADER
#include <set>
#include <string>
#include <jthread.h>
#include <jmutex.h>
#include "irrlichttypes.h"
#include "exceptions.h"
// Player privileges. These form a bitmask stored in the privs field
// of the player, and define things they're allowed to do. See also
// the static methods Player::privsToString and stringToPrivs that
// convert these to human-readable form.
const u64 PRIV_INTERACT = 1; // Can interact
const u64 PRIV_TELEPORT = 2; // Can teleport
const u64 PRIV_SETTIME = 4; // Can set the time
const u64 PRIV_PRIVS = 8; // Can grant and revoke privileges
const u64 PRIV_SERVER = 16; // Can manage the server (e.g. shutodwn
// ,settings)
const u64 PRIV_SHOUT = 32; // Can broadcast chat messages to all
// players
const u64 PRIV_BAN = 64; // Can ban players
const u64 PRIV_GIVE = 128; // Can give stuff
const u64 PRIV_PASSWORD = 256; // Can set other players' passwords
// Default privileges - these can be overriden for new players using the
// config option "default_privs" - however, this value still applies for
// players that existed before the privileges system was added.
const u64 PRIV_DEFAULT = PRIV_INTERACT|PRIV_SHOUT;
const u64 PRIV_ALL = 0x7FFFFFFFFFFFFFFFULL;
const u64 PRIV_INVALID = 0x8000000000000000ULL;
std::set<std::string> privsToSet(u64 privs);
// Convert a privileges value into a human-readable string,
// with each component separated by a comma.
std::string privsToString(u64 privs);
// Converts a comma-seperated list of privilege values into a
// privileges value. The reverse of privsToString(). Returns
// PRIV_INVALID if there is anything wrong with the input.
u64 stringToPrivs(std::string str);
struct AuthData
{
std::string pwd;
u64 privs;
AuthData():
privs(PRIV_DEFAULT)
{
}
};
class AuthNotFoundException : public BaseException
{
public:
AuthNotFoundException(const char *s):
BaseException(s)
{}
};
class AuthManager
{
public:
AuthManager(const std::string &authfilepath);
~AuthManager();
void load();
void save();
bool exists(const std::string &username);
void set(const std::string &username, AuthData ad);
void add(const std::string &username);
std::string getPassword(const std::string &username);
void setPassword(const std::string &username,
const std::string &password);
u64 getPrivs(const std::string &username);
void setPrivs(const std::string &username, u64 privs);
bool isModified();
private:
JMutex m_mutex;
std::string m_authfilepath;
core::map<std::string, AuthData> m_authdata;
bool m_modified;
};
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -38,6 +38,13 @@ static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
bool base64_is_valid(std::string const& s)
{
for(int i=0; i<s.size(); i++)
if(!is_base64(s[i])) return false;
return true;
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;

View File

@@ -1,4 +1,5 @@
#include <string>
bool base64_is_valid(std::string const& s);
std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -290,6 +290,9 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
// FOV and aspect ratio
m_aspect = (f32)screensize.X / (f32) screensize.Y;
m_fov_y = fov_degrees * PI / 180.0;
// Increase vertical FOV on lower aspect ratios (<16:10)
m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect)));
// WTF is this? It can't be right
m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y));
m_cameranode->setAspectRatio(m_aspect);
m_cameranode->setFOV(m_fov_y);
@@ -348,7 +351,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
if ((hypot(speed.X, speed.Z) > BS) &&
(player->touching_ground) &&
(g_settings->getBool("view_bobbing") == true) &&
(g_settings->getBool("free_move") == false))
(g_settings->getBool("free_move") == false ||
!m_gamedef->checkLocalPrivilege("fly")))
{
// Start animation
m_view_bobbing_state = 1;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -1397,45 +1397,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
}
else if(command == TOCLIENT_PLAYERITEM)
{
std::string datastring((char*)&data[2], datasize-2);
std::istringstream is(datastring, std::ios_base::binary);
u16 count = readU16(is);
for (u16 i = 0; i < count; ++i) {
u16 peer_id = readU16(is);
Player *player = m_env.getPlayer(peer_id);
if (player == NULL)
{
infostream<<"Client: ignoring player item "
<< deSerializeString(is)
<< " for non-existing peer id " << peer_id
<< std::endl;
continue;
} else if (player->isLocal()) {
infostream<<"Client: ignoring player item "
<< deSerializeString(is)
<< " for local player" << std::endl;
continue;
} else {
InventoryList *inv = player->inventory.getList("main");
std::string itemstring(deSerializeString(is));
ItemStack item;
item.deSerialize(itemstring, m_itemdef);
inv->changeItem(0, item);
if(itemstring.empty())
{
infostream<<"Client: empty player item for peer "
<<peer_id<<std::endl;
}
else
{
infostream<<"Client: player item for peer "
<<peer_id<<": "<<itemstring<<std::endl;
}
}
}
infostream<<"Client: WARNING: Ignoring TOCLIENT_PLAYERITEM"<<std::endl;
}
else if(command == TOCLIENT_DEATHSCREEN)
{
@@ -1677,10 +1639,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
int client_id = -1;
switch(type){
case 0: // local
client_id = m_sound->playSound(name, false, gain);
client_id = m_sound->playSound(name, loop, gain);
break;
case 1: // positional
client_id = m_sound->playSoundAt(name, false, gain, pos);
client_id = m_sound->playSoundAt(name, loop, gain, pos);
break;
case 2: { // object
ClientActiveObject *cao = m_env.getActiveObject(object_id);
@@ -1712,6 +1674,21 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
m_sound->stopSound(client_id);
}
}
else if(command == TOCLIENT_PRIVILEGES)
{
std::string datastring((char*)&data[2], datasize-2);
std::istringstream is(datastring, std::ios_base::binary);
m_privileges.clear();
infostream<<"Client: Privileges updated: ";
u16 num_privileges = readU16(is);
for(u16 i=0; i<num_privileges; i++){
std::string priv = deSerializeString(is);
m_privileges.insert(priv);
infostream<<priv<<" ";
}
infostream<<std::endl;
}
else
{
infostream<<"Client: Ignoring unknown command "
@@ -1763,33 +1740,23 @@ void Client::interact(u8 action, const PointedThing& pointed)
Send(0, data, true);
}
void Client::sendSignNodeText(v3s16 p, std::string text)
void Client::sendNodemetaFields(v3s16 p, const std::string &formname,
const std::map<std::string, std::string> &fields)
{
/*
u16 command
v3s16 p
u16 textlen
textdata
*/
std::ostringstream os(std::ios_base::binary);
u8 buf[12];
// Write command
writeU16(buf, TOSERVER_SIGNNODETEXT);
os.write((char*)buf, 2);
// Write p
writeV3S16(buf, p);
os.write((char*)buf, 6);
u16 textlen = text.size();
// Write text length
writeS16(buf, textlen);
os.write((char*)buf, 2);
writeU16(os, TOSERVER_NODEMETA_FIELDS);
writeV3S16(os, p);
os<<serializeString(formname);
writeU16(os, fields.size());
for(std::map<std::string, std::string>::const_iterator
i = fields.begin(); i != fields.end(); i++){
const std::string &name = i->first;
const std::string &value = i->second;
os<<serializeString(name);
os<<serializeLongString(value);
}
// Write text
os.write((char*)text.c_str(), textlen);
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
@@ -2371,32 +2338,41 @@ ClientEvent Client::getClientEvent()
void Client::afterContentReceived()
{
verbosestream<<"Client::afterContentReceived() started"<<std::endl;
assert(m_itemdef_received);
assert(m_nodedef_received);
assert(m_media_received);
// remove the information about which checksum each texture
// ought to have
m_media_name_sha1_map.clear();
// Rebuild inherited images and recreate textures
verbosestream<<"Rebuilding images and textures"<<std::endl;
m_tsrc->rebuildImagesAndTextures();
// Update texture atlas
verbosestream<<"Updating texture atlas"<<std::endl;
if(g_settings->getBool("enable_texture_atlas"))
m_tsrc->buildMainAtlas(this);
// Update node aliases
verbosestream<<"Updating node aliases"<<std::endl;
m_nodedef->updateAliases(m_itemdef);
// Update node textures
verbosestream<<"Updating node textures"<<std::endl;
m_nodedef->updateTextures(m_tsrc);
// Update item textures and meshes
verbosestream<<"Updating item textures and meshes"<<std::endl;
m_itemdef->updateTexturesAndMeshes(this);
// Start mesh update thread after setting up content definitions
verbosestream<<"Starting mesh update thread"<<std::endl;
m_mesh_update_thread.Start();
verbosestream<<"Client::afterContentReceived() done"<<std::endl;
}
float Client::getRTT(void)

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -20,8 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENT_HEADER
#define CLIENT_HEADER
#ifndef SERVER
#include "connection.h"
#include "environment.h"
#include "common_irrlicht.h"
@@ -35,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventorymanager.h"
#include "filesys.h"
#include "filecache.h"
#include "localplayer.h"
struct MeshMakeData;
class MapBlockMesh;
@@ -211,11 +210,12 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
void interact(u8 action, const PointedThing& pointed);
void sendSignNodeText(v3s16 p, std::string text);
void sendNodemetaFields(v3s16 p, const std::string &formname,
const std::map<std::string, std::string> &fields);
void sendInventoryAction(InventoryAction *a);
void sendChatMessage(const std::wstring &message);
void sendChangePassword(const std::wstring oldpassword,
const std::wstring newpassword);
const std::wstring newpassword);
void sendDamage(u8 damage);
void sendRespawn();
@@ -262,14 +262,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
u16 getHP();
float getAvgRtt()
{
try{
return m_con.GetPeerAvgRTT(PEER_ID_SERVER);
} catch(con::PeerNotFoundException){
return 1337;
}
}
bool checkPrivilege(const std::string &priv)
{ return (m_privileges.count(priv) != 0); }
bool getChatMessage(std::wstring &message);
void typeChatMessage(const std::wstring& message);
@@ -312,6 +306,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
virtual u16 allocateUnknownNodeId(const std::string &name);
virtual ISoundManager* getSoundManager();
virtual MtEventManager* getEventManager();
virtual bool checkLocalPrivilege(const std::string &priv)
{ return checkPrivilege(priv); }
private:
@@ -392,9 +388,10 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
std::map<int, s32> m_sounds_client_to_server;
// And relations to objects
std::map<int, u16> m_sounds_to_objects;
};
#endif // !SERVER
// Privileges
std::set<std::string> m_privileges;
};
#endif // !CLIENT_HEADER

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -324,6 +324,16 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
Occlusion culling
*/
// No occlusion culling when free_move is on and camera is
// inside ground
bool occlusion_culling_enabled = true;
if(g_settings->getBool("free_move")){
MapNode n = getNodeNoEx(cam_pos_nodes);
if(n.getContent() == CONTENT_IGNORE ||
nodemgr->get(n).solidness == 2)
occlusion_culling_enabled = false;
}
v3s16 cpn = block->getPos() * MAP_BLOCKSIZE;
cpn += v3s16(MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2);
float step = BS*1;
@@ -334,6 +344,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
s16 bs2 = MAP_BLOCKSIZE/2 + 1;
u32 needed_count = 1;
if(
occlusion_culling_enabled &&
isOccluded(this, spn, cpn + v3s16(0,0,0),
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
@@ -598,9 +609,9 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
if(z_directions[0].X < -99){
for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
z_directions[i] = v3f(
0.01 * myrand_range(-80, 80),
0.01 * myrand_range(-100, 100),
1.0,
0.01 * myrand_range(-80, 80)
0.01 * myrand_range(-100, 100)
);
z_offsets[i] = 0.01 * myrand_range(0,100);
}

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -50,9 +50,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PROTOCOL_VERSION 9:
ContentFeatures and NodeDefManager use a different serialization
format; better for future version cross-compatibility
Many things
PROTOCOL_VERSION 10:
TOCLIENT_PRIVILEGES
Version raised to force 'fly' and 'fast' privileges into effect.
*/
#define PROTOCOL_VERSION 9
#define PROTOCOL_VERSION 10
#define PROTOCOL_ID 0x4f457403
@@ -200,7 +204,7 @@ enum ToClientCommand
wstring reason
*/
TOCLIENT_PLAYERITEM = 0x36,
TOCLIENT_PLAYERITEM = 0x36, // Obsolete
/*
u16 command
u16 count of player items
@@ -291,6 +295,15 @@ enum ToClientCommand
u16 command
s32 sound_id
*/
TOCLIENT_PRIVILEGES = 0x41,
/*
u16 command
u16 number of privileges
for each privilege
u16 len
u8[len] privilege
*/
};
enum ToServerCommand
@@ -402,7 +415,7 @@ enum ToServerCommand
wstring message
*/
TOSERVER_SIGNNODETEXT = 0x33,
TOSERVER_SIGNNODETEXT = 0x33, // obsolete
/*
u16 command
v3s16 p
@@ -471,6 +484,20 @@ enum ToServerCommand
s32[len] sound_id
*/
TOSERVER_NODEMETA_FIELDS = 0x3b,
/*
u16 command
v3s16 p
u16 len
u8[len] form name (reserved for future use)
u16 number of fields
for each field:
u16 len
u8[len] field name
u32 len
u8[len] field value
*/
TOSERVER_REQUEST_MEDIA = 0x40,
/*
u16 command

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -213,8 +213,7 @@ void Clouds::render()
v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f;
video::S3DVertex v[4] =
{
video::S3DVertex v[4] = {
video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1),
video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1),
video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0),
@@ -236,88 +235,88 @@ void Clouds::render()
{
switch(i)
{
case 0: // top
for(int j=0;j<4;j++){
v[j].Normal = v3f(0,1,0);
}
v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
v[2].Pos.X= rx; v[2].Pos.Y= ry; v[2].Pos.Z= rz;
v[3].Pos.X= rx; v[3].Pos.Y= ry, v[3].Pos.Z=-rz;
break;
case 1: // back
if(CONTAINS(xi, zi-1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi-1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_1;
v[j].Normal = v3f(0,0,-1);
}
v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
break;
case 2: //right
if(CONTAINS(xi+1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi+1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_2;
v[j].Normal = v3f(1,0,0);
}
v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
break;
case 3: // front
if(CONTAINS(xi, zi+1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi+1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_1;
v[j].Normal = v3f(0,0,-1);
}
v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
break;
case 4: // left
if(CONTAINS(xi-1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi-1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color=c_side_2;
v[j].Normal = v3f(-1,0,0);
}
v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
break;
case 5: // bottom
for(int j=0;j<4;j++){
v[j].Color=c_bottom;
v[j].Normal = v3f(0,-1,0);
}
v[0].Pos.X= rx; v[0].Pos.Y=-ry; v[0].Pos.Z= rz;
v[1].Pos.X=-rx; v[1].Pos.Y=-ry; v[1].Pos.Z= rz;
v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
break;
case 0: // top
for(int j=0;j<4;j++){
v[j].Normal.set(0,1,0);
}
v[0].Pos.set(-rx, ry,-rz);
v[1].Pos.set(-rx, ry, rz);
v[2].Pos.set( rx, ry, rz);
v[3].Pos.set( rx, ry,-rz);
break;
case 1: // back
if(CONTAINS(xi, zi-1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi-1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_1;
v[j].Normal.set(0,0,-1);
}
v[0].Pos.set(-rx, ry,-rz);
v[1].Pos.set( rx, ry,-rz);
v[2].Pos.set( rx,-ry,-rz);
v[3].Pos.set(-rx,-ry,-rz);
break;
case 2: //right
if(CONTAINS(xi+1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi+1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_2;
v[j].Normal.set(1,0,0);
}
v[0].Pos.set( rx, ry,-rz);
v[1].Pos.set( rx, ry, rz);
v[2].Pos.set( rx,-ry, rz);
v[3].Pos.set( rx,-ry,-rz);
break;
case 3: // front
if(CONTAINS(xi, zi+1, cloud_radius_i)){
u32 j = GETINDEX(xi, zi+1, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_1;
v[j].Normal.set(0,0,-1);
}
v[0].Pos.set( rx, ry, rz);
v[1].Pos.set(-rx, ry, rz);
v[2].Pos.set(-rx,-ry, rz);
v[3].Pos.set( rx,-ry, rz);
break;
case 4: // left
if(CONTAINS(xi-1, zi, cloud_radius_i)){
u32 j = GETINDEX(xi-1, zi, cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_2;
v[j].Normal.set(-1,0,0);
}
v[0].Pos.set(-rx, ry, rz);
v[1].Pos.set(-rx, ry,-rz);
v[2].Pos.set(-rx,-ry,-rz);
v[3].Pos.set(-rx,-ry, rz);
break;
case 5: // bottom
for(int j=0;j<4;j++){
v[j].Color = c_bottom;
v[j].Normal.set(0,-1,0);
}
v[0].Pos.set( rx,-ry, rz);
v[1].Pos.set(-rx,-ry, rz);
v[2].Pos.set(-rx,-ry,-rz);
v[3].Pos.set( rx,-ry,-rz);
break;
}
v3f pos = v3f(p0.X,m_cloud_y,p0.Y);
v3f pos(p0.X, m_cloud_y, p0.Y);
for(u16 i=0; i<4; i++)
v[i].Pos += pos;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -29,6 +29,10 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
{
collisionMoveResult result;
// If there is no speed, there are no collisions
if(speed_f.getLength() == 0)
return result;
v3f oldpos_f = pos_f;
v3s16 oldpos_i = floatToInt(oldpos_f, BS);
@@ -196,6 +200,10 @@ collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
f32 dtime, v3f &pos_f, v3f &speed_f)
{
collisionMoveResult final_result;
// If there is no speed, there are no collisions
if(speed_f.getLength() == 0)
return final_result;
// Maximum time increment (for collision detection etc)
// time = distance / speed

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -353,9 +353,11 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(BufferedPacket &p, bool reliable)
<<" != sp->reliable="<<sp->reliable
<<std::endl;
// If chunk already exists, cancel
// If chunk already exists, ignore it.
// Sometimes two identical packets may arrive when there is network
// lag and the server re-sends stuff.
if(sp->chunks.find(chunk_num) != NULL)
throw AlreadyExistsException("Chunk already in buffer");
return SharedBuffer<u8>();
// Cut chunk data out of packet
u32 chunkdatasize = p.data.getSize() - headersize;

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -99,9 +99,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Length of cracking animation in count of images
#define CRACK_ANIMATION_LENGTH 5
// Some stuff needed by old code moved to here from heightmap.h
#define GROUNDHEIGHT_NOTFOUND_SETVALUE (-10e6)
#define GROUNDHEIGHT_VALID_MINVALUE ( -9e6)
// Maximum hit points of a player
#define PLAYER_MAX_HP 20
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -36,9 +36,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_cso.h"
#include "sound.h"
#include "nodedef.h"
#include "localplayer.h"
class Settings;
struct ToolCapabilities;
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
/*
@@ -533,28 +536,37 @@ void ItemCAO::initialize(const std::string &data)
}
/*
LuaEntityCAO
GenericCAO
*/
#include "luaentity_common.h"
#include "genericobject.h"
class LuaEntityCAO : public ClientActiveObject
class GenericCAO : public ClientActiveObject
{
private:
// Only set at initialization
std::string m_name;
bool m_is_player;
bool m_is_local_player; // determined locally
// Property-ish things
ObjectProperties m_prop;
//
scene::ISceneManager *m_smgr;
IrrlichtDevice *m_irr;
core::aabbox3d<f32> m_selection_box;
scene::IMeshSceneNode *m_meshnode;
scene::IBillboardSceneNode *m_spritenode;
scene::ITextSceneNode* m_textnode;
v3f m_position;
v3f m_velocity;
v3f m_acceleration;
float m_yaw;
s16 m_hp;
struct LuaEntityProperties *m_prop;
SmoothTranslator pos_translator;
// Spritesheet/animation stuff
v2f m_tx_size;
v2s16 m_tx_basepos;
bool m_initial_tx_basepos_set;
bool m_tx_select_horiz_by_yawpitch;
int m_anim_frame;
int m_anim_num_frames;
@@ -562,28 +574,40 @@ class LuaEntityCAO : public ClientActiveObject
float m_anim_timer;
ItemGroupList m_armor_groups;
float m_reset_textures_timer;
bool m_visuals_expired;
float m_step_distance_counter;
u8 m_last_light;
public:
LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env):
GenericCAO(IGameDef *gamedef, ClientEnvironment *env):
ClientActiveObject(0, gamedef, env),
//
m_is_player(false),
m_is_local_player(false),
//
m_smgr(NULL),
m_irr(NULL),
m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.),
m_meshnode(NULL),
m_spritenode(NULL),
m_textnode(NULL),
m_position(v3f(0,10*BS,0)),
m_velocity(v3f(0,0,0)),
m_acceleration(v3f(0,0,0)),
m_yaw(0),
m_hp(1),
m_prop(new LuaEntityProperties),
m_tx_size(1,1),
m_tx_basepos(0,0),
m_initial_tx_basepos_set(false),
m_tx_select_horiz_by_yawpitch(false),
m_anim_frame(0),
m_anim_num_frames(1),
m_anim_framelength(0.2),
m_anim_timer(0),
m_reset_textures_timer(-1)
m_reset_textures_timer(-1),
m_visuals_expired(false),
m_step_distance_counter(0),
m_last_light(255)
{
if(gamedef == NULL)
ClientActiveObject::registerType(getType(), create);
@@ -591,108 +615,62 @@ class LuaEntityCAO : public ClientActiveObject
void initialize(const std::string &data)
{
infostream<<"LuaEntityCAO: Got init data"<<std::endl;
infostream<<"GenericCAO: Got init data"<<std::endl;
std::istringstream is(data, std::ios::binary);
// version
u8 version = readU8(is);
// check version
if(version != 1)
if(version != 0){
errorstream<<"GenericCAO: Unsupported init data version"
<<std::endl;
return;
// pos
}
m_name = deSerializeString(is);
m_is_player = readU8(is);
m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
// hp
m_hp = readS16(is);
// properties
std::istringstream prop_is(deSerializeLongString(is), std::ios::binary);
m_prop->deSerialize(prop_is);
infostream<<"m_prop: "<<m_prop->dump()<<std::endl;
m_selection_box = m_prop->collisionbox;
m_selection_box.MinEdge *= BS;
m_selection_box.MaxEdge *= BS;
pos_translator.init(m_position);
m_tx_size.X = 1.0 / m_prop->spritediv.X;
m_tx_size.Y = 1.0 / m_prop->spritediv.Y;
m_tx_basepos.X = m_tx_size.X * m_prop->initial_sprite_basepos.X;
m_tx_basepos.Y = m_tx_size.Y * m_prop->initial_sprite_basepos.Y;
int num_messages = readU8(is);
for(int i=0; i<num_messages; i++){
std::string message = deSerializeLongString(is);
processMessage(message);
}
pos_translator.init(m_position);
updateNodePos();
if(m_is_player){
Player *player = m_env->getPlayer(m_name.c_str());
if(player && player->isLocal()){
m_is_local_player = true;
}
}
}
~LuaEntityCAO()
~GenericCAO()
{
delete m_prop;
}
static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
{
return new LuaEntityCAO(gamedef, env);
return new GenericCAO(gamedef, env);
}
u8 getType() const
{
return ACTIVEOBJECT_TYPE_LUAENTITY;
return ACTIVEOBJECT_TYPE_GENERIC;
}
core::aabbox3d<f32>* getSelectionBox()
{
if(!m_prop.is_visible || m_is_local_player)
return NULL;
return &m_selection_box;
}
v3f getPosition()
{
return pos_translator.vect_show;
}
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
IrrlichtDevice *irr)
{
m_smgr = smgr;
if(m_meshnode != NULL || m_spritenode != NULL)
return;
//video::IVideoDriver* driver = smgr->getVideoDriver();
if(m_prop->visual == "sprite"){
infostream<<"LuaEntityCAO::addToScene(): single_sprite"<<std::endl;
m_spritenode = smgr->addBillboardSceneNode(
NULL, v2f(1, 1), v3f(0,0,0), -1);
m_spritenode->setMaterialTexture(0,
tsrc->getTextureRaw("unknown_block.png"));
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
m_spritenode->setColor(video::SColor(255,0,0,0));
m_spritenode->setVisible(false); /* Set visible when brightness is known */
m_spritenode->setSize(m_prop->visual_size*BS);
{
const float txs = 1.0 / 1;
const float tys = 1.0 / 1;
setBillboardTextureMatrix(m_spritenode,
txs, tys, 0, 0);
}
} else if(m_prop->visual == "cube"){
infostream<<"LuaEntityCAO::addToScene(): cube"<<std::endl;
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
m_meshnode->setScale(v3f(1));
// Will be shown when we know the brightness
m_meshnode->setVisible(false);
} else {
infostream<<"LuaEntityCAO::addToScene(): \""<<m_prop->visual
<<"\" not supported"<<std::endl;
}
updateTextures("");
updateNodePos();
}
void removeFromScene()
{
@@ -706,10 +684,157 @@ class LuaEntityCAO : public ClientActiveObject
}
}
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
IrrlichtDevice *irr)
{
m_smgr = smgr;
m_irr = irr;
if(m_meshnode != NULL || m_spritenode != NULL)
return;
m_visuals_expired = false;
if(!m_prop.is_visible || m_is_local_player)
return;
//video::IVideoDriver* driver = smgr->getVideoDriver();
if(m_prop.visual == "sprite"){
infostream<<"GenericCAO::addToScene(): single_sprite"<<std::endl;
m_spritenode = smgr->addBillboardSceneNode(
NULL, v2f(1, 1), v3f(0,0,0), -1);
m_spritenode->setMaterialTexture(0,
tsrc->getTextureRaw("unknown_block.png"));
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
u8 li = m_last_light;
m_spritenode->setColor(video::SColor(255,li,li,li));
m_spritenode->setSize(m_prop.visual_size*BS);
{
const float txs = 1.0 / 1;
const float tys = 1.0 / 1;
setBillboardTextureMatrix(m_spritenode,
txs, tys, 0, 0);
}
}
else if(m_prop.visual == "upright_sprite")
{
scene::SMesh *mesh = new scene::SMesh();
double dx = BS*m_prop.visual_size.X/2;
double dy = BS*m_prop.visual_size.Y/2;
{ // Front
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
u8 li = m_last_light;
video::SColor c(255,li,li,li);
video::S3DVertex vertices[4] =
{
video::S3DVertex(-dx,-dy,0, 0,0,0, c, 0,1),
video::S3DVertex(dx,-dy,0, 0,0,0, c, 1,1),
video::S3DVertex(dx,dy,0, 0,0,0, c, 1,0),
video::S3DVertex(-dx,dy,0, 0,0,0, c, 0,0),
};
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
}
{ // Back
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
u8 li = m_last_light;
video::SColor c(255,li,li,li);
video::S3DVertex vertices[4] =
{
video::S3DVertex(dx,-dy,0, 0,0,0, c, 1,1),
video::S3DVertex(-dx,-dy,0, 0,0,0, c, 0,1),
video::S3DVertex(-dx,dy,0, 0,0,0, c, 0,0),
video::S3DVertex(dx,dy,0, 0,0,0, c, 1,0),
};
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
}
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
// Set it to use the materials of the meshbuffers directly.
// This is needed for changing the texture in the future
m_meshnode->setReadOnlyMaterials(true);
}
else if(m_prop.visual == "cube"){
infostream<<"GenericCAO::addToScene(): cube"<<std::endl;
scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
m_meshnode->setScale(v3f(m_prop.visual_size.X,
m_prop.visual_size.Y,
m_prop.visual_size.X));
u8 li = m_last_light;
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
} else if(m_prop.visual == "wielditem"){
infostream<<"GenericCAO::addToScene(): node"<<std::endl;
infostream<<"textures: "<<m_prop.textures.size()<<std::endl;
if(m_prop.textures.size() >= 1){
infostream<<"textures[0]: "<<m_prop.textures[0]<<std::endl;
IItemDefManager *idef = m_gamedef->idef();
ItemStack item(m_prop.textures[0], 1, 0, "", idef);
scene::IMesh *mesh = item.getDefinition(idef).wield_mesh;
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
m_meshnode->setScale(v3f(m_prop.visual_size.X/2,
m_prop.visual_size.Y/2,
m_prop.visual_size.X/2));
u8 li = m_last_light;
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
}
} else {
infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual
<<"\" not supported"<<std::endl;
}
updateTextures("");
scene::ISceneNode *node = NULL;
if(m_spritenode)
node = m_spritenode;
else if(m_meshnode)
node = m_meshnode;
if(node && m_is_player && !m_is_local_player){
// Add a text node for showing the name
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
std::wstring wname = narrow_to_wide(m_name);
m_textnode = smgr->addTextSceneNode(gui->getBuiltInFont(),
wname.c_str(), video::SColor(255,255,255,255), node);
m_textnode->setPosition(v3f(0, BS*1.1, 0));
}
updateNodePos();
}
void expireVisuals()
{
m_visuals_expired = true;
}
void updateLight(u8 light_at_pos)
{
bool is_visible = (m_hp != 0);
u8 li = decode_light(light_at_pos);
m_last_light = li;
video::SColor color(255,li,li,li);
if(m_meshnode){
setMeshColor(m_meshnode->getMesh(), color);
@@ -730,6 +855,9 @@ class LuaEntityCAO : public ClientActiveObject
{
if(m_meshnode){
m_meshnode->setPosition(pos_translator.vect_show);
v3f rot = m_meshnode->getRotation();
rot.Y = -m_yaw;
m_meshnode->setRotation(rot);
}
if(m_spritenode){
m_spritenode->setPosition(pos_translator.vect_show);
@@ -738,8 +866,16 @@ class LuaEntityCAO : public ClientActiveObject
void step(float dtime, ClientEnvironment *env)
{
if(m_prop->physical){
core::aabbox3d<f32> box = m_prop->collisionbox;
v3f lastpos = pos_translator.vect_show;
if(m_visuals_expired && m_smgr && m_irr){
m_visuals_expired = false;
removeFromScene();
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
}
if(m_prop.physical){
core::aabbox3d<f32> box = m_prop.collisionbox;
box.MinEdge *= BS;
box.MaxEdge *= BS;
collisionMoveResult moveresult;
@@ -767,6 +903,20 @@ class LuaEntityCAO : public ClientActiveObject
updateNodePos();
}
float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
m_step_distance_counter += moved;
if(m_step_distance_counter > 1.5*BS){
m_step_distance_counter = 0;
if(!m_is_local_player && m_prop.makes_footstep_sound){
INodeDefManager *ndef = m_gamedef->ndef();
v3s16 p = floatToInt(getPosition() + v3f(0,
(m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS);
MapNode n = m_env->getMap().getNodeNoEx(p);
SimpleSoundSpec spec = ndef->get(n).sound_footstep;
m_gamedef->sound()->playSoundAt(spec, false, getPosition());
}
}
m_anim_timer += dtime;
if(m_anim_timer >= m_anim_framelength){
m_anim_timer -= m_anim_framelength;
@@ -784,6 +934,10 @@ class LuaEntityCAO : public ClientActiveObject
updateTextures("");
}
}
if(fabs(m_prop.automatic_rotate) > 0.001){
m_yaw += dtime * m_prop.automatic_rotate * 180 / PI;
updateNodePos();
}
}
void updateTexturePos()
@@ -838,76 +992,125 @@ class LuaEntityCAO : public ClientActiveObject
{
ITextureSource *tsrc = m_gamedef->tsrc();
if(m_spritenode){
std::string texturestring = "unknown_block.png";
if(m_prop->textures.size() >= 1)
texturestring = m_prop->textures[0];
texturestring += mod;
m_spritenode->setMaterialTexture(0,
tsrc->getTextureRaw(texturestring));
}
if(m_meshnode){
for (u32 i = 0; i < 6; ++i)
if(m_spritenode)
{
if(m_prop.visual == "sprite")
{
std::string texturestring = "unknown_block.png";
if(m_prop->textures.size() > i)
texturestring = m_prop->textures[i];
if(m_prop.textures.size() >= 1)
texturestring = m_prop.textures[0];
texturestring += mod;
AtlasPointer ap = tsrc->getTexture(texturestring);
m_spritenode->setMaterialTexture(0,
tsrc->getTextureRaw(texturestring));
}
}
if(m_meshnode)
{
if(m_prop.visual == "cube")
{
for (u32 i = 0; i < 6; ++i)
{
std::string texturestring = "unknown_block.png";
if(m_prop.textures.size() > i)
texturestring = m_prop.textures[i];
texturestring += mod;
AtlasPointer ap = tsrc->getTexture(texturestring);
// Get the tile texture and atlas transformation
video::ITexture* atlas = ap.atlas;
v2f pos = ap.pos;
v2f size = ap.size;
// Get the tile texture and atlas transformation
video::ITexture* atlas = ap.atlas;
v2f pos = ap.pos;
v2f size = ap.size;
// Set material flags and texture
video::SMaterial& material = m_meshnode->getMaterial(i);
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setTexture(0, atlas);
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
// Set material flags and texture
video::SMaterial& material = m_meshnode->getMaterial(i);
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setTexture(0, atlas);
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
}
}
else if(m_prop.visual == "upright_sprite")
{
scene::IMesh *mesh = m_meshnode->getMesh();
{
std::string tname = "unknown_object.png";
if(m_prop.textures.size() >= 1)
tname = m_prop.textures[0];
tname += mod;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
buf->getMaterial().setTexture(0,
tsrc->getTextureRaw(tname));
}
{
std::string tname = "unknown_object.png";
if(m_prop.textures.size() >= 2)
tname = m_prop.textures[1];
else if(m_prop.textures.size() >= 1)
tname = m_prop.textures[0];
tname += mod;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
buf->getMaterial().setTexture(0,
tsrc->getTextureRaw(tname));
}
}
}
}
void processMessage(const std::string &data)
{
//infostream<<"LuaEntityCAO: Got message"<<std::endl;
//infostream<<"GenericCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
if(cmd == LUAENTITY_CMD_UPDATE_POSITION) // update position
if(cmd == GENERIC_CMD_SET_PROPERTIES)
{
m_prop = gob_read_set_properties(is);
m_selection_box = m_prop.collisionbox;
m_selection_box.MinEdge *= BS;
m_selection_box.MaxEdge *= BS;
m_tx_size.X = 1.0 / m_prop.spritediv.X;
m_tx_size.Y = 1.0 / m_prop.spritediv.Y;
if(!m_initial_tx_basepos_set){
m_initial_tx_basepos_set = true;
m_tx_basepos = m_prop.initial_sprite_basepos;
}
expireVisuals();
}
else if(cmd == GENERIC_CMD_UPDATE_POSITION)
{
// do_interpolate
bool do_interpolate = readU8(is);
// pos
m_position = readV3F1000(is);
// velocity
m_velocity = readV3F1000(is);
// acceleration
m_acceleration = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
// is_end_position (for interpolation)
if(fabs(m_prop.automatic_rotate) < 0.001)
m_yaw = readF1000(is);
bool do_interpolate = readU8(is);
bool is_end_position = readU8(is);
// update_interval
float update_interval = readF1000(is);
// Place us a bit higher if we're physical, to not sink into
// the ground due to sucky collision detection...
if(m_prop.physical)
m_position += v3f(0,0.002,0);
if(do_interpolate){
if(!m_prop->physical)
if(!m_prop.physical)
pos_translator.update(m_position, is_end_position, update_interval);
} else {
pos_translator.init(m_position);
}
updateNodePos();
}
else if(cmd == LUAENTITY_CMD_SET_TEXTURE_MOD) // set texture modification
else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD)
{
std::string mod = deSerializeString(is);
updateTextures(mod);
}
else if(cmd == LUAENTITY_CMD_SET_SPRITE) // set sprite
else if(cmd == GENERIC_CMD_SET_SPRITE)
{
v2s16 p = readV2S16(is);
int num_frames = readU16(is);
@@ -921,15 +1124,14 @@ class LuaEntityCAO : public ClientActiveObject
updateTexturePos();
}
else if(cmd == LUAENTITY_CMD_PUNCHED)
else if(cmd == GENERIC_CMD_PUNCHED)
{
/*s16 damage =*/ readS16(is);
s16 result_hp = readS16(is);
m_hp = result_hp;
// TODO: Execute defined fast response
}
else if(cmd == LUAENTITY_CMD_UPDATE_ARMOR_GROUPS)
else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS)
{
m_armor_groups.clear();
int armor_groups_size = readU16(is);
@@ -952,7 +1154,7 @@ class LuaEntityCAO : public ClientActiveObject
toolcap,
punchitem,
time_from_last_punch);
if(result.did_punch && result.damage != 0)
{
if(result.damage < m_hp){
@@ -963,13 +1165,15 @@ class LuaEntityCAO : public ClientActiveObject
// As there is no definition, make a smoke puff
ClientSimpleObject *simple = createSmokePuff(
m_smgr, m_env, m_position,
m_prop->visual_size * BS);
m_prop.visual_size * BS);
m_env->addSimpleObject(simple);
}
// TODO: Execute defined fast response
// Flashing shall suffice as there is no definition
m_reset_textures_timer = 0.05;
if(result.damage >= 2)
m_reset_textures_timer += 0.05 * result.damage;
updateTextures("^[brighten");
m_reset_textures_timer = 0.1;
}
return false;
@@ -978,7 +1182,7 @@ class LuaEntityCAO : public ClientActiveObject
std::string debugInfoText()
{
std::ostringstream os(std::ios::binary);
os<<"LuaEntityCAO hp="<<m_hp<<"\n";
os<<"GenericCAO hp="<<m_hp<<"\n";
os<<"armor={";
for(ItemGroupList::const_iterator i = m_armor_groups.begin();
i != m_armor_groups.end(); i++){
@@ -990,307 +1194,6 @@ class LuaEntityCAO : public ClientActiveObject
};
// Prototype
LuaEntityCAO proto_LuaEntityCAO(NULL, NULL);
/*
PlayerCAO
*/
class PlayerCAO : public ClientActiveObject
{
private:
core::aabbox3d<f32> m_selection_box;
scene::IMeshSceneNode *m_node;
scene::ITextSceneNode* m_text;
std::string m_name;
v3f m_position;
float m_yaw;
SmoothTranslator pos_translator;
bool m_is_local_player;
LocalPlayer *m_local_player;
float m_damage_visual_timer;
bool m_dead;
float m_step_distance_counter;
public:
PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
ClientActiveObject(0, gamedef, env),
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.0,BS/3.),
m_node(NULL),
m_text(NULL),
m_position(v3f(0,10*BS,0)),
m_yaw(0),
m_is_local_player(false),
m_local_player(NULL),
m_damage_visual_timer(0),
m_dead(false),
m_step_distance_counter(0)
{
if(gamedef == NULL)
ClientActiveObject::registerType(getType(), create);
}
void initialize(const std::string &data)
{
infostream<<"PlayerCAO: Got init data"<<std::endl;
std::istringstream is(data, std::ios::binary);
// version
u8 version = readU8(is);
// check version
if(version != 0)
return;
// name
m_name = deSerializeString(is);
// pos
m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
// dead
m_dead = readU8(is);
pos_translator.init(m_position);
Player *player = m_env->getPlayer(m_name.c_str());
if(player && player->isLocal()){
m_is_local_player = true;
m_local_player = (LocalPlayer*)player;
}
}
~PlayerCAO()
{
if(m_node)
m_node->remove();
}
static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
{
return new PlayerCAO(gamedef, env);
}
u8 getType() const
{
return ACTIVEOBJECT_TYPE_PLAYER;
}
core::aabbox3d<f32>* getSelectionBox()
{
if(m_is_local_player)
return NULL;
if(m_dead)
return NULL;
return &m_selection_box;
}
v3f getPosition()
{
return pos_translator.vect_show;
}
void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
IrrlichtDevice *irr)
{
if(m_node != NULL)
return;
if(m_is_local_player)
return;
//video::IVideoDriver* driver = smgr->getVideoDriver();
gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
scene::SMesh *mesh = new scene::SMesh();
{ // Front
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
video::SColor c(255,255,255,255);
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
};
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
}
{ // Back
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
video::SColor c(255,255,255,255);
video::S3DVertex vertices[4] =
{
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
};
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
}
m_node = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
// Set it to use the materials of the meshbuffers directly.
// This is needed for changing the texture in the future
m_node->setReadOnlyMaterials(true);
updateNodePos();
// Add a text node for showing the name
std::wstring wname = narrow_to_wide(m_name);
m_text = smgr->addTextSceneNode(gui->getBuiltInFont(),
wname.c_str(), video::SColor(255,255,255,255), m_node);
m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
updateTextures("");
updateVisibility();
updateNodePos();
}
void removeFromScene()
{
if(m_node == NULL)
return;
m_node->remove();
m_node = NULL;
}
void updateLight(u8 light_at_pos)
{
if(m_node == NULL)
return;
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
setMeshColor(m_node->getMesh(), color);
updateVisibility();
}
v3s16 getLightPosition()
{
return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
}
void updateVisibility()
{
if(m_node == NULL)
return;
m_node->setVisible(!m_dead);
}
void updateNodePos()
{
if(m_node == NULL)
return;
m_node->setPosition(pos_translator.vect_show);
v3f rot = m_node->getRotation();
rot.Y = -m_yaw;
m_node->setRotation(rot);
}
void step(float dtime, ClientEnvironment *env)
{
v3f lastpos = pos_translator.vect_show;
pos_translator.translate(dtime);
float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
updateVisibility();
updateNodePos();
if(m_damage_visual_timer > 0){
m_damage_visual_timer -= dtime;
if(m_damage_visual_timer <= 0){
updateTextures("");
}
}
m_step_distance_counter += moved;
if(m_step_distance_counter > 1.5*BS){
m_step_distance_counter = 0;
if(!m_is_local_player){
INodeDefManager *ndef = m_gamedef->ndef();
v3s16 p = floatToInt(getPosition()+v3f(0,-0.5*BS, 0), BS);
MapNode n = m_env->getMap().getNodeNoEx(p);
SimpleSoundSpec spec = ndef->get(n).sound_footstep;
m_gamedef->sound()->playSoundAt(spec, false, getPosition());
}
}
}
void processMessage(const std::string &data)
{
//infostream<<"PlayerCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
if(cmd == 0) // update position
{
// pos
m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
pos_translator.update(m_position, false);
updateNodePos();
}
else if(cmd == 1) // punched
{
// damage
s16 damage = readS16(is);
m_damage_visual_timer = 0.05;
if(damage >= 2)
m_damage_visual_timer += 0.05 * damage;
updateTextures("^[brighten");
}
else if(cmd == 2) // died or respawned
{
m_dead = readU8(is);
updateVisibility();
}
}
void updateTextures(const std::string &mod)
{
if(!m_node)
return;
ITextureSource *tsrc = m_gamedef->tsrc();
scene::IMesh *mesh = m_node->getMesh();
if(mesh){
{
std::string tname = "player.png";
tname += mod;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
buf->getMaterial().setTexture(0,
tsrc->getTextureRaw(tname));
}
{
std::string tname = "player_back.png";
tname += mod;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
buf->getMaterial().setTexture(0,
tsrc->getTextureRaw(tname));
}
}
}
};
// Prototype
PlayerCAO proto_PlayerCAO(NULL, NULL);
GenericCAO proto_GenericCAO(NULL, NULL);

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -210,8 +210,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
top_is_same_liquid = true;
u16 l = 0;
// If this liquid emits light and doesn't contain light, draw
// it at what it emits, for an increased effect
u8 light_source = nodedef->get(n).light_source;
if(light_source != 0){
//l = decode_light(undiminish_light(light_source));
l = decode_light(light_source);
l = l | (l<<8);
}
// Use the light of the node on top if possible
if(nodedef->get(ntop).param_type == CPT_LIGHT)
else if(nodedef->get(ntop).param_type == CPT_LIGHT)
l = getInteriorLight(ntop, 0, data);
// Otherwise use the light of this node (the liquid)
else
@@ -727,12 +735,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
TileSpec tile = getNodeTile(n, p, v3s16(0,0,0), data);
TileSpec tile_nocrack = tile;
tile_nocrack.material_flags &= ~MATERIAL_FLAG_CRACK;
// A hack to put wood the right way around in the posts
ITextureSource *tsrc = data->m_gamedef->tsrc();
TileSpec tile_rot = tile;
tile_rot.texture = tsrc->getTexture(tsrc->getTextureName(
tile.texture.id) + "^[transformR90");
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l);
const f32 post_rad=(f32)BS/10;
const f32 bar_rad=(f32)BS/20;
const f32 post_rad=(f32)BS/8;
const f32 bar_rad=(f32)BS/16;
const f32 bar_len=(f32)(BS/2)-post_rad;
v3f pos = intToFloat(p, BS);
@@ -742,13 +756,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
post.MinEdge += pos;
post.MaxEdge += pos;
f32 postuv[24]={
0.4,0.4,0.6,0.6,
0.4,0.4,0.6,0.6,
0.35,0,0.65,1,
0.35,0,0.65,1,
0.35,0,0.65,1,
0.35,0,0.65,1};
makeCuboid(&collector, post, &tile, 1, c, postuv);
6/16.,6/16.,10/16.,10/16.,
6/16.,6/16.,10/16.,10/16.,
0/16.,0,4/16.,1,
4/16.,0,8/16.,1,
8/16.,0,12/16.,1,
12/16.,0,16/16.,1};
makeCuboid(&collector, post, &tile_rot, 1, c, postuv);
// Now a section of fence, +X, if there's a post there
v3s16 p2 = p;
@@ -762,17 +776,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
bar.MinEdge += pos;
bar.MaxEdge += pos;
f32 xrailuv[24]={
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6};
0/16.,2/16.,16/16.,4/16.,
0/16.,4/16.,16/16.,6/16.,
6/16.,6/16.,8/16.,8/16.,
10/16.,10/16.,12/16.,12/16.,
0/16.,8/16.,16/16.,10/16.,
0/16.,14/16.,16/16.,16/16.};
makeCuboid(&collector, bar, &tile_nocrack, 1,
c, xrailuv);
bar.MinEdge.Y -= BS/2;
bar.MaxEdge.Y -= BS/2;
// TODO: no crack
makeCuboid(&collector, bar, &tile_nocrack, 1,
c, xrailuv);
}
@@ -789,13 +802,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
bar.MinEdge += pos;
bar.MaxEdge += pos;
f32 zrailuv[24]={
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6,
0,0.4,1,0.6};
3/16.,1/16.,5/16.,5/16., // cannot rotate; stretch
4/16.,1/16.,6/16.,5/16., // for wood texture instead
0/16.,9/16.,16/16.,11/16.,
0/16.,6/16.,16/16.,8/16.,
6/16.,6/16.,8/16.,8/16.,
10/16.,10/16.,12/16.,12/16.};
makeCuboid(&collector, bar, &tile_nocrack, 1,
c, zrailuv);
bar.MinEdge.Y -= BS/2;
@@ -856,7 +868,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
if(n_plus_z_plus_y.getContent() == thiscontent)
is_rail_z_plus_y[1] = true;
bool is_rail_x_all[] = {false, false};
bool is_rail_z_all[] = {false, false};
is_rail_x_all[0]=is_rail_x[0] || is_rail_x_minus_y[0] || is_rail_x_plus_y[0];
@@ -864,30 +875,69 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
is_rail_z_all[0]=is_rail_z[0] || is_rail_z_minus_y[0] || is_rail_z_plus_y[0];
is_rail_z_all[1]=is_rail_z[1] || is_rail_z_minus_y[1] || is_rail_z_plus_y[1];
bool is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);//is really straight, rails on both sides
int adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
// reasonable default, flat straight unrotated rail
bool is_straight = true;
int adjacencies = 0;
int angle = 0;
u8 tileindex = 0;
if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1]) //is straight because sloped
// check for sloped rail
if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1])
{
adjacencies = 5; //5 means sloped
is_straight = true;
is_straight = true; // sloped is always straight
}
else
{
// is really straight, rails on both sides
is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);
adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
}
// Assign textures
u8 tileindex = 0; // straight
if(adjacencies < 2)
tileindex = 0; // straight
else if(adjacencies == 2)
{
if(is_straight)
tileindex = 0; // straight
else
switch (adjacencies) {
case 1:
if(is_rail_x_all[0] || is_rail_x_all[1])
angle = 90;
break;
case 2:
if(!is_straight)
tileindex = 1; // curved
}
else if(adjacencies == 3)
if(is_rail_x_all[0] && is_rail_x_all[1])
angle = 90;
if(is_rail_z_all[0] && is_rail_z_all[1]){
if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
}
else if(is_rail_x_all[0] && is_rail_z_all[0])
angle = 270;
else if(is_rail_x_all[0] && is_rail_z_all[1])
angle = 180;
else if(is_rail_x_all[1] && is_rail_z_all[1])
angle = 90;
break;
case 3:
// here is where the potential to 'switch' a junction is, but not implemented at present
tileindex = 2; // t-junction
else if(adjacencies == 4)
if(!is_rail_x_all[1])
angle=180;
if(!is_rail_z_all[0])
angle=90;
if(!is_rail_z_all[1])
angle=270;
break;
case 4:
tileindex = 3; // crossing
break;
case 5: //sloped
if(is_rail_z_plus_y[0])
angle = 180;
if(is_rail_x_plus_y[0])
angle = 90;
if(is_rail_x_plus_y[1])
angle = -90;
break;
default:
break;
}
TileSpec tile = getNodeTileN(n, p, tileindex, data);
tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
@@ -916,61 +966,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
ap.x0(), ap.y0()),
};
// Rotate textures
int angle = 0;
if(adjacencies == 1)
{
if(is_rail_x_all[0] || is_rail_x_all[1])
angle = 90;
}
if(adjacencies == 2)
{
if(is_rail_x_all[0] && is_rail_x_all[1])
{
angle = 90;
}
if(is_rail_z_all[0] && is_rail_z_all[1])
{
if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
}
else if(is_rail_x_all[0] && is_rail_z_all[0])
angle = 270;
else if(is_rail_x_all[0] && is_rail_z_all[1])
angle = 180;
else if(is_rail_x_all[1] && is_rail_z_all[1])
angle = 90;
}
if(adjacencies == 3)
{
if(!is_rail_x_all[0])
angle=0;
if(!is_rail_x_all[1])
angle=180;
if(!is_rail_z_all[0])
angle=90;
if(!is_rail_z_all[1])
angle=270;
}
//adjacencies 4: Crossing
if(adjacencies == 5) //sloped
{
if(is_rail_z_plus_y[0])
angle = 180;
if(is_rail_x_plus_y[0])
angle = 90;
if(is_rail_x_plus_y[1])
angle = -90;
}
if(angle != 0) {
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(angle);
}
for(s32 i=0; i<4; i++)
{
if(angle != 0)
vertices[i].Pos.rotateXZBy(angle);
vertices[i].Pos += intToFloat(p, BS);
}

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -1,32 +1,27 @@
/*
Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "content_nodemeta.h"
#include <map>
#include "inventory.h"
#include "log.h"
#include "utility.h"
#include "craftdef.h"
#include "gamedef.h"
class Inventory;
#include <sstream>
#define NODEMETA_GENERIC 1
#define NODEMETA_SIGN 14
@@ -34,809 +29,167 @@ class Inventory;
#define NODEMETA_FURNACE 16
#define NODEMETA_LOCKABLE_CHEST 17
core::map<u16, NodeMetadata::Factory> NodeMetadata::m_types;
core::map<std::string, NodeMetadata::Factory2> NodeMetadata::m_names;
// Returns true if node timer must be set
static bool content_nodemeta_deserialize_legacy_body(
std::istream &is, s16 id, NodeMetadata *meta)
{
meta->clear();
class SignNodeMetadata : public NodeMetadata
{
public:
SignNodeMetadata(IGameDef *gamedef, std::string text);
//~SignNodeMetadata();
virtual u16 typeId() const;
virtual const char* typeName() const
{ return "sign"; }
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
static NodeMetadata* create(IGameDef *gamedef);
virtual NodeMetadata* clone(IGameDef *gamedef);
virtual void serializeBody(std::ostream &os);
virtual std::string infoText();
virtual bool allowsTextInput(){ return true; }
virtual std::string getText(){ return m_text; }
virtual void setText(const std::string &t){ m_text = t; }
private:
std::string m_text;
};
class ChestNodeMetadata : public NodeMetadata
{
public:
ChestNodeMetadata(IGameDef *gamedef);
~ChestNodeMetadata();
virtual u16 typeId() const;
virtual const char* typeName() const
{ return "chest"; }
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
static NodeMetadata* create(IGameDef *gamedef);
virtual NodeMetadata* clone(IGameDef *gamedef);
virtual void serializeBody(std::ostream &os);
virtual std::string infoText();
virtual Inventory* getInventory() {return m_inventory;}
virtual bool nodeRemovalDisabled();
virtual std::string getInventoryDrawSpecString();
private:
Inventory *m_inventory;
};
class LockingChestNodeMetadata : public NodeMetadata
{
public:
LockingChestNodeMetadata(IGameDef *gamedef);
~LockingChestNodeMetadata();
virtual u16 typeId() const;
virtual const char* typeName() const
{ return "locked_chest"; }
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
static NodeMetadata* create(IGameDef *gamedef);
virtual NodeMetadata* clone(IGameDef *gamedef);
virtual void serializeBody(std::ostream &os);
virtual std::string infoText();
virtual Inventory* getInventory() {return m_inventory;}
virtual bool nodeRemovalDisabled();
virtual std::string getInventoryDrawSpecString();
virtual std::string getOwner(){ return m_text; }
virtual void setOwner(std::string t){ m_text = t; }
private:
Inventory *m_inventory;
std::string m_text;
};
class FurnaceNodeMetadata : public NodeMetadata
{
public:
FurnaceNodeMetadata(IGameDef *gamedef);
~FurnaceNodeMetadata();
virtual u16 typeId() const;
virtual const char* typeName() const
{ return "furnace"; }
virtual NodeMetadata* clone(IGameDef *gamedef);
static NodeMetadata* create(std::istream &is, IGameDef *gamedef);
static NodeMetadata* create(IGameDef *gamedef);
virtual void serializeBody(std::ostream &os);
virtual std::string infoText();
virtual Inventory* getInventory() {return m_inventory;}
virtual void inventoryModified();
virtual bool step(float dtime);
virtual bool nodeRemovalDisabled();
virtual std::string getInventoryDrawSpecString();
protected:
bool getCookResult(bool remove, std::string &cookresult, float &cooktime);
bool getBurnResult(bool remove, float &burntime);
private:
Inventory *m_inventory;
std::string m_infotext;
float m_step_accumulator;
float m_fuel_totaltime;
float m_fuel_time;
float m_src_totaltime;
float m_src_time;
};
/*
SignNodeMetadata
*/
// Prototype
SignNodeMetadata proto_SignNodeMetadata(NULL, "");
SignNodeMetadata::SignNodeMetadata(IGameDef *gamedef, std::string text):
NodeMetadata(gamedef),
m_text(text)
{
NodeMetadata::registerType(typeId(), typeName(), create, create);
}
u16 SignNodeMetadata::typeId() const
{
return NODEMETA_SIGN;
}
NodeMetadata* SignNodeMetadata::create(std::istream &is, IGameDef *gamedef)
{
std::string text = deSerializeString(is);
return new SignNodeMetadata(gamedef, text);
}
NodeMetadata* SignNodeMetadata::create(IGameDef *gamedef)
{
return new SignNodeMetadata(gamedef, "");
}
NodeMetadata* SignNodeMetadata::clone(IGameDef *gamedef)
{
return new SignNodeMetadata(gamedef, m_text);
}
void SignNodeMetadata::serializeBody(std::ostream &os)
{
os<<serializeString(m_text);
}
std::string SignNodeMetadata::infoText()
{
return std::string("\"")+m_text+"\"";
}
/*
ChestNodeMetadata
*/
// Prototype
ChestNodeMetadata proto_ChestNodeMetadata(NULL);
ChestNodeMetadata::ChestNodeMetadata(IGameDef *gamedef):
NodeMetadata(gamedef)
{
NodeMetadata::registerType(typeId(), typeName(), create, create);
m_inventory = NULL;
}
ChestNodeMetadata::~ChestNodeMetadata()
{
delete m_inventory;
}
u16 ChestNodeMetadata::typeId() const
{
return NODEMETA_CHEST;
}
NodeMetadata* ChestNodeMetadata::create(std::istream &is, IGameDef *gamedef)
{
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->deSerialize(is);
return d;
}
NodeMetadata* ChestNodeMetadata::create(IGameDef *gamedef)
{
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->addList("0", 8*4);
return d;
}
NodeMetadata* ChestNodeMetadata::clone(IGameDef *gamedef)
{
ChestNodeMetadata *d = new ChestNodeMetadata(gamedef);
d->m_inventory = new Inventory(*m_inventory);
return d;
}
void ChestNodeMetadata::serializeBody(std::ostream &os)
{
m_inventory->serialize(os);
}
std::string ChestNodeMetadata::infoText()
{
return "Chest";
}
bool ChestNodeMetadata::nodeRemovalDisabled()
{
/*
Disable removal if chest contains something
*/
InventoryList *list = m_inventory->getList("0");
if(list == NULL)
return false;
if(list->getUsedSlots() == 0)
return false;
return true;
}
std::string ChestNodeMetadata::getInventoryDrawSpecString()
{
return
"invsize[8,9;]"
"list[current_name;0;0,0;8,4;]"
"list[current_player;main;0,5;8,4;]";
}
/*
LockingChestNodeMetadata
*/
// Prototype
LockingChestNodeMetadata proto_LockingChestNodeMetadata(NULL);
LockingChestNodeMetadata::LockingChestNodeMetadata(IGameDef *gamedef):
NodeMetadata(gamedef)
{
NodeMetadata::registerType(typeId(), typeName(), create, create);
m_inventory = NULL;
}
LockingChestNodeMetadata::~LockingChestNodeMetadata()
{
delete m_inventory;
}
u16 LockingChestNodeMetadata::typeId() const
{
return NODEMETA_LOCKABLE_CHEST;
}
NodeMetadata* LockingChestNodeMetadata::create(std::istream &is, IGameDef *gamedef)
{
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
d->setOwner(deSerializeString(is));
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->deSerialize(is);
return d;
}
NodeMetadata* LockingChestNodeMetadata::create(IGameDef *gamedef)
{
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->addList("0", 8*4);
return d;
}
NodeMetadata* LockingChestNodeMetadata::clone(IGameDef *gamedef)
{
LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef);
d->m_inventory = new Inventory(*m_inventory);
return d;
}
void LockingChestNodeMetadata::serializeBody(std::ostream &os)
{
os<<serializeString(m_text);
m_inventory->serialize(os);
}
std::string LockingChestNodeMetadata::infoText()
{
return "Locking Chest";
}
bool LockingChestNodeMetadata::nodeRemovalDisabled()
{
/*
Disable removal if chest contains something
*/
InventoryList *list = m_inventory->getList("0");
if(list == NULL)
return false;
if(list->getUsedSlots() == 0)
return false;
return true;
}
std::string LockingChestNodeMetadata::getInventoryDrawSpecString()
{
return
"invsize[8,9;]"
"list[current_name;0;0,0;8,4;]"
"list[current_player;main;0,5;8,4;]";
}
/*
FurnaceNodeMetadata
*/
// Prototype
FurnaceNodeMetadata proto_FurnaceNodeMetadata(NULL);
FurnaceNodeMetadata::FurnaceNodeMetadata(IGameDef *gamedef):
NodeMetadata(gamedef)
{
NodeMetadata::registerType(typeId(), typeName(), create, create);
m_inventory = NULL;
m_infotext = "Furnace is inactive";
m_step_accumulator = 0;
m_fuel_totaltime = 0;
m_fuel_time = 0;
m_src_totaltime = 0;
m_src_time = 0;
}
FurnaceNodeMetadata::~FurnaceNodeMetadata()
{
delete m_inventory;
}
u16 FurnaceNodeMetadata::typeId() const
{
return NODEMETA_FURNACE;
}
NodeMetadata* FurnaceNodeMetadata::clone(IGameDef *gamedef)
{
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(m_gamedef);
d->m_inventory = new Inventory(*m_inventory);
return d;
}
NodeMetadata* FurnaceNodeMetadata::create(std::istream &is, IGameDef *gamedef)
{
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->deSerialize(is);
int temp = 0;
is>>temp;
d->m_fuel_totaltime = (float)temp/10;
temp = 0;
is>>temp;
d->m_fuel_time = (float)temp/10;
temp = 0;
is>>temp;
d->m_src_totaltime = (float)temp/10;
temp = 0;
is>>temp;
d->m_src_time = (float)temp/10;
if(is.eof())
if(id == NODEMETA_GENERIC) // GenericNodeMetadata (0.4-dev)
{
// Old furnaces didn't serialize src_totaltime and src_time
d->m_src_totaltime = 0;
d->m_src_time = 0;
d->m_infotext = "";
}
else
{
// New furnaces also serialize the infotext (so that the
// client doesn't need to have the list of cooking recipes).
d->m_infotext = deSerializeJsonString(is);
}
meta->getInventory()->deSerialize(is);
deSerializeLongString(is); // m_text
deSerializeString(is); // m_owner
return d;
}
NodeMetadata* FurnaceNodeMetadata::create(IGameDef *gamedef)
{
FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->addList("fuel", 1);
d->m_inventory->addList("src", 1);
d->m_inventory->addList("dst", 4);
return d;
}
void FurnaceNodeMetadata::serializeBody(std::ostream &os)
{
m_inventory->serialize(os);
os<<itos(m_fuel_totaltime*10)<<" ";
os<<itos(m_fuel_time*10)<<" ";
os<<itos(m_src_totaltime*10)<<" ";
os<<itos(m_src_time*10)<<" ";
os<<serializeJsonString(m_infotext);
}
std::string FurnaceNodeMetadata::infoText()
{
return m_infotext;
}
bool FurnaceNodeMetadata::nodeRemovalDisabled()
{
/*
Disable removal if furnace is not empty
*/
InventoryList *list[3] = {m_inventory->getList("src"),
m_inventory->getList("dst"), m_inventory->getList("fuel")};
for(int i = 0; i < 3; i++) {
if(list[i] == NULL)
continue;
if(list[i]->getUsedSlots() == 0)
continue;
return true;
}
return false;
}
void FurnaceNodeMetadata::inventoryModified()
{
infostream<<"Furnace inventory modification callback"<<std::endl;
}
bool FurnaceNodeMetadata::step(float dtime)
{
if(dtime > 60.0)
infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
InventoryList *dst_list = m_inventory->getList("dst");
assert(dst_list);
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
bool changed = false;
while(m_step_accumulator > interval)
{
m_step_accumulator -= interval;
dtime = interval;
//infostream<<"Furnace step dtime="<<dtime<<std::endl;
bool changed_this_loop = false;
// Check
// 1. if the source item is cookable
// 2. if there is room for the cooked item
std::string cookresult;
float cooktime;
bool cookable = getCookResult(false, cookresult, cooktime);
ItemStack cookresult_item;
bool room_available = false;
if(cookable)
{
cookresult_item.deSerialize(cookresult, m_gamedef->idef());
room_available = dst_list->roomForItem(cookresult_item);
}
// Step fuel time
bool burning = (m_fuel_time < m_fuel_totaltime);
if(burning)
{
changed_this_loop = true;
m_fuel_time += dtime;
}
std::string infotext;
if(room_available)
{
float burntime;
if(burning)
{
changed_this_loop = true;
m_src_time += dtime;
m_src_totaltime = cooktime;
infotext = "Furnace is cooking";
}
else if(getBurnResult(true, burntime))
{
// Fuel inserted
changed_this_loop = true;
m_fuel_time = 0;
m_fuel_totaltime = burntime;
//m_src_time += dtime;
//m_src_totaltime = cooktime;
infotext = "Furnace is cooking";
}
else
{
m_src_time = 0;
m_src_totaltime = 0;
infotext = "Furnace is out of fuel";
}
if(m_src_totaltime > 0.001 && m_src_time >= m_src_totaltime)
{
// One item fully cooked
changed_this_loop = true;
dst_list->addItem(cookresult_item);
getCookResult(true, cookresult, cooktime); // decrement source
m_src_totaltime = 0;
m_src_time = 0;
}
}
else
{
// Not cookable or no room available
m_src_totaltime = 0;
m_src_time = 0;
if(cookable)
infotext = "Furnace is overloaded";
else if(burning)
infotext = "Furnace is active";
else
{
infotext = "Furnace is inactive";
m_fuel_totaltime = 0;
m_fuel_time = 0;
}
}
// Do this so it doesn't always show (0%) for weak fuel
if(m_fuel_totaltime > 3) {
infotext += " (";
infotext += itos(m_fuel_time/m_fuel_totaltime*100);
infotext += "%)";
}
if(infotext != m_infotext)
{
m_infotext = infotext;
changed_this_loop = true;
}
if(burning && m_fuel_time >= m_fuel_totaltime)
{
m_fuel_time = 0;
m_fuel_totaltime = 0;
}
if(changed_this_loop)
{
changed = true;
}
else
{
m_step_accumulator = 0;
break;
}
}
return changed;
}
std::string FurnaceNodeMetadata::getInventoryDrawSpecString()
{
return
"invsize[8,9;]"
"list[current_name;fuel;2,3;1,1;]"
"list[current_name;src;2,1;1,1;]"
"list[current_name;dst;5,1;2,2;]"
"list[current_player;main;0,5;8,4;]";
}
bool FurnaceNodeMetadata::getCookResult(bool remove,
std::string &cookresult, float &cooktime)
{
std::vector<ItemStack> items;
InventoryList *src_list = m_inventory->getList("src");
assert(src_list);
items.push_back(src_list->getItem(0));
CraftInput ci(CRAFT_METHOD_COOKING, 1, items);
CraftOutput co;
bool found = m_gamedef->getCraftDefManager()->getCraftResult(
ci, co, remove, m_gamedef);
if(remove)
src_list->changeItem(0, ci.items[0]);
cookresult = co.item;
cooktime = co.time;
return found;
}
bool FurnaceNodeMetadata::getBurnResult(bool remove, float &burntime)
{
std::vector<ItemStack> items;
InventoryList *fuel_list = m_inventory->getList("fuel");
assert(fuel_list);
items.push_back(fuel_list->getItem(0));
CraftInput ci(CRAFT_METHOD_FUEL, 1, items);
CraftOutput co;
bool found = m_gamedef->getCraftDefManager()->getCraftResult(
ci, co, remove, m_gamedef);
if(remove)
fuel_list->changeItem(0, ci.items[0]);
burntime = co.time;
return found;
}
/*
GenericNodeMetadata
*/
class GenericNodeMetadata : public NodeMetadata
{
private:
Inventory *m_inventory;
std::string m_text;
std::string m_owner;
std::string m_infotext;
std::string m_inventorydrawspec;
bool m_allow_text_input;
bool m_removal_disabled;
bool m_enforce_owner;
bool m_inventory_modified;
bool m_text_modified;
std::map<std::string, std::string> m_stringvars;
public:
u16 typeId() const
{
return NODEMETA_GENERIC;
}
const char* typeName() const
{
return "generic";
}
GenericNodeMetadata(IGameDef *gamedef):
NodeMetadata(gamedef),
m_inventory(NULL),
m_text(""),
m_owner(""),
m_infotext("GenericNodeMetadata"),
m_inventorydrawspec(""),
m_allow_text_input(false),
m_removal_disabled(false),
m_enforce_owner(false),
m_inventory_modified(false),
m_text_modified(false)
{
NodeMetadata::registerType(typeId(), typeName(), create, create);
}
virtual ~GenericNodeMetadata()
{
delete m_inventory;
}
NodeMetadata* clone(IGameDef *gamedef)
{
GenericNodeMetadata *d = new GenericNodeMetadata(m_gamedef);
d->m_inventory = new Inventory(*m_inventory);
d->m_text = m_text;
d->m_owner = m_owner;
d->m_infotext = m_infotext;
d->m_inventorydrawspec = m_inventorydrawspec;
d->m_allow_text_input = m_allow_text_input;
d->m_removal_disabled = m_removal_disabled;
d->m_enforce_owner = m_enforce_owner;
d->m_inventory_modified = m_inventory_modified;
d->m_text_modified = m_text_modified;
return d;
}
static NodeMetadata* create(IGameDef *gamedef)
{
GenericNodeMetadata *d = new GenericNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
return d;
}
static NodeMetadata* create(std::istream &is, IGameDef *gamedef)
{
GenericNodeMetadata *d = new GenericNodeMetadata(gamedef);
d->m_inventory = new Inventory(gamedef->idef());
d->m_inventory->deSerialize(is);
d->m_text = deSerializeLongString(is);
d->m_owner = deSerializeString(is);
d->m_infotext = deSerializeString(is);
d->m_inventorydrawspec = deSerializeString(is);
d->m_allow_text_input = readU8(is);
d->m_removal_disabled = readU8(is);
d->m_enforce_owner = readU8(is);
meta->setString("infotext",deSerializeString(is));
meta->setString("formspec",deSerializeString(is));
readU8(is); // m_allow_text_input
readU8(is); // m_allow_removal
readU8(is); // m_enforce_owner
int num_vars = readU32(is);
for(int i=0; i<num_vars; i++){
std::string name = deSerializeString(is);
std::string var = deSerializeLongString(is);
d->m_stringvars[name] = var;
meta->setString(name, var);
}
return d;
}
void serializeBody(std::ostream &os)
{
m_inventory->serialize(os);
os<<serializeLongString(m_text);
os<<serializeString(m_owner);
os<<serializeString(m_infotext);
os<<serializeString(m_inventorydrawspec);
writeU8(os, m_allow_text_input);
writeU8(os, m_removal_disabled);
writeU8(os, m_enforce_owner);
int num_vars = m_stringvars.size();
writeU32(os, num_vars);
for(std::map<std::string, std::string>::iterator
i = m_stringvars.begin(); i != m_stringvars.end(); i++){
os<<serializeString(i->first);
os<<serializeLongString(i->second);
}
}
std::string infoText()
{
return m_infotext;
}
Inventory* getInventory()
{
return m_inventory;
}
void inventoryModified()
{
m_inventory_modified = true;
}
bool step(float dtime)
{
return false;
}
bool nodeRemovalDisabled()
else if(id == NODEMETA_SIGN) // SignNodeMetadata
{
return m_removal_disabled;
meta->setString("text", deSerializeString(is));
//meta->setString("infotext","\"${text}\"");
meta->setString("infotext",
std::string("\"") + meta->getString("text") + "\"");
meta->setString("formspec","hack:sign_text_input");
return false;
}
std::string getInventoryDrawSpecString()
else if(id == NODEMETA_CHEST) // ChestNodeMetadata
{
return m_inventorydrawspec;
}
bool allowsTextInput()
{
return m_allow_text_input;
}
std::string getText()
{
return m_text;
}
void setText(const std::string &t)
{
m_text = t;
m_text_modified = true;
}
std::string getOwner()
{
if(m_enforce_owner)
return m_owner;
else
return "";
}
void setOwner(std::string t)
{
m_owner = t;
}
/* Interface for GenericNodeMetadata */
meta->getInventory()->deSerialize(is);
void setInfoText(const std::string &text)
{
infostream<<"GenericNodeMetadata::setInfoText(\""
<<text<<"\")"<<std::endl;
m_infotext = text;
// Rename inventory list "0" to "main"
Inventory *inv = meta->getInventory();
if(!inv->getList("main") && inv->getList("0")){
inv->getList("0")->setName("main");
}
assert(inv->getList("main") && !inv->getList("0"));
meta->setString("formspec","invsize[8,9;]"
"list[current_name;main;0,0;8,4;]"
"list[current_player;main;0,5;8,4;]");
return false;
}
void setInventoryDrawSpec(const std::string &text)
else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata
{
m_inventorydrawspec = text;
}
void setAllowTextInput(bool b)
{
m_allow_text_input = b;
}
void setRemovalDisabled(bool b)
{
m_removal_disabled = b;
}
void setEnforceOwner(bool b)
{
m_enforce_owner = b;
}
bool isInventoryModified()
{
return m_inventory_modified;
}
void resetInventoryModified()
{
m_inventory_modified = false;
}
bool isTextModified()
{
return m_text_modified;
}
void resetTextModified()
{
m_text_modified = false;
}
void setString(const std::string &name, const std::string &var)
{
m_stringvars[name] = var;
}
std::string getString(const std::string &name)
{
std::map<std::string, std::string>::iterator i;
i = m_stringvars.find(name);
if(i == m_stringvars.end())
return "";
return i->second;
}
};
meta->setString("owner", deSerializeString(is));
meta->getInventory()->deSerialize(is);
// Prototype
GenericNodeMetadata proto_GenericNodeMetadata(NULL);
// Rename inventory list "0" to "main"
Inventory *inv = meta->getInventory();
if(!inv->getList("main") && inv->getList("0")){
inv->getList("0")->setName("main");
}
assert(inv->getList("main") && !inv->getList("0"));
meta->setString("formspec","invsize[8,9;]"
"list[current_name;main;0,0;8,4;]"
"list[current_player;main;0,5;8,4;]");
return false;
}
else if(id == NODEMETA_FURNACE) // FurnaceNodeMetadata
{
meta->getInventory()->deSerialize(is);
int temp = 0;
is>>temp;
meta->setString("fuel_totaltime", ftos((float)temp/10));
temp = 0;
is>>temp;
meta->setString("fuel_time", ftos((float)temp/10));
temp = 0;
is>>temp;
//meta->setString("src_totaltime", ftos((float)temp/10));
temp = 0;
is>>temp;
meta->setString("src_time", ftos((float)temp/10));
meta->setString("formspec","invsize[8,9;]"
"list[current_name;fuel;2,3;1,1;]"
"list[current_name;src;2,1;1,1;]"
"list[current_name;dst;5,1;2,2;]"
"list[current_player;main;0,5;8,4;]");
return true;
}
else
{
throw SerializationError("Unknown legacy node metadata");
}
}
static bool content_nodemeta_deserialize_legacy_meta(
std::istream &is, NodeMetadata *meta)
{
// Read id
s16 id = readS16(is);
// Read data
std::string data = deSerializeString(is);
std::istringstream tmp_is(data, std::ios::binary);
return content_nodemeta_deserialize_legacy_body(tmp_is, id, meta);
}
void content_nodemeta_deserialize_legacy(std::istream &is,
NodeMetadataList *meta, NodeTimerList *timers,
IGameDef *gamedef)
{
meta->clear();
timers->clear();
u16 version = readU16(is);
if(version > 1)
{
infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
<<std::endl;
throw SerializationError(__FUNCTION_NAME);
}
u16 count = readU16(is);
for(u16 i=0; i<count; i++)
{
u16 p16 = readU16(is);
v3s16 p(0,0,0);
p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
p.Y += p16 / MAP_BLOCKSIZE;
p16 -= p.Y * MAP_BLOCKSIZE;
p.X += p16;
if(meta->get(p) != NULL)
{
infostream<<"WARNING: "<<__FUNCTION_NAME<<": "
<<"already set data at position"
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
<<std::endl;
continue;
}
NodeMetadata *data = new NodeMetadata(gamedef);
bool need_timer = content_nodemeta_deserialize_legacy_meta(is, data);
meta->set(p, data);
if(need_timer)
timers->set(p, NodeTimer(1., 0.));
}
}
void content_nodemeta_serialize_legacy(std::ostream &os, NodeMetadataList *meta)
{
// Sorry, I was too lazy to implement this. --kahrl
writeU16(os, 1); // version
writeU16(os, 0); // count
}
// END

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -21,6 +21,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define CONTENT_NODEMETA_HEADER
#include "nodemetadata.h"
#include "nodetimer.h"
/*
Legacy nodemeta definitions
*/
void content_nodemeta_deserialize_legacy(std::istream &is,
NodeMetadataList *meta, NodeTimerList *timers,
IGameDef *gamedef);
void content_nodemeta_serialize_legacy(std::ostream &os, NodeMetadataList *meta);
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -32,5 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Special type, not stored as a static object
#define ACTIVEOBJECT_TYPE_PLAYER 100
// Special type, only exists as CAO
#define ACTIVEOBJECT_TYPE_GENERIC 101
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -26,6 +26,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h" // For compressZlib
#include "tool.h" // For ToolCapabilities
#include "gamedef.h"
#include "player.h"
#include "scriptapi.h"
#include "genericobject.h"
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
@@ -333,9 +336,6 @@ ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
LuaEntitySAO
*/
#include "scriptapi.h"
#include "luaentity_common.h"
// Prototype (registers item for deserialization)
LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", "");
@@ -345,11 +345,11 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
m_init_name(name),
m_init_state(state),
m_registered(false),
m_prop(new LuaEntityProperties),
m_hp(-1),
m_velocity(0,0,0),
m_acceleration(0,0,0),
m_yaw(0),
m_properties_sent(true),
m_last_sent_yaw(0),
m_last_sent_position(0,0,0),
m_last_sent_velocity(0,0,0),
@@ -374,7 +374,6 @@ LuaEntitySAO::~LuaEntitySAO()
lua_State *L = m_env->getLua();
scriptapi_luaentity_rm(L, m_id);
}
delete m_prop;
}
void LuaEntitySAO::addedToEnvironment()
@@ -387,13 +386,12 @@ void LuaEntitySAO::addedToEnvironment()
if(m_registered){
// Get properties
scriptapi_luaentity_get_properties(L, m_id, m_prop);
scriptapi_luaentity_get_properties(L, m_id, &m_prop);
// Initialize HP from properties
m_hp = m_prop->hp_max;
m_hp = m_prop.hp_max;
// Activate entity, supplying serialized state
scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
}
// Activate entity, supplying serialized state
scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
}
ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
@@ -433,10 +431,19 @@ ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
void LuaEntitySAO::step(float dtime, bool send_recommended)
{
if(!m_properties_sent)
{
m_properties_sent = true;
std::string str = getPropertyPacket();
// create message and add to list
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
m_last_sent_position_timer += dtime;
if(m_prop->physical){
core::aabbox3d<f32> box = m_prop->collisionbox;
if(m_prop.physical){
core::aabbox3d<f32> box = m_prop.collisionbox;
box.MinEdge *= BS;
box.MaxEdge *= BS;
collisionMoveResult moveresult;
@@ -482,16 +489,10 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
if(m_armor_groups_sent == false){
m_armor_groups_sent = true;
std::ostringstream os(std::ios::binary);
writeU8(os, LUAENTITY_CMD_UPDATE_ARMOR_GROUPS);
writeU16(os, m_armor_groups.size());
for(ItemGroupList::const_iterator i = m_armor_groups.begin();
i != m_armor_groups.end(); i++){
os<<serializeString(i->first);
writeS16(os, i->second);
}
std::string str = gob_cmd_update_armor_groups(
m_armor_groups);
// create message and add to list
ActiveObjectMessage aom(getId(), true, os.str());
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
}
@@ -499,18 +500,15 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
std::string LuaEntitySAO::getClientInitializationData()
{
std::ostringstream os(std::ios::binary);
// version
writeU8(os, 1);
// pos
writeU8(os, 0); // version
os<<serializeString(""); // name
writeU8(os, 0); // is_player
writeV3F1000(os, m_base_position);
// yaw
writeF1000(os, m_yaw);
// hp
writeS16(os, m_hp);
// properties
std::ostringstream prop_os(std::ios::binary);
m_prop->serialize(prop_os);
os<<serializeLongString(prop_os.str());
writeU8(os, 2); // number of messages stuffed in here
os<<serializeLongString(getPropertyPacket()); // message 1
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
// return result
return os.str();
}
@@ -573,15 +571,9 @@ int LuaEntitySAO::punch(v3f dir,
<<" hp, health now "<<getHP()<<" hp"<<std::endl;
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, LUAENTITY_CMD_PUNCHED);
// damage
writeS16(os, result.damage);
// result_hp
writeS16(os, getHP());
std::string str = gob_cmd_punched(result.damage, getHP());
// create message and add to list
ActiveObjectMessage aom(getId(), true, os.str());
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
@@ -604,17 +596,6 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker)
scriptapi_luaentity_rightclick(L, m_id, clicker);
}
void LuaEntitySAO::setHP(s16 hp)
{
if(hp < 0) hp = 0;
m_hp = hp;
}
s16 LuaEntitySAO::getHP()
{
return m_hp;
}
void LuaEntitySAO::setPos(v3f pos)
{
m_base_position = pos;
@@ -644,6 +625,33 @@ std::string LuaEntitySAO::getDescription()
return os.str();
}
void LuaEntitySAO::setHP(s16 hp)
{
if(hp < 0) hp = 0;
m_hp = hp;
}
s16 LuaEntitySAO::getHP() const
{
return m_hp;
}
void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
{
m_armor_groups = armor_groups;
m_armor_groups_sent = false;
}
ObjectProperties* LuaEntitySAO::accessObjectProperties()
{
return &m_prop;
}
void LuaEntitySAO::notifyObjectPropertiesModified()
{
m_properties_sent = false;
}
void LuaEntitySAO::setVelocity(v3f velocity)
{
m_velocity = velocity;
@@ -676,29 +684,23 @@ float LuaEntitySAO::getYaw()
void LuaEntitySAO::setTextureMod(const std::string &mod)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, LUAENTITY_CMD_SET_TEXTURE_MOD);
// parameters
os<<serializeString(mod);
std::string str = gob_cmd_set_texture_mod(mod);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
bool select_horiz_by_yawpitch)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, LUAENTITY_CMD_SET_SPRITE);
// parameters
writeV2S16(os, p);
writeU16(os, num_frames);
writeF1000(os, framelength);
writeU8(os, select_horiz_by_yawpitch);
std::string str = gob_cmd_set_sprite(
p,
num_frames,
framelength,
select_horiz_by_yawpitch
);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
@@ -707,10 +709,9 @@ std::string LuaEntitySAO::getName()
return m_init_name;
}
void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
std::string LuaEntitySAO::getPropertyPacket()
{
m_armor_groups = armor_groups;
m_armor_groups_sent = false;
return gob_cmd_set_properties(m_prop);
}
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
@@ -725,27 +726,423 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
float update_interval = m_env->getSendRecommendedInterval();
std::ostringstream os(std::ios::binary);
// command
writeU8(os, LUAENTITY_CMD_UPDATE_POSITION);
// do_interpolate
writeU8(os, do_interpolate);
// pos
writeV3F1000(os, m_base_position);
// velocity
writeV3F1000(os, m_velocity);
// acceleration
writeV3F1000(os, m_acceleration);
// yaw
writeF1000(os, m_yaw);
// is_end_position (for interpolation)
writeU8(os, is_movement_end);
// update_interval (for interpolation)
writeF1000(os, update_interval);
std::string str = gob_cmd_update_position(
m_base_position,
m_velocity,
m_acceleration,
m_yaw,
do_interpolate,
is_movement_end,
update_interval
);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
ActiveObjectMessage aom(getId(), false, str);
m_messages_out.push_back(aom);
}
/*
PlayerSAO
*/
// No prototype, PlayerSAO does not need to be deserialized
PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
const std::set<std::string> &privs, bool is_singleplayer):
ServerActiveObject(env_, v3f(0,0,0)),
m_player(player_),
m_peer_id(peer_id_),
m_inventory(NULL),
m_last_good_position(0,0,0),
m_last_good_position_age(0),
m_time_from_last_punch(0),
m_wield_index(0),
m_position_not_sent(false),
m_armor_groups_sent(false),
m_properties_sent(true),
m_privs(privs),
m_is_singleplayer(is_singleplayer),
// public
m_teleported(false),
m_inventory_not_sent(false),
m_hp_not_sent(false),
m_wielded_item_not_sent(false)
{
assert(m_player);
assert(m_peer_id != 0);
setBasePosition(m_player->getPosition());
m_inventory = &m_player->inventory;
m_armor_groups["choppy"] = 2;
m_armor_groups["fleshy"] = 3;
m_prop.hp_max = PLAYER_MAX_HP;
m_prop.physical = false;
m_prop.weight = 75;
m_prop.collisionbox = core::aabbox3d<f32>(-1/3.,-1.0,-1/3., 1/3.,1.0,1/3.);
m_prop.visual = "upright_sprite";
m_prop.visual_size = v2f(1, 2);
m_prop.textures.clear();
m_prop.textures.push_back("player.png");
m_prop.textures.push_back("player_back.png");
m_prop.spritediv = v2s16(1,1);
m_prop.is_visible = (getHP() != 0);
m_prop.makes_footstep_sound = true;
}
PlayerSAO::~PlayerSAO()
{
if(m_inventory != &m_player->inventory)
delete m_inventory;
}
std::string PlayerSAO::getDescription()
{
return std::string("player ") + m_player->getName();
}
// Called after id has been set and has been inserted in environment
void PlayerSAO::addedToEnvironment()
{
ServerActiveObject::addedToEnvironment();
ServerActiveObject::setBasePosition(m_player->getPosition());
m_player->setPlayerSAO(this);
m_player->peer_id = m_peer_id;
m_last_good_position = m_player->getPosition();
m_last_good_position_age = 0.0;
}
// Called before removing from environment
void PlayerSAO::removingFromEnvironment()
{
ServerActiveObject::removingFromEnvironment();
if(m_player->getPlayerSAO() == this)
{
m_player->setPlayerSAO(NULL);
m_player->peer_id = 0;
}
}
bool PlayerSAO::isStaticAllowed() const
{
return false;
}
bool PlayerSAO::unlimitedTransferDistance() const
{
return g_settings->getBool("unlimited_player_transfer_distance");
}
std::string PlayerSAO::getClientInitializationData()
{
std::ostringstream os(std::ios::binary);
writeU8(os, 0); // version
os<<serializeString(m_player->getName()); // name
writeU8(os, 1); // is_player
writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
writeF1000(os, m_player->getYaw());
writeS16(os, getHP());
writeU8(os, 2); // number of messages stuffed in here
os<<serializeLongString(getPropertyPacket()); // message 1
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
return os.str();
}
std::string PlayerSAO::getStaticData()
{
assert(0);
return "";
}
void PlayerSAO::step(float dtime, bool send_recommended)
{
if(!m_properties_sent)
{
m_properties_sent = true;
std::string str = getPropertyPacket();
// create message and add to list
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
m_time_from_last_punch += dtime;
if(m_is_singleplayer)
{
m_last_good_position = m_player->getPosition();
m_last_good_position_age = 0;
}
else
{
/*
Check player movements
NOTE: Actually the server should handle player physics like the
client does and compare player's position to what is calculated
on our side. This is required when eg. players fly due to an
explosion.
*/
float player_max_speed = 0;
float player_max_speed_up = 0;
if(m_privs.count("fast") != 0){
// Fast speed
player_max_speed = BS * 20;
player_max_speed_up = BS * 20;
} else {
// Normal speed
player_max_speed = BS * 4.0;
player_max_speed_up = BS * 4.0;
}
// Tolerance
player_max_speed *= 2.5;
player_max_speed_up *= 2.5;
m_last_good_position_age += dtime;
if(m_last_good_position_age >= 1.0){
float age = m_last_good_position_age;
v3f diff = (m_player->getPosition() - m_last_good_position);
float d_vert = diff.Y;
diff.Y = 0;
float d_horiz = diff.getLength();
/*infostream<<m_player->getName()<<"'s horizontal speed is "
<<(d_horiz/age)<<std::endl;*/
if(d_horiz <= age * player_max_speed &&
(d_vert < 0 || d_vert < age * player_max_speed_up)){
m_last_good_position = m_player->getPosition();
} else {
actionstream<<"Player "<<m_player->getName()
<<" moved too fast; resetting position"
<<std::endl;
m_player->setPosition(m_last_good_position);
m_teleported = true;
}
m_last_good_position_age = 0;
}
}
if(send_recommended == false)
return;
if(m_position_not_sent)
{
m_position_not_sent = false;
float update_interval = m_env->getSendRecommendedInterval();
std::string str = gob_cmd_update_position(
m_player->getPosition() + v3f(0,BS*1,0),
v3f(0,0,0),
v3f(0,0,0),
m_player->getYaw(),
true,
false,
update_interval
);
// create message and add to list
ActiveObjectMessage aom(getId(), false, str);
m_messages_out.push_back(aom);
}
if(m_wielded_item_not_sent)
{
m_wielded_item_not_sent = false;
// GenericCAO has no special way to show this
}
if(m_armor_groups_sent == false){
m_armor_groups_sent = true;
std::string str = gob_cmd_update_armor_groups(
m_armor_groups);
// create message and add to list
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
}
void PlayerSAO::setBasePosition(const v3f &position)
{
ServerActiveObject::setBasePosition(position);
m_position_not_sent = true;
}
void PlayerSAO::setPos(v3f pos)
{
m_player->setPosition(pos);
// Movement caused by this command is always valid
m_last_good_position = pos;
m_last_good_position_age = 0;
// Force position change on client
m_teleported = true;
}
void PlayerSAO::moveTo(v3f pos, bool continuous)
{
m_player->setPosition(pos);
// Movement caused by this command is always valid
m_last_good_position = pos;
m_last_good_position_age = 0;
// Force position change on client
m_teleported = true;
}
int PlayerSAO::punch(v3f dir,
const ToolCapabilities *toolcap,
ServerActiveObject *puncher,
float time_from_last_punch)
{
if(!toolcap)
return 0;
// No effect if PvP disabled
if(g_settings->getBool("enable_pvp") == false){
if(puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER){
std::string str = gob_cmd_punched(0, getHP());
// create message and add to list
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
return 0;
}
}
HitParams hitparams = getHitParams(m_armor_groups, toolcap,
time_from_last_punch);
actionstream<<"Player "<<m_player->getName()<<" punched by "
<<puncher->getDescription()<<", damage "<<hitparams.hp
<<" HP"<<std::endl;
setHP(getHP() - hitparams.hp);
if(hitparams.hp != 0)
{
std::string str = gob_cmd_punched(hitparams.hp, getHP());
// create message and add to list
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
return hitparams.wear;
}
void PlayerSAO::rightClick(ServerActiveObject *clicker)
{
}
s16 PlayerSAO::getHP() const
{
return m_player->hp;
}
void PlayerSAO::setHP(s16 hp)
{
s16 oldhp = m_player->hp;
if(hp < 0)
hp = 0;
else if(hp > PLAYER_MAX_HP)
hp = PLAYER_MAX_HP;
if(hp < oldhp && g_settings->getBool("enable_damage") == false)
{
m_hp_not_sent = true; // fix wrong prediction on client
return;
}
m_player->hp = hp;
if(hp != oldhp)
m_hp_not_sent = true;
// On death or reincarnation send an active object message
if((hp == 0) != (oldhp == 0))
{
// Will send new is_visible value based on (getHP()!=0)
m_properties_sent = false;
// Send new HP
std::string str = gob_cmd_punched(0, getHP());
ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom);
}
}
void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
{
m_armor_groups = armor_groups;
m_armor_groups_sent = false;
}
ObjectProperties* PlayerSAO::accessObjectProperties()
{
return &m_prop;
}
void PlayerSAO::notifyObjectPropertiesModified()
{
m_properties_sent = false;
}
Inventory* PlayerSAO::getInventory()
{
return m_inventory;
}
const Inventory* PlayerSAO::getInventory() const
{
return m_inventory;
}
InventoryLocation PlayerSAO::getInventoryLocation() const
{
InventoryLocation loc;
loc.setPlayer(m_player->getName());
return loc;
}
void PlayerSAO::setInventoryModified()
{
m_inventory_not_sent = true;
}
std::string PlayerSAO::getWieldList() const
{
return "main";
}
int PlayerSAO::getWieldIndex() const
{
return m_wield_index;
}
void PlayerSAO::setWieldIndex(int i)
{
if(i != m_wield_index)
{
m_wield_index = i;
m_wielded_item_not_sent = true;
}
}
void PlayerSAO::disconnected()
{
m_peer_id = 0;
m_removed = true;
if(m_player->getPlayerSAO() == this)
{
m_player->setPlayerSAO(NULL);
m_player->peer_id = 0;
}
}
void PlayerSAO::createCreativeInventory()
{
if(m_inventory != &m_player->inventory)
delete m_inventory;
m_inventory = new Inventory(m_player->inventory);
m_inventory->clearContents();
scriptapi_get_creative_inventory(m_env->getLua(), this);
}
std::string PlayerSAO::getPropertyPacket()
{
m_prop.is_visible = (getHP() != 0);
return gob_cmd_set_properties(m_prop);
}

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -23,18 +23,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serverobject.h"
#include "content_object.h"
#include "itemgroup.h"
#include "player.h"
#include "object_properties.h"
ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
const std::string itemstring);
/*
LuaEntitySAO
This is the only SAO that needs to have a bunch of it's internals exposed.
LuaEntitySAO needs some internals exposed.
*/
struct LuaEntityProperties;
class LuaEntitySAO : public ServerActiveObject
{
public:
@@ -42,7 +40,9 @@ class LuaEntitySAO : public ServerActiveObject
const std::string &name, const std::string &state);
~LuaEntitySAO();
u8 getType() const
{return ACTIVEOBJECT_TYPE_LUAENTITY;}
{ return ACTIVEOBJECT_TYPE_LUAENTITY; }
u8 getSendType() const
{ return ACTIVEOBJECT_TYPE_GENERIC; }
virtual void addedToEnvironment();
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
@@ -59,7 +59,10 @@ class LuaEntitySAO : public ServerActiveObject
float getMinimumSavedMovement();
std::string getDescription();
void setHP(s16 hp);
s16 getHP();
s16 getHP() const;
void setArmorGroups(const ItemGroupList &armor_groups);
ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified();
/* LuaEntitySAO-specific */
void setVelocity(v3f velocity);
v3f getVelocity();
@@ -71,21 +74,22 @@ class LuaEntitySAO : public ServerActiveObject
void setSprite(v2s16 p, int num_frames, float framelength,
bool select_horiz_by_yawpitch);
std::string getName();
void setArmorGroups(const ItemGroupList &armor_groups);
private:
std::string getPropertyPacket();
void sendPosition(bool do_interpolate, bool is_movement_end);
std::string m_init_name;
std::string m_init_state;
bool m_registered;
struct LuaEntityProperties *m_prop;
struct ObjectProperties m_prop;
s16 m_hp;
v3f m_velocity;
v3f m_acceleration;
float m_yaw;
ItemGroupList m_armor_groups;
bool m_properties_sent;
float m_last_sent_yaw;
v3f m_last_sent_position;
v3f m_last_sent_velocity;
@@ -94,5 +98,124 @@ class LuaEntitySAO : public ServerActiveObject
bool m_armor_groups_sent;
};
/*
PlayerSAO needs some internals exposed.
*/
class PlayerSAO : public ServerActiveObject
{
public:
PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
const std::set<std::string> &privs, bool is_singleplayer);
~PlayerSAO();
u8 getType() const
{ return ACTIVEOBJECT_TYPE_PLAYER; }
u8 getSendType() const
{ return ACTIVEOBJECT_TYPE_GENERIC; }
std::string getDescription();
/*
Active object <-> environment interface
*/
void addedToEnvironment();
void removingFromEnvironment();
bool isStaticAllowed() const;
bool unlimitedTransferDistance() const;
std::string getClientInitializationData();
std::string getStaticData();
void step(float dtime, bool send_recommended);
void setBasePosition(const v3f &position);
void setPos(v3f pos);
void moveTo(v3f pos, bool continuous);
/*
Interaction interface
*/
int punch(v3f dir,
const ToolCapabilities *toolcap,
ServerActiveObject *puncher,
float time_from_last_punch);
void rightClick(ServerActiveObject *clicker);
s16 getHP() const;
void setHP(s16 hp);
void setArmorGroups(const ItemGroupList &armor_groups);
ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified();
/*
Inventory interface
*/
Inventory* getInventory();
const Inventory* getInventory() const;
InventoryLocation getInventoryLocation() const;
void setInventoryModified();
std::string getWieldList() const;
int getWieldIndex() const;
void setWieldIndex(int i);
/*
PlayerSAO-specific
*/
void disconnected();
void createCreativeInventory();
Player* getPlayer()
{
return m_player;
}
u16 getPeerID() const
{
return m_peer_id;
}
v3f getLastGoodPosition() const
{
return m_last_good_position;
}
float resetTimeFromLastPunch()
{
float r = m_time_from_last_punch;
m_time_from_last_punch = 0.0;
return r;
}
void updatePrivileges(const std::set<std::string> &privs,
bool is_singleplayer)
{
m_privs = privs;
m_is_singleplayer = is_singleplayer;
}
private:
std::string getPropertyPacket();
Player *m_player;
u16 m_peer_id;
Inventory *m_inventory;
v3f m_last_good_position;
float m_last_good_position_age;
float m_time_from_last_punch;
int m_wield_index;
bool m_position_not_sent;
ItemGroupList m_armor_groups;
bool m_armor_groups_sent;
bool m_properties_sent;
struct ObjectProperties m_prop;
// Cached privileges for enforcement
std::set<std::string> m_privs;
bool m_is_singleplayer;
public:
// Some flags used by Server
bool m_teleported;
bool m_inventory_not_sent;
bool m_hp_not_sent;
bool m_wielded_item_not_sent;
};
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -27,6 +27,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h"
#include "inventory.h"
// Check if input matches recipe
// Takes recipe groups into account
static bool inputItemMatchesRecipe(const std::string &inp_name,
const std::string &rec_name, IItemDefManager *idef)
{
// Exact name
if(inp_name == rec_name)
return true;
// Group
if(rec_name.substr(0,6) == "group:" && idef->isKnown(inp_name)){
std::string rec_group = rec_name.substr(6);
const struct ItemDefinition &def = idef->get(inp_name);
if(itemgroup_get(def.groups, rec_group) != 0)
return true;
}
// Didn't match
return false;
}
// Deserialize an itemstring then return the name of the item
static std::string craftGetItemName(const std::string &itemstring, IGameDef *gamedef)
@@ -260,6 +280,7 @@ std::string CraftOutput::dump() const
/*
CraftReplacements
*/
std::string CraftReplacements::dump() const
{
std::ostringstream os(std::ios::binary);
@@ -276,6 +297,27 @@ std::string CraftReplacements::dump() const
return os.str();
}
void CraftReplacements::serialize(std::ostream &os) const
{
writeU16(os, pairs.size());
for(u32 i=0; i<pairs.size(); i++)
{
os<<serializeString(pairs[i].first);
os<<serializeString(pairs[i].second);
}
}
void CraftReplacements::deSerialize(std::istream &is)
{
pairs.clear();
u32 count = readU16(is);
for(u32 i=0; i<count; i++)
{
std::string first = deSerializeString(is);
std::string second = deSerializeString(is);
pairs.push_back(std::make_pair(first, second));
}
}
/*
CraftDefinition
@@ -381,9 +423,9 @@ bool CraftDefinitionShaped::check(const CraftInput &input, IGameDef *gamedef) co
unsigned int rec_x = rec_min_x + x;
unsigned int rec_y = rec_min_y + y;
if(
inp_names[inp_y * inp_width + inp_x] !=
rec_names[rec_y * rec_width + rec_x]
if(!inputItemMatchesRecipe(
inp_names[inp_y * inp_width + inp_x],
rec_names[rec_y * rec_width + rec_x], gamedef->idef())
){
return false;
}
@@ -418,12 +460,7 @@ void CraftDefinitionShaped::serializeBody(std::ostream &os) const
writeU16(os, recipe.size());
for(u32 i=0; i<recipe.size(); i++)
os<<serializeString(recipe[i]);
writeU16(os, replacements.pairs.size());
for(u32 i=0; i<replacements.pairs.size(); i++)
{
os<<serializeString(replacements.pairs[i].first);
os<<serializeString(replacements.pairs[i].second);
}
replacements.serialize(os);
}
void CraftDefinitionShaped::deSerializeBody(std::istream &is, int version)
@@ -436,14 +473,7 @@ void CraftDefinitionShaped::deSerializeBody(std::istream &is, int version)
u32 count = readU16(is);
for(u32 i=0; i<count; i++)
recipe.push_back(deSerializeString(is));
replacements.pairs.clear();
count = readU16(is);
for(u32 i=0; i<count; i++)
{
std::string first = deSerializeString(is);
std::string second = deSerializeString(is);
replacements.pairs.push_back(std::make_pair(first, second));
}
replacements.deSerialize(is);
}
/*
@@ -497,12 +527,7 @@ void CraftDefinitionShapeless::serializeBody(std::ostream &os) const
writeU16(os, recipe.size());
for(u32 i=0; i<recipe.size(); i++)
os<<serializeString(recipe[i]);
writeU16(os, replacements.pairs.size());
for(u32 i=0; i<replacements.pairs.size(); i++)
{
os<<serializeString(replacements.pairs[i].first);
os<<serializeString(replacements.pairs[i].second);
}
replacements.serialize(os);
}
void CraftDefinitionShapeless::deSerializeBody(std::istream &is, int version)
@@ -514,14 +539,7 @@ void CraftDefinitionShapeless::deSerializeBody(std::istream &is, int version)
u32 count = readU16(is);
for(u32 i=0; i<count; i++)
recipe.push_back(deSerializeString(is));
replacements.pairs.clear();
count = readU16(is);
for(u32 i=0; i<count; i++)
{
std::string first = deSerializeString(is);
std::string second = deSerializeString(is);
replacements.pairs.push_back(std::make_pair(first, second));
}
replacements.deSerialize(is);
}
/*
@@ -664,7 +682,7 @@ CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef
void CraftDefinitionCooking::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementInput(input, gamedef);
craftDecrementOrReplaceInput(input, replacements, gamedef);
}
std::string CraftDefinitionCooking::dump() const
@@ -672,7 +690,8 @@ std::string CraftDefinitionCooking::dump() const
std::ostringstream os(std::ios::binary);
os<<"(cooking, output=\""<<output
<<"\", recipe=\""<<recipe
<<"\", cooktime="<<cooktime<<")";
<<"\", cooktime="<<cooktime<<")"
<<", replacements="<<replacements.dump()<<")";
return os.str();
}
@@ -681,6 +700,7 @@ void CraftDefinitionCooking::serializeBody(std::ostream &os) const
os<<serializeString(output);
os<<serializeString(recipe);
writeF1000(os, cooktime);
replacements.serialize(os);
}
void CraftDefinitionCooking::deSerializeBody(std::istream &is, int version)
@@ -690,6 +710,7 @@ void CraftDefinitionCooking::deSerializeBody(std::istream &is, int version)
output = deSerializeString(is);
recipe = deSerializeString(is);
cooktime = readF1000(is);
replacements.deSerialize(is);
}
/*
@@ -725,14 +746,15 @@ CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *ga
void CraftDefinitionFuel::decrementInput(CraftInput &input, IGameDef *gamedef) const
{
craftDecrementInput(input, gamedef);
craftDecrementOrReplaceInput(input, replacements, gamedef);
}
std::string CraftDefinitionFuel::dump() const
{
std::ostringstream os(std::ios::binary);
os<<"(fuel, recipe=\""<<recipe
<<"\", burntime="<<burntime<<")";
<<"\", burntime="<<burntime<<")"
<<", replacements="<<replacements.dump()<<")";
return os.str();
}
@@ -740,6 +762,7 @@ void CraftDefinitionFuel::serializeBody(std::ostream &os) const
{
os<<serializeString(recipe);
writeF1000(os, burntime);
replacements.serialize(os);
}
void CraftDefinitionFuel::deSerializeBody(std::istream &is, int version)
@@ -748,6 +771,7 @@ void CraftDefinitionFuel::deSerializeBody(std::istream &is, int version)
"unsupported CraftDefinitionFuel version");
recipe = deSerializeString(is);
burntime = readF1000(is);
replacements.deSerialize(is);
}
/*

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -106,6 +106,8 @@ struct CraftReplacements
pairs(pairs_)
{}
std::string dump() const;
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
};
/*
@@ -270,8 +272,9 @@ class CraftDefinitionCooking: public CraftDefinition
CraftDefinitionCooking(
const std::string &output_,
const std::string &recipe_,
float cooktime_):
output(output_), recipe(recipe_), cooktime(cooktime_)
float cooktime_,
const CraftReplacements &replacements_):
output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
{}
virtual ~CraftDefinitionCooking(){}
@@ -293,6 +296,8 @@ class CraftDefinitionCooking: public CraftDefinition
std::string recipe;
// Time in seconds
float cooktime;
// Replacement items for decrementInput()
CraftReplacements replacements;
};
/*
@@ -305,8 +310,10 @@ class CraftDefinitionFuel: public CraftDefinition
CraftDefinitionFuel():
recipe(""), burntime()
{}
CraftDefinitionFuel(std::string recipe_, float burntime_):
recipe(recipe_), burntime(burntime_)
CraftDefinitionFuel(std::string recipe_,
float burntime_,
const CraftReplacements &replacements_):
recipe(recipe_), burntime(burntime_), replacements(replacements_)
{}
virtual ~CraftDefinitionFuel(){}
@@ -326,6 +333,8 @@ class CraftDefinitionFuel: public CraftDefinition
std::string recipe;
// Time in seconds
float burntime;
// Replacement items for decrementInput()
CraftReplacements replacements;
};
/*

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -25,7 +25,6 @@ void set_default_settings(Settings *settings)
settings->setDefault("port", "");
settings->setDefault("name", "");
settings->setDefault("footprints", "false");
// Client stuff
@@ -70,10 +69,14 @@ void set_default_settings(Settings *settings)
settings->setDefault("wanted_fps", "30");
settings->setDefault("fps_max", "60");
// A bit more than the server will send around the player, to make fog blend well
settings->setDefault("viewing_range_nodes_min", "35");
settings->setDefault("viewing_range_nodes_max", "160");
settings->setDefault("viewing_range_nodes_min", "35");
settings->setDefault("screenW", "800");
settings->setDefault("screenH", "600");
settings->setDefault("fullscreen", "false");
settings->setDefault("fullscreen_bpp", "24");
settings->setDefault("fsaa", "0");
settings->setDefault("vsync", "false");
settings->setDefault("address", "");
settings->setDefault("random_input", "false");
settings->setDefault("client_unload_unused_data_timeout", "600");
@@ -81,7 +84,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("fov", "72");
settings->setDefault("view_bobbing", "true");
settings->setDefault("new_style_water", "false");
settings->setDefault("new_style_leaves", "false");
settings->setDefault("new_style_leaves", "true");
settings->setDefault("smooth_lighting", "true");
settings->setDefault("enable_texture_atlas", "true");
settings->setDefault("texture_path", "");
@@ -94,10 +97,12 @@ void set_default_settings(Settings *settings)
settings->setDefault("enable_clouds", "true");
settings->setDefault("screenshot_path", ".");
settings->setDefault("view_bobbing_amount", "1.0");
settings->setDefault("enable_3d_clouds", "false");
settings->setDefault("enable_3d_clouds", "true");
settings->setDefault("opaque_water", "false");
settings->setDefault("console_color", "(0,0,0)");
settings->setDefault("console_alpha", "200");
settings->setDefault("enable_sound", "true");
settings->setDefault("sound_volume", "0.8");
// Server stuff
// "map-dir" doesn't exist by default.
@@ -111,7 +116,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("fixed_map_seed", "");
settings->setDefault("give_initial_stuff", "false");
settings->setDefault("default_password", "");
settings->setDefault("default_privs", "build, shout");
settings->setDefault("default_privs", "interact, shout");
settings->setDefault("unlimited_player_transfer_distance", "true");
settings->setDefault("enable_pvp", "true");
@@ -123,14 +128,14 @@ void set_default_settings(Settings *settings)
// This causes frametime jitter on client side, or does it?
settings->setDefault("max_simultaneous_block_sends_per_client", "4");
settings->setDefault("max_simultaneous_block_sends_server_total", "20");
settings->setDefault("max_block_send_distance", "10");
settings->setDefault("max_block_generate_distance", "6");
settings->setDefault("max_block_send_distance", "9");
settings->setDefault("max_block_generate_distance", "7");
settings->setDefault("time_send_interval", "5");
settings->setDefault("time_speed", "96");
settings->setDefault("time_speed", "72");
settings->setDefault("server_unload_unused_data_timeout", "29");
settings->setDefault("server_map_save_interval", "5.3");
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
settings->setDefault("enable_experimental", "false");
settings->setDefault("dedicated_server_step", "0.05");
settings->setDefault("ignore_world_load_errors", "false");
}

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -37,9 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodemetadata.h"
#include "main.h" // For g_settings, g_profiler
#include "gamedef.h"
#include "serverremoteplayer.h"
#ifndef SERVER
#include "clientmap.h"
#include "localplayer.h"
#endif
#include "daynightratio.h"
@@ -368,7 +368,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
//infostream<<"Checking player file "<<path<<std::endl;
// Load player to see what is its name
ServerRemotePlayer testplayer(this);
RemotePlayer testplayer(m_gamedef);
{
// Open file and deserialize
std::ifstream is(path.c_str(), std::ios_base::binary);
@@ -482,7 +482,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
//infostream<<"Checking player file "<<path<<std::endl;
// Load player to see what is its name
ServerRemotePlayer testplayer(this);
RemotePlayer testplayer(m_gamedef);
{
// Open file and deserialize
std::ifstream is(path.c_str(), std::ios_base::binary);
@@ -510,12 +510,10 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
if(player == NULL)
{
//infostream<<"Is a new player"<<std::endl;
player = new ServerRemotePlayer(this);
player = new RemotePlayer(m_gamedef);
newplayer = true;
}
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
// Load player
{
verbosestream<<"Reading player "<<testplayer.getName()<<" from "
@@ -527,9 +525,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
srp->deSerialize(is);
srp->m_last_good_position = srp->getBasePosition();
srp->m_last_good_position_age = 0;
player->deSerialize(is);
}
if(newplayer)
@@ -637,13 +633,15 @@ class ABMHandler
i->timer -= trigger_interval;
actual_interval = trigger_interval;
}
ActiveABM aabm;
aabm.abm = abm;
float intervals = actual_interval / trigger_interval;
if(intervals == 0)
continue;
float chance = abm->getTriggerChance();
if(chance == 0)
chance = 1;
aabm.chance = 1.0 / pow((float)1.0/chance, (float)intervals);
ActiveABM aabm;
aabm.abm = abm;
aabm.chance = chance / intervals;
if(aabm.chance == 0)
aabm.chance = 1;
// Trigger neighbors
@@ -651,27 +649,30 @@ class ABMHandler
= abm->getRequiredNeighbors();
for(std::set<std::string>::iterator
i = required_neighbors_s.begin();
i != required_neighbors_s.end(); i++){
content_t c = ndef->getId(*i);
if(c == CONTENT_IGNORE)
continue;
aabm.required_neighbors.insert(c);
i != required_neighbors_s.end(); i++)
{
ndef->getIds(*i, aabm.required_neighbors);
}
// Trigger contents
std::set<std::string> contents_s = abm->getTriggerContents();
for(std::set<std::string>::iterator
i = contents_s.begin(); i != contents_s.end(); i++){
content_t c = ndef->getId(*i);
if(c == CONTENT_IGNORE)
continue;
std::map<content_t, std::list<ActiveABM> >::iterator j;
j = m_aabms.find(c);
if(j == m_aabms.end()){
std::list<ActiveABM> aabmlist;
m_aabms[c] = aabmlist;
i = contents_s.begin(); i != contents_s.end(); i++)
{
std::set<content_t> ids;
ndef->getIds(*i, ids);
for(std::set<content_t>::const_iterator k = ids.begin();
k != ids.end(); k++)
{
content_t c = *k;
std::map<content_t, std::list<ActiveABM> >::iterator j;
j = m_aabms.find(c);
if(j == m_aabms.end()){
std::list<ActiveABM> aabmlist;
m_aabms[c] = aabmlist;
j = m_aabms.find(c);
}
j->second.push_back(aabm);
}
j->second.push_back(aabm);
}
}
}
@@ -772,18 +773,11 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
// Activate stored objects
activateObjects(block);
// Run node metadata
bool changed = block->m_node_metadata->step((float)dtime_s);
if(changed)
{
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.p = block->getPos();
m_map->dispatchEvent(&event);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"node metadata modified in activateBlock");
}
// Run node timers
std::map<v3s16, f32> elapsed_timers =
block->m_node_timers.step((float)dtime_s);
if(!elapsed_timers.empty())
errorstream<<"Node timers don't work yet!"<<std::endl;
/* Handle ActiveBlockModifiers */
ABMHandler abmhandler(m_abms, dtime_s, this, false);
@@ -1063,18 +1057,11 @@ void ServerEnvironment::step(float dtime)
block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD,
"Timestamp older than 60s (step)");
// Run node metadata
bool changed = block->m_node_metadata->step(dtime);
if(changed)
{
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.p = p;
m_map->dispatchEvent(&event);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"node metadata modified in step");
}
// Run node timers
std::map<v3s16, f32> elapsed_timers =
block->m_node_timers.step(dtime);
if(!elapsed_timers.empty())
errorstream<<"Node timers don't work yet!"<<std::endl;
}
}
@@ -1747,6 +1734,15 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
force_delete = true;
} else {
u16 new_id = pending_delete ? id : 0;
// If static counterpart already exists, remove it first.
// This shouldn't happen, but happens rarely for some
// unknown reason. Unsuccessful attempts have been made to
// find said reason.
if(new_id && block->m_static_objects.m_active.find(new_id)){
infostream<<"ServerEnv: WARNING: Performing hack #83274"
<<std::endl;
block->m_static_objects.remove(new_id);
}
block->m_static_objects.insert(new_id, s_obj);
// Only mark block as modified if data changed considerably
@@ -1890,7 +1886,8 @@ void ClientEnvironment::step(float dtime)
stepTimeOfDay(dtime);
// Get some settings
bool free_move = g_settings->getBool("free_move");
bool fly_allowed = m_gamedef->checkLocalPrivilege("fly");
bool free_move = fly_allowed && g_settings->getBool("free_move");
// Get local player
LocalPlayer *lplayer = getLocalPlayer();
@@ -2004,13 +2001,15 @@ void ClientEnvironment::step(float dtime)
if(info.t == COLLISION_FALL)
{
//f32 tolerance = BS*10; // 2 without damage
f32 tolerance = BS*12; // 3 without damage
//f32 tolerance = BS*12; // 3 without damage
f32 tolerance = BS*14; // 5 without damage
f32 factor = 1;
if(info.speed > tolerance)
{
f32 damage_f = (info.speed - tolerance)/BS*factor;
u16 damage = (u16)(damage_f+0.5);
damageLocalPlayer(damage, true);
if(damage != 0)
damageLocalPlayer(damage, true);
}
}
}
@@ -2074,7 +2073,7 @@ void ClientEnvironment::step(float dtime)
catch(InvalidPositionException &e){
light = blend_light(getDayNightRatio(), LIGHT_SUN, 0);
}
player->updateLight(light);
player->light = light;
}
/*
@@ -2226,8 +2225,19 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
obj->setId(id);
obj->initialize(init_data);
try
{
obj->initialize(init_data);
}
catch(SerializationError &e)
{
errorstream<<"ClientEnvironment::addActiveObject():"
<<" id="<<id<<" type="<<type
<<": SerializationError in initialize(),"
<<" init_data="<<serializeJsonString(init_data)
<<std::endl;
}
addActiveObject(obj);
}
@@ -2258,7 +2268,18 @@ void ClientEnvironment::processActiveObjectMessage(u16 id,
<<std::endl;
return;
}
obj->processMessage(data);
try
{
obj->processMessage(data);
}
catch(SerializationError &e)
{
errorstream<<"ClientEnvironment::processActiveObjectMessage():"
<<" id="<<id<<" type="<<obj->getType()
<<" SerializationError in processMessage(),"
<<" message="<<serializeJsonString(data)
<<std::endl;
}
}
/*

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Part of Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -125,7 +125,7 @@ HeightPoint ground_height(u64 seed, v2s16 p2d)
hp.ma = (4)*BS;
/*hp.gh = BS*base_rock_level_2d(seed, p2d);
hp.ma = BS*get_mud_add_amount(seed, p2d);*/
hp.have_sand = mapgen::get_have_sand(seed, p2d);
hp.have_sand = mapgen::get_have_beach(seed, p2d);
if(hp.gh > BS*WATER_LEVEL)
hp.tree_amount = mapgen::tree_amount_2d(seed, p2d);
else

View File

@@ -3,16 +3,16 @@ Part of Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -4,16 +4,16 @@ Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2012 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -4,16 +4,16 @@ Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2012 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -214,6 +214,7 @@ bool DeleteSingleFileOrEmptyDirectory(std::string path)
#include <errno.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
std::vector<DirListNode> GetDirListing(std::string pathstring)
{

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -103,7 +103,9 @@ struct TextDestNodeMetadata : public TextDest
std::string ntext = wide_to_narrow(text);
infostream<<"Changing text of a sign node: "
<<ntext<<std::endl;
m_client->sendSignNodeText(m_p, ntext);
std::map<std::string, std::string> fields;
fields["text"] = ntext;
m_client->sendNodemetaFields(m_p, "", fields);
}
v3s16 m_p;
@@ -130,6 +132,28 @@ class MainRespawnInitiator: public IRespawnInitiator
Client *m_client;
};
/* Form update callback */
class NodeMetadataFormSource: public IFormSource
{
public:
NodeMetadataFormSource(ClientMap *map, v3s16 p):
m_map(map),
m_p(p)
{
}
std::string getForm()
{
NodeMetadata *meta = m_map->getNodeMetadata(m_p);
if(!meta)
return "";
return meta->getString("formspec");
}
ClientMap *m_map;
v3s16 m_p;
};
/*
Hotbar draw routine
*/
@@ -955,10 +979,14 @@ void the_game(
ISoundManager *sound = NULL;
bool sound_is_dummy = false;
#if USE_SOUND
infostream<<"Attempting to use OpenAL audio"<<std::endl;
sound = createOpenALSoundManager(&soundfetcher);
if(!sound)
infostream<<"Failed to initialize OpenAL audio"<<std::endl;
if(g_settings->getBool("enable_sound")){
infostream<<"Attempting to use OpenAL audio"<<std::endl;
sound = createOpenALSoundManager(&soundfetcher);
if(!sound)
infostream<<"Failed to initialize OpenAL audio"<<std::endl;
} else {
infostream<<"Sound disabled."<<std::endl;
}
#endif
if(!sound){
infostream<<"Using dummy audio."<<std::endl;
@@ -1563,24 +1591,19 @@ void the_game(
GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1,
&g_menumgr, v2s16(8,7),
&g_menumgr,
&client, gamedef);
InventoryLocation inventoryloc;
inventoryloc.setCurrentPlayer();
core::array<GUIInventoryMenu::DrawSpec> draw_spec;
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", inventoryloc, "main",
v2s32(0, 3), v2s32(8, 4)));
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", inventoryloc, "craft",
v2s32(3, 0), v2s32(3, 3)));
draw_spec.push_back(GUIInventoryMenu::DrawSpec(
"list", inventoryloc, "craftpreview",
v2s32(7, 1), v2s32(1, 1)));
menu->setDrawSpec(draw_spec);
menu->setFormSpec(
"invsize[8,7.5;]"
//"image[1,0.6;1,2;player.png]"
"list[current_player;main;0,3.5;8,4;]"
"list[current_player;craft;3,0;3,3;]"
"list[current_player;craftpreview;7,1;1,1;]"
, inventoryloc);
menu->drop();
}
@@ -1636,6 +1659,8 @@ void the_game(
g_settings->set("free_move","true");
statustext = L"free_move enabled";
statustext_time = 0;
if(!client.checkPrivilege("fly"))
statustext += L" (note: no 'fly' privilege)";
}
}
else if(input->wasKeyDown(getKeySetting("keymap_fastmove")))
@@ -1651,6 +1676,8 @@ void the_game(
g_settings->set("fast_move","true");
statustext = L"fast_move enabled";
statustext_time = 0;
if(!client.checkPrivilege("fast"))
statustext += L" (note: no 'fast' privilege)";
}
}
else if(input->wasKeyDown(getKeySetting("keymap_screenshot")))
@@ -2076,8 +2103,9 @@ void the_game(
// Update sound listener
sound->updateListener(camera.getCameraNode()->getPosition(),
v3f(0,0,0), // velocity
camera.getCameraNode()->getTarget(),
camera.getDirection(),
camera.getCameraNode()->getUpVector());
sound->setListenerGain(g_settings->getFloat("sound_volume"));
/*
Update sound maker
@@ -2186,7 +2214,7 @@ void the_game(
ClientMap &map = client.getEnv().getClientMap();
NodeMetadata *meta = map.getNodeMetadata(nodepos);
if(meta){
infotext = narrow_to_wide(meta->infoText());
infotext = narrow_to_wide(meta->getString("infotext"));
} else {
MapNode n = map.getNode(nodepos);
if(nodedef->get(n).tname_tiles[0] == "unknown_block.png"){
@@ -2311,35 +2339,8 @@ void the_game(
{
infostream<<"Ground right-clicked"<<std::endl;
// If metadata provides an inventory view, activate it
if(meta && meta->getInventoryDrawSpecString() != "" && !random_input)
{
infostream<<"Launching custom inventory view"<<std::endl;
InventoryLocation inventoryloc;
inventoryloc.setNodeMeta(nodepos);
/*
Create menu
*/
core::array<GUIInventoryMenu::DrawSpec> draw_spec;
v2s16 invsize =
GUIInventoryMenu::makeDrawSpecArrayFromString(
draw_spec,
meta->getInventoryDrawSpecString(),
inventoryloc);
GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1,
&g_menumgr, invsize,
&client, gamedef);
menu->setDrawSpec(draw_spec);
menu->drop();
}
// If metadata provides text input, activate text input
else if(meta && meta->allowsTextInput() && !random_input)
// sign special case, at least until formspec is properly implemented
if(meta && meta->getString("formspec") == "hack:sign_text_input" && !random_input)
{
infostream<<"Launching metadata text input"<<std::endl;
@@ -2347,12 +2348,32 @@ void the_game(
TextDest *dest = new TextDestNodeMetadata(nodepos, &client);
std::wstring wtext = narrow_to_wide(meta->getText());
std::wstring wtext = narrow_to_wide(meta->getString("text"));
(new GUITextInputMenu(guienv, guiroot, -1,
&g_menumgr, dest,
wtext))->drop();
}
// If metadata provides an inventory view, activate it
else if(meta && meta->getString("formspec") != "" && !random_input)
{
infostream<<"Launching custom inventory view"<<std::endl;
InventoryLocation inventoryloc;
inventoryloc.setNodeMeta(nodepos);
/* Create menu */
GUIInventoryMenu *menu =
new GUIInventoryMenu(guienv, guiroot, -1,
&g_menumgr,
&client, gamedef);
menu->setFormSpec(meta->getString("formspec"),
inventoryloc);
menu->setFormSource(new NodeMetadataFormSource(
&client.getEnv().getClientMap(), nodepos));
menu->drop();
}
// Otherwise report right click to server
else
{
@@ -2596,11 +2617,12 @@ void the_game(
char temptext[300];
snprintf(temptext, 300,
"(% .1f, % .1f, % .1f)"
" (yaw = %.1f)",
" (yaw = %.1f) (seed = %lli)",
player_position.X/BS,
player_position.Y/BS,
player_position.Z/BS,
wrapDegrees_0_360(camera_yaw));
wrapDegrees_0_360(camera_yaw),
client.getMapSeed());
guitext2->setText(narrow_to_wide(temptext).c_str());
guitext2->setVisible(true);

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -50,10 +50,15 @@ class IGameDef
// Used for keeping track of names/ids of unknown nodes
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
// Only usable on the client
virtual ISoundManager* getSoundManager()=0;
virtual MtEventManager* getEventManager()=0;
// Used on the client
virtual bool checkLocalPrivilege(const std::string &priv)
{ return false; }
// Shorthands
IItemDefManager* idef(){return getItemDefManager();}
INodeDefManager* ndef(){return getNodeDefManager();}

120
src/genericobject.cpp Normal file
View File

@@ -0,0 +1,120 @@
/*
Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "genericobject.h"
#include "utility.h"
#include <sstream>
std::string gob_cmd_set_properties(const ObjectProperties &prop)
{
std::ostringstream os(std::ios::binary);
writeU8(os, GENERIC_CMD_SET_PROPERTIES);
prop.serialize(os);
return os.str();
}
ObjectProperties gob_read_set_properties(std::istream &is)
{
ObjectProperties prop;
prop.deSerialize(is);
return prop;
}
std::string gob_cmd_update_position(
v3f position,
v3f velocity,
v3f acceleration,
f32 yaw,
bool do_interpolate,
bool is_movement_end,
f32 update_interval
){
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_UPDATE_POSITION);
// pos
writeV3F1000(os, position);
// velocity
writeV3F1000(os, velocity);
// acceleration
writeV3F1000(os, acceleration);
// yaw
writeF1000(os, yaw);
// do_interpolate
writeU8(os, do_interpolate);
// is_end_position (for interpolation)
writeU8(os, is_movement_end);
// update_interval (for interpolation)
writeF1000(os, update_interval);
return os.str();
}
std::string gob_cmd_set_texture_mod(const std::string &mod)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_TEXTURE_MOD);
// parameters
os<<serializeString(mod);
return os.str();
}
std::string gob_cmd_set_sprite(
v2s16 p,
u16 num_frames,
f32 framelength,
bool select_horiz_by_yawpitch
){
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_SPRITE);
// parameters
writeV2S16(os, p);
writeU16(os, num_frames);
writeF1000(os, framelength);
writeU8(os, select_horiz_by_yawpitch);
return os.str();
}
std::string gob_cmd_punched(s16 damage, s16 result_hp)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_PUNCHED);
// damage
writeS16(os, damage);
// result_hp
writeS16(os, result_hp);
return os.str();
}
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups)
{
std::ostringstream os(std::ios::binary);
writeU8(os, GENERIC_CMD_UPDATE_ARMOR_GROUPS);
writeU16(os, armor_groups.size());
for(ItemGroupList::const_iterator i = armor_groups.begin();
i != armor_groups.end(); i++){
os<<serializeString(i->first);
writeS16(os, i->second);
}
return os.str();
}

63
src/genericobject.h Normal file
View File

@@ -0,0 +1,63 @@
/*
Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GENERICOBJECT_HEADER
#define GENERICOBJECT_HEADER
#include <string>
#include "irrlichttypes.h"
#include <iostream>
#define GENERIC_CMD_SET_PROPERTIES 0
#define GENERIC_CMD_UPDATE_POSITION 1
#define GENERIC_CMD_SET_TEXTURE_MOD 2
#define GENERIC_CMD_SET_SPRITE 3
#define GENERIC_CMD_PUNCHED 4
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 5
#include "object_properties.h"
std::string gob_cmd_set_properties(const ObjectProperties &prop);
ObjectProperties gob_read_set_properties(std::istream &is);
std::string gob_cmd_update_position(
v3f position,
v3f velocity,
v3f acceleration,
f32 yaw,
bool do_interpolate,
bool is_movement_end,
f32 update_interval
);
std::string gob_cmd_set_texture_mod(const std::string &mod);
std::string gob_cmd_set_sprite(
v2s16 p,
u16 num_frames,
f32 framelength,
bool select_horiz_by_yawpitch
);
std::string gob_cmd_punched(s16 damage, s16 result_hp);
#include "itemgroup.h"
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups);
#endif

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

View File

@@ -3,16 +3,16 @@ Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
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 General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

Some files were not shown because too many files have changed in this diff Show More