Compare commits

...

448 Commits

Author SHA1 Message Date
Perttu Ahola
c349708eab Make it to compile on MSVC2010 2011-10-21 18:37:43 +03:00
Perttu Ahola
9c3e0a8040 0.3.dev-20111021 2011-10-21 18:29:13 +03:00
Perttu Ahola
7f25183936 Some tuning in m_max_packets_per_second algorithm 2011-10-21 11:52:26 +03:00
Perttu Ahola
4b6138e69b Improve Connection with threading and some kind of congestion control 2011-10-20 23:04:09 +03:00
Perttu Ahola
b6fcbc5fba Default max_simultaneous_block_sends_server_total to 2 to make network not cough too much on the fixed block sending code 2011-10-19 19:34:47 +03:00
Perttu Ahola
ed870a7237 Fix apple inventory texture 2011-10-19 02:36:46 +03:00
Perttu Ahola
3a06fb8831 Fix and tune block sending 2011-10-19 02:17:23 +03:00
Perttu Ahola
d47120aeb3 Add enable_2d_clouds setting for usage on lower-end machines 2011-10-18 23:55:55 +03:00
Perttu Ahola
9b907dd65a Try to tune fog to work well on high-end machines also 2011-10-18 21:08:31 +03:00
Perttu Ahola
28f2fdb6de Fix possible NULL dereference in MobV2CAO::step 2011-10-18 19:53:34 +03:00
Perttu Ahola
4e1055543c Tune map rendering and related diagnostics 2011-10-18 19:18:01 +03:00
Perttu Ahola
8ead29a302 set backface culling off again for torches, ladders, rails and signs 2011-10-18 18:32:35 +03:00
Perttu Ahola
fe98fe342a ...Make the the server buildable again after the last commit 2011-10-18 17:20:54 +03:00
Perttu Ahola
554f7f120c Improve rendering and fix tiling in mesh generation 2011-10-18 13:56:35 +03:00
Perttu Ahola
05ab58cd14 Automate texture listing for texture atlas making 2011-10-18 11:31:23 +03:00
Perttu Ahola
eae2d35ca5 Fix client profiler print interval 2011-10-18 10:36:52 +03:00
Perttu Ahola
85002883bd Better handling of SendFailedException in Connection 2011-10-18 03:42:23 +03:00
Perttu Ahola
22b07bdb30 Fix object duplication bug 2011-10-18 02:58:15 +03:00
Perttu Ahola
fe338745a3 Make active_block_range default to 2 2011-10-18 00:41:17 +03:00
Perttu Ahola
6ce0c61dc0 Fix possible NULL pointer access in MobV2CAO 2011-10-18 00:41:02 +03:00
Perttu Ahola
78f4142f4f Add /clearobjects 2011-10-18 00:01:50 +03:00
Perttu Ahola
ea1fda5ebc Made a scheme to get rid of the objects in the worst object flooded blocks 2011-10-17 20:57:58 +03:00
Perttu Ahola
67db77b8b3 Modify default active block range 2011-10-17 20:41:43 +03:00
Perttu Ahola
64c4d00693 F2 toggles profiler display in client 2011-10-17 20:40:55 +03:00
Perttu Ahola
6661d9be1a Attempt to fix objects getting multiplicated by objects getting deactivated in a different block than where they were loaded and then the original block, from where the static object was removed, not getting saved at unload 2011-10-17 20:19:37 +03:00
Perttu Ahola
c41f1c960b Fix minetest.conf.example a bit 2011-10-17 20:04:35 +03:00
Perttu Ahola
9a62a909bc Add a log message to SEnv and make it load objects if there are < 51 of them, to load blocks that were limited to 50 2011-10-17 19:44:28 +03:00
Perttu Ahola
93f4d2b3f1 Catch SendFailedException when replying back in Connection::Receive() 2011-10-17 18:02:26 +03:00
Perttu Ahola
558a133044 Display RTT (round trip time, ping) on client status text 2011-10-17 17:18:50 +03:00
Perttu Ahola
5037efdea9 Add some rendering statistics to profiler 2011-10-17 17:06:28 +03:00
Perttu Ahola
e9888c8e25 Workaround for blocks having a huge amount of active objects; add log messages related to active objects for investigation 2011-10-17 11:52:38 +03:00
Perttu Ahola
3daaff3a42 Remove very floody log message of MobV2SAO 2011-10-17 11:45:06 +03:00
celeron55
d39f98aeb0 Improve active object handling log output 2011-10-17 10:47:06 +03:00
celeron55
30c21b4abd Fix partly double printed debug.txt 2011-10-17 10:46:16 +03:00
Perttu Ahola
cfd19dcdb5 Fix punching of oerkkis 2011-10-17 01:58:38 +03:00
Perttu Ahola
b0481b9db1 Fix chest not working after walked away and came back 2011-10-17 01:04:22 +03:00
Perttu Ahola
5f39885975 Improve inventory debug output 2011-10-17 01:03:45 +03:00
Perttu Ahola
9ff8067426 Fix items showing up as sticks when placed in world 2011-10-17 00:08:27 +03:00
Perttu Ahola
162619a426 Fix to-transparend conversion of backgrounds of sprite image files that don't have an alpha channel 2011-10-16 23:41:43 +03:00
Perttu Ahola
2419d0029a Some more profiler stuff to get the hang on what really uses CPU 2011-10-16 22:39:35 +03:00
Perttu Ahola
b8f2dcea4d Improve debug profiler usage for investigating CPU usage of server 2011-10-16 21:16:44 +03:00
Perttu Ahola
07d000cc54 When granting or revoking privileges, notify the target player too 2011-10-16 20:03:43 +03:00
Perttu Ahola
6470743e51 Make dungeon masters not shoot the walls with no reason 2011-10-16 19:39:20 +03:00
Perttu Ahola
143dce6672 When player times out, log the action as a timeout rather than regular quitting 2011-10-16 19:38:56 +03:00
Perttu Ahola
96b2d1fd29 Check NULL pointer properly in some new code trying to log new stuff 2011-10-16 18:50:30 +03:00
Perttu Ahola
369177aa80 Better player damage prevention when falling on unloaded blocks, not involving getting stuck in there. 2011-10-16 18:45:17 +03:00
Perttu Ahola
0bf533f753 Switch more stuff to use the logging thing and fix segfault on player leave from server as introduced in a previous switch-to-logging commit 2011-10-16 16:28:12 +03:00
Perttu Ahola
67a6bc4ab5 Fix map delete on windows (concatenate paths correctly with / or \ depending on OS) 2011-10-16 16:16:47 +03:00
Perttu Ahola
ef397dca7c Update changelog (albeit a bit late) 2011-10-16 15:20:04 +03:00
Perttu Ahola
b65a5aceb0 Use the logger; also, default to not showing much crap in console. Use --info-on-stderr to enable crap. 2011-10-16 14:57:53 +03:00
Perttu Ahola
4846846a2d Initially add small and tight logging facility 2011-10-16 12:45:00 +03:00
Perttu Ahola
414c614893 Add peaceful / not peaceful distinction in mobs and the only_peaceful_mobs setting 2011-10-16 11:52:33 +03:00
Perttu Ahola
a17abae128 Update Linux build instructions in README.txt a bit and list the bat script used for releases 2011-10-16 03:08:11 +03:00
Perttu Ahola
286edd4f1e Update version number to 0.3.dev-20111016 2011-10-16 00:53:37 +03:00
Perttu Ahola
4914eb29d1 Replace M_PI with PI 2011-10-16 00:24:51 +03:00
Perttu Ahola
825953bbdc Fix some "Conditional jump or move depends on uninitialised value(s)" valgrind detections 2011-10-15 23:07:43 +03:00
Perttu Ahola
fd6452749e Resource file handling for exe icon for MinGW 2011-10-15 17:05:16 +03:00
Perttu Ahola
7c2639ddd9 Make view bobbing amount configurable 2011-10-15 16:32:24 +03:00
Perttu Ahola
3f58028d31 Make dungeon masters though and make oerkkis disappear when they get to you (because hitting them doesn't work for some unknown reason) 2011-10-15 16:04:25 +03:00
Perttu Ahola
94dfececf6 strict_protocol_version_checking setting; PROTOCOL_VERSION in clientserver.h; clean up defaultsettings.cpp and minetest.conf.example 2011-10-15 15:02:28 +03:00
Perttu Ahola
74febd5c31 Handle death and respawn better 2011-10-15 14:46:59 +03:00
Perttu Ahola
857fe0551c Set a better version number 2011-10-15 12:51:30 +03:00
Perttu Ahola
5341bf59c2 Improve mobv2 2011-10-15 12:17:21 +03:00
Perttu Ahola
43a28f04fa mobv2 2011-10-15 02:28:57 +03:00
Perttu Ahola
080002f8ed Lock mutex when accessing m_env in Server::~Server 2011-10-14 12:39:25 +03:00
Perttu Ahola
853a78681e In CMake scripts: New version number, fix MSVC stuff 2011-10-14 09:55:39 +03:00
Perttu Ahola
9e46cbf7ea Header file tweaking; mainly for speed 2011-10-12 13:53:38 +03:00
Perttu Ahola
b60b58b627 Saner block modification flag operation for not saving everything always 2011-10-12 10:53:37 +03:00
Kahrl
3e975d8f28 minetestmapper: Fix the way ylist is computed, use cStringIO instead of rolling own Bytestream, remove some artifacts when drawing underground blocks, introduce a --drawunderground switch (defaults to of), 'blocknum' renamed to 'content'. 2011-09-27 02:38:19 +02:00
Perttu Ahola
a7833cca22 Merge remote-tracking branch 'marktraceur/master' 2011-09-26 22:41:06 +03:00
Perttu Ahola
08ac3454cc minetestmapper speed tweaks (kahrl & JacobF) 2011-09-26 22:31:34 +03:00
Perttu Ahola
3ca847b4e1 Add apple color to minetestmapper and fix cactus color 2011-09-26 20:55:00 +03:00
Perttu Ahola
e7fcc08d26 Fix minetestmapper.py 2011-09-26 20:54:42 +03:00
Perttu Ahola
520b470217 Merge remote-tracking branch 'kahrl/sectors2sqlite-fix' 2011-09-26 20:01:46 +03:00
Perttu Ahola
9a7471b740 Rotate wielded tool the right way and modify axe graphics accordingly 2011-09-26 16:10:54 +03:00
Perttu Ahola
061d4b4202 Merge branch 'view_bobbing_and_vielded_tool' 2011-09-26 15:10:02 +03:00
Perttu Ahola
2ecd53ce09 Fix single-frame lag in camera yaw/pitch, tune view bobbing and add wielded tool movement when walking and tweak stuff a bit 2011-09-26 15:09:04 +03:00
Kahrl
561bb64963 Support Python 2 and 3 in sectors2sqlite.py. 2011-09-26 13:24:21 +02:00
Kahrl
d5899a53fd Fix processing of blocks below y=0 in sectors2sqlite.py. 2011-09-26 13:10:22 +02:00
Perttu Ahola
b9e680d06c Server user limit configuration option 2011-09-26 11:57:51 +03:00
Perttu Ahola
0ccc0ac927 Merge remote-tracking branch 'darkrose/master' 2011-09-26 11:57:28 +03:00
celeron55
63eca0feb2 Merge pull request #10 from joshbeck/master
Fixed null pointer dereference errors found by cppcheck
2011-09-24 00:55:05 -07:00
Joshua Beck
ae561d705f Fixed null pointer dereference errors found by cppcheck 2011-09-24 02:11:43 -05:00
Mark Holmquist
bc01ae4cbd Fixed merge issues with saplings, ready to pull now! 2011-09-23 18:19:47 -07:00
Mark Holmquist
319f43e6d2 Fixed saplings growing into trees (thanks so much, Kahrl!)
Put the random interval back to 1 in 50 chance. It's not as rare as rats, but rarer than grass.
2011-09-23 18:14:35 -07:00
Mark Holmquist
f19919546d Adding sapling texture 2011-09-23 18:13:53 -07:00
Mark Holmquist
85f119e1e6 Adding (most) of the sapling functionality. It has yet to work, since MEET_OTHER was not implemented at the time of this commit. Hopefully it will work when merged with celeron's latest. 2011-09-23 18:13:53 -07:00
darkrose
8b875d71d1 remove content_* things from map.cpp 2011-09-23 18:04:48 +10:00
Perttu Ahola
789c88509c Move PLATFORM_LIBS around to make sqlite3 link with libdl on some distros 2011-09-23 08:48:58 +03:00
Perttu Ahola
bdf54908aa Make client report a newer version number to the server than 2011-07-31 does and make the server enforce it 2011-09-22 20:47:47 +03:00
Perttu Ahola
7244f09111 Oh well, let's call it just 0.2.20110922 2011-09-22 18:22:04 +03:00
Perttu Ahola
ca748ad44c Update changelog and version to 0.2.20110922_rc1 2011-09-22 18:15:05 +03:00
darkrose
79cb754358 added locking chest texture 2011-09-22 19:12:17 +10:00
darkrose
582e450bad added locking chests - clean patch 2011-09-22 19:11:48 +10:00
Perttu Ahola
ae6d83a41e Better apple tree generation 2011-09-21 23:31:55 +03:00
Kahrl
3e012122d1 Simplistic wielded tool lighting, added setMeshVerticesColor to utility.h and refactored some other code into calls of that 2011-09-21 18:37:29 +02:00
Kahrl
a4a2c34831 reduce view bobbing slightly 2011-09-21 15:54:06 +02:00
Kahrl
36af9bb027 Create a separate scene manager for the wielded tool. This fixes the glitchyness in large map coordinates and some depth buffer problems. (The tool doesn't bob anymore when walking, this will be fixed later.) Fix MSVC build (thanks to dannydark). 2011-09-21 01:42:52 +02:00
Kahrl
6599002149 fix a numerical problem, but tool is still jittery 2011-09-20 18:25:29 +02:00
Kahrl
cbd2bcf102 Fix jittery view bobbing at large map coordinates again. Wielded tool still has problems there 2011-09-20 18:19:26 +02:00
Kahrl
01f3ae1c50 Digging animation 2011-09-20 11:06:16 +02:00
Kahrl
eaff4616ad fix some normals 2011-09-19 17:11:53 +02:00
Kahrl
ab42549b1e Wielded tool updates, leaves and glass work now 2011-09-19 17:08:42 +02:00
Kahrl
02726f0003 Convert any inventory item into a mesh, bring back InventoryItem::getImageRay(), some const-correctness fixes 2011-09-19 06:37:24 +02:00
Kahrl
36bcbca9ac Added sprite extruder 2011-09-19 03:01:11 +02:00
Kahrl
4ed837bcfa trying some view bobbing changes 2011-09-18 17:02:30 +02:00
Kahrl
54f3796f91 Oops, up vector is needed. 2011-09-18 02:24:43 +02:00
Kahrl
ae66d611f2 This looks more like MC view bobbing, but still not even close 2011-09-18 02:17:39 +02:00
Perttu Ahola
b22cb69a15 Merge remote-tracking branch 'sfan5/apple-trees' 2011-09-16 19:09:13 +03:00
Kahrl
40707e3c5b SQLite needs to be linked with -ldl on some Linux distros. 2011-09-16 19:06:45 +03:00
Kahrl
acfb2bb8bc Revert some changes that could lead to slower map transfer and increaed network load. 2011-09-16 18:03:58 +02:00
JacobF
7f51bccf47 update minetestmapper so it can read the database also 2011-09-16 18:59:33 +03:00
Perttu Ahola
bfa5ad483f Update changelog 2011-09-16 18:59:17 +03:00
Kahrl
ae89aa55b9 Updated colors.txt (which is used by minetestmapper) 2011-09-15 23:09:00 +02:00
Kahrl
63266928a5 Made wielded tool move slightly (and smoothly) during view bobbing. Making the tool be a child node of an empty scene node instead of the camera scene node seemingly fixed the uncontrollable tool jitter, too. 2011-09-15 01:53:42 +02:00
Kahrl
fc92da4324 View bobbing is slower in the water. 2011-09-15 01:53:42 +02:00
sfan5
88dc8c694e Added Iron Apple which heals 4 Hearts 2011-09-12 20:10:17 +02:00
sfan5
785a2fd23a Changed the Heal Amount of Apples from 6 to 2 2011-09-12 19:44:26 +02:00
sfan5
4328a6442b Fixed duplication bug 2011-09-11 19:17:14 +02:00
sfan5
6496b1cf1f Removed Spaces 2011-09-11 18:16:07 +02:00
sfan5
c0caedc373 Added Apple Trees 2011-09-11 17:50:44 +02:00
Kahrl
524cf237b8 inventory displays tool breakage bar again 2011-09-08 17:45:39 +02:00
Kahrl
e4cb004460 trying something else... also replaced M_PI by PI everywhere 2011-09-08 16:10:44 +02:00
Kahrl
71418639d3 attempting to merge Queatz/the-wielded-tool and kahrl/viewbobbing, something doesn't work right yet 2011-09-08 14:21:56 +02:00
Kahrl
f2ec226521 minor view bobbing improvements 2011-09-08 13:34:28 +02:00
Kahrl
0931d4b7ff make it slightly less annoying :o) 2011-09-08 13:14:59 +02:00
Kahrl
ccadebabba Implemented view bobbing (testing simple lemniscate shape) 2011-09-08 13:03:55 +02:00
Kahrl
18771a39cf Commented out debug statements again 2011-09-08 01:24:47 +02:00
Kahrl
baf7da9d4a Collected and moved existing camera infrastructure from game.cpp to camera.cpp and camera.h. Introduced configuration settings 'fov' which chooses the camera's (vertical) field of view and 'view_bobbing' which currently does nothing. Other code refactored to not expect the FOV to be a build time constant. 2011-09-08 01:08:47 +02:00
Kahrl
c0b35fa429 Removed unused camera_position and camera_direction fields from Client. Moved ClientEnvironment::drawPostFx to ClientMap::renderPostFx -- this will make the camera management classes easier to write, as ClientMap already knows the camera position but ClientEnvironment doesn't and has to be told about it. This also eliminates the need for Client::getEnv(). Made the post effect color a content feature defined in content_mapnode.h. 2011-09-07 19:21:28 +02:00
JacobF
f31b0a3361 Display which tool the player is holding
And some simple animation when trying to dig...
2011-09-07 10:56:04 -04:00
Perttu Ahola
d28ea57083 Note about texture atlas 2011-09-07 01:27:04 +03:00
Perttu Ahola
8e26c5c066 Add note about trans_table_19. 2011-09-07 01:19:48 +03:00
Perttu Ahola
5c1074aa7d Remove block file from disk when saved to database 2011-09-06 20:28:45 +03:00
JacobF
bd72091150 Pause in unloaded territory instead of collide 2011-09-06 20:07:43 +03:00
Perttu Ahola
faf3d7902a Make Connection::Send cancel silently if peer doesn't exist. 2011-09-06 19:39:23 +03:00
Perttu Ahola
63f1ded167 Update version number to something more proper for this stage of development (0.2.201109xx_dev) 2011-09-06 19:22:00 +03:00
Perttu Ahola
3c30ab2807 Speed up periodical map unloading by moving beginSave() and endSave() to outer loop in Map::timerUpdate() 2011-09-06 19:16:36 +03:00
Perttu Ahola
310fa10035 Merge remote-tracking branch 'queatz/sqlite-map' 2011-09-06 18:04:02 +03:00
Perttu Ahola
bc847e8cc2 Fix bug in posix file/directory removal wrapper, as pointed out by kahrl 2011-09-06 17:52:03 +03:00
Perttu Ahola
b82952bdba Fix some texture stuff: remove item_fence.png, use fence.png, remove inexisting cactus.png from texture atlas (replace with nothing because cactus is rare) 2011-09-06 17:13:24 +03:00
Kahrl
570a8dbf22 allow specifying a fixed seed in the config file for generating the map (fixed_map_seed) 2011-09-06 17:05:17 +03:00
JacobF
c68ea19e8d Now SAOs will reflect changes to their temporary inventory object
Also, the temp item wasn't being deleted, might have been a memory leak.
Now you will only eat 1 item off a stack
2011-09-06 16:36:11 +03:00
JacobF
0c91d01866 Cull empty lines... 2011-09-04 17:06:23 -04:00
JacobF
e34cef312f Files to database converter 2011-09-04 17:02:50 -04:00
JacobF
d670c831c2 These numbers were well exceeding 2^32... 2011-09-04 17:01:28 -04:00
JacobF
d1a16f24cf Initial sqlite3 maps.
* The map will reside in world/map.sqlite
* It will load from the sectors folder but will not save there
2011-09-02 19:07:14 -04:00
JacobF
2d872ce3fa Furnace was crashing stuff again 2011-09-02 17:33:06 -04:00
JacobF
e3c58eff1c Merge branch 'master' of /media/Field/Software/minetest-queatz/minetest-sqlite/.. into sqlite-map 2011-09-02 16:59:17 -04:00
JacobF
99de37ff94 Update to SQLite 3.7.7.1 2011-09-01 18:27:30 -04:00
JacobF
5e3b9e3578 * Furnace would say it was overloaded when it had a non-cookable source
* I didn't understand that expression last fix and now the furnace would burn fuel
even when it had no source item.
2011-09-01 15:39:15 -04:00
Perttu Ahola
ad795c9f0c Merge remote-tracking branch 'queatz/furnace-fix' 2011-08-31 17:04:12 +03:00
Perttu Ahola
d6d479f94c Updated changelog 2011-08-31 00:43:34 +03:00
JacobF
6415528f96 If there was no source item in a furnace it would cause a segmentation fault. 2011-08-30 11:38:53 -04:00
Perttu Ahola
4af1f2963c Merge remote-tracking branch 'kahrl/dissector' 2011-08-30 14:24:33 +03:00
Perttu Ahola
ba0322f353 Merge remote-tracking branch 'queatz/mmb10' 2011-08-30 14:24:23 +03:00
Perttu Ahola
1a705523c0 Merge remote-tracking branch 'queatz/furnace-is-not-blackhole' 2011-08-30 14:24:12 +03:00
Perttu Ahola
87b9e5467d Merge remote-tracking branch 'queatz/furnace-is-not-out-nor-can-rat-escape' 2011-08-30 14:24:07 +03:00
Perttu Ahola
625dac8d8c Merge remote-tracking branch 'queatz/privs' 2011-08-30 14:23:44 +03:00
JacobF
134e49cc8e Merged 2 branches because they relied on each other.
This one contains these changes from main c55:
* Adds a function to check if there is room for a specific item
* Using that, you can now pick up rats if you have a full inventory and a not full rat stack
* Furnace would cook only 1 item if that item used the last available result slot, now it will continue
* Furnace will say it's overloaded
* Furnace won't wait until the next step to start on the next item
 - This caused small fuels to cook slower than meant to
 - Also caused furnaces to say they were out of fuel after finishing the last fuel item
2011-08-25 19:27:50 -04:00
Kahrl
cab426ffa3 dissector branch: fix for doc/protocol.txt: CONTROLTYPE_DISCO is 3 2011-08-25 21:32:48 +02:00
Kahrl
3edf2bb417 dissector branch: fix description of TOCLIENT_PLAYERITEM in clientserver.h 2011-08-25 21:31:28 +02:00
Kahrl
9ebfbd150e dissector branch: added wireshark dissector minetest.lua 2011-08-25 21:29:41 +02:00
JacobF
e278742c5e Middle mouse click will move 10 items around at a time. 2011-08-25 12:43:19 -04:00
JacobF
ef08163c38 Don't remove furnace if something is inside it. 2011-08-24 18:53:06 -04:00
JacobF
2e82268a67 If a user doesn't have build rights, don't allow them to move items to and from their inventory 2011-08-23 22:08:09 -04:00
JacobF
00bdfad5f6 The password box in the mainmenu is focused if there is already a name and address filled in 2011-08-23 22:06:35 -04:00
Perttu Ahola
efd8dabd91 Lava is now better visible inside water. (a crappy hack) 2011-08-23 03:01:01 +03:00
Perttu Ahola
e4f443a57a Inventory transparency; very loosely based on sapier's commits.
Also contains some commented-out code for testing out different looks
in the future.
2011-08-23 00:33:38 +03:00
Perttu Ahola
d4df20a913 if creative mode and player has no build privileges, cannot drop items. 2011-08-22 22:55:17 +03:00
Perttu Ahola
db495668ae Fixed water mesh generation acting weird next to sand 2011-08-22 22:44:43 +03:00
Perttu Ahola
996c653490 Fix byte count in serialization of "F1000"
Some access violations and segfaults and strange behaviour might have
been caused by this.
2011-08-22 22:17:26 +03:00
Perttu Ahola
4acad897cf Fixed some protocol comment errors in clientserver.h and elsewhere
-- TOCLIENT_OBJECTDATA: peer ID field is missing
-- TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD: added: init length should be u32, not u16
2011-08-22 22:04:46 +03:00
Giuseppe Bilotta
b37fffc2c5 Hopefully fix 'dangling water'
If a block has (at least visible) liquids, the block below should also
be flowed in.
2011-08-22 21:45:13 +03:00
Perttu Ahola
a99450ab72 Possibly fixed the extremely rare PeerNotFound loop bug.
See explanation in http://2pktfkt.de/irc/minetest-delta/2011-08-22.html
2011-08-22 21:27:11 +03:00
Perttu Ahola
7776d6228e Update README.txt 2011-08-22 15:01:09 +03:00
Perttu Ahola
5415256a52 Merge remote-tracking branch 'oblomov/me_cmd' 2011-08-22 14:46:54 +03:00
Perttu Ahola
836e43db60 Merge remote-tracking branch 'oblomov/new_input' 2011-08-22 14:46:52 +03:00
Giuseppe Bilotta
9c94538fb7 Change way commands are displayed in chat window 2011-08-22 13:43:53 +02:00
Giuseppe Bilotta
53eedd3ba4 Introduce hotkey for calling up a command window
This is just a chat window with the / text pre-loaded.
2011-08-22 13:02:08 +02:00
Giuseppe Bilotta
42134bb49e Send KEY_END when (re)creating a text input
This ensures that on creation and when resizing the cursor is at the end
of the text rather than at the beginnig.
2011-08-22 13:02:08 +02:00
Giuseppe Bilotta
0488bf54d3 /me command 2011-08-22 13:02:08 +02:00
Giuseppe Bilotta
da19aee307 Server now supports replies without prefix 2011-08-22 13:02:08 +02:00
Giuseppe Bilotta
d2c0b4905a Defines for server command context flags 2011-08-22 13:02:08 +02:00
Giuseppe Bilotta
153f07fdfb Remove distinction between /# and / commands
No need to make the server command syntax more complicated than
necessary. If the need ever arise, we'll find some other way to
distinguish the client commands. Also, the /# syntax is deprecated and
will be made obsolete in time.
2011-08-22 13:02:08 +02:00
Giuseppe Bilotta
7e610aece5 Overhaul the input system
This allows us to map the keys which are not considered in
irrlicht's EKEY_CODE system, such as \, [, /, ] etc.
2011-08-22 13:01:11 +02:00
Giuseppe Bilotta
16aedc0ef6 Fix typos in key names 2011-08-22 12:52:15 +02:00
Perttu Ahola
6596e585fe Flowing lava updates lighting 2011-08-22 13:19:07 +03:00
Perttu Ahola
f98eda4d52 Merge remote-tracking branch 'oblomov/liquid_fixes' 2011-08-22 12:53:18 +03:00
Perttu Ahola
23717510c2 Merge branch 'lava' 2011-08-22 12:53:02 +03:00
Giuseppe Bilotta
c51564ab5b Optimize for viscosity 1 2011-08-16 20:38:44 +02:00
Giuseppe Bilotta
1eb14c7743 Viscous fluids 2011-08-16 20:37:46 +02:00
Giuseppe Bilotta
56e9f97294 Make sure all neighbors of changed fluids are activated
This should fix the remaining cases of fluid not advancing or not
retreating.
2011-08-16 18:05:28 +02:00
Giuseppe Bilotta
774faf4e85 Let the liquids flow in the open
No need to curb their spread artificially.
2011-08-16 17:42:28 +02:00
Giuseppe Bilotta
d0711821f3 Ensure air neighbors to liquids that can flow are enqueued for transformation 2011-08-16 17:42:14 +02:00
Giuseppe Bilotta
7024b45197 Ensure param2 is set correctly in transformLiquids 2011-08-16 16:50:38 +02:00
Giuseppe Bilotta
5fce673a56 Use defines for liquid levels 2011-08-16 16:50:38 +02:00
Perttu Ahola
29c9d3d5f4 Implemented MEET_OTHER 2011-08-16 12:23:19 +03:00
Giuseppe Bilotta
708f1c336e transformLiquid: small optimization and whitespace cleanup 2011-08-16 06:42:11 +02:00
Perttu Ahola
dc4ac0b96f small fix to transformLiquids 2011-08-15 18:49:44 +03:00
Perttu Ahola
296748d32e Fixed liquid mesh generation 2011-08-15 17:45:35 +03:00
Perttu Ahola
ad408f269c Add lava to creative inventory (hmm, we're shortly running out of creative inventory space) 2011-08-15 16:57:57 +03:00
Perttu Ahola
e57754868f Hopefully fixed msvc "'sqrt' : ambiguous call to overloaded function" 2011-08-15 15:11:00 +03:00
Perttu Ahola
0c7e7f4998 Non-vertex-alpha texture material for lava 2011-08-15 12:08:41 +03:00
Giuseppe Bilotta
136657bcc1 Get rid of makepackage_binary.sh
It's outdated, and it would be better to use cmake's packaging
capabilities instead, for better cross-platformness.
2011-08-15 11:07:30 +02:00
Giuseppe Bilotta
dc16820e02 Cleanup root
These scripts should not be in the root but in util/ and in fact
they are, so let's get rid of these.
2011-08-15 11:05:05 +02:00
Perttu Ahola
4b85608e30 modified mapgen to generate less lava 2011-08-15 11:56:16 +03:00
Perttu Ahola
8ab77f4153 Added #define WATER_ALPHA in content_mapnode.cpp 2011-08-15 11:51:33 +03:00
Perttu Ahola
472585a7e8 tuned lava/universal damage code 2011-08-15 11:49:39 +03:00
Perttu Ahola
8f42a8be0c lava! 2011-08-15 02:04:56 +03:00
Perttu Ahola
c4b707bca2 Windows.h -> windows.h for cross-mingw build 2011-08-14 21:26:07 +03:00
Perttu Ahola
9e35fe8c37 Merge remote-tracking branch 'speedprog/fixedNotFindingData' 2011-08-13 14:05:01 +03:00
Giuseppe Bilotta
385904d75a Let Settings accept a const char* directly 2011-08-13 07:33:43 +02:00
Giuseppe Bilotta
b1e0b7728b Fix keycode_to_keyname return value 2011-08-13 07:31:46 +02:00
Giuseppe Bilotta
eb255e6870 Clean up key names handling
Constify keycode and move the static array of localizable names from the
guiKeyChangeMenu header to the implementation file, changing its name.
2011-08-12 23:42:00 +02:00
Giuseppe Bilotta
72e4c8f523 Fix use of && instead of & 2011-08-12 23:34:12 +02:00
Perttu Ahola
835d2e4b5f Removed assert if creating texture atlas image fails; cancel creating image instead. 2011-08-12 17:17:47 +03:00
Constantin Wenger
94b42a79d7 fixed not finding data dir if installed 2011-08-12 14:26:37 +02:00
Perttu Ahola
e40da2341c Fixed/extended/modified ban stuff to be good for inclusion 2011-08-12 13:11:27 +03:00
Perttu Ahola
7aa72c56b6 Merge remote-tracking branch 'speedprog/banByIp' 2011-08-12 11:55:51 +03:00
Constantin Wenger
5784c14ab7 added ipban support
commands:
/#ipban <nick>
/#ipunban <ip>
2011-08-12 03:37:18 +02:00
Perttu Ahola
3028bbb95b Updated .gitignore to ignore vim swap files 2011-08-12 00:33:24 +03:00
Giuseppe Bilotta
dfdc817db3 Typo fix 2011-08-11 19:45:44 +02:00
Giuseppe Bilotta
f4856a33c9 .gitattributes
Marking *.cpp files as C++ files makes for nicer diffs when using
--color-words or similar options.
2011-08-11 17:57:40 +02:00
Giuseppe Bilotta
371af9c241 Notify other players of wielded item change 2011-08-11 15:22:36 +02:00
Giuseppe Bilotta
88a9bae160 constify inventory item serialization 2011-08-11 15:22:36 +02:00
Giuseppe Bilotta
ecd5c5f920 Clients inform server on wielded item
This is done with the new TOSERVER_PLAYERITEM message, that informs the
server on the index of the wielded item.
2011-08-11 15:22:36 +02:00
Giuseppe Bilotta
91d1186cbb Keep track of player item 2011-08-11 15:22:36 +02:00
Giuseppe Bilotta
467b3cf4c1 Some inventory const-ification 2011-08-11 15:22:35 +02:00
Giuseppe Bilotta
c007d8219e Server should use the same eye position as the client 2011-08-11 15:22:35 +02:00
Giuseppe Bilotta
b318e82356 Refactor player's eye position coding
Collect the player's eye position coding in a Player method, and
use it in client to pass the eye position information to the game.
2011-08-11 15:22:35 +02:00
Giuseppe Bilotta
98fa00db12 Introduce Player::getLightPosition
This is currently only used in the lighting update for remote
players in client.
2011-08-11 15:22:35 +02:00
Perttu Ahola
69fca4f3cb Merged some FreeBSD fixes 2011-08-11 12:32:36 +03:00
q66
f6ed45fc20 Proper placement of binary files. 2011-08-11 11:19:33 +02:00
q66
e81ff1e833 Gettext fix for *BSD - require special linkage as glibc is not used 2011-08-11 11:19:05 +02:00
q66
43b6ca0d14 Prevent threadid_t from losing precision when casted on 64bit systems 2011-08-11 10:52:27 +02:00
Giuseppe Bilotta
34492ce480 Respect base virtual functions' signatures 2011-08-08 16:15:53 +02:00
Giuseppe Bilotta
163c38e175 Always return from non-void functions
This quiets a warning in Clang.
2011-08-08 16:13:48 +02:00
Giuseppe Bilotta
11be390110 Keys should be s32, not u32
At least two reasons for this:
* activeKey is treated as signed (check for sign, assign -1, etc)
* the ID retrieved from Irrlicht's events are signed
2011-08-08 16:12:15 +02:00
Giuseppe Bilotta
ea26a9f543 Remove spurious assignment 2011-08-08 16:11:37 +02:00
Giuseppe Bilotta
f9e1b0cd97 InventoryAction is a struct, not a class 2011-08-08 15:38:20 +02:00
Giuseppe Bilotta
805564dcf2 Clang doesn't like -Wno-unused-but-set-variable
The release versions of CMake don't yet properly support flag checking
in Clang, so we need to exclude it explicitly for the time being.
2011-08-11 10:08:58 +02:00
Giuseppe Bilotta
76fb792544 Project uses C++, so use CHECK_CXX_COMPILER_FLAG
Although this doesn't change much for our specific case, it can make a
difference for some flags, so use the appropriate macro.
2011-08-11 10:06:48 +02:00
Dmitry Marakasov
ff35014eff Fix data paths for FreeBSD 2011-08-02 02:50:16 +04:00
Dmitry Marakasov
de868d24c1 Fix "integer constant is too large for 'long' type" error 2011-08-02 02:49:15 +04:00
Dmitry Marakasov
318a730c45 Check whether -Wno-unused-but-set-variable is supported before using
it. It seems to only be available on recent (>=4.6) versions of gcc.
2011-08-01 22:17:32 +04:00
Perttu Ahola
9017c51e7f the zlib error print function now prints to dstream (debug.txt) 2011-08-08 12:11:41 +03:00
Perttu Ahola
bdb66aced7 removed broken and old tags and re-added 0.2.20110731_3 2011-08-05 11:54:54 +03:00
Perttu Ahola
ab83444cc3 Added tag 0.2.20110731_3 for changeset a519d6832511 2011-08-05 11:52:58 +03:00
Perttu Ahola
64a6da3e45 merged delta and c55 2011-08-05 11:22:13 +03:00
Giuseppe Bilotta
dd9909a574 minetestmapper can be run from any directory
If it doesn't find colors.txt locally, it looks for the one in the
directory of the script itself.
2011-08-05 08:45:15 +02:00
Giuseppe Bilotta
59c58f230e Some obvious errors in the new fluid flow management 2011-08-05 08:45:15 +02:00
Giuseppe Bilotta
f79069f5b3 MapNode is a struct, not a class 2011-08-05 08:45:15 +02:00
Giuseppe Bilotta
f5e0ba266e Some more Italian translations 2011-08-05 08:45:15 +02:00
Constantin Wenger
7361f29527 fixed some error :/ 2011-08-05 08:45:15 +02:00
Constantin Wenger
1d009a37df changed on string in german translation to fit to gui 2011-08-05 08:45:15 +02:00
Constantin Wenger
0fb208e63c updated po update script to detect wgettext and N_ 2011-08-05 08:45:15 +02:00
Constantin Wenger
dade01be29 update op PO files 2011-08-05 08:45:15 +02:00
Constantin Wenger
45057667f1 update to german translation 2011-08-05 08:45:15 +02:00
Constantin Wenger
4ab4e33450 marked strings as translation
now translated if set to a button
2011-08-05 08:45:15 +02:00
Constantin Wenger
0cfca69b42 fixed displaying special chars in the keychange menu 2011-08-05 08:45:15 +02:00
Constantin Wenger
1278a57afe added danish translation made by Frederik Helth 2011-08-05 08:45:15 +02:00
Nils Dagsson Moskopp
071c0b5536 * Welcome to OMSK. 2011-08-05 08:45:15 +02:00
Nils Dagsson Moskopp
735fa8b652 * README updated 2011-08-03 19:01:55 +02:00
Perttu Ahola
0b37f98e16 * fix for broken water 2011-08-03 19:00:25 +02:00
Perttu Ahola
5f8809e425 Fixed farmesh to such that it was a long time ago. 2011-08-03 13:03:30 +03:00
Nils Dagsson Moskopp
f143e269f4 Merge pull request #48 from Oblomov/master
Minor code cleanups (always in the gettext area, but no functional changs)
2011-08-02 01:49:31 -07:00
Giuseppe Bilotta
1d1aec9631 Use wgettext 2011-08-02 10:11:40 +02:00
Giuseppe Bilotta
817180bd55 Introduce wgettext
All usages of gettext() are converted to wchars, so let's factor this
into a single inline.
2011-08-02 10:11:40 +02:00
Giuseppe Bilotta
60bd878f0a Get rid of unused variables 2011-08-02 10:11:39 +02:00
Nils Dagsson Moskopp
bbd8e645a2 * README updated 2011-08-01 21:18:57 +02:00
Perttu Ahola
97d659c9fd added TODO in main.cpp 2011-08-01 19:21:43 +03:00
Nils Dagsson Moskopp
7b8227039f * papyrus texture now darker and edgier 2011-08-01 16:49:42 +02:00
Nils Dagsson Moskopp
363487c97b * less clumsy ladder texture, based on rails 2011-08-01 15:47:02 +02:00
Nils Dagsson Moskopp
f6bc662194 Merge pull request #47 from MarkTraceur/master
More better ladders
2011-08-01 05:59:40 -07:00
Mark Holmquist
7bd9e53ae6 Changing CONTENT_LADDER to be an extended block 2011-08-01 09:22:56 +02:00
Mark Holmquist
267744a568 Fixing ladders again 2011-08-01 09:22:44 +02:00
Mark Holmquist
8e67f4c4e6 Fixed a few problems in the ladder update, and changed the speed to account for gravity 2011-08-01 09:22:36 +02:00
Mark Holmquist
1c59cff832 Ladders implemented! 2011-08-01 09:22:36 +02:00
Mark Holmquist
bc2819cab2 Added ladders--they don't have any use yet, though 2011-08-01 09:22:36 +02:00
Nils Dagsson Moskopp
7ece67727d Merge remote-tracking branch 'origin/upstream' 2011-07-31 20:04:04 +02:00
Perttu Ahola
303351de6d Added tag 0.2.20110731_3 for changeset b277d01700f6 2011-07-31 15:55:00 +03:00
Nils Dagsson Moskopp
831003156c Merge pull request #44 from SpeedProg/master
last fix was shit, so a fix for the fix -_-
2011-07-31 05:35:27 -07:00
Constantin Wenger
54de4afd75 last fix was shit but this one works (tested) 2011-07-31 14:28:07 +02:00
Nils Dagsson Moskopp
c01c487c62 Merge branch 'master' of github.com:erlehmann/minetest-delta 2011-07-30 23:08:52 +02:00
Nils Dagsson Moskopp
2f6e931921 Merge pull request #41 from SpeedProg/master
fixe gettext I hope
2011-07-30 14:08:18 -07:00
Constantin Wenger
50dc2d8112 fixe for msvc broke linux 2011-07-30 23:05:40 +02:00
Nils Dagsson Moskopp
f4d7530587 Merge branch 'master' of github.com:erlehmann/minetest-delta 2011-07-30 22:33:26 +02:00
Nils Dagsson Moskopp
185c0bd587 Merge pull request #40 from SpeedProg/master
translated some word to german
2011-07-30 13:33:08 -07:00
Constantin Wenger
3c0090c0df german translation update, translated some of the new strings 2011-07-30 22:28:18 +02:00
Nils Dagsson Moskopp
6199252cda Merge pull request #39 from SpeedProg/master
fixes for gettext to workaround some bad behaviour of Irrlicht
2011-07-30 13:28:14 -07:00
Constantin Wenger
c08720bfba this fixes problem with msvc++ and should work on other systems and so on anyway. 2011-07-30 22:08:16 +02:00
Constantin Wenger
4882bda667 changed one forgotten en_US.UTF-8 to C 2011-07-30 22:08:16 +02:00
Constantin Wenger
a817419fe4 fixed redefinitivon of gettext.h is included more than once 2011-07-30 22:08:16 +02:00
Constantin Wenger
37bf9a666a set some more text to gettext and updated po files 2011-07-30 22:08:16 +02:00
Constantin Wenger
cd6d204a9d changed some strings of the german translation to fit in the areas 2011-07-30 22:08:16 +02:00
Constantin Wenger
9baae3a701 set locales to C because en_US not installed on some systems, only UTF-8 version and en_US.UTF-8 does not work. 2011-07-30 22:08:16 +02:00
Constantin Wenger
92f504f98d fixed displaying "umlauts" (deutsch umlaute) and hopefully other non ASCII chars, too 2011-07-30 22:03:25 +02:00
Nils Dagsson Moskopp
75816150ec * honor environment variables, use utf-8 2011-07-30 21:17:04 +02:00
Nils Dagsson Moskopp
4681392bac * PEP 8 compliance 2011-07-30 21:05:33 +02:00
Nils Dagsson Moskopp
17830c5894 - removed old minetestmapper 2011-07-30 20:37:53 +02:00
Wolfgang Fellger
edbcf7c039 * support for content types extension in minetestmapper 2011-07-30 20:35:55 +02:00
Nils Dagsson Moskopp
96bee29e35 Merge branch 'upstream/master' 2011-07-30 19:47:55 +02:00
Nils Dagsson Moskopp
82ea534997 * README updated 2011-07-30 19:30:43 +02:00
Nils Dagsson Moskopp
a4fe2a7c75 - compiling with translations works again 2011-07-30 19:28:44 +02:00
Nils Dagsson Moskopp
4ef9c7675a Merge remote-tracking branch 'origin/upstream' 2011-07-30 18:55:43 +02:00
Nils Dagsson Moskopp
f69123050b Merge branch 'master' of github.com:erlehmann/minetest-delta 2011-07-24 20:04:20 +02:00
Nils Dagsson Moskopp
a5a9c9f799 Merge pull request #36 from Oblomov/master
Some more gettext stuff
2011-07-24 11:00:38 -07:00
Giuseppe Bilotta
cce210f676 Locale dir should be parallel to global data dir 2011-07-24 19:23:03 +02:00
Giuseppe Bilotta
a8e493122e Read config from gettext.h
Otherwise the USE_GETTEXT define might not be visible.
2011-07-24 19:13:34 +02:00
Giuseppe Bilotta
e00d7ee5be Italian translations 2011-07-24 19:06:17 +02:00
Nils Dagsson Moskopp
ad6b087353 + 24x24 rendering of SVG minetest icon, polished manually to look crisp 2011-07-24 18:51:44 +02:00
Giuseppe Bilotta
3715e39e5d Actually make USE_GETTEXT available in the source 2011-07-24 18:34:10 +02:00
Giuseppe Bilotta
423109e64c Two more instances of unhardcoding the project name 2011-07-24 18:12:11 +02:00
Nils Dagsson Moskopp
71b7d92597 Merge pull request #35 from Oblomov/master
some more gettext fixes
2011-07-24 09:01:10 -07:00
Giuseppe Bilotta
e034f8a2a3 Sanitize GETTEXT usage macros
Now the user-level option is called ENABLE_GETTEXT, and USE_GETTEXT is
only set to true if gettext was enabled and found. This simplifies all
check to USE_GETTEXT only rather than the double checks for it being
enabled and found.
2011-07-24 16:52:59 +02:00
Giuseppe Bilotta
47381bde3b Bring po update out of cmake again
This solves two issues at once:
* CMake would delete po files during ‘make clean’ because it thought
  they were autogenerated and not just managed
* the only gettext tools readily available in Windows are so old they
  don't support options like --package-name

The change also moves minetest.pot down one level, so we don't need to
special case ‘en’ anymore.

The downside is of course that you need some sane POSIX shell to update
the po files.
2011-07-24 16:52:59 +02:00
Giuseppe Bilotta
c578efb32b Refactor gettext init
Put the gettext init code in a macro and define it appropriately
depending on whether gettext is actually available or not.
2011-07-24 16:52:59 +02:00
Giuseppe Bilotta
5aa2679be7 Do not package en translation, since we don't build it 2011-07-24 09:19:25 +02:00
Giuseppe Bilotta
d4e7faca21 Gettext domain should match the project name
This partially reverts 023cc0d37776976b4b192b7363f73a5d2debdef6, goes
back to using PROJECT_NAME for the filename and also uses PROJECT_NAME
as text domain in the source code.
2011-07-24 09:19:25 +02:00
Giuseppe Bilotta
4ffba76bb3 Place project name and gettext use in config 2011-07-24 09:18:29 +02:00
Nils Dagsson Moskopp
f4a08f7fb3 Merge pull request #34 from SpeedProg/master
Changes to make gettext enabled if it is found
2011-07-23 19:01:51 -07:00
Constantin Wenger
f6d9bcc9bb updated cmakerules to autodetect if gettext can be used
fixed error if gettext is disabled
2011-07-23 22:36:11 +02:00
Nils Dagsson Moskopp
a7daf8e652 * README updated 2011-07-22 21:56:00 +02:00
Constantin Wenger
4771b4951d change in readme of a lib 2011-07-22 20:55:00 +02:00
Constantin Wenger
383698186f Merge remote-tracking branch 'upstream/master' 2011-07-22 20:53:29 +02:00
Constantin Wenger
fb4c3ab4fb fixed some problems with filenames of the translations 2011-07-22 20:40:47 +02:00
Constantin Wenger
96ad0c8638 updated some parts which don't really make a problem but are better this way 2011-07-22 20:40:46 +02:00
Nils Dagsson Moskopp
7985d746f9 Merge branch 'upstream/master' 2011-07-22 20:16:58 +02:00
Nils Dagsson Moskopp
a45f287ae1 Merge pull request #32 from Oblomov/master
Gettext + misc fixes
2011-07-22 10:30:55 -07:00
Giuseppe Bilotta
7d9dd352cf Declare USE_GETTEXT option 2011-07-22 14:42:04 +02:00
Constantin Wenger
a09660dc85 fixed problem with displaying special chars 2011-07-22 13:27:30 +02:00
Giuseppe Bilotta
d78e5e7329 updatepo cmake rule
Get rid of the system-specific updatelocales.sh and introduce an
updatepo cmake rule. po files are also updated before creating the mo
files, and we now keep the .pot file (in the po/en directory). To
stabilize the po file creation, file contents are sorted by source
filename.

Update po files in the process.
2011-07-22 12:40:29 +02:00
Giuseppe Bilotta
e61b2f99c1 Static naming of po file
The po file should not be named c55 if we're in ∆. But since it is not
exposed at installation time, we don't actually need its name to be
based on the project name at all, so just call it minetest.po
2011-07-22 09:58:02 +02:00
Giuseppe Bilotta
d386f02893 Refactor mo creation/installation 2011-07-22 09:36:17 +02:00
Giuseppe Bilotta
5a3218e535 Use project name for mo files 2011-07-22 08:33:08 +02:00
Giuseppe Bilotta
02653573d2 Merge remote-tracking branch 'erlehmann/master'
Conflicts (from the introduction of fr translations):
	src/CMakeLists.txt
2011-07-22 07:48:22 +02:00
Constantin Wenger
5c66664aef changed some lines to fit the 80chars limit 2011-07-22 07:25:40 +02:00
Nils Dagsson Moskopp
21b7a272c4 * nicer firefly texture 2011-07-21 20:13:31 +02:00
Nils Dagsson Moskopp
17a47b3335 + unknown block is sick 2011-07-21 17:36:23 +02:00
Nils Dagsson Moskopp
89bbff18e5 Merge pull request #29 from cisoun/master
Add french translation.
2011-07-21 07:33:34 -07:00
Constantin Wenger
fc95d00b2f fixed not finding dll for gettext in MSVC 2011-07-21 16:21:01 +02:00
Cyriaque Skrapits
3f4f844eeb Added missing .po fil.e 2011-07-21 16:14:18 +02:00
Cyriaque Skrapits
6875ead7cf Added french translation. 2011-07-21 16:09:57 +02:00
Nils Dagsson Moskopp
5388e8b124 * different collision box for fireflies so they now hover above the ground 2011-07-21 15:40:00 +02:00
Giuseppe Bilotta
02b14090c2 Reorganize cmake gettext message output to ease debugging 2011-07-21 15:16:59 +02:00
Giuseppe Bilotta
56a744599f Restore "Leave address blank" position 2011-07-21 15:12:58 +02:00
Giuseppe Bilotta
9fa4b72a47 Find correct library for MSVC vs MingW in Winows 2011-07-21 14:50:15 +02:00
Giuseppe Bilotta
3e78b29cae Only install locale files if using gettext 2011-07-21 14:46:23 +02:00
Giuseppe Bilotta
d63c160bd6 Uppercase DEFINED or cmake 2.8.4 complains 2011-07-21 13:59:50 +02:00
Constantin Wenger
2a6c0fc17f updated some path because the dlls are mostly under bin not lib
added explanation why libintl must not belinked under some oses
2011-07-21 13:24:37 +02:00
Giuseppe Bilotta
1340da7b54 Refactor and clean up gettext management 2011-07-21 12:33:29 +02:00
Giuseppe Bilotta
89af509d10 Make gettext optional 2011-07-21 09:03:41 +02:00
Weedy
89b8b792c1 Tweak makefiles to add -delta suffix. 2011-07-21 09:03:20 +02:00
Weedy
a19491dbd2 Fix win32 MSVC compile. (screw gettext) 2011-07-21 09:03:17 +02:00
Nils Dagsson Moskopp
f5c6e3973c Merge pull request #27 from Oblomov/master
* regression fix for windows build.
2011-07-20 14:29:01 -07:00
Giuseppe Bilotta
e7beaac6f5 Move package search out of conditional
This unbreaks the Windows build which would otherwise have problems at
the jthread level.
2011-07-20 23:09:28 +02:00
Nils Dagsson Moskopp
84684e53ed + fireflies 2011-07-20 22:05:57 +02:00
Nils Dagsson Moskopp
4c0e36a5e9 * README updated 2011-07-20 19:14:40 +02:00
Nils Dagsson Moskopp
8ed83250d7 Merge branch 'master' of github.com:erlehmann/minetest-delta 2011-07-20 18:56:32 +02:00
Nils Dagsson Moskopp
360a8918dd Merge pull request #24 from SpeedProg/master
gettext paths problem
2011-07-20 09:56:23 -07:00
Constantin Wenger
4d43a67419 fixed problem with wront paths in gettext 2011-07-20 18:49:18 +02:00
Nils Dagsson Moskopp
33e80dae7f Merge branch 'master' of github.com:erlehmann/minetest-delta 2011-07-20 18:29:48 +02:00
Nils Dagsson Moskopp
4f53619a15 Merge pull request #23 from Oblomov/master
Some misc usability patches
2011-07-20 09:29:07 -07:00
Giuseppe Bilotta
3fb5b7a3bd Set the window caption for the initial window too 2011-07-20 17:59:48 +02:00
Giuseppe Bilotta
bcd3e1af2f Check the data path before usage
When not running in place, check if the assumed data path in
../share/APPNAME exists. If it doesn't exist, fall back to ../data
instead. This allows the program to run successfully from the checkout
directory even without the run-in-place flag active.
2011-07-20 17:59:48 +02:00
Giuseppe Bilotta
cd45ae3d0f Use system sqlite3/jthread libs if available 2011-07-20 17:59:48 +02:00
Nils Dagsson Moskopp
e5dc58e710 Merge branch 'master' of github.com:erlehmann/minetest-delta 2011-07-20 17:56:49 +02:00
Nils Dagsson Moskopp
cef7bb0619 Merge pull request #22 from SpeedProg/master
added gettext support
2011-07-20 08:56:35 -07:00
Constantin Wenger
a006b828a6 updated german po file for minetest-delta (prior it was for minetest)
set +x on bashscript
2011-07-20 17:00:54 +02:00
Constantin Wenger
052bb24c7f added gettext support
german translation file
and bashscript to update translations
2011-07-20 16:51:19 +02:00
Nils Dagsson Moskopp
3c630c0d90 Merge branch 'upstream/master' 2011-07-20 14:20:07 +02:00
Nils Dagsson Moskopp
d0810b0156 * README updated (graphics licensing) 2011-07-20 02:45:15 +02:00
Nils Dagsson Moskopp
ffd3cdf519 * by popular request, fewer clouds 2011-07-20 02:44:51 +02:00
Nils Dagsson Moskopp
ac2e822ea1 * README updated 2011-07-19 23:35:12 +02:00
Nils Dagsson Moskopp
0cd2972d60 + minetest application icon 2011-07-19 23:32:01 +02:00
Nils Dagsson Moskopp
821ff68f54 * initialize liquid_kind properly so compiler does not bitch about it 2011-07-19 02:02:50 +02:00
Nils Dagsson Moskopp
e8eb4d233b + fake shading for the volumetric clouds 2011-07-19 01:43:30 +02:00
Nils Dagsson Moskopp
414d1ff9e2 + volumetric clouds (thanks teddydestodes) 2011-07-18 22:50:14 +02:00
Felix Krause
7d92ce061d final fixes to liquid flow, works now as intended 2011-07-18 02:38:57 +02:00
Felix Krause
a1e2a8bec6 fixes to liquid transformation 2011-07-18 02:38:48 +02:00
Felix Krause
f34a9b6a71 fixed refactoring issues // slowed down water flow a bit
* liquid flow no longer does random things when transformed
* if a flowi
ng liquid node doesn't have a solid block as neighbor, its spread distan
ce is shortened by 1
2011-07-18 02:38:32 +02:00
Felix Krause
def870953a * refactored liquid transformation code (has some flaws)
Completely rewrote the liquid transformation. The algorithm now exclusively modifies the current node in one iteration. Another change is that MapNode.param2 now stores a bit that tells other nodes if a flowing liquid node flows downwards. This is accomplished by two masks on param2 for the "flow down" bit and the "liquid level" bits.

This will be the base of future improvements to the liquid flow. However, in the current state flowing liquid does not always disappear when cut off its source. Be aware that this branch is work in progress.
2011-07-18 02:37:19 +02:00
Nils Dagsson Moskopp
f2c6330505 * Омская птица 2011-07-18 02:09:55 +02:00
Nils Dagsson Moskopp
077ffa5231 * changed GUI to indicate Minetest Δ 2011-07-17 22:33:51 +02:00
Nils Dagsson Moskopp
0802edf582 * README updated 2011-07-16 17:14:58 +02:00
Nils Dagsson Moskopp
8bfa56648d Merge remote-tracking branch 'origin/upstream' 2011-07-16 16:52:45 +02:00
Nils Dagsson Moskopp
4d20f1283f * fix automerge regression 2011-07-15 20:16:02 +02:00
Nils Dagsson Moskopp
0a38e542c1 * regression fix, clay occurs again now 2011-07-15 06:37:47 +02:00
Nils Dagsson Moskopp
96f551a287 * possibly nicer trees 2011-07-15 02:23:41 +02:00
Nils Dagsson Moskopp
af05e4b2de Merge branch 'upstream/master'
Conflicts:
	data/oerkki1.png
	src/client.cpp
2011-07-14 22:43:28 +02:00
Nils Dagsson Moskopp
4415d95c50 * possibly improved water flow, by flyx86
- When flowing liquid starts to flow down, it stops contributing to its neighboring nodes' liquid level (possibly transforming it back to air)
- Flowing liquid turns into a source if there are at least 2 adjacent liquid source nodes
- If a new liquid flow reaches existing flowing liquid, the existing liquid is now updated properly.
2011-07-14 16:17:53 +02:00
Nils Dagsson Moskopp
1cdf210e4f * possible fix for large cubic holes in map 2011-07-13 23:12:18 +02:00
Nils Dagsson Moskopp
b0ad5ce8e2 * slightly different values for 3d perlin noise 2011-07-13 23:10:41 +02:00
Nils Dagsson Moskopp
b2447393e4 * regression fix, papyrus should appear again now 2011-07-13 16:21:20 +02:00
Nils Dagsson Moskopp
63ce6eee5c * README updated 2011-07-11 16:22:14 +02:00
Jiří Procházka
858b2d7439 + farmesh config options 2011-07-11 15:01:43 +02:00
Nils Dagsson Moskopp
6103e59c19 * amended upstream branch notes 2011-07-09 18:22:39 +02:00
Nils Dagsson Moskopp
a106c0dbdc + notes regarding upstream conversion from mercurial using hg-fast-export 2011-07-09 18:14:05 +02:00
Nils Dagsson Moskopp
f37a3a84fa Merge pull request #13 from Bahamada/upstream_merge
Upstream merge
2011-06-27 06:56:26 -07:00
Sebastian Rühl
13cf5425db backported cactus, papyrus and clay 2011-06-26 13:47:21 +02:00
Sebastian Rühl
fb6ac9a1a6 small fix 2011-06-26 12:52:03 +02:00
Sebastian Rühl
033ae0dcae Merge branch 'master' of https://github.com/erlehmann/minetest-delta.git into upstream_merge
Conflicts:
	.gitignore
	CMakeLists.txt
	data/heart.png
	src/CMakeLists.txt
	src/game.cpp
	src/guiMainMenu.cpp
	src/inventory.cpp
	src/map.cpp
	src/mapblock.cpp
	src/mapnode.cpp
	src/mapnode.h
	src/materials.cpp
	src/server.cpp

Signed-off-by: Sebastian Rühl <bahamada_basti@yahoo.de>
2011-06-26 12:24:32 +02:00
Nils Dagsson Moskopp
e261cc9e8f + rail block bounding box 2011-06-08 05:27:55 +02:00
Nils Dagsson Moskopp
2ec160454a * README updated 2011-06-07 19:41:03 +02:00
Nils Dagsson Moskopp
51d308c666 + rail 2011-06-07 19:24:30 +02:00
Nils Dagsson Moskopp
b3c439fb16 * README updated 2011-06-03 13:39:07 +02:00
Nils Dagsson Moskopp
15ae9ca8a2 + bookshelf in minetestmapper, same color as wood 2011-06-03 13:31:42 +02:00
Nils Dagsson Moskopp
c3cd89705d * point out setInventoryTextureCube() is broken with a FIXME 2011-06-03 13:13:31 +02:00
Nils Dagsson Moskopp
1bd25925cb + paper, book, bookshelf 2011-06-03 13:12:56 +02:00
Nils Dagsson Moskopp
17e17ceb59 * README updated 2011-06-03 00:57:39 +02:00
Nils Dagsson Moskopp
8da4a4276f + papyrus in minetestmapper 2011-06-03 00:56:27 +02:00
Nils Dagsson Moskopp
3bb1cfdf36 + papyrus 2011-06-03 00:55:28 +02:00
Nils Dagsson Moskopp
e627f023a0 * made cactus color darker 2011-06-03 00:52:46 +02:00
Nils Dagsson Moskopp
bd5cdbf1a4 + check if sectors/sectors2 directories exist before attempting to read them 2011-06-02 17:21:58 +02:00
Nils Dagsson Moskopp
34e57da1ca * encoding fix 2011-06-02 17:19:50 +02:00
Nils Dagsson Moskopp
de8996ac3b * tabs to spaces 2011-06-02 17:13:05 +02:00
Nils Dagsson Moskopp
33264d0fb6 * ignore minetestmapper output 2011-06-02 16:54:05 +02:00
Nils Dagsson Moskopp
cc65bda2cc + sandstone color value now in minetestmapper 2011-06-02 16:52:25 +02:00
Nils Dagsson Moskopp
4b2b65df9f + minetestmapper2, colors modified for Minetest Δ 2011-06-02 16:17:50 +02:00
Nils Dagsson Moskopp
4800f1df97 * README updated 2011-06-02 03:03:47 +02:00
Nils Dagsson Moskopp
9850df35ae Merge pull request #1 from TeddyDesTodes/master
+ submenu for key assignment, fast_move and free_move can now be toggled
2011-06-01 17:20:37 -07:00
teddydestodes
7dfa3442fe Merge remote-tracking branch 'upstream/master' 2011-06-01 19:47:10 +02:00
teddydestodes
58bc6f3a18 added new submenu for key assignment
configwriting/saving isn't complete and will break your config if you use fancy keys
2011-06-01 19:44:07 +02:00
Nils Dagsson Moskopp
a75c31143a * README updated 2011-06-01 17:19:28 +02:00
Nils Dagsson Moskopp
15b375827e Merge pull request #5 from bucket-T/master
MacOSX build support
2011-06-01 08:08:41 -07:00
Nils Dagsson Moskopp
60578e0950 * README updated 2011-06-01 16:46:49 +02:00
teddydestodes
09d7654f46 Merge remote-tracking branch 'bucket-t/master' 2011-06-01 14:43:27 +02:00
MrLoom
28234f6e54 MacOSX build support 2011-06-01 14:13:22 +02:00
teddydestodes
63fe487d93 Merge remote-tracking branch 'upstream/master' 2011-06-01 14:11:52 +02:00
Nils Dagsson Moskopp
d2b2c7c09e * improved fence dimensions (cuboid side lengths now multiples of 2, textures should fit better) 2011-06-01 20:06:16 +08:00
Nils Dagsson Moskopp
c930a92b72 * clay is rarer now 2011-06-01 08:09:28 +02:00
Nils Dagsson Moskopp
cffd40c5d6 + clay and associated items 2011-06-01 04:57:46 +02:00
Nils Dagsson Moskopp
fb78854e9b + brick 2011-05-31 22:04:09 +02:00
Nils Dagsson Moskopp
461f53945d * menulogo now shows minetest delta 2011-05-31 20:52:20 +02:00
Nils Dagsson Moskopp
6c3ca42e0e + fence inventory icon 2011-05-31 03:54:39 +02:00
Nils Dagsson Moskopp
0f4c83eb98 * improved fence dimensions (cuboid side lengths now multiples of 2, textures should fit better) 2011-05-31 02:56:23 +02:00
Nils Dagsson Moskopp
880aa870a0 + cactii 2011-05-30 14:42:08 +02:00
Nils Dagsson Moskopp
cf136f1935 + .gitignore 2011-05-30 01:21:37 +08:00
teddydestodes
ca26de72c9 fast_move and free_move can now be toggled 2011-05-29 19:17:42 +02:00
Nils Dagsson Moskopp
af574e58fe + .gitignore 2011-05-29 19:08:59 +02:00
Nils Dagsson Moskopp
ed81aa8aae + README in main directory 2011-05-29 19:03:59 +02:00
Nils Dagsson Moskopp
9ab64658ba * better heart icon 2011-05-29 18:49:02 +02:00
Nils Dagsson Moskopp
3504a66eda * better glass graphics 2011-05-29 18:48:39 +02:00
Nils Dagsson Moskopp
3f0ac7adce * better rat graphics 2011-05-29 18:48:21 +02:00
Nils Dagsson Moskopp
0076339914 * enemies are now omsk birds 2011-05-29 18:47:40 +02:00
Nils Dagsson Moskopp
2176f4d697 * better player graphics 2011-05-29 18:45:50 +02:00
Nils Dagsson Moskopp
843ffba567 + sandstone 2011-05-29 18:44:42 +02:00
140 changed files with 20851 additions and 10885 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
*.cpp diff=cpp
*.h diff=cpp

1
.gitignore vendored
View File

@@ -9,6 +9,7 @@ src/jthread/CMakeFiles/*
src/jthread/Makefile
src/jthread/cmake_config.h
src/jthread/cmake_install.cmake
.*.swp
minetest.conf
bin/
CMakeCache.txt

29
.hgtags
View File

@@ -1,28 +1 @@
c37bcfd89dd627fdb131ae3f77fcaab02721bf76 working
69547bd6be420eb40f55524fd2131cbbaa2e0e29 110107195706-exp
e3c3c8e27bbc8c9b61710517a78944deb1c61696 110211211322
23880c78e40c50ad54fcd8844510f7a423b37f2a 110212200513
20c49c98c92a62df457b773c562df41d4167492b 110214175330
10be2b71f965585af90af96903e83b4ddff52bf9 20110424_0
9b05d4bfee9312aef4182fa6f63b4237368cec34 0.2.20110529_0
6fa0a8b40406aa567f8fa84b5e2045a7e3762c1d 0.2.20110529_1
cf6dd618ef0b7514c81ae87749733b5a328fc763 0.2.20110529_2
96efc17b4cd92aacbe947b520a6ba91727d42f03 0.2.20110602_0
0000000000000000000000000000000000000000 0.2.20110602_0
6f17cd3f6c5481e6abc906fc441980c764632cbc 0.2.20110602_0
dd08a9b5cb84d55b7576bb3fde3068dd263bc3bc 0.2.20110618_0_dev
25aa2021937f7a8b36808390983cebbc16ae6965 0.2.20110704_0
25aa2021937f7a8b36808390983cebbc16ae6965 0.2.20110704_0
0000000000000000000000000000000000000000 0.2.20110704_0
0000000000000000000000000000000000000000 0.2.20110704_0
65263ec55caf526e3f3e0bdc6657ce42daee46bc 0.2.20110704_0
06c62112b503e746d5d8cc40f951974447d590b7 0.2.20110731_0
705a7e95b8710c8cada5524d8c7bb658f4b710d9 0.2.20110731_1
4a6cf9491306988b24c79438ee6398885c432fce 0.2.20110731_2
4a6cf9491306988b24c79438ee6398885c432fce 0.2.20110731_2
0000000000000000000000000000000000000000 0.2.20110731_2
0000000000000000000000000000000000000000 0.2.20110731_2
8ad16fbce9a4da45b2552ad8b400a5a127722acc 0.2.20110731_2
c87e28deaabf4a776c261b3a09b6bf5ea3e04abf 0.2.20110731_3
c87e28deaabf4a776c261b3a09b6bf5ea3e04abf 0.2.20110731_3
0000000000000000000000000000000000000000 0.2.20110731_3
a519d683251105654d2a146ae7b91d3850b6504c 0.2.20110731_3

View File

@@ -7,11 +7,14 @@ endif(${CMAKE_VERSION} STREQUAL "2.8.2")
# This can be read from ${PROJECT_NAME} after project() is called
project(minetest)
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
set(VERSION_MAJOR 0)
set(VERSION_MINOR 2)
set(VERSION_PATCH 20110731_3)
set(VERSION_MINOR 3)
set(VERSION_PATCH dev-20111021)
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
MESSAGE(STATUS "*** Will build version ${VERSION_STRING} ***")
# Configuration options
if(WIN32)

View File

@@ -26,11 +26,11 @@ Map directory:
- Map is stored in a directory, which can be removed to generate a new map.
- There is a command-line option for it: --map-dir
- For a RUN_IN_PLACE build, it is located in:
../map
../world
- Otherwise something like this:
Windows: C:\Documents and Settings\user\Application Data\minetest\map
Linux: ~/.minetest/map
OS X: ~/Library/Application Support/minetest/map
Windows: C:\Documents and Settings\user\Application Data\minetest\world
Linux: ~/.minetest/world
OS X: ~/Library/Application Support/minetest/world
Configuration file:
-------------------
@@ -157,6 +157,8 @@ Compiling on Windows:
GETTEXT_MSGFMT DIR/gettext/bin/msgfmt
-----------------
- Hit "Configure"
- Hit "Configure" once again 8)
- If something is still coloured red, you have a problem.
- Hit "Generate"
If using MSVC:
- Open the generated minetest.sln

View File

@@ -16,21 +16,6 @@ FIND_PROGRAM(GETTEXT_MSGFMT
PATHS "${CUSTOM_GETTEXT_PATH}/bin"
DOC "path to msgfmt")
FIND_PROGRAM(GETTEXT_MSGMERGE
NAMES msgmerge
PATHS "${CUSTOM_GETTEXT_PATH}/bin"
DOC "path to msgmerge")
FIND_PROGRAM(GETTEXT_MSGEN
NAMES msgen
PATHS "${CUSTOM_GETTEXT_PATH}/bin"
DOC "path to msgen")
FIND_PROGRAM(GETTEXT_EXTRACT
NAMES xgettext
PATHS "${CUSTOM_GETTEXT_PATH}/bin"
DOC "path to xgettext")
# modern Linux, as well as Mac, seem to not need require special linking
# they do not because gettext is part of glibc
# TODO check the requirements on other BSDs and older Linux
@@ -56,7 +41,6 @@ IF (WIN32)
DOC "gettext *iconv*.lib")
ENDIF(WIN32)
IF(GETTEXT_INCLUDE_DIR AND GETTEXT_MSGFMT)
IF (WIN32)
# in the Win32 case check also for the extra linking requirements
@@ -64,6 +48,10 @@ IF(GETTEXT_INCLUDE_DIR AND GETTEXT_MSGFMT)
SET(GETTEXT_FOUND TRUE)
ENDIF()
ELSE(WIN32)
# *BSD variants require special linkage as they don't use glibc
IF(${CMAKE_SYSTEM_NAME} MATCHES "BSD")
SET(GETTEXT_LIBRARY "intl")
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "BSD")
SET(GETTEXT_FOUND TRUE)
ENDIF(WIN32)
ENDIF()
@@ -71,10 +59,14 @@ ENDIF()
IF(GETTEXT_FOUND)
SET(GETTEXT_PO_PATH ${CMAKE_SOURCE_DIR}/po)
SET(GETTEXT_MO_BUILD_PATH ${CMAKE_BINARY_DIR}/locale/<locale>/LC_MESSAGES)
SET(GETTEXT_MO_DEST_PATH locale/<locale>/LC_MESSAGES)
SET(GETTEXT_MO_DEST_PATH ${DATADIR}/../locale/<locale>/LC_MESSAGES)
FILE(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*")
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot)
MACRO(SET_MO_PATHS _buildvar _destvar _locale)
STRING(REPLACE "<locale>" ${_locale} ${_buildvar} ${GETTEXT_MO_BUILD_PATH})
STRING(REPLACE "<locale>" ${_locale} ${_destvar} ${GETTEXT_MO_DEST_PATH})
ENDMACRO(SET_MO_PATHS)
ELSE()
SET(GETTEXT_INCLUDE_DIR "")
SET(GETTEXT_LIBRARY "")
ENDIF()

BIN
data/apple.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

BIN
data/apple_iron.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

BIN
data/chest_lock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

BIN
data/dungeon_master.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
data/fireball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

BIN
data/ladder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

BIN
data/lava.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

BIN
data/sapling.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 927 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

After

Width:  |  Height:  |  Size: 927 B

View File

@@ -53,12 +53,12 @@ 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
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
$ wget https://bitbucket.org/celeron55/minetest/get/tip.tar.gz
$ tar xf tip.tar.gz
$ cd minetest
$ wget https://github.com/celeron55/minetest/tarball/master -O master.tar.gz
$ tar xf master.tar.gz
$ cd celeron55-minetest-286edd4 (or similar)
Build a version that runs directly from the source directory:
$ cmake . -DRUN_IN_PLACE=1
@@ -163,6 +163,22 @@ Compiling on Windows:
- You should now have a working game with the executable in
DIR/minetest/bin/minetest.exe
Windows releases of minetest are built using a bat script like this:
--------------------------------------------------------------------
set installpath="C:\tmp\minetest_install"
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
set sourcedir=%CD%
set builddir=%sourcedir%\bvc10
mkdir %builddir%
pushd %builddir%
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=1 -DCMAKE_INSTALL_PREFIX=%installpath%
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Release
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" INSTALL.vcxproj /p:Configuration=Release
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" PACKAGE.vcxproj /p:Configuration=Release
popd
License of Minetest-c55
-----------------------

View File

@@ -3,6 +3,39 @@ Minetest-c55 changelog
This should contain all the major changes.
For minor stuff, refer to the commit log of the repository.
0.3.dev-20111021:
- Modify dungeon masters to only try to shoot players
- Fix object duplication bug at block load/unload bug
- Improve network layer
0.3.dev-20111016:
- Locked chest
- Server user limit setting (max_users)
- Wielded tool is shown in HUD
- View bobbing
- Saplings that drop from leaf blocks and when placed on ground will grow to trees
- Optimized map saving (does not re-save everything all the time)
- New mob system and new mob: dungeon master
- Death/respawn screen
0.2.20110922_3:
- Fix the build for MSVC2010; also released for windows using MSVC2010.
0.2.20110922_1:
- Make client report a newer version number to the server than 2011-07-31 does and make server disallow old clients
0.2.20110922:
- Map is saved in an SQLite database file (by Queatz)
- Ladders (MarkTraceur)
- Lava
- Apple trees (sfan5)
- Slightly better looking inventory with transparency
- /me chat command (Oblomov)
- Using chosen map seed possible through fixed_map_seed configuration option (kahrl)
- Fix the long-existed PeerNotFound loop bug
- Some translations and localization-related fixes
- Lots of small fixes
2011-07-31_3:
- Fixes a bug that made the server to deny non-empty passwords from players connecting the first time

View File

@@ -85,5 +85,10 @@ Furnace metadata:
Chest metadata:
TBD
Locking Chest metadata:
u16 string_len
u8[string_len] string
TBD
// END

View File

@@ -42,7 +42,7 @@ Initialization:
u8 channel = 0
# Control packet header
u8 type = TYPE_CONTROL = 0
u8 controltype = CONTROLTYPE_DISCO = 2
u8 controltype = CONTROLTYPE_DISCO = 3
- Here's a quick untested connect-disconnect done in PHP:
# host: ip of server (use gethostbyname(hostname) to get from a dns name)
@@ -61,7 +61,7 @@ function check_if_minetestserver_up($host, $port)
$peer_id = substr($buf, 9, 2);
# Disconnect
$buf = "\x4f\x45\x74\x03".$peer_id."\x00\x00\x02";
$buf = "\x4f\x45\x74\x03".$peer_id."\x00\x00\x03";
socket_sendto($socket, $buf, strlen($buf), 0, $host, $port);
socket_close($socket);

271
genmap.py
View File

@@ -1,271 +0,0 @@
#!/usr/bin/python2
# This is an example script that generates some valid map data.
import struct
import random
import os
import sys
import zlib
import array
from pnoise import pnoise
# Old directory format:
# world/sectors/XXXXZZZZ/YYYY
# XXXX,YYYY,ZZZZ = coordinates in hexadecimal
# fffe = -2
# ffff = -1
# 0000 = 0
# 0001 = 1
#
# New directory format:
# world/sectors2/XXX/ZZZ/YYYY
# XXX,YYYY,ZZZ = coordinates in hexadecimal
# fffe = -2
# ffff = -1
# 0000 = 0
# 0001 = 1
# ffe = -2
# fff = -1
# 000 = 0
# 001 = 1
#
# For more proper file format documentation, refer to mapformat.txt
# For node type documentation, refer to mapnode.h
# NodeMetadata documentation is not complete, refer to nodemeta.cpp
#
# Seed for generating terrain
SEED = 0
# 0=old, 1=new
SECTOR_DIR_FORMAT = 1
mapdir = "world"
def to4h(i):
s = "";
s += '{0:1x}'.format((i>>12) & 0x000f)
s += '{0:1x}'.format((i>>8) & 0x000f)
s += '{0:1x}'.format((i>>4) & 0x000f)
s += '{0:1x}'.format((i>>0) & 0x000f)
return s
def to3h(i):
s = "";
s += '{0:1x}'.format((i>>8) & 0x000f)
s += '{0:1x}'.format((i>>4) & 0x000f)
s += '{0:1x}'.format((i>>0) & 0x000f)
return s
def get_sector_dir(px, pz):
global SECTOR_DIR_FORMAT
if SECTOR_DIR_FORMAT == 0:
return "/sectors/"+to4h(px)+to4h(pz)
elif SECTOR_DIR_FORMAT == 1:
return "/sectors2/"+to3h(px)+"/"+to3h(pz)
else:
assert(0)
def getrand_air_stone():
i = random.randrange(0,2)
if i==0:
return 0
return 254
# 3-dimensional vector (position)
class v3:
def __init__(self, x=0, y=0, z=0):
self.X = x
self.Y = y
self.Z = z
class NodeMeta:
def __init__(self, type_id, data):
self.type_id = type_id
self.data = data
class StaticObject:
def __init__(self):
self.type_id = 0
self.data = ""
def ser_u16(i):
return chr((i>>8)&0xff) + chr((i>>0)&0xff)
def ser_u32(i):
return (chr((i>>24)&0xff) + chr((i>>16)&0xff)
+ chr((i>>8)&0xff) + chr((i>>0)&0xff))
# A 16x16x16 chunk of map
class MapBlock:
def __init__(self):
self.content = array.array('B')
self.param1 = array.array('B')
self.param2 = array.array('B')
for i in range(16*16*16):
# Initialize to air
self.content.append(254)
# Full light on sunlight, none when no sunlight
self.param1.append(15)
# No additional parameters
self.param2.append(0)
# key = v3 pos
# value = NodeMeta
self.nodemeta = {}
# key = v3 pos
# value = StaticObject
self.static_objects = {}
def set_content(self, v3, b):
self.content[v3.Z*16*16+v3.Y*16+v3.X] = b
def set_param1(self, v3, b):
self.param1[v3.Z*16*16+v3.Y*16+v3.X] = b
def set_param2(self, v3, b):
self.param2[v3.Z*16*16+v3.Y*16+v3.X] = b
# Get data for serialization. Returns a string.
def serialize_data(self):
s = ""
for i in range(16*16*16):
s += chr(self.content[i])
for i in range(16*16*16):
s += chr(self.param1[i])
for i in range(16*16*16):
s += chr(self.param2[i])
return s
def serialize_nodemeta(self):
s = ""
s += ser_u16(1)
s += ser_u16(len(self.nodemeta))
for pos, meta in self.nodemeta.items():
pos_i = pos.Z*16*16 + pos.Y*16 + pos.X
s += ser_u16(pos_i)
s += ser_u16(meta.type_id)
s += ser_u16(len(meta.data))
s += meta.data
return s
def serialize_staticobj(self):
s = ""
s += chr(0)
s += ser_u16(len(self.static_objects))
for pos, obj in self.static_objects.items():
pos_i = pos.Z*16*16 + pos.Y*16 + pos.X
s += ser_s32(pos.X*1000)
s += ser_s32(pos.Y*1000)
s += ser_s32(pos.Z*1000)
s += ser_u16(obj.type_id)
s += ser_u16(len(obj.data))
s += obj.data
return s
def writeblock(mapdir, px,py,pz, block):
sectordir = mapdir + get_sector_dir(px, pz);
try:
os.makedirs(sectordir)
except OSError:
pass
path = sectordir+"/"+to4h(py)
print("writing block file "+path)
f = open(sectordir+"/"+to4h(py), "wb")
if f == None:
return
# version
version = 17
f.write(struct.pack('B', version))
# flags
# 0x01=is_undg, 0x02=dn_diff, 0x04=lighting_expired
flags = 0 + 0x02 + 0x04
f.write(struct.pack('B', flags))
# data
c_obj = zlib.compressobj()
c_obj.compress(block.serialize_data())
f.write(struct.pack('BB', 0x78, 0x9c)) # zlib magic number
f.write(c_obj.flush())
# node metadata
c_obj = zlib.compressobj()
c_obj.compress(block.serialize_nodemeta())
f.write(struct.pack('BB', 0x78, 0x9c)) # zlib magic number
f.write(c_obj.flush())
# mapblockobject count
f.write(ser_u16(0))
# static objects
f.write(block.serialize_staticobj())
# timestamp
f.write(ser_u32(0xffffffff))
f.close()
for z0 in range(-1,3):
for x0 in range(-1,3):
for y0 in range(-1,3):
print("generating block "+str(x0)+","+str(y0)+","+str(z0))
#v3 blockp = v3(x0,y0,z0)
# Create a MapBlock
block = MapBlock()
# Generate stuff in it
for z in range(0,16):
for x in range(0,16):
h = 20.0*pnoise((x0*16+x)/100.,(z0*16+z)/100.,SEED+0)
h += 5.0*pnoise((x0*16+x)/25.,(z0*16+z)/25.,SEED+0)
if pnoise((x0*16+x)/25.,(z0*16+z)/25.,SEED+92412) > 0.05:
h += 10
#print("r="+str(r))
# This enables comparison by ==
h = int(h)
for y in range(0,16):
p = v3(x,y,z)
b = 254
y1 = y0*16+y
if y1 <= h-3:
b = 0 #stone
elif y1 <= h and y1 <= 0:
b = 8 #mud
elif y1 == h:
b = 1 #grass
elif y1 < h:
b = 8 #mud
elif y1 <= 1:
b = 9 #water
# Material content
block.set_content(p, b)
# Place a sign at the center at surface level.
# Placing a sign means placing the sign node and
# adding node metadata to the mapblock.
if x == 8 and z == 8 and y0*16 <= h-1 and (y0+1)*16-1 > h:
p = v3(8,h+1-y0*16,8)
# 14 = Sign
content_type = 14
block.set_content(p, content_type)
# This places the sign to the bottom of the cube.
# Working values: 0x01, 0x02, 0x04, 0x08, 0x10, 0x20
block.set_param2(p, 0x08)
# Then add metadata to hold the text of the sign
s = "Hello at sector ("+str(x0)+","+str(z0)+")"
meta = NodeMeta(content_type, ser_u16(len(s))+s)
block.nodemeta[p] = meta
# Write it on disk
writeblock(mapdir, x0,y0,z0, block)
#END

View File

@@ -1,67 +0,0 @@
#!/bin/sh
PROJECT_NAME=minetest-delta
PACKAGEDIR=../$PROJECT_NAME-packages
PACKAGENAME=$PROJECT_NAME-binary-`date +%y%m%d%H%M%S`
PACKAGEPATH=$PACKAGEDIR/$PACKAGENAME
mkdir -p $PACKAGEPATH
mkdir -p $PACKAGEPATH/bin
mkdir -p $PACKAGEPATH/data
mkdir -p $PACKAGEPATH/doc
mkdir -p $PACKAGEPATH/locale/de/LC_MESSAGES/
cp minetest.conf.example $PACKAGEPATH/
cp bin/$PROJECT_NAME.exe $PACKAGEPATH/bin/
cp bin/Irrlicht.dll $PACKAGEPATH/bin/
cp bin/zlibwapi.dll $PACKAGEPATH/bin/
#cp bin/test $PACKAGEPATH/bin/
#cp bin/fasttest $PACKAGEPATH/bin/
#cp bin/server $PACKAGEPATH/bin/
#cp ../irrlicht/irrlicht-1.7.1/lib/Linux/libIrrlicht.a $PACKAGEPATH/bin/
#cp ../jthread/jthread-1.2.1/src/.libs/libjthread-1.2.1.so $PACKAGEPATH/bin/
cp -r data/fontlucida.png $PACKAGEPATH/data/
cp -r data/player.png $PACKAGEPATH/data/
cp -r data/player_back.png $PACKAGEPATH/data/
cp -r data/stone.png $PACKAGEPATH/data/
cp -r data/grass.png $PACKAGEPATH/data/
cp -r data/grass_footsteps.png $PACKAGEPATH/data/
cp -r data/water.png $PACKAGEPATH/data/
cp -r data/tree.png $PACKAGEPATH/data/
cp -r data/leaves.png $PACKAGEPATH/data/
cp -r data/mese.png $PACKAGEPATH/data/
cp -r data/cloud.png $PACKAGEPATH/data/
cp -r data/sign.png $PACKAGEPATH/data/
cp -r data/sign_back.png $PACKAGEPATH/data/
cp -r data/rat.png $PACKAGEPATH/data/
cp -r data/mud.png $PACKAGEPATH/data/
cp -r data/torch.png $PACKAGEPATH/data/
cp -r data/torch_on_floor.png $PACKAGEPATH/data/
cp -r data/torch_on_ceiling.png $PACKAGEPATH/data/
cp -r data/tree_top.png $PACKAGEPATH/data/
cp -r data/coalstone.png $PACKAGEPATH/data/
cp -r data/crack.png $PACKAGEPATH/data/
cp -r data/wood.png $PACKAGEPATH/data/
cp -r data/stick.png $PACKAGEPATH/data/
cp -r data/tool_wpick.png $PACKAGEPATH/data/
cp -r data/tool_stpick.png $PACKAGEPATH/data/
cp -r data/tool_mesepick.png $PACKAGEPATH/data/
cp -r data/grass_side.png $PACKAGEPATH/data/
cp -r data/lump_of_coal.png $PACKAGEPATH/data/
cp -r data/lump_of_iron.png $PACKAGEPATH/data/
cp -r data/mineral_coal.png $PACKAGEPATH/data/
cp -r data/mineral_iron.png $PACKAGEPATH/data/
cp -r data/sand.png $PACKAGEPATH/data/
#cp -r data/pauseMenu.gui $PACKAGEPATH/data/
cp -r doc/README.txt $PACKAGEPATH/doc/README.txt
cp -r locale/de/LC_MESSAGES/$PROJECT_NAME.mo $PACKAGEPATH/locale/de/LC_MESSAGES/
cd $PACKAGEDIR
rm $PACKAGENAME.zip
zip -r $PACKAGENAME.zip $PACKAGENAME

BIN
minetest-icon-24x24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

View File

@@ -39,6 +39,8 @@
#keymap_jump = KEY_SPACE
#keymap_sneak = KEY_LSHIFT
#keymap_inventory = KEY_KEY_I
# Go down ladder / go down in fly mode / go fast in fast mode
#keymap_special1 = KEY_KEY_E
#keymap_chat = KEY_KEY_T
#keymap_rangeselect = KEY_KEY_R
#keymap_freemove = KEY_KEY_K
@@ -46,7 +48,6 @@
#keymap_frametime_graph = KEY_F1
#keymap_screenshot = KEY_F12
# Some (temporary) keys for debugging
#keymap_special1 = KEY_KEY_E
#keymap_print_debug_stacks = KEY_KEY_P
# The desired FPS
@@ -58,8 +59,8 @@
#viewing_range_nodes_max = 300
#viewing_range_nodes_min = 25
# Initial window size
screenW# = 800
screenH# = 600
#screenW = 800
#screenH = 600
# Address to connect to (#blank = start local server)
#address =
# Enable random user input, for testing
@@ -103,41 +104,54 @@ screenH# = 600
#invisible_stone = false
# Path for screenshots
#screenshot_path = .
# Amount of view bobbing (0 = no view bobbing, 1.0 = normal, 2.0 = double)
#view_bobbing_amount = 1.0
#
# Server stuff
#
# Map directory (everything in the world is stored here)
#map-#dir = /custom/map
#map-dir = /custom/map
# Message of the Day
#motd = Welcome to this awesome Minetest server!
# Maximum number of players connected simultaneously
#max_users = 20
# Set to false to allow old clients to connect
#strict_protocol_version_checking = true
# Set to true to enable creative mode (unlimited inventory)
#creative_mode = false
# Enable players getting damage and dying
#enable_damage = false
# Despawn all non-peaceful mobs
#only_peaceful_mobs = false
# A chosen map seed for a new map, leave empty for random
#fixed_map_seed =
# Gives some stuff to players at the beginning
#give_initial_stuff = false
# New users need to input this password
#default_password =
# Available privileges: build, teleport, settime, privs, shout
#default_privs = build, shout
# 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
# Profiler data print interval. #0 = disable.
#profiler_print_interval = 0
#enable_mapgen_debug_info = false
# Player and object positions are sent at intervals specified by this
#objectdata_interval = 0.2
#active_object_range = 2
#active_object_send_range_blocks = 3
#active_block_range = 2
#max_simultaneous_block_sends_per_client = 2
#max_simultaneous_block_sends_server_total = 8
#max_block_send_distance = 8
#max_block_generate_distance = 8
#max_block_send_distance = 7
#max_block_generate_distance = 5
#time_send_interval = 20
# Length of day/night cycle. 72=20min, 360=4min, 1=24hour
#time_speed = 72
#server_unload_unused_data_timeout = 60
#server_map_save_interval = 60
#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

View File

@@ -1,25 +0,0 @@
0 128 128 128
1 107 134 51
2 39 66 106
3 255 255 0
4 86 58 31
5 48 95 8
6 102 129 38
7 178 178 0
8 101 84 36
9 39 66 106
12 104 78 42
13 210 194 156
14 117 86 41
15 128 79 0
16 118 118 118
18 123 123 123
19 199 199 199
20 183 183 222
21 103 78 42
22 219 202 178
23 78 154 6
24 204 0 0
25 211 215 207
26 138 226 52
27 104 78 42

View File

@@ -1,275 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Made by j0gge, modified by celeron55
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
# Requires Python Imaging Library: http://www.pythonware.com/products/pil/
# Some speed-up: ...lol, actually it slows it down.
#import psyco ; psyco.full()
#from psyco.classes import *
import zlib
import Image, ImageDraw
import os
import string
import time
def hex_to_int(h):
i = int(h,16)
if(i > 2047):
i-=4096
return i
def hex4_to_int(h):
i = int(h,16)
if(i > 32767):
i-=65536
return i
def int_to_hex3(i):
if(i < 0):
return "%03X" % (i + 4096)
else:
return "%03X" % i
def int_to_hex4(i):
if(i < 0):
return "%04X" % (i + 65536)
else:
return "%04X" % i
def limit(i,l,h):
if(i>h):
i=h
if(i<l):
i=l
return i
# Fix these!
path="../map/"
output="map.png"
sector_xmin = -1000/16
sector_xmax = 1000/16
sector_zmin = -1000/16
sector_zmax = 1000/16
# Load color information for the blocks.
colors = {}
f = file("colors.txt")
for line in f:
values = string.split(line)
colors[int(values[0])] = (int(values[1]), int(values[2]), int(values[3]))
f.close()
xlist = []
zlist = []
# List all sectors to memory and calculate the width and heigth of the resulting picture.
if os.path.exists(path + "sectors2"):
for filename in os.listdir(path + "sectors2"):
for filename2 in os.listdir(path + "sectors2/" + filename):
x = hex_to_int(filename)
z = hex_to_int(filename2)
if x < sector_xmin or x > sector_xmax:
continue
if z < sector_zmin or z > sector_zmax:
continue
xlist.append(x)
zlist.append(z)
if os.path.exists(path + "sectors"):
for filename in os.listdir(path + "sectors"):
x = hex4_to_int(filename[:4])
z = hex4_to_int(filename[-4:])
if x < sector_xmin or x > sector_xmax:
continue
if z < sector_zmin or z > sector_zmax:
continue
xlist.append(x)
zlist.append(z)
w = (max(xlist) - min(xlist)) * 16 + 16
h = (max(zlist) - min(zlist)) * 16 + 16
print "w="+str(w)+" h="+str(h)
im = Image.new("RGB", (w, h), "white")
impix = im.load()
stuff={}
starttime = time.time()
# Go through all sectors.
for n in range(len(xlist)):
#if n > 500:
# break
if n % 200 == 0:
nowtime = time.time()
dtime = nowtime - starttime
n_per_second = 1.0 * n / dtime
if n_per_second != 0:
seconds_per_n = 1.0 / n_per_second
time_guess = seconds_per_n * len(xlist)
remaining_s = time_guess - dtime
remaining_minutes = int(remaining_s / 60)
remaining_s -= remaining_minutes * 60;
print("Processing sector "+str(n)+" of "+str(len(xlist))
+" ("+str(round(100.0*n/len(xlist), 1))+"%)"
+" (ETA: "+str(remaining_minutes)+"m "
+str(int(remaining_s))+"s)")
xpos = xlist[n]
zpos = zlist[n]
xhex = int_to_hex3(xpos)
zhex = int_to_hex3(zpos)
xhex4 = int_to_hex4(xpos)
zhex4 = int_to_hex4(zpos)
sector1 = xhex4.lower() + zhex4.lower()
sector2 = xhex.lower() + "/" + zhex.lower()
ylist=[]
sectortype = ""
try:
for filename in os.listdir(path + "sectors/" + sector1):
if(filename != "meta"):
pos = int(filename,16)
if(pos > 32767):
pos-=65536
ylist.append(pos)
sectortype = "old"
except OSError:
pass
if sectortype != "old":
try:
for filename in os.listdir(path + "sectors2/" + sector2):
if(filename != "meta"):
pos = int(filename,16)
if(pos > 32767):
pos-=65536
ylist.append(pos)
sectortype = "new"
except OSError:
pass
if sectortype == "":
continue
ylist.sort()
# Make a list of pixels of the sector that are to be looked for.
pixellist = []
for x in range(16):
for y in range(16):
pixellist.append((x,y))
# Go through the Y axis from top to bottom.
for ypos in reversed(ylist):
yhex = int_to_hex4(ypos)
filename = ""
if sectortype == "old":
filename = path + "sectors/" + sector1 + "/" + yhex.lower()
else:
filename = path + "sectors2/" + sector2 + "/" + yhex.lower()
f = file(filename, "rb")
# Let's just memorize these even though it's not really necessary.
version = f.read(1)
flags = f.read(1)
dec_o = zlib.decompressobj()
try:
mapdata = dec_o.decompress(f.read())
except:
mapdata = []
f.close()
if(len(mapdata)<4096):
print "bad: " + xhex+zhex+"/"+yhex + " " + len(mapdata)
else:
chunkxpos=xpos*16
chunkypos=ypos*16
chunkzpos=zpos*16
for (x,z) in reversed(pixellist):
for y in reversed(range(16)):
datapos=x+y*16+z*256
if(ord(mapdata[datapos])!=254):
try:
pixellist.remove((x,z))
# Memorize information on the type and height of the block and for drawing the picture.
stuff[(chunkxpos+x,chunkzpos+z)]=(chunkypos+y,ord(mapdata[datapos]))
break
except:
print "strange block: " + xhex+zhex+"/"+yhex + " x: " + str(x) + " y: " + str(y) + " z: " + str(z) + " block: " + str(ord(mapdata[datapos]))
# After finding all the pixeld in the sector, we can move on to the next sector without having to continue the Y axis.
if(len(pixellist)==0):
break
print "Drawing image"
# Drawing the picture
starttime = time.time()
n = 0
minx = min(xlist)
minz = min(zlist)
for (x,z) in stuff.iterkeys():
if n % 500000 == 0:
nowtime = time.time()
dtime = nowtime - starttime
n_per_second = 1.0 * n / dtime
if n_per_second != 0:
listlen = len(stuff)
seconds_per_n = 1.0 / n_per_second
time_guess = seconds_per_n * listlen
remaining_s = time_guess - dtime
remaining_minutes = int(remaining_s / 60)
remaining_s -= remaining_minutes * 60;
print("Drawing pixel "+str(n)+" of "+str(listlen)
+" ("+str(round(100.0*n/listlen, 1))+"%)"
+" (ETA: "+str(remaining_minutes)+"m "
+str(int(remaining_s))+"s)")
n += 1
(r,g,b)=colors[stuff[(x,z)][1]]
# Comparing heights of a couple of adjacent blocks and changing brightness accordingly.
try:
y1=stuff[(x-1,z)][0]
y2=stuff[(x,z-1)][0]
y=stuff[(x,z)][0]
d=(y-y1+y-y2)*12
if(d>36):
d=36
r=limit(r+d,0,255)
g=limit(g+d,0,255)
b=limit(b+d,0,255)
except:
pass
#impix[w-1-(x-minx*16),h-1-(z-minz*16)]=(r,g,b)
impix[x-minx*16,h-1-(z-minz*16)]=(r,g,b)
# Flip the picture to make it right and save.
#print "Transposing"
#im=im.transpose(Image.FLIP_TOP_BOTTOM)
print "Saving"
im.save(output)

486
po/da/minetest.po Normal file
View File

@@ -0,0 +1,486 @@
# German translations for minetest-c55 package.
# Copyright (C) 2011 celeron
# This file is distributed under the same license as the minetest-c55 package.
# Frederik Helth <Guides@live.dk>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-08-02 12:36+0200\n"
"PO-Revision-Date: 2011-08-02 00:31+0100\n"
"Last-Translator: Frederik Helth <Guides@live.dk>\n"
"Language-Team: \n"
"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
msgstr ""
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
msgstr "Frem"
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
msgstr "Tilbage"
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
msgstr "Venstre"
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
msgstr "Højre"
#: src/guiKeyChangeMenu.cpp:158
msgid "Use"
msgstr "Brug"
#: src/guiKeyChangeMenu.cpp:173
msgid "Sneak"
msgstr "Snig"
#: src/guiKeyChangeMenu.cpp:189
msgid "Jump"
msgstr "Hop"
#: src/guiKeyChangeMenu.cpp:204
msgid "Inventory"
msgstr "Ting"
#: src/guiKeyChangeMenu.cpp:220
msgid "Chat"
msgstr "Chat"
#: src/guiKeyChangeMenu.cpp:236
msgid "Toggle fly"
msgstr "Flyvning"
#: src/guiKeyChangeMenu.cpp:251
msgid "Toggle fast"
msgstr "Hurtig flyvning"
#: src/guiKeyChangeMenu.cpp:266
msgid "Range select"
msgstr "Afstands load"
#: src/guiKeyChangeMenu.cpp:283
msgid "Print stacks"
msgstr "Print stykker"
#: src/guiKeyChangeMenu.cpp:298
msgid "Save"
msgstr "Gem"
#: src/guiKeyChangeMenu.cpp:304 src/guiKeyChangeMenu.h:33
msgid "Cancel"
msgstr "Afslut"
#: 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
msgid "press Key"
msgstr "Tryk knap"
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
msgstr "Venstre Knap"
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
msgstr "Midt Knap"
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
msgstr "Højre Knap"
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
msgstr "Tilbage"
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
msgstr "Rens"
#: src/guiKeyChangeMenu.h:34
msgid "Return"
msgstr "Tilbage"
#: 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 "Kontrol"
#: 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 "Accepter"
#: src/guiKeyChangeMenu.h:37
msgid "End"
msgstr "Slut"
#: src/guiKeyChangeMenu.h:37
msgid "Home"
msgstr "Hjem"
#: src/guiKeyChangeMenu.h:37
msgid "Mode Change"
msgstr "Mode skift"
#: src/guiKeyChangeMenu.h:37
msgid "Next"
msgstr "Næste"
#: src/guiKeyChangeMenu.h:37
msgid "Priot"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Space"
msgstr "Mellemrum"
#: src/guiKeyChangeMenu.h:38
msgid "Down"
msgstr "Ned"
#: src/guiKeyChangeMenu.h:38
msgid "Execute"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Print"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Select"
msgstr "Vælge"
#: src/guiKeyChangeMenu.h:38
msgid "Up"
msgstr "Op"
#: src/guiKeyChangeMenu.h:39
msgid "Delete"
msgstr "Slet"
#: src/guiKeyChangeMenu.h:39
msgid "Help"
msgstr "Hjælp"
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
msgstr "Indset"
#: src/guiKeyChangeMenu.h:39
msgid "Snapshot"
msgstr "Screenshot"
#: src/guiKeyChangeMenu.h:42
msgid "Left Windows"
msgstr "Venstre windows"
#: 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
msgid "Play"
msgstr "Spil"
#: src/guiKeyChangeMenu.h:58
msgid "Zoom"
msgstr ""
#: src/guiMainMenu.cpp:181
msgid "Name/Password"
msgstr "Navn/kodeord"
#: src/guiMainMenu.cpp:206
msgid "Address/Port"
msgstr "Adresse/port"
#: src/guiMainMenu.cpp:228
msgid "Leave address blank to start a local server."
msgstr "Lad black for at spille localt"
#: src/guiMainMenu.cpp:235
msgid "Fancy trees"
msgstr "Fancy trær"
#: src/guiMainMenu.cpp:241
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:249
msgid "Start Game / Connect"
msgstr "Start spil"
#: src/guiMainMenu.cpp:258
msgid "Change keys"
msgstr "Indstillinger"
#: src/guiMainMenu.cpp:281
msgid "Creative Mode"
msgstr "Kreativ mode"
#: src/guiMainMenu.cpp:287
msgid "Enable Damage"
msgstr "Tag imod skade"
#: src/guiMainMenu.cpp:295
msgid "Delete map"
msgstr "Slet mappen"
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
msgid "Proceed"
msgstr "Fortsæt"
#: src/guiPasswordChange.cpp:103
msgid "Old Password"
msgstr "Gamle kodeord"
#: src/guiPasswordChange.cpp:120
msgid "New Password"
msgstr "Nye kodeord"
#: src/guiPasswordChange.cpp:136
msgid "Confirm Password"
msgstr "Gentag kodeord"
#: src/guiPasswordChange.cpp:153
msgid "Change"
msgstr "Skift"
#: src/guiPasswordChange.cpp:162
msgid "Passwords do not match!"
msgstr "Kodeordne matcher ikke hinanden!"
#: src/guiPauseMenu.cpp:111
msgid "Continue"
msgstr "Fortsæt"
#: src/guiPauseMenu.cpp:118
msgid "Change Password"
msgstr "Skift kodeord"
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
msgstr "Logud"
#: src/guiPauseMenu.cpp:132
msgid "Exit to OS"
msgstr "Afslut til OS"
#: src/guiPauseMenu.cpp:139
msgid ""
"Default Controls:\n"
"- WASD: Walk\n"
"- Mouse left: dig/hit\n"
"- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Inventory menu\n"
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""

View File

@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-07-22 11:00+0200\n"
"PO-Revision-Date: 2011-07-20 16:58+0100\n"
"POT-Creation-Date: 2011-08-02 12:36+0200\n"
"PO-Revision-Date: 2011-08-02 11:54+0100\n"
"Last-Translator: Constantin Wenger <constantin.wenger@googlemail.com>\n"
"Language-Team: Deutsch <>\n"
"Language: de\n"
@@ -17,92 +17,467 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
#: src/guiMainMenu.cpp:180
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
msgstr "TASTEN EINST."
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
msgstr "Vorwärts"
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
msgstr "Rückwärts"
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
msgstr "Links"
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
msgstr "Rechts"
#: src/guiKeyChangeMenu.cpp:158
msgid "Use"
msgstr "Benutzen"
#: src/guiKeyChangeMenu.cpp:173
msgid "Sneak"
msgstr "Kriechen"
#: src/guiKeyChangeMenu.cpp:189
msgid "Jump"
msgstr "Springen"
#: src/guiKeyChangeMenu.cpp:204
msgid "Inventory"
msgstr "Inventar"
#: src/guiKeyChangeMenu.cpp:220
msgid "Chat"
msgstr "Chat"
#: src/guiKeyChangeMenu.cpp:236
msgid "Toggle fly"
msgstr "Fliegen umsch."
#: src/guiKeyChangeMenu.cpp:251
msgid "Toggle fast"
msgstr "Speed umsch."
#: src/guiKeyChangeMenu.cpp:266
msgid "Range select"
msgstr "Entfernung wählen"
#: src/guiKeyChangeMenu.cpp:283
msgid "Print stacks"
msgstr "Stack ausgeben"
#: src/guiKeyChangeMenu.cpp:298
msgid "Save"
msgstr "Speichern"
#: src/guiKeyChangeMenu.cpp:304 src/guiKeyChangeMenu.h:33
msgid "Cancel"
msgstr "Abbrechen"
#: 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
msgid "press Key"
msgstr "Taste drücken"
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
msgstr "linke Taste"
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
msgstr "Rücktaste"
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
msgstr "löschen"
#: src/guiKeyChangeMenu.h:34
msgid "Return"
msgstr "Return"
#: src/guiKeyChangeMenu.h:34
msgid "Tab"
msgstr "Tab"
#: src/guiKeyChangeMenu.h:34
msgid "X Button 2"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Capital"
msgstr "Feststellen"
#: src/guiKeyChangeMenu.h:35
msgid "Control"
msgstr "Strg"
#: src/guiKeyChangeMenu.h:35
msgid "Kana"
msgstr ""
#: src/guiKeyChangeMenu.h:35
msgid "Menu"
msgstr "Menü"
#: src/guiKeyChangeMenu.h:35
msgid "Pause"
msgstr "Pause"
#: src/guiKeyChangeMenu.h:35
msgid "Shift"
msgstr "Umsch."
#: src/guiKeyChangeMenu.h:36
msgid "Convert"
msgstr ""
#: src/guiKeyChangeMenu.h:36
msgid "Escape"
msgstr "Escape"
#: 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 "Annehmen"
#: src/guiKeyChangeMenu.h:37
msgid "End"
msgstr "Ende"
#: src/guiKeyChangeMenu.h:37
msgid "Home"
msgstr "Pos1"
#: src/guiKeyChangeMenu.h:37
msgid "Mode Change"
msgstr ""
#: src/guiKeyChangeMenu.h:37
msgid "Next"
msgstr "Bild runter"
#: src/guiKeyChangeMenu.h:37
msgid "Priot"
msgstr "Bild hoch"
#: src/guiKeyChangeMenu.h:37
msgid "Space"
msgstr "Leertaste"
#: src/guiKeyChangeMenu.h:38
msgid "Down"
msgstr "Runter"
#: src/guiKeyChangeMenu.h:38
msgid "Execute"
msgstr "Ausführen"
#: src/guiKeyChangeMenu.h:38
msgid "Print"
msgstr "Druck"
#: src/guiKeyChangeMenu.h:38
msgid "Select"
msgstr "Select"
#: src/guiKeyChangeMenu.h:38
msgid "Up"
msgstr "Hoch"
#: src/guiKeyChangeMenu.h:39
msgid "Delete"
msgstr "Entf"
#: src/guiKeyChangeMenu.h:39
msgid "Help"
msgstr "Hilfe"
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
msgstr "Einfg"
#: src/guiKeyChangeMenu.h:39
msgid "Snapshot"
msgstr "Schnapschuss"
#: src/guiKeyChangeMenu.h:42
msgid "Left Windows"
msgstr "Win links"
#: src/guiKeyChangeMenu.h:43
msgid "Apps"
msgstr ""
#: src/guiKeyChangeMenu.h:43
msgid "Numpad 0"
msgstr "Ziffernblock 0"
#: src/guiKeyChangeMenu.h:43
msgid "Numpad 1"
msgstr "Ziffernblock 1"
#: src/guiKeyChangeMenu.h:43
msgid "Right Windows"
msgstr "Win rechts"
#: src/guiKeyChangeMenu.h:43
msgid "Sleep"
msgstr "Schlaf"
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 2"
msgstr "Ziffernblock 2"
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 3"
msgstr "Ziffernblock 3"
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 4"
msgstr "Ziffernblock 4"
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 5"
msgstr "Ziffernblock 5"
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 6"
msgstr "Ziffernblock 6"
#: src/guiKeyChangeMenu.h:44
msgid "Numpad 7"
msgstr "Ziffernblock 7"
#: src/guiKeyChangeMenu.h:45
msgid "Numpad *"
msgstr "Ziffernblock *"
#: src/guiKeyChangeMenu.h:45
msgid "Numpad +"
msgstr "Ziffernblock +"
#: src/guiKeyChangeMenu.h:45
msgid "Numpad -"
msgstr "Ziffernblock -"
#: src/guiKeyChangeMenu.h:45
msgid "Numpad /"
msgstr "Ziffernblock /"
#: src/guiKeyChangeMenu.h:45
msgid "Numpad 8"
msgstr "Ziffernblock 8"
#: src/guiKeyChangeMenu.h:45
msgid "Numpad 9"
msgstr "Ziffernblock 9"
#: src/guiKeyChangeMenu.h:49
msgid "Num Lock"
msgstr "Num"
#: src/guiKeyChangeMenu.h:49
msgid "Scroll Lock"
msgstr "Rollen"
#: src/guiKeyChangeMenu.h:50
msgid "Left Shift"
msgstr "Umsch. links"
#: src/guiKeyChangeMenu.h:50
msgid "Right Shight"
msgstr "Umsch. rechts"
#: src/guiKeyChangeMenu.h:51
msgid "Left Control"
msgstr "Strg links"
#: src/guiKeyChangeMenu.h:51
msgid "Left Menu"
msgstr "Alt"
#: src/guiKeyChangeMenu.h:51
msgid "Right Control"
msgstr "Strg rechts"
#: src/guiKeyChangeMenu.h:51
msgid "Right Menu"
msgstr "Alt Gr"
#: src/guiKeyChangeMenu.h:53
msgid "Comma"
msgstr "Komma"
#: src/guiKeyChangeMenu.h:53
msgid "Minus"
msgstr "Minus"
#: src/guiKeyChangeMenu.h:53
msgid "Period"
msgstr "Punkt"
#: src/guiKeyChangeMenu.h:53
msgid "Plus"
msgstr "Plus"
#: 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
msgid "Play"
msgstr "Play"
#: src/guiKeyChangeMenu.h:58
msgid "Zoom"
msgstr "Zoom"
#: src/guiMainMenu.cpp:181
msgid "Name/Password"
msgstr "Name/Passwort"
#: src/guiMainMenu.cpp:203
#: src/guiMainMenu.cpp:206
msgid "Address/Port"
msgstr "Adresse / Port"
#: src/guiMainMenu.cpp:223
#: src/guiMainMenu.cpp:228
msgid "Leave address blank to start a local server."
msgstr "Lasse die Adresse frei um einen eigenen Server zu starten"
#: src/guiMainMenu.cpp:230
#: src/guiMainMenu.cpp:235
msgid "Fancy trees"
msgstr "Schöne Bäume"
#: src/guiMainMenu.cpp:236
#: src/guiMainMenu.cpp:241
msgid "Smooth Lighting"
msgstr "Besseres Licht"
#: src/guiMainMenu.cpp:244
#: src/guiMainMenu.cpp:249
msgid "Start Game / Connect"
msgstr "Spiel starten / Verbinden"
#: src/guiMainMenu.cpp:253
#: src/guiMainMenu.cpp:258
msgid "Change keys"
msgstr "Tastenbelegung ändern"
msgstr "Tasten ändern"
#: src/guiMainMenu.cpp:276
#: src/guiMainMenu.cpp:281
msgid "Creative Mode"
msgstr "Kreativitätsmodus"
#: src/guiMainMenu.cpp:282
#: src/guiMainMenu.cpp:287
msgid "Enable Damage"
msgstr "Schaden einschalten"
#: src/guiMainMenu.cpp:290
#: src/guiMainMenu.cpp:295
msgid "Delete map"
msgstr "Karte löschen"
#: src/guiMessageMenu.cpp:93 src/guiTextInputMenu.cpp:111
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
msgid "Proceed"
msgstr "Fortsetzen"
#: src/guiPasswordChange.cpp:102
#: src/guiPasswordChange.cpp:103
msgid "Old Password"
msgstr "Altes Passwort"
#: src/guiPasswordChange.cpp:117
#: src/guiPasswordChange.cpp:120
msgid "New Password"
msgstr "Neues Passwort"
#: src/guiPasswordChange.cpp:131
#: src/guiPasswordChange.cpp:136
msgid "Confirm Password"
msgstr "Passwort wiederholen"
#: src/guiPasswordChange.cpp:146
#: src/guiPasswordChange.cpp:153
msgid "Change"
msgstr "Ändern"
#: src/guiPasswordChange.cpp:155
#: src/guiPasswordChange.cpp:162
msgid "Passwords do not match!"
msgstr "Passwörter passen nicht zusammen"
#: src/guiPauseMenu.cpp:110
#: src/guiPauseMenu.cpp:111
msgid "Continue"
msgstr "Weiter"
#: src/guiPauseMenu.cpp:117
#: src/guiPauseMenu.cpp:118
msgid "Change Password"
msgstr "Passwort ändern"
#: src/guiPauseMenu.cpp:124
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
msgstr "Verbindung trennen"
#: src/guiPauseMenu.cpp:131
#: src/guiPauseMenu.cpp:132
msgid "Exit to OS"
msgstr "Programm beenden"
#: src/guiPauseMenu.cpp:138
#: src/guiPauseMenu.cpp:139
#, fuzzy
msgid ""
"Keys:\n"
"Default Controls:\n"
"- WASD: Walk\n"
"- Mouse left: dig blocks\n"
"- Mouse right: place blocks\n"
"- Mouse left: dig/hit\n"
"- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
@@ -113,11 +488,11 @@ msgid ""
msgstr ""
"Tastenkürzel:\n"
"- WASD: Gehen\n"
"- linke Maustaste: dig blocks\n"
"- rechte Maustaste: place blocks\n"
"- linke Maustaste: Blöcke aufnehmen \n"
"- rechte Maustaste: Blöche ablegen\n"
"- Mausrad: Item auswählen\n"
"- 0...9: Item auswählen\n"
"- Shift: ducken\n"
"- R: Alle geladenen Kartenteile anzeigen, umschalten\n"
"- R: alle geladenen Blöcke anzeigen (wechseln)\n"
"- I: Inventarmenü\n"
"- T: Chat\n"

View File

@@ -1,113 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-07-24 11:32+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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiMainMenu.cpp:180
msgid "Name/Password"
msgstr ""
#: src/guiMainMenu.cpp:203
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:223
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:230
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:236
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:244
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:253
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:276
msgid "Creative Mode"
msgstr ""
#: src/guiMainMenu.cpp:282
msgid "Enable Damage"
msgstr ""
#: src/guiMainMenu.cpp:290
msgid "Delete map"
msgstr ""
#: src/guiMessageMenu.cpp:93 src/guiTextInputMenu.cpp:111
msgid "Proceed"
msgstr ""
#: src/guiPasswordChange.cpp:102
msgid "Old Password"
msgstr ""
#: src/guiPasswordChange.cpp:117
msgid "New Password"
msgstr ""
#: src/guiPasswordChange.cpp:131
msgid "Confirm Password"
msgstr ""
#: src/guiPasswordChange.cpp:146
msgid "Change"
msgstr ""
#: src/guiPasswordChange.cpp:155
msgid "Passwords do not match!"
msgstr ""
#: src/guiPauseMenu.cpp:110
msgid "Continue"
msgstr ""
#: src/guiPauseMenu.cpp:117
msgid "Change Password"
msgstr ""
#: src/guiPauseMenu.cpp:124
msgid "Disconnect"
msgstr ""
#: src/guiPauseMenu.cpp:131
msgid "Exit to OS"
msgstr ""
#: src/guiPauseMenu.cpp:138
msgid ""
"Keys:\n"
"- WASD: Walk\n"
"- Mouse left: dig blocks\n"
"- Mouse right: place blocks\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Inventory menu\n"
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-07-22 11:00+0200\n"
"POT-Creation-Date: 2011-08-02 12:36+0200\n"
"PO-Revision-Date: 2011-07-21 15:48+0200\n"
"Last-Translator: Cyriaque 'Cisoun' Skrapits <cysoun@gmail.com>\n"
"Language-Team: Français <>\n"
@@ -17,92 +17,469 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
#: src/guiMainMenu.cpp:180
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
msgstr ""
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
msgstr ""
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
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
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
msgid "press Key"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
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
#, fuzzy
msgid "Mode Change"
msgstr "Changer"
#: 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
#, fuzzy
msgid "Delete"
msgstr "Supprimer carte"
#: src/guiKeyChangeMenu.h:39
msgid "Help"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
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
msgid "Play"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "Zoom"
msgstr ""
#: src/guiMainMenu.cpp:181
msgid "Name/Password"
msgstr "Nom / MdP"
#: src/guiMainMenu.cpp:203
#: src/guiMainMenu.cpp:206
msgid "Address/Port"
msgstr "Adresse / Port"
#: src/guiMainMenu.cpp:223
#: src/guiMainMenu.cpp:228
msgid "Leave address blank to start a local server."
msgstr "Laisser l'adresse vide pour lancer un serveur local."
#: src/guiMainMenu.cpp:230
#: src/guiMainMenu.cpp:235
msgid "Fancy trees"
msgstr "Arbres spéciaux"
#: src/guiMainMenu.cpp:236
#: src/guiMainMenu.cpp:241
msgid "Smooth Lighting"
msgstr "Lumière douce"
#: src/guiMainMenu.cpp:244
#: src/guiMainMenu.cpp:249
msgid "Start Game / Connect"
msgstr "Démarrer / Connecter"
#: src/guiMainMenu.cpp:253
#: src/guiMainMenu.cpp:258
msgid "Change keys"
msgstr "Changer touches"
#: src/guiMainMenu.cpp:276
#: src/guiMainMenu.cpp:281
msgid "Creative Mode"
msgstr "Mode créatif"
#: src/guiMainMenu.cpp:282
#: src/guiMainMenu.cpp:287
msgid "Enable Damage"
msgstr "Activer blessures"
#: src/guiMainMenu.cpp:290
#: src/guiMainMenu.cpp:295
msgid "Delete map"
msgstr "Supprimer carte"
#: src/guiMessageMenu.cpp:93 src/guiTextInputMenu.cpp:111
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
msgid "Proceed"
msgstr "OK"
#: src/guiPasswordChange.cpp:102
#: src/guiPasswordChange.cpp:103
msgid "Old Password"
msgstr "Ancien mot de passe"
#: src/guiPasswordChange.cpp:117
#: src/guiPasswordChange.cpp:120
msgid "New Password"
msgstr "Nouveau mot de passe"
#: src/guiPasswordChange.cpp:131
#: src/guiPasswordChange.cpp:136
msgid "Confirm Password"
msgstr "Confirmer mot de passe"
#: src/guiPasswordChange.cpp:146
#: src/guiPasswordChange.cpp:153
msgid "Change"
msgstr "Changer"
#: src/guiPasswordChange.cpp:155
#: src/guiPasswordChange.cpp:162
msgid "Passwords do not match!"
msgstr "Mauvaise correspondance!"
#: src/guiPauseMenu.cpp:110
#: src/guiPauseMenu.cpp:111
msgid "Continue"
msgstr "Continuer"
#: src/guiPauseMenu.cpp:117
#: src/guiPauseMenu.cpp:118
msgid "Change Password"
msgstr "Changer mot de passe"
#: src/guiPauseMenu.cpp:124
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
msgstr "Déconnection"
#: src/guiPauseMenu.cpp:131
#: src/guiPauseMenu.cpp:132
msgid "Exit to OS"
msgstr "Quitter le jeu"
#: src/guiPauseMenu.cpp:138
#: src/guiPauseMenu.cpp:139
#, fuzzy
msgid ""
"Keys:\n"
"Default Controls:\n"
"- WASD: Walk\n"
"- Mouse left: dig blocks\n"
"- Mouse right: place blocks\n"
"- Mouse left: dig/hit\n"
"- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"

499
po/it/minetest.po Normal file
View File

@@ -0,0 +1,499 @@
# Italian translations for minetest package.
# Copyright (C) 2011 THE minetest'S COPYRIGHT HOLDER
# This file is distributed under the same license as the minetest package.
# Giuseppe Bilotta <giuseppe.bilotta@gmail.com>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: minetest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-08-02 12:36+0200\n"
"PO-Revision-Date: 2011-07-24 18:56+0200\n"
"Last-Translator: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>\n"
"Language-Team: Italian\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
msgstr ""
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
msgstr "Avanti"
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
msgstr "Indietro"
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
msgstr "Sinistra"
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
msgstr "Destra"
#: src/guiKeyChangeMenu.cpp:158
msgid "Use"
msgstr "Usa"
#: src/guiKeyChangeMenu.cpp:173
msgid "Sneak"
msgstr ""
#: src/guiKeyChangeMenu.cpp:189
msgid "Jump"
msgstr "Salta"
#: src/guiKeyChangeMenu.cpp:204
msgid "Inventory"
msgstr "Invetario"
#: src/guiKeyChangeMenu.cpp:220
msgid "Chat"
msgstr "Parla"
#: 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 "Salva"
#: src/guiKeyChangeMenu.cpp:304 src/guiKeyChangeMenu.h:33
msgid "Cancel"
msgstr "Annulla"
#: 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
msgid "press Key"
msgstr "premi tasto"
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
msgstr "Tasto sinistro"
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
msgstr "Tasto centrale"
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
msgstr "Tasto destro"
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
msgstr "Indietro"
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Return"
msgstr "Invio"
#: 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 "Spazio"
#: src/guiKeyChangeMenu.h:38
msgid "Down"
msgstr "Giù"
#: src/guiKeyChangeMenu.h:38
msgid "Execute"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Print"
msgstr "Stampa"
#: src/guiKeyChangeMenu.h:38
msgid "Select"
msgstr ""
#: src/guiKeyChangeMenu.h:38
msgid "Up"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Delete"
msgstr "Cancella"
#: src/guiKeyChangeMenu.h:39
msgid "Help"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
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
msgid "Play"
msgstr ""
#: src/guiKeyChangeMenu.h:58
msgid "Zoom"
msgstr ""
#: src/guiMainMenu.cpp:181
msgid "Name/Password"
msgstr "Nome/Password"
#: src/guiMainMenu.cpp:206
msgid "Address/Port"
msgstr "Indirizzo/Porta"
#: src/guiMainMenu.cpp:228
msgid "Leave address blank to start a local server."
msgstr "Lascia vuoto l'indirizzo per avviare un server locale"
#: src/guiMainMenu.cpp:235
msgid "Fancy trees"
msgstr "Alberi strani"
#: src/guiMainMenu.cpp:241
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:249
msgid "Start Game / Connect"
msgstr "Avvia Gioco / Connetti"
#: src/guiMainMenu.cpp:258
msgid "Change keys"
msgstr "Modifica tasti"
#: src/guiMainMenu.cpp:281
msgid "Creative Mode"
msgstr "Modalità creativa"
#: src/guiMainMenu.cpp:287
msgid "Enable Damage"
msgstr "Attiva Danno"
#: src/guiMainMenu.cpp:295
msgid "Delete map"
msgstr "Cancella mappa"
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
msgid "Proceed"
msgstr "Procedi"
#: src/guiPasswordChange.cpp:103
msgid "Old Password"
msgstr "Vecchia password"
#: src/guiPasswordChange.cpp:120
msgid "New Password"
msgstr "Nuova password"
#: src/guiPasswordChange.cpp:136
msgid "Confirm Password"
msgstr "Conferma password"
#: src/guiPasswordChange.cpp:153
msgid "Change"
msgstr "Modifica"
#: src/guiPasswordChange.cpp:162
msgid "Passwords do not match!"
msgstr "Le password non corrispondono!"
#: src/guiPauseMenu.cpp:111
msgid "Continue"
msgstr "Continua"
#: src/guiPauseMenu.cpp:118
msgid "Change Password"
msgstr "Cambia password"
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
msgstr "Disconnetti"
#: src/guiPauseMenu.cpp:132
msgid "Exit to OS"
msgstr "Esci al S.O."
#: src/guiPauseMenu.cpp:139
#, fuzzy
msgid ""
"Default Controls:\n"
"- WASD: Walk\n"
"- Mouse left: dig/hit\n"
"- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Inventory menu\n"
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""
"Tasti:\n"
"- WASD: Cammina\n"
"- Mouse left: scava blocchi\n"
"- Mouse right: piazza blocchi\n"
"- Mouse wheel: seleziona oggetto\n"
"- 0...9: seleziona oggetto\n"
"- Shift: furtivo\n"
"- R: (Dis)attiva motra tutti i blocchi caricati\n"
"- I: Inventario\n"
"- ESC: Questo menu\n"
"- T: Parla\n"

487
po/minetest.pot Normal file
View File

@@ -0,0 +1,487 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: minetest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-08-02 12:36+0200\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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiKeyChangeMenu.cpp:84
msgid "KEYBINDINGS"
msgstr ""
#: src/guiKeyChangeMenu.cpp:94
msgid "Forward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:111
msgid "Backward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:127 src/guiKeyChangeMenu.h:38
msgid "Left"
msgstr ""
#: src/guiKeyChangeMenu.cpp:142 src/guiKeyChangeMenu.h:38
msgid "Right"
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
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
msgid "press Key"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Left Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Middle Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "Right Button"
msgstr ""
#: src/guiKeyChangeMenu.h:33
msgid "X Button 1"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Back"
msgstr ""
#: src/guiKeyChangeMenu.h:34
msgid "Clear"
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
msgid "Delete"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Help"
msgstr ""
#: src/guiKeyChangeMenu.h:39
msgid "Insert"
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
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
msgid "Creative Mode"
msgstr ""
#: src/guiMainMenu.cpp:287
msgid "Enable Damage"
msgstr ""
#: src/guiMainMenu.cpp:295
msgid "Delete map"
msgstr ""
#: src/guiMessageMenu.cpp:94 src/guiTextInputMenu.cpp:112
msgid "Proceed"
msgstr ""
#: src/guiPasswordChange.cpp:103
msgid "Old Password"
msgstr ""
#: src/guiPasswordChange.cpp:120
msgid "New Password"
msgstr ""
#: src/guiPasswordChange.cpp:136
msgid "Confirm Password"
msgstr ""
#: src/guiPasswordChange.cpp:153
msgid "Change"
msgstr ""
#: src/guiPasswordChange.cpp:162
msgid "Passwords do not match!"
msgstr ""
#: src/guiPauseMenu.cpp:111
msgid "Continue"
msgstr ""
#: src/guiPauseMenu.cpp:118
msgid "Change Password"
msgstr ""
#: src/guiPauseMenu.cpp:125
msgid "Disconnect"
msgstr ""
#: src/guiPauseMenu.cpp:132
msgid "Exit to OS"
msgstr ""
#: src/guiPauseMenu.cpp:139
msgid ""
"Default Controls:\n"
"- WASD: Walk\n"
"- Mouse left: dig/hit\n"
"- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Inventory menu\n"
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""

View File

@@ -1,15 +1,19 @@
cmake_minimum_required( VERSION 2.6 )
project(minetest)
cmake_minimum_required( VERSION 2.6 )
if(RUN_IN_PLACE)
add_definitions ( -DRUN_IN_PLACE )
endif(RUN_IN_PLACE)
OPTION(USE_GETTEXT "Use GetText for internationalization" OFF)
# user-visible option to enable/disable gettext usage
OPTION(ENABLE_GETTEXT "Use GetText for internationalization" ON)
if(USE_GETTEXT)
find_package(GettextLib REQUIRED)
# this is only set to 1 if gettext is enabled _and_ available
set(USE_GETTEXT 0)
find_package(GettextLib)
if(GETTEXT_FOUND AND ENABLE_GETTEXT)
message(STATUS "gettext include path: ${GETTEXT_INCLUDE_DIR}")
message(STATUS "gettext msgfmt path: ${GETTEXT_MSGFMT}")
if(WIN32)
@@ -17,16 +21,13 @@ if(USE_GETTEXT)
message(STATUS "gettext dll: ${GETTEXT_DLL}")
message(STATUS "gettext iconv dll: ${GETTEXT_ICONV_DLL}")
endif()
if (GETTEXT_FOUND)
add_definitions( -DUSE_GETTEXT )
message(STATUS "GetText enabled; locales found: ${GETTEXT_AVAILABLE_LOCALES}")
else()
message(STATUS "ERROR: GetText enabled but not found, disabling")
set(USE_GETTEXT FALSE)
endif(GETTEXT_FOUND)
else(USE_GETTEXT)
set(USE_GETTEXT 1)
message(STATUS "GetText enabled; locales found: ${GETTEXT_AVAILABLE_LOCALES}")
elseif(GETTEXT_FOUND AND NOT ENABLE_GETTEXT)
MESSAGE(STATUS "GetText found but disabled;")
else(GETTEXT_FOUND AND ENABLE_GETTEXT)
message(STATUS "GetText disabled")
endif(USE_GETTEXT)
endif(GETTEXT_FOUND AND ENABLE_GETTEXT)
if(NOT MSVC)
set(USE_GPROF 0 CACHE BOOL "Use -pg flag for g++")
@@ -73,7 +74,7 @@ else()
endif(APPLE)
endif(BUILD_CLIENT)
find_package(ZLIB REQUIRED)
set(PLATFORM_LIBS -lpthread)
set(PLATFORM_LIBS -lpthread ${CMAKE_DL_LIBS})
#set(CLIENT_PLATFORM_LIBS -lXxf86vm)
# This way Xxf86vm is found on OpenBSD too
find_library(XXF86VM_LIBRARY Xxf86vm)
@@ -89,12 +90,12 @@ configure_file(
)
set(common_SRCS
log.cpp
content_sao.cpp
mapgen.cpp
content_inventory.cpp
content_nodemeta.cpp
content_craft.cpp
content_mapblock.cpp
content_mapnode.cpp
auth.cpp
collision.cpp
@@ -107,7 +108,6 @@ set(common_SRCS
defaultsettings.cpp
mapnode.cpp
voxel.cpp
mapblockobject.cpp
inventory.cpp
debug.cpp
serialization.cpp
@@ -126,20 +126,32 @@ set(common_SRCS
test.cpp
sha1.cpp
base64.cpp
ban.cpp
)
# This gives us the icon
if(WIN32 AND MSVC)
set(common_SRCS ${common_SRCS} winresource.rc)
if(WIN32)
if(MINGW)
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)
SET(common_SRCS ${common_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/winresource_rc.o)
else(MINGW) # Probably MSVC
set(common_SRCS ${common_SRCS} winresource.rc)
endif(MINGW)
endif()
# Client sources
set(minetest_SRCS
${common_SRCS}
MyBillboardSceneNode.cpp
content_mapblock.cpp
content_cao.cpp
mapblock_mesh.cpp
farmesh.cpp
keycode.cpp
camera.cpp
clouds.cpp
clientobject.cpp
guiMainMenu.cpp
@@ -149,6 +161,7 @@ set(minetest_SRCS
guiInventoryMenu.cpp
guiPauseMenu.cpp
guiPasswordChange.cpp
guiDeathScreen.cpp
client.cpp
tile.cpp
game.cpp
@@ -172,7 +185,7 @@ include_directories(
${SQLITE3_INCLUDE_DIR}
)
set(EXECUTABLE_OUTPUT_PATH ../bin)
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin")
if(BUILD_CLIENT)
add_executable(${PROJECT_NAME} ${minetest_SRCS})
@@ -186,10 +199,10 @@ if(BUILD_CLIENT)
${PNG_LIBRARIES}
${X11_LIBRARIES}
${GETTEXT_LIBRARY}
${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS}
${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY}
${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS}
)
endif(BUILD_CLIENT)
@@ -198,9 +211,9 @@ if(BUILD_SERVER)
target_link_libraries(
${PROJECT_NAME}server
${ZLIB_LIBRARIES}
${PLATFORM_LIBS}
${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY}
${PLATFORM_LIBS}
)
endif(BUILD_SERVER)
@@ -208,17 +221,23 @@ endif(BUILD_SERVER)
# Set some optimizations and tweaks
#
include(CheckCXXCompilerFlag)
if(MSVC)
# Visual Studio
# EHa enables SEH exceptions (used for catching segfaults)
set(CMAKE_CXX_FLAGS_RELEASE "/EHa /MD /O2 /Ob2 /Oi /Ot /Oy /GL /FD /MT /GS- /arch:SSE /fp:fast /D NDEBUG /D _HAS_ITERATOR_DEBUGGING=0 /TP")
set(CMAKE_CXX_FLAGS_RELEASE "/EHa /O2 /Ob2 /Oi /Ot /Oy /GL /FD /MT /GS- /arch:SSE /fp:fast /D NDEBUG /D _HAS_ITERATOR_DEBUGGING=0 /TP")
#set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /NODEFAULTLIB:\"libcmtd.lib\" /NODEFAULTLIB:\"libcmt.lib\"")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG")
# Debug build doesn't catch exceptions by itself
# Add some optimizations because otherwise it's VERY slow
set(CMAKE_CXX_FLAGS_DEBUG "/MDd /Zi /Ob0 /Od /RTC1")
# Flags for C files (sqlite)
# /MT = Link statically with standard library stuff
set(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /MT")
if(BUILD_SERVER)
set_target_properties(${PROJECT_NAME}server PROPERTIES
@@ -234,8 +253,11 @@ else()
set(RELEASE_WARNING_FLAGS "")
endif()
if(NOT APPLE)
set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-but-set-variable")
if(NOT APPLE AND NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
CHECK_CXX_COMPILER_FLAG("-Wno-unused-but-set-variable" HAS_UNUSED_BUT_SET_VARIABLE_WARNING)
if(HAS_UNUSED_BUT_SET_VARIABLE_WARNING)
set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-but-set-variable")
endif(HAS_UNUSED_BUT_SET_VARIABLE_WARNING)
endif()
if(APPLE)
@@ -274,7 +296,7 @@ if(BUILD_CLIENT)
install(FILES ${images} DESTINATION ${DATADIR})
if (USE_GETTEXT)
if(USE_GETTEXT)
foreach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
set(MO_BUILD_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo")
@@ -305,54 +327,29 @@ if(BUILD_SERVER)
endif(BUILD_SERVER)
if (USE_GETTEXT)
add_custom_command(OUTPUT "${GETTEXT_PO_PATH}/en"
COMMAND ${CMAKE_COMMAND} -E make_directory "${GETTEXT_PO_PATH}/en"
COMMENT "po-update [en]: creating translation template base directory")
set(POT_FILE "${GETTEXT_PO_PATH}/en/minetest.pot")
file(GLOB GETTEXT_POT_DEPS *.cpp *.h)
file(GLOB GETTEXT_POT_DEPS_REL RELATIVE ${CMAKE_SOURCE_DIR} *.cpp *.h)
add_custom_command(OUTPUT ${POT_FILE}
COMMAND ${GETTEXT_EXTRACT} -F -n -o ${POT_FILE} ${GETTEXT_POT_DEPS_REL}
DEPENDS "${GETTEXT_PO_PATH}/en" ${GETTEXT_POT_DEPS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "po-update [en]: updating translation template")
set(PO_FILES)
set(MO_FILES)
foreach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
# skip the 'en' locale which is treated separately
if (NOT LOCALE STREQUAL "en")
set(PO_FILE_PATH "${GETTEXT_PO_PATH}/${LOCALE}/minetest.po")
add_custom_command(OUTPUT ${PO_FILE_PATH}
COMMAND ${GETTEXT_MSGMERGE} -F -U ${PO_FILE_PATH} ${POT_FILE}
DEPENDS ${POT_FILE}
WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
COMMENT "po-update [${LOCALE}]: updating strings")
set(PO_FILE_PATH "${GETTEXT_PO_PATH}/${LOCALE}/minetest.po")
set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
set(MO_FILE_PATH "${MO_BUILD_PATH}/${PROJECT_NAME}.mo")
add_custom_command(OUTPUT ${MO_BUILD_PATH}
COMMAND ${CMAKE_COMMAND} -E make_directory ${MO_BUILD_PATH}
COMMENT "mo-update [${LOCALE}]: Creating locale directory.")
set_mo_paths(MO_BUILD_PATH MO_DEST_PATH ${LOCALE})
add_custom_command(OUTPUT ${MO_BUILD_PATH}
COMMAND ${CMAKE_COMMAND} -E make_directory ${MO_BUILD_PATH}
COMMENT "mo-update [${LOCALE}]: Creating locale directory.")
add_custom_command(
OUTPUT ${MO_FILE_PATH}
COMMAND ${GETTEXT_MSGFMT} -o ${MO_FILE_PATH} ${PO_FILE_PATH}
DEPENDS ${MO_BUILD_PATH} ${PO_FILE_PATH}
WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
COMMENT "mo-update [${LOCALE}]: Creating mo file."
)
set(MO_FILE_PATH "${MO_BUILD_PATH}/minetest.mo")
add_custom_command(
OUTPUT ${MO_FILE_PATH}
COMMAND ${GETTEXT_MSGFMT} -o ${MO_FILE_PATH} ${PO_FILE_PATH}
DEPENDS ${MO_BUILD_PATH} ${PO_FILE_PATH}
WORKING_DIRECTORY "${GETTEXT_PO_PATH}/${LOCALE}"
COMMENT "mo-update [${LOCALE}]: Creating mo file."
)
set(MO_FILES ${MO_FILES} ${MO_FILE_PATH})
set(PO_FILES ${PO_FILES} ${PO_FILE_PATH})
endif(NOT LOCALE STREQUAL "en")
set(MO_FILES ${MO_FILES} ${MO_FILE_PATH})
endforeach(LOCALE ${GETTEXT_AVAILABLE_LOCALES})
add_custom_target(translations ALL COMMENT "mo update" DEPENDS ${MO_FILES})
add_custom_target(updatepo COMMENT "po update" DEPENDS ${PO_FILES})
endif(USE_GETTEXT)
# Subdirectories

View File

@@ -0,0 +1,202 @@
// Copyright (C) 2002-2010 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "MyBillboardSceneNode.h"
#include "IVideoDriver.h"
#include "ISceneManager.h"
#include "ICameraSceneNode.h"
namespace irr
{
namespace scene
{
//! constructor
MyBillboardSceneNode::MyBillboardSceneNode(ISceneNode* parent,
ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::dimension2d<f32>& size)
: IBillboardSceneNode(parent, mgr, id, position)
{
#ifdef _DEBUG
setDebugName("MyBillboardSceneNode");
#endif
setSize(size);
indices[0] = 0;
indices[1] = 2;
indices[2] = 1;
indices[3] = 0;
indices[4] = 3;
indices[5] = 2;
video::SColor colorTop = video::SColor(0xFFFFFFFF);
video::SColor colorBottom = video::SColor(0xFFFFFFFF);
vertices[0].TCoords.set(1.0f, 1.0f);
vertices[0].Color = colorBottom;
vertices[1].TCoords.set(1.0f, 0.0f);
vertices[1].Color = colorTop;
vertices[2].TCoords.set(0.0f, 0.0f);
vertices[2].Color = colorTop;
vertices[3].TCoords.set(0.0f, 1.0f);
vertices[3].Color = colorBottom;
}
//! pre render event
void MyBillboardSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
//! render
void MyBillboardSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
ICameraSceneNode* camera = SceneManager->getActiveCamera();
if (!camera || !driver)
return;
// make billboard look to camera
core::vector3df pos = getAbsolutePosition();
core::vector3df campos = camera->getAbsolutePosition();
core::vector3df target = camera->getTarget();
core::vector3df up = camera->getUpVector();
core::vector3df view = target - campos;
view.normalize();
core::vector3df horizontal = up.crossProduct(view);
if ( horizontal.getLength() == 0 )
{
horizontal.set(up.Y,up.X,up.Z);
}
horizontal.normalize();
horizontal *= 0.5f * Size.Width;
core::vector3df vertical = horizontal.crossProduct(view);
vertical.normalize();
vertical *= 0.5f * Size.Height;
view *= -1.0f;
for (s32 i=0; i<4; ++i)
vertices[i].Normal = view;
vertices[0].Pos = pos + horizontal + vertical;
vertices[1].Pos = pos + horizontal - vertical;
vertices[2].Pos = pos - horizontal - vertical;
vertices[3].Pos = pos - horizontal + vertical;
// draw
if ( DebugDataVisible & scene::EDS_BBOX )
{
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
video::SMaterial m;
m.Lighting = false;
driver->setMaterial(m);
driver->draw3DBox(BBox, video::SColor(0,208,195,152));
}
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
driver->setMaterial(Material);
driver->drawIndexedTriangleList(vertices, 4, indices, 2);
}
//! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& MyBillboardSceneNode::getBoundingBox() const
{
return BBox;
}
//! sets the size of the billboard
void MyBillboardSceneNode::setSize(const core::dimension2d<f32>& size)
{
Size = size;
if (Size.Width == 0.0f)
Size.Width = 1.0f;
if (Size.Height == 0.0f )
Size.Height = 1.0f;
f32 avg = (size.Width + size.Height)/6;
BBox.MinEdge.set(-avg,-avg,-avg);
BBox.MaxEdge.set(avg,avg,avg);
}
video::SMaterial& MyBillboardSceneNode::getMaterial(u32 i)
{
return Material;
}
//! returns amount of materials used by this scene node.
u32 MyBillboardSceneNode::getMaterialCount() const
{
return 1;
}
//! gets the size of the billboard
const core::dimension2d<f32>& MyBillboardSceneNode::getSize() const
{
return Size;
}
//! Set the color of all vertices of the billboard
//! \param overallColor: the color to set
void MyBillboardSceneNode::setColor(const video::SColor & overallColor)
{
for(u32 vertex = 0; vertex < 4; ++vertex)
vertices[vertex].Color = overallColor;
}
//! Set the color of the top and bottom vertices of the billboard
//! \param topColor: the color to set the top vertices
//! \param bottomColor: the color to set the bottom vertices
void MyBillboardSceneNode::setColor(const video::SColor & topColor, const video::SColor & bottomColor)
{
vertices[0].Color = bottomColor;
vertices[1].Color = topColor;
vertices[2].Color = topColor;
vertices[3].Color = bottomColor;
}
//! Gets the color of the top and bottom vertices of the billboard
//! \param[out] topColor: stores the color of the top vertices
//! \param[out] bottomColor: stores the color of the bottom vertices
void MyBillboardSceneNode::getColor(video::SColor & topColor, video::SColor & bottomColor) const
{
bottomColor = vertices[0].Color;
topColor = vertices[1].Color;
}
void MyBillboardSceneNode::setTCoords(u32 i, core::vector2d<f32> c)
{
vertices[i].TCoords = c;
}
} // end namespace scene
} // end namespace irr

View File

@@ -0,0 +1,77 @@
// Copyright (C) 2002-2010 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_BILLBOARD_SCENE_NODE_H_INCLUDED__
#define __C_BILLBOARD_SCENE_NODE_H_INCLUDED__
#include "IBillboardSceneNode.h"
#include "S3DVertex.h"
namespace irr
{
namespace scene
{
//! Scene node which is a billboard. A billboard is like a 3d sprite: A 2d element,
//! which always looks to the camera.
class MyBillboardSceneNode : virtual public IBillboardSceneNode
{
public:
//! constructor
MyBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::dimension2d<f32>& size);
//! pre render event
virtual void OnRegisterSceneNode();
//! render
virtual void render();
//! returns the axis aligned bounding box of this node
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! sets the size of the billboard
virtual void setSize(const core::dimension2d<f32>& size);
//! gets the size of the billboard
virtual const core::dimension2d<f32>& getSize() const;
virtual video::SMaterial& getMaterial(u32 i);
//! returns amount of materials used by this scene node.
virtual u32 getMaterialCount() const;
//! Set the color of all vertices of the billboard
//! \param overallColor: the color to set
virtual void setColor(const video::SColor & overallColor);
//! Set the color of the top and bottom vertices of the billboard
//! \param topColor: the color to set the top vertices
//! \param bottomColor: the color to set the bottom vertices
virtual void setColor(const video::SColor & topColor, const video::SColor & bottomColor);
//! Gets the color of the top and bottom vertices of the billboard
//! \param[out] topColor: stores the color of the top vertices
//! \param[out] bottomColor: stores the color of the bottom vertices
virtual void getColor(video::SColor& topColor, video::SColor& bottomColor) const;
virtual void setTCoords(u32 i, core::vector2d<f32> c);
private:
core::dimension2d<f32> Size;
core::aabbox3d<f32> BBox;
video::SMaterial Material;
video::S3DVertex vertices[4];
u16 indices[6];
};
} // end namespace scene
} // end namespace irr
#endif

View File

@@ -40,6 +40,8 @@ std::string privsToString(u64 privs)
os<<"privs,";
if(privs & PRIV_SHOUT)
os<<"shout,";
if(privs & PRIV_BAN)
os<<"ban,";
if(os.tellp())
{
// Drop the trailing comma. (Why on earth can't
@@ -70,6 +72,8 @@ u64 stringToPrivs(std::string str)
privs |= PRIV_PRIVS;
else if(s == "shout")
privs |= PRIV_SHOUT;
else if(s == "ban")
privs |= PRIV_BAN;
else
return PRIV_INVALID;
}

View File

@@ -38,6 +38,7 @@ 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
// Default privileges - these can be overriden for new players using the
// config option "default_privs" - however, this value still applies for

163
src/ban.cpp Normal file
View File

@@ -0,0 +1,163 @@
/*
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 "ban.h"
#include <fstream>
#include <jmutexautolock.h>
#include <sstream>
#include <set>
#include "strfnd.h"
#include "debug.h"
BanManager::BanManager(const std::string &banfilepath):
m_banfilepath(banfilepath),
m_modified(false)
{
m_mutex.Init();
try{
load();
}
catch(SerializationError &e)
{
dstream<<"WARNING: BanManager: creating "
<<m_banfilepath<<std::endl;
}
}
BanManager::~BanManager()
{
save();
}
void BanManager::load()
{
JMutexAutoLock lock(m_mutex);
dstream<<"BanManager: loading from "<<m_banfilepath<<std::endl;
std::ifstream is(m_banfilepath.c_str(), std::ios::binary);
if(is.good() == false)
{
dstream<<"BanManager: failed loading from "<<m_banfilepath<<std::endl;
throw SerializationError("BanManager::load(): Couldn't open file");
}
for(;;)
{
if(is.eof() || is.good() == false)
break;
std::string line;
std::getline(is, line, '\n');
Strfnd f(line);
std::string ip = trim(f.next("|"));
std::string name = trim(f.next("|"));
if(ip.empty())
continue;
m_ips[ip] = name;
}
m_modified = false;
}
void BanManager::save()
{
JMutexAutoLock lock(m_mutex);
dstream<<"BanManager: saving to "<<m_banfilepath<<std::endl;
std::ofstream os(m_banfilepath.c_str(), std::ios::binary);
if(os.good() == false)
{
dstream<<"BanManager: failed loading from "<<m_banfilepath<<std::endl;
throw SerializationError("BanManager::load(): Couldn't open file");
}
for(std::map<std::string, std::string>::iterator
i = m_ips.begin();
i != m_ips.end(); i++)
{
os<<i->first<<"|"<<i->second<<"\n";
}
m_modified = false;
}
bool BanManager::isIpBanned(const std::string &ip)
{
JMutexAutoLock lock(m_mutex);
return m_ips.find(ip) != m_ips.end();
}
std::string BanManager::getBanDescription(const std::string &ip_or_name)
{
JMutexAutoLock lock(m_mutex);
std::string s = "";
for(std::map<std::string, std::string>::iterator
i = m_ips.begin();
i != m_ips.end(); i++)
{
if(i->first == ip_or_name || i->second == ip_or_name
|| ip_or_name == "")
s += i->first + "|" + i->second + ", ";
}
s = s.substr(0, s.size()-2);
return s;
}
std::string BanManager::getBanName(const std::string &ip)
{
JMutexAutoLock lock(m_mutex);
std::map<std::string, std::string>::iterator i = m_ips.find(ip);
if(i == m_ips.end())
return "";
return i->second;
}
void BanManager::add(const std::string &ip, const std::string &name)
{
JMutexAutoLock lock(m_mutex);
m_ips[ip] = name;
m_modified = true;
}
void BanManager::remove(const std::string &ip_or_name)
{
JMutexAutoLock lock(m_mutex);
//m_ips.erase(m_ips.find(ip));
// Find out all ip-name pairs that match the ip or name
std::set<std::string> ips_to_delete;
for(std::map<std::string, std::string>::iterator
i = m_ips.begin();
i != m_ips.end(); i++)
{
if(i->first == ip_or_name || i->second == ip_or_name)
ips_to_delete.insert(i->first);
}
// Erase them
for(std::set<std::string>::iterator
i = ips_to_delete.begin();
i != ips_to_delete.end(); i++)
{
m_ips.erase(*i);
}
m_modified = true;
}
bool BanManager::isModified()
{
JMutexAutoLock lock(m_mutex);
return m_modified;
}

52
src/ban.h Normal file
View File

@@ -0,0 +1,52 @@
/*
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 BAN_HEADER
#define BAN_HEADER
#include <map>
#include <string>
#include <jthread.h>
#include <jmutex.h>
#include "common_irrlicht.h"
#include "exceptions.h"
class BanManager
{
public:
BanManager(const std::string &bannfilepath);
~BanManager();
void load();
void save();
bool isIpBanned(const std::string &ip);
// Supplying ip_or_name = "" lists all bans.
std::string getBanDescription(const std::string &ip_or_name);
std::string getBanName(const std::string &ip);
void add(const std::string &ip, const std::string &name);
void remove(const std::string &ip_or_name);
bool isModified();
private:
JMutex m_mutex;
std::string m_banfilepath;
std::map<std::string, std::string> m_ips;
bool m_modified;
};
#endif

903
src/camera.cpp Normal file
View File

@@ -0,0 +1,903 @@
/*
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
(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 "camera.h"
#include "debug.h"
#include "client.h"
#include "main.h" // for g_settings
#include "map.h"
#include "player.h"
#include "tile.h"
#include <cmath>
#include <SAnimatedMesh.h>
#include "settings.h"
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr),
m_playernode(NULL),
m_headnode(NULL),
m_cameranode(NULL),
m_wieldmgr(NULL),
m_wieldnode(NULL),
m_draw_control(draw_control),
m_viewing_range_min(5.0),
m_viewing_range_max(5.0),
m_camera_position(0,0,0),
m_camera_direction(0,0,0),
m_aspect(1.0),
m_fov_x(1.0),
m_fov_y(1.0),
m_wanted_frametime(0.0),
m_added_frametime(0),
m_added_frames(0),
m_range_old(0),
m_frametime_old(0),
m_frametime_counter(0),
m_time_per_range(30. / 50), // a sane default of 30ms per 50 nodes of range
m_view_bobbing_anim(0),
m_view_bobbing_state(0),
m_view_bobbing_speed(0),
m_digging_anim(0),
m_digging_button(-1)
{
//dstream<<__FUNCTION_NAME<<std::endl;
// note: making the camera node a child of the player node
// would lead to unexpected behaviour, so we don't do that.
m_playernode = smgr->addEmptySceneNode(smgr->getRootSceneNode());
m_headnode = smgr->addEmptySceneNode(m_playernode);
m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode());
m_cameranode->bindTargetAndRotation(true);
// This needs to be in its own scene manager. It is drawn after
// all other 3D scene nodes and before the GUI.
m_wieldmgr = smgr->createNewSceneManager();
m_wieldmgr->addCameraSceneNode();
m_wieldnode = new ExtrudedSpriteSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr);
updateSettings();
}
Camera::~Camera()
{
m_wieldmgr->drop();
m_wieldnode->drop();
}
bool Camera::successfullyCreated(std::wstring& error_message)
{
if (m_playernode == NULL)
{
error_message = L"Failed to create the player scene node";
return false;
}
if (m_headnode == NULL)
{
error_message = L"Failed to create the head scene node";
return false;
}
if (m_cameranode == NULL)
{
error_message = L"Failed to create the camera scene node";
return false;
}
if (m_wieldmgr == NULL)
{
error_message = L"Failed to create the wielded item scene manager";
return false;
}
if (m_wieldnode == NULL)
{
error_message = L"Failed to create the wielded item scene node";
return false;
}
return true;
}
// Returns the fractional part of x
inline f32 my_modf(f32 x)
{
double dummy;
return modf(x, &dummy);
}
void Camera::step(f32 dtime)
{
if (m_view_bobbing_state != 0)
{
//f32 offset = dtime * m_view_bobbing_speed * 0.035;
f32 offset = dtime * m_view_bobbing_speed * 0.030;
if (m_view_bobbing_state == 2)
{
#if 0
// Animation is getting turned off
if (m_view_bobbing_anim < 0.5)
m_view_bobbing_anim -= offset;
else
m_view_bobbing_anim += offset;
if (m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1)
{
m_view_bobbing_anim = 0;
m_view_bobbing_state = 0;
}
#endif
#if 1
// Animation is getting turned off
if(m_view_bobbing_anim < 0.25){
m_view_bobbing_anim -= offset;
} else if(m_view_bobbing_anim > 0.75){
m_view_bobbing_anim += offset;
} if(m_view_bobbing_anim < 0.5){
m_view_bobbing_anim += offset;
if(m_view_bobbing_anim > 0.5)
m_view_bobbing_anim = 0.5;
} else {
m_view_bobbing_anim -= offset;
if(m_view_bobbing_anim < 0.5)
m_view_bobbing_anim = 0.5;
}
if(m_view_bobbing_anim <= 0 || m_view_bobbing_anim >= 1 ||
fabs(m_view_bobbing_anim - 0.5) < 0.01)
{
m_view_bobbing_anim = 0;
m_view_bobbing_state = 0;
}
#endif
}
else
{
m_view_bobbing_anim = my_modf(m_view_bobbing_anim + offset);
}
}
if (m_digging_button != -1)
{
f32 offset = dtime * 3.5;
m_digging_anim += offset;
if (m_digging_anim >= 1)
{
m_digging_anim = 0;
m_digging_button = -1;
}
}
}
void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize)
{
// Set player node transformation
m_playernode->setPosition(player->getPosition());
m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0));
m_playernode->updateAbsolutePosition();
// Set head node transformation
m_headnode->setPosition(player->getEyeOffset());
m_headnode->setRotation(v3f(player->getPitch(), 0, 0));
m_headnode->updateAbsolutePosition();
// Compute relative camera position and target
v3f rel_cam_pos = v3f(0,0,0);
v3f rel_cam_target = v3f(0,0,1);
v3f rel_cam_up = v3f(0,1,0);
if (m_view_bobbing_anim != 0)
{
f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
#if 1
f32 bobknob = 1.2;
f32 bobtmp = sin(pow(bobfrac, bobknob) * PI);
//f32 bobtmp2 = cos(pow(bobfrac, bobknob) * PI);
v3f bobvec = v3f(
0.3 * bobdir * sin(bobfrac * PI),
-0.28 * bobtmp * bobtmp,
0.);
//rel_cam_pos += 0.2 * bobvec;
//rel_cam_target += 0.03 * bobvec;
//rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * PI);
float f = 1.0;
f *= g_settings->getFloat("view_bobbing_amount");
rel_cam_pos += bobvec * f;
//rel_cam_target += 0.995 * bobvec * f;
rel_cam_target += bobvec * f;
rel_cam_target.Z -= 0.005 * bobvec.Z * f;
//rel_cam_target.X -= 0.005 * bobvec.X * f;
//rel_cam_target.Y -= 0.005 * bobvec.Y * f;
rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * PI * f);
#else
f32 angle_deg = 1 * bobdir * sin(bobfrac * PI);
f32 angle_rad = angle_deg * PI / 180;
f32 r = 0.05;
v3f off = v3f(
r * sin(angle_rad),
r * (cos(angle_rad) - 1),
0);
rel_cam_pos += off;
//rel_cam_target += off;
rel_cam_up.rotateXYBy(angle_deg);
#endif
}
// Compute absolute camera position and target
m_headnode->getAbsoluteTransformation().transformVect(m_camera_position, rel_cam_pos);
m_headnode->getAbsoluteTransformation().rotateVect(m_camera_direction, rel_cam_target - rel_cam_pos);
v3f abs_cam_up;
m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up);
// Set camera node transformation
m_cameranode->setPosition(m_camera_position);
m_cameranode->setUpVector(abs_cam_up);
// *100.0 helps in large map coordinates
m_cameranode->setTarget(m_camera_position + 100 * m_camera_direction);
// FOV and and aspect ratio
m_aspect = (f32)screensize.X / (f32) screensize.Y;
m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y));
m_cameranode->setAspectRatio(m_aspect);
m_cameranode->setFOV(m_fov_y);
// Just so big a value that everything rendered is visible
// Some more allowance that m_viewing_range_max * BS because of active objects etc.
m_cameranode->setFarValue(m_viewing_range_max * BS * 10);
// Position the wielded item
v3f wield_position = v3f(45, -35, 65);
v3f wield_rotation = v3f(-100, 110, -100);
if (m_digging_button != -1)
{
f32 digfrac = m_digging_anim;
wield_position.X -= 30 * sin(pow(digfrac, 0.8f) * PI);
wield_position.Y += 15 * sin(digfrac * 2 * PI);
wield_position.Z += 5 * digfrac;
// Euler angles are PURE EVIL, so why not use quaternions?
core::quaternion quat_begin(wield_rotation * core::DEGTORAD);
core::quaternion quat_end(v3f(90, -10, -130) * core::DEGTORAD);
core::quaternion quat_slerp;
quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * PI));
quat_slerp.toEuler(wield_rotation);
wield_rotation *= core::RADTODEG;
}
else {
f32 bobfrac = my_modf(m_view_bobbing_anim);
wield_position.X -= sin(bobfrac*PI*2.0) * 3.0;
wield_position.Y += sin(my_modf(bobfrac*2.0)*PI) * 3.0;
}
m_wieldnode->setPosition(wield_position);
m_wieldnode->setRotation(wield_rotation);
m_wieldnode->updateLight(player->light);
// Render distance feedback loop
updateViewingRange(frametime);
// If the player seems to be walking on solid ground,
// view bobbing is enabled and free_move is off,
// start (or continue) the view bobbing animation.
v3f speed = player->getSpeed();
if ((hypot(speed.X, speed.Z) > BS) &&
(player->touching_ground) &&
(g_settings->getBool("view_bobbing") == true) &&
(g_settings->getBool("free_move") == false))
{
// Start animation
m_view_bobbing_state = 1;
m_view_bobbing_speed = MYMIN(speed.getLength(), 40);
}
else if (m_view_bobbing_state == 1)
{
// Stop animation
m_view_bobbing_state = 2;
m_view_bobbing_speed = 60;
}
}
void Camera::updateViewingRange(f32 frametime_in)
{
if (m_draw_control.range_all)
return;
m_added_frametime += frametime_in;
m_added_frames += 1;
// Actually this counter kind of sucks because frametime is busytime
m_frametime_counter -= frametime_in;
if (m_frametime_counter > 0)
return;
m_frametime_counter = 0.2;
/*dstream<<__FUNCTION_NAME
<<": Collected "<<m_added_frames<<" frames, total of "
<<m_added_frametime<<"s."<<std::endl;
dstream<<"m_draw_control.blocks_drawn="
<<m_draw_control.blocks_drawn
<<", m_draw_control.blocks_would_have_drawn="
<<m_draw_control.blocks_would_have_drawn
<<std::endl;*/
m_draw_control.wanted_min_range = m_viewing_range_min;
m_draw_control.wanted_max_blocks = (2.0*m_draw_control.blocks_would_have_drawn)+1;
if (m_draw_control.wanted_max_blocks < 10)
m_draw_control.wanted_max_blocks = 10;
f32 block_draw_ratio = 1.0;
if (m_draw_control.blocks_would_have_drawn != 0)
{
block_draw_ratio = (f32)m_draw_control.blocks_drawn
/ (f32)m_draw_control.blocks_would_have_drawn;
}
// Calculate the average frametime in the case that all wanted
// blocks had been drawn
f32 frametime = m_added_frametime / m_added_frames / block_draw_ratio;
m_added_frametime = 0.0;
m_added_frames = 0;
f32 wanted_frametime_change = m_wanted_frametime - frametime;
//dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl;
// If needed frametime change is small, just return
// This value was 0.4 for many months until 2011-10-18 by c55;
// Let's see how this works out.
if (fabs(wanted_frametime_change) < m_wanted_frametime*0.33)
{
//dstream<<"ignoring small wanted_frametime_change"<<std::endl;
return;
}
f32 range = m_draw_control.wanted_range;
f32 new_range = range;
f32 d_range = range - m_range_old;
f32 d_frametime = frametime - m_frametime_old;
if (d_range != 0)
{
m_time_per_range = d_frametime / d_range;
}
// The minimum allowed calculated frametime-range derivative:
// Practically this sets the maximum speed of changing the range.
// The lower this value, the higher the maximum changing speed.
// A low value here results in wobbly range (0.001)
// A high value here results in slow changing range (0.0025)
// SUGG: This could be dynamically adjusted so that when
// the camera is turning, this is lower
//f32 min_time_per_range = 0.0015;
f32 min_time_per_range = 0.0010;
//f32 min_time_per_range = 0.05 / range;
if(m_time_per_range < min_time_per_range)
{
m_time_per_range = min_time_per_range;
//dstream<<"m_time_per_range="<<m_time_per_range<<" (min)"<<std::endl;
}
else
{
//dstream<<"m_time_per_range="<<m_time_per_range<<std::endl;
}
f32 wanted_range_change = wanted_frametime_change / m_time_per_range;
// Dampen the change a bit to kill oscillations
//wanted_range_change *= 0.9;
//wanted_range_change *= 0.75;
wanted_range_change *= 0.5;
//dstream<<"wanted_range_change="<<wanted_range_change<<std::endl;
// If needed range change is very small, just return
if(fabs(wanted_range_change) < 0.001)
{
//dstream<<"ignoring small wanted_range_change"<<std::endl;
return;
}
new_range += wanted_range_change;
//f32 new_range_unclamped = new_range;
new_range = MYMAX(new_range, m_viewing_range_min);
new_range = MYMIN(new_range, m_viewing_range_max);
/*dstream<<"new_range="<<new_range_unclamped
<<", clamped to "<<new_range<<std::endl;*/
m_draw_control.wanted_range = new_range;
m_range_old = new_range;
m_frametime_old = frametime;
}
void Camera::updateSettings()
{
m_viewing_range_min = g_settings->getS16("viewing_range_nodes_min");
m_viewing_range_min = MYMAX(5.0, m_viewing_range_min);
m_viewing_range_max = g_settings->getS16("viewing_range_nodes_max");
m_viewing_range_max = MYMAX(m_viewing_range_min, m_viewing_range_max);
f32 fov_degrees = g_settings->getFloat("fov");
fov_degrees = MYMAX(fov_degrees, 10.0);
fov_degrees = MYMIN(fov_degrees, 170.0);
m_fov_y = fov_degrees * PI / 180.0;
f32 wanted_fps = g_settings->getFloat("wanted_fps");
wanted_fps = MYMAX(wanted_fps, 1.0);
m_wanted_frametime = 1.0 / wanted_fps;
}
void Camera::wield(const InventoryItem* item)
{
if (item != NULL)
{
bool isCube = false;
// Try to make a MaterialItem cube.
if (std::string(item->getName()) == "MaterialItem")
{
// A block-type material
MaterialItem* mat_item = (MaterialItem*) item;
content_t content = mat_item->getMaterial();
if (content_features(content).solidness || content_features(content).visual_solidness)
{
m_wieldnode->setCube(content_features(content).tiles);
m_wieldnode->setScale(v3f(30));
isCube = true;
}
}
// If that failed, make an extruded sprite.
if (!isCube)
{
m_wieldnode->setSprite(item->getImageRaw());
m_wieldnode->setScale(v3f(40));
}
m_wieldnode->setVisible(true);
}
else
{
// Bare hands
m_wieldnode->setVisible(false);
}
}
void Camera::setDigging(s32 button)
{
if (m_digging_button == -1)
m_digging_button = button;
}
void Camera::drawWieldedTool()
{
m_wieldmgr->getVideoDriver()->clearZBuffer();
scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera();
cam->setAspectRatio(m_cameranode->getAspectRatio());
cam->setFOV(m_cameranode->getFOV());
cam->setNearValue(0.1);
cam->setFarValue(100);
m_wieldmgr->drawAll();
}
ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode(
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id,
const v3f& position,
const v3f& rotation,
const v3f& scale
):
ISceneNode(parent, mgr, id, position, rotation, scale)
{
m_meshnode = mgr->addMeshSceneNode(NULL, this, -1, v3f(0,0,0), v3f(0,0,0), v3f(1,1,1), true);
m_thickness = 0.1;
m_cubemesh = NULL;
m_is_cube = false;
m_light = LIGHT_MAX;
}
ExtrudedSpriteSceneNode::~ExtrudedSpriteSceneNode()
{
removeChild(m_meshnode);
if (m_cubemesh)
m_cubemesh->drop();
}
void ExtrudedSpriteSceneNode::setSprite(video::ITexture* texture)
{
if (texture == NULL)
{
m_meshnode->setVisible(false);
return;
}
io::path name = getExtrudedName(texture);
scene::IMeshCache* cache = SceneManager->getMeshCache();
scene::IAnimatedMesh* mesh = cache->getMeshByName(name);
if (mesh != NULL)
{
// Extruded texture has been found in cache.
m_meshnode->setMesh(mesh);
}
else
{
// Texture was not yet extruded, do it now and save in cache
mesh = extrude(texture);
if (mesh == NULL)
{
dstream << "Warning: failed to extrude sprite" << std::endl;
m_meshnode->setVisible(false);
return;
}
cache->addMesh(name, mesh);
m_meshnode->setMesh(mesh);
mesh->drop();
}
m_meshnode->setScale(v3f(1, 1, m_thickness));
m_meshnode->getMaterial(0).setTexture(0, texture);
m_meshnode->getMaterial(0).setFlag(video::EMF_LIGHTING, false);
m_meshnode->getMaterial(0).setFlag(video::EMF_BILINEAR_FILTER, false);
m_meshnode->getMaterial(0).MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
m_meshnode->setVisible(true);
m_is_cube = false;
updateLight(m_light);
}
void ExtrudedSpriteSceneNode::setCube(const TileSpec tiles[6])
{
if (m_cubemesh == NULL)
m_cubemesh = createCubeMesh();
m_meshnode->setMesh(m_cubemesh);
m_meshnode->setScale(v3f(1));
for (int i = 0; i < 6; ++i)
{
// Get the tile texture and atlas transformation
video::ITexture* atlas = tiles[i].texture.atlas;
v2f pos = tiles[i].texture.pos;
v2f size = tiles[i].texture.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);
tiles[i].applyMaterialOptions(material);
material.setTexture(0, atlas);
material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
}
m_meshnode->setVisible(true);
m_is_cube = true;
updateLight(m_light);
}
void ExtrudedSpriteSceneNode::updateLight(u8 light)
{
m_light = light;
u8 li = decode_light(light);
// Set brightness one lower than incoming light
diminish_light(li);
video::SColor color(255,li,li,li);
setMeshVerticesColor(m_meshnode->getMesh(), color);
}
void ExtrudedSpriteSceneNode::removeSpriteFromCache(video::ITexture* texture)
{
scene::IMeshCache* cache = SceneManager->getMeshCache();
scene::IAnimatedMesh* mesh = cache->getMeshByName(getExtrudedName(texture));
if (mesh != NULL)
cache->removeMesh(mesh);
}
void ExtrudedSpriteSceneNode::setSpriteThickness(f32 thickness)
{
m_thickness = thickness;
if (!m_is_cube)
m_meshnode->setScale(v3f(1, 1, thickness));
}
const core::aabbox3d<f32>& ExtrudedSpriteSceneNode::getBoundingBox() const
{
return m_meshnode->getBoundingBox();
}
void ExtrudedSpriteSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
void ExtrudedSpriteSceneNode::render()
{
// do nothing
}
io::path ExtrudedSpriteSceneNode::getExtrudedName(video::ITexture* texture)
{
io::path path = texture->getName();
path.append("/[extruded]");
return path;
}
scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrudeARGB(u32 width, u32 height, u8* data)
{
const s32 argb_wstep = 4 * width;
const s32 alpha_threshold = 1;
scene::IMeshBuffer* buf = new scene::SMeshBuffer();
video::SColor c(255,255,255,255);
// Front and back
{
video::S3DVertex vertices[8] =
{
video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
video::S3DVertex(+0.5,-0.5,+0.5, 0,0,+1, c, 1,1),
video::S3DVertex(+0.5,+0.5,+0.5, 0,0,+1, c, 1,0),
video::S3DVertex(-0.5,+0.5,+0.5, 0,0,+1, c, 0,0),
video::S3DVertex(-0.5,-0.5,+0.5, 0,0,+1, c, 0,1),
};
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
buf->append(vertices, 8, indices, 12);
}
// "Interior"
// (add faces where a solid pixel is next to a transparent one)
u8* solidity = new u8[(width+2) * (height+2)];
u32 wstep = width + 2;
for (u32 y = 0; y < height + 2; ++y)
{
u8* scanline = solidity + y * wstep;
if (y == 0 || y == height + 1)
{
for (u32 x = 0; x < width + 2; ++x)
scanline[x] = 0;
}
else
{
scanline[0] = 0;
u8* argb_scanline = data + (y - 1) * argb_wstep;
for (u32 x = 0; x < width; ++x)
scanline[x+1] = (argb_scanline[x*4+3] >= alpha_threshold);
scanline[width + 1] = 0;
}
}
// without this, there would be occasional "holes" in the mesh
f32 eps = 0.01;
for (u32 y = 0; y <= height; ++y)
{
u8* scanline = solidity + y * wstep + 1;
for (u32 x = 0; x <= width; ++x)
{
if (scanline[x] && !scanline[x + wstep])
{
u32 xx = x + 1;
while (scanline[xx] && !scanline[xx + wstep])
++xx;
f32 vx1 = (x - eps) / (f32) width - 0.5;
f32 vx2 = (xx + eps) / (f32) width - 0.5;
f32 vy = 0.5 - (y - eps) / (f32) height;
f32 tx1 = x / (f32) width;
f32 tx2 = xx / (f32) width;
f32 ty = (y - 0.5) / (f32) height;
video::S3DVertex vertices[8] =
{
video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty),
video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty),
video::S3DVertex(vx2,vy,+0.5, 0,-1,0, c, tx2,ty),
video::S3DVertex(vx1,vy,+0.5, 0,-1,0, c, tx1,ty),
};
u16 indices[6] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
x = xx - 1;
}
if (!scanline[x] && scanline[x + wstep])
{
u32 xx = x + 1;
while (!scanline[xx] && scanline[xx + wstep])
++xx;
f32 vx1 = (x - eps) / (f32) width - 0.5;
f32 vx2 = (xx + eps) / (f32) width - 0.5;
f32 vy = 0.5 - (y + eps) / (f32) height;
f32 tx1 = x / (f32) width;
f32 tx2 = xx / (f32) width;
f32 ty = (y + 0.5) / (f32) height;
video::S3DVertex vertices[8] =
{
video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty),
video::S3DVertex(vx1,vy,+0.5, 0,1,0, c, tx1,ty),
video::S3DVertex(vx2,vy,+0.5, 0,1,0, c, tx2,ty),
video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty),
};
u16 indices[6] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
x = xx - 1;
}
}
}
for (u32 x = 0; x <= width; ++x)
{
u8* scancol = solidity + x + wstep;
for (u32 y = 0; y <= height; ++y)
{
if (scancol[y * wstep] && !scancol[y * wstep + 1])
{
u32 yy = y + 1;
while (scancol[yy * wstep] && !scancol[yy * wstep + 1])
++yy;
f32 vx = (x - eps) / (f32) width - 0.5;
f32 vy1 = 0.5 - (y - eps) / (f32) height;
f32 vy2 = 0.5 - (yy + eps) / (f32) height;
f32 tx = (x - 0.5) / (f32) width;
f32 ty1 = y / (f32) height;
f32 ty2 = yy / (f32) height;
video::S3DVertex vertices[8] =
{
video::S3DVertex(vx,vy1,-0.5, 1,0,0, c, tx,ty1),
video::S3DVertex(vx,vy1,+0.5, 1,0,0, c, tx,ty1),
video::S3DVertex(vx,vy2,+0.5, 1,0,0, c, tx,ty2),
video::S3DVertex(vx,vy2,-0.5, 1,0,0, c, tx,ty2),
};
u16 indices[6] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
y = yy - 1;
}
if (!scancol[y * wstep] && scancol[y * wstep + 1])
{
u32 yy = y + 1;
while (!scancol[yy * wstep] && scancol[yy * wstep + 1])
++yy;
f32 vx = (x + eps) / (f32) width - 0.5;
f32 vy1 = 0.5 - (y - eps) / (f32) height;
f32 vy2 = 0.5 - (yy + eps) / (f32) height;
f32 tx = (x + 0.5) / (f32) width;
f32 ty1 = y / (f32) height;
f32 ty2 = yy / (f32) height;
video::S3DVertex vertices[8] =
{
video::S3DVertex(vx,vy1,-0.5, -1,0,0, c, tx,ty1),
video::S3DVertex(vx,vy2,-0.5, -1,0,0, c, tx,ty2),
video::S3DVertex(vx,vy2,+0.5, -1,0,0, c, tx,ty2),
video::S3DVertex(vx,vy1,+0.5, -1,0,0, c, tx,ty1),
};
u16 indices[6] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
y = yy - 1;
}
}
}
// Add to mesh
scene::SMesh* mesh = new scene::SMesh();
buf->recalculateBoundingBox();
mesh->addMeshBuffer(buf);
buf->drop();
mesh->recalculateBoundingBox();
scene::SAnimatedMesh* anim_mesh = new scene::SAnimatedMesh(mesh);
mesh->drop();
return anim_mesh;
}
scene::IAnimatedMesh* ExtrudedSpriteSceneNode::extrude(video::ITexture* texture)
{
scene::IAnimatedMesh* mesh = NULL;
core::dimension2d<u32> size = texture->getSize();
video::ECOLOR_FORMAT format = texture->getColorFormat();
if (format == video::ECF_A8R8G8B8)
{
// Texture is in the correct color format, we can pass it
// to extrudeARGB right away.
void* data = texture->lock(true);
if (data == NULL)
return NULL;
mesh = extrudeARGB(size.Width, size.Height, (u8*) data);
texture->unlock();
}
else
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
video::IImage* img1 = driver->createImageFromData(format, size, texture->lock(true));
if (img1 == NULL)
return NULL;
// img1 is in the texture's color format, convert to 8-bit ARGB
video::IImage* img2 = driver->createImage(video::ECF_A8R8G8B8, size);
if (img2 != NULL)
{
img1->copyTo(img2);
img1->drop();
mesh = extrudeARGB(size.Width, size.Height, (u8*) img2->lock());
img2->unlock();
img2->drop();
}
img1->drop();
}
return mesh;
}
scene::IMesh* ExtrudedSpriteSceneNode::createCubeMesh()
{
video::SColor c(255,255,255,255);
video::S3DVertex vertices[24] =
{
// Up
video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1),
video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0),
video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1),
// Down
video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0),
video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1),
video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1),
// Right
video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1),
video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0),
video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0),
video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1),
// Left
video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1),
video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1),
video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0),
video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0),
// Back
video::S3DVertex(-0.5,-0.5,+0.5, 0,0,1, c, 1,1),
video::S3DVertex(+0.5,-0.5,+0.5, 0,0,1, c, 0,1),
video::S3DVertex(+0.5,+0.5,+0.5, 0,0,1, c, 0,0),
video::S3DVertex(-0.5,+0.5,+0.5, 0,0,1, c, 1,0),
// Front
video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
};
u16 indices[6] = {0,1,2,2,3,0};
scene::SMesh* mesh = new scene::SMesh();
for (u32 i=0; i<6; ++i)
{
scene::IMeshBuffer* buf = new scene::SMeshBuffer();
buf->append(vertices + 4 * i, 4, indices, 6);
buf->recalculateBoundingBox();
mesh->addMeshBuffer(buf);
buf->drop();
}
mesh->recalculateBoundingBox();
return mesh;
}

233
src/camera.h Normal file
View File

@@ -0,0 +1,233 @@
/*
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
(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 CAMERA_HEADER
#define CAMERA_HEADER
#include "common_irrlicht.h"
#include "inventory.h"
#include "tile.h"
#include "utility.h"
#include <ICameraSceneNode.h>
#include <IMeshCache.h>
#include <IAnimatedMesh.h>
class LocalPlayer;
class MapDrawControl;
class ExtrudedSpriteSceneNode;
/*
Client camera class, manages the player and camera scene nodes, the viewing distance
and performs view bobbing etc. It also displays the wielded tool in front of the
first-person camera.
*/
class Camera
{
public:
Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control);
~Camera();
// Get player scene node.
// This node is positioned at the player's torso (without any view bobbing),
// as given by Player::m_position. Yaw is applied but not pitch.
inline scene::ISceneNode* getPlayerNode() const
{
return m_playernode;
}
// Get head scene node.
// It has the eye transformation and pitch applied,
// but no view bobbing.
inline scene::ISceneNode* getHeadNode() const
{
return m_headnode;
}
// Get camera scene node.
// It has the eye transformation, pitch and view bobbing applied.
inline scene::ICameraSceneNode* getCameraNode() const
{
return m_cameranode;
}
// Get the camera position (in absolute scene coordinates).
// This has view bobbing applied.
inline v3f getPosition() const
{
return m_camera_position;
}
// Get the camera direction (in absolute camera coordinates).
// This has view bobbing applied.
inline v3f getDirection() const
{
return m_camera_direction;
}
// Horizontal field of view
inline f32 getFovX() const
{
return m_fov_x;
}
// Vertical field of view
inline f32 getFovY() const
{
return m_fov_y;
}
// Get maximum of getFovX() and getFovY()
inline f32 getFovMax() const
{
return MYMAX(m_fov_x, m_fov_y);
}
// Checks if the constructor was able to create the scene nodes
bool successfullyCreated(std::wstring& error_message);
// Step the camera: updates the viewing range and view bobbing.
void step(f32 dtime);
// Update the camera from the local player's position.
// frametime is used to adjust the viewing range.
void update(LocalPlayer* player, f32 frametime, v2u32 screensize);
// Render distance feedback loop
void updateViewingRange(f32 frametime_in);
// Update settings from g_settings
void updateSettings();
// Replace the wielded item mesh
void wield(const InventoryItem* item);
// Start digging animation
// Pass 0 for left click, 1 for right click
void setDigging(s32 button);
// Draw the wielded tool.
// This has to happen *after* the main scene is drawn.
// Warning: This clears the Z buffer.
void drawWieldedTool();
private:
// Scene manager and nodes
scene::ISceneManager* m_smgr;
scene::ISceneNode* m_playernode;
scene::ISceneNode* m_headnode;
scene::ICameraSceneNode* m_cameranode;
scene::ISceneManager* m_wieldmgr;
ExtrudedSpriteSceneNode* m_wieldnode;
// draw control
MapDrawControl& m_draw_control;
// viewing_range_min_nodes setting
f32 m_viewing_range_min;
// viewing_range_max_nodes setting
f32 m_viewing_range_max;
// Absolute camera position
v3f m_camera_position;
// Absolute camera direction
v3f m_camera_direction;
// Field of view and aspect ratio stuff
f32 m_aspect;
f32 m_fov_x;
f32 m_fov_y;
// Stuff for viewing range calculations
f32 m_wanted_frametime;
f32 m_added_frametime;
s16 m_added_frames;
f32 m_range_old;
f32 m_frametime_old;
f32 m_frametime_counter;
f32 m_time_per_range;
// View bobbing animation frame (0 <= m_view_bobbing_anim < 1)
f32 m_view_bobbing_anim;
// If 0, view bobbing is off (e.g. player is standing).
// If 1, view bobbing is on (player is walking).
// If 2, view bobbing is getting switched off.
s32 m_view_bobbing_state;
// Speed of view bobbing animation
f32 m_view_bobbing_speed;
// Digging animation frame (0 <= m_digging_anim < 1)
f32 m_digging_anim;
// If -1, no digging animation
// If 0, left-click digging animation
// If 1, right-click digging animation
s32 m_digging_button;
};
/*
A scene node that displays a 2D mesh extruded into the third dimension,
to add an illusion of depth.
Since this class was created to display the wielded tool of the local
player, and only tools and items are rendered like this (but not solid
content like stone and mud, which are shown as cubes), the option to
draw a textured cube instead is provided.
*/
class ExtrudedSpriteSceneNode: public scene::ISceneNode
{
public:
ExtrudedSpriteSceneNode(
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id = -1,
const v3f& position = v3f(0,0,0),
const v3f& rotation = v3f(0,0,0),
const v3f& scale = v3f(1,1,1));
~ExtrudedSpriteSceneNode();
void setSprite(video::ITexture* texture);
void setCube(const TileSpec tiles[6]);
f32 getSpriteThickness() const { return m_thickness; }
void setSpriteThickness(f32 thickness);
void updateLight(u8 light);
void removeSpriteFromCache(video::ITexture* texture);
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual void OnRegisterSceneNode();
virtual void render();
private:
scene::IMeshSceneNode* m_meshnode;
f32 m_thickness;
scene::IMesh* m_cubemesh;
bool m_is_cube;
u8 m_light;
// internal extrusion helper methods
io::path getExtrudedName(video::ITexture* texture);
scene::IAnimatedMesh* extrudeARGB(u32 width, u32 height, u8* data);
scene::IAnimatedMesh* extrude(video::ITexture* texture);
scene::IMesh* createCubeMesh();
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -113,7 +113,8 @@ enum ClientEventType
{
CE_NONE,
CE_PLAYER_DAMAGE,
CE_PLAYER_FORCE_MOVE
CE_PLAYER_FORCE_MOVE,
CE_DEATHSCREEN,
};
struct ClientEvent
@@ -129,6 +130,12 @@ struct ClientEvent
f32 pitch;
f32 yaw;
} player_force_move;
struct{
bool set_camera_point_target;
f32 camera_point_target_x;
f32 camera_point_target_y;
f32 camera_point_target_z;
} deathscreen;
};
};
@@ -183,33 +190,36 @@ class Client : public con::PeerHandler, public InventoryManager
void groundAction(u8 action, v3s16 nodepos_undersurface,
v3s16 nodepos_oversurface, u16 item);
void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
void clickActiveObject(u8 button, u16 id, u16 item);
void clickActiveObject(u8 button, u16 id, u16 item_i);
void sendSignText(v3s16 blockpos, s16 id, std::string text);
void sendSignNodeText(v3s16 p, std::string text);
void sendInventoryAction(InventoryAction *a);
void sendChatMessage(const std::wstring &message);
void sendChangePassword(const std::wstring oldpassword,
const std::wstring newpassword);
void sendDamage(u8 damage);
void sendRespawn();
// locks envlock
void removeNode(v3s16 p);
// locks envlock
void addNode(v3s16 p, MapNode n);
void updateCamera(v3f pos, v3f dir);
void updateCamera(v3f pos, v3f dir, f32 fov);
void renderPostFx();
// Returns InvalidPositionException if not found
MapNode getNode(v3s16 p);
// Wrapper to Map
NodeMetadata* getNodeMetadata(v3s16 p);
v3f getPlayerPosition();
LocalPlayer* getLocalPlayer();
void setPlayerControl(PlayerControl &control);
void selectPlayerItem(u16 item);
// Returns true if the inventory of the local player has been
// updated from the server. If it is true, it is set to false.
bool getLocalInventoryUpdated();
@@ -221,14 +231,6 @@ class Client : public con::PeerHandler, public InventoryManager
Inventory* getInventory(InventoryContext *c, std::string id);
void inventoryAction(InventoryAction *a);
// Gets closest object pointed by the shootline
// Returns NULL if not found
MapBlockObject * getSelectedObject(
f32 max_d,
v3f from_pos_f_on_map,
core::line3d<f32> shootline_on_map
);
// Gets closest object pointed by the shootline
// Returns NULL if not found
ClientActiveObject * getSelectedActiveObject(
@@ -249,11 +251,11 @@ class Client : public con::PeerHandler, public InventoryManager
float getAvgRtt()
{
//JMutexAutoLock lock(m_con_mutex); //bulk comment-out
con::Peer *peer = m_con.GetPeerNoEx(PEER_ID_SERVER);
if(peer == NULL)
return 0.0;
return peer->avg_rtt;
try{
return m_con.GetPeerAvgRTT(PEER_ID_SERVER);
} catch(con::PeerNotFoundException){
return 1337;
}
}
bool getChatMessage(std::wstring &message)
@@ -266,6 +268,12 @@ class Client : public con::PeerHandler, public InventoryManager
void addChatMessage(const std::wstring &message)
{
if (message[0] == L'/') {
m_chat_queue.push_back(
(std::wstring)L"issued command: "+message);
return;
}
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
LocalPlayer *player = m_env.getLocalPlayer();
assert(player != NULL);
@@ -292,15 +300,8 @@ class Client : public con::PeerHandler, public InventoryManager
{
return m_access_denied_reason;
}
/*
This should only be used for calling the special drawing stuff in
ClientEnvironment
*/
ClientEnvironment * getEnv()
{
return &m_env;
}
float getRTT(void);
private:
@@ -314,6 +315,8 @@ class Client : public con::PeerHandler, public InventoryManager
void sendPlayerPos();
// This sends the player's current name etc to the server
void sendPlayerInfo();
// Send the item number 'item' as player item to the server
void sendPlayerItem(u16 item);
float m_packetcounter_timer;
float m_connection_reinit_timer;
@@ -330,9 +333,6 @@ class Client : public con::PeerHandler, public InventoryManager
IrrlichtDevice *m_device;
v3f camera_position;
v3f camera_direction;
// Server serialization version
u8 m_server_ser_ver;

View File

@@ -45,7 +45,7 @@ ClientActiveObject* ClientActiveObject::create(u8 type)
{
// If factory is not found, just return.
dstream<<"WARNING: ClientActiveObject: No factory for type="
<<type<<std::endl;
<<(int)type<<std::endl;
return NULL;
}

View File

@@ -51,6 +51,7 @@ class ClientActiveObject : public ActiveObject
virtual core::aabbox3d<f32>* getSelectionBox(){return NULL;}
virtual core::aabbox3d<f32>* getCollisionBox(){return NULL;}
virtual v3f getPosition(){return v3f(0,0,0);}
virtual bool doShowSelectionBox(){return true;}
// Step object in time
virtual void step(float dtime, ClientEnvironment *env){}
@@ -59,7 +60,7 @@ class ClientActiveObject : public ActiveObject
virtual void processMessage(const std::string &data){}
virtual std::string infoText() {return "";}
/*
This takes the return value of
ServerActiveObject::getClientInitializationData
@@ -69,6 +70,10 @@ class ClientActiveObject : public ActiveObject
// Create a certain type of ClientActiveObject
static ClientActiveObject* create(u8 type);
// If returns true, punch will not be sent to the server
virtual bool directReportPunch(const std::string &toolname, v3f dir)
{ return false; }
protected:
// Used for creating objects based on type
typedef ClientActiveObject* (*Factory)();

View File

@@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h"
#define PROTOCOL_VERSION 3
#define PROTOCOL_ID 0x4f457403
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
@@ -90,6 +92,7 @@ enum ToClientCommand
u16 command
u16 number of player positions
for each player:
u16 peer_id
v3s32 position*100
v3s32 speed*100
s32 pitch*100
@@ -124,7 +127,7 @@ enum ToClientCommand
for all added objects {
u16 id
u8 type
u16 initialization data length
u32 initialization data length
string initialization data
}
*/
@@ -160,6 +163,24 @@ enum ToClientCommand
u16 reason_length
wstring reason
*/
TOCLIENT_PLAYERITEM = 0x36,
/*
u16 command
u16 count of player items
for all player items {
u16 peer id
u16 length of serialized item
string serialized item
}
*/
TOCLIENT_DEATHSCREEN = 0x37,
/*
u16 command
u8 bool set camera point target
v3f1000 camera point target (to point the death cause or whatever)
*/
};
enum ToServerCommand
@@ -301,6 +322,18 @@ enum ToServerCommand
[30] u8[28] new password
*/
TOSERVER_PLAYERITEM=0x37,
/*
Sent to change selected item.
[0] u16 TOSERVER_PLAYERITEM
[2] u16 item
*/
TOSERVER_RESPAWN=0x38,
/*
u16 TOSERVER_RESPAWN
*/
};
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)

View File

@@ -21,6 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "noise.h"
#include "constants.h"
#include "debug.h"
#include "main.h" // For g_profiler and g_settings
#include "profiler.h"
#include "settings.h"
Clouds::Clouds(
scene::ISceneNode* parent,
@@ -76,6 +79,12 @@ void Clouds::render()
if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID)
return;
ScopeProfiler sp(g_profiler, "Rendering of clouds, avg", SPT_AVG);
int num_faces_to_draw = 6;
if(g_settings->getBool("enable_2d_clouds"))
num_faces_to_draw = 1;
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(m_material);
@@ -144,7 +153,7 @@ void Clouds::render()
f32 ry = 8*BS;
f32 rz = cloud_size;
for(int i=0;i<6;i++)
for(int i=0; i<num_faces_to_draw; i++)
{
switch(i)
{

View File

@@ -3,14 +3,16 @@
#ifndef CMAKE_CONFIG_H
#define CMAKE_CONFIG_H
#define PROJECT_NAME "@PROJECT_NAME@"
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#define VERSION_STRING "@VERSION_STRING@"
#define USE_GETTEXT @USE_GETTEXT@
#ifdef NDEBUG
#define BUILD_TYPE "Release"
#else
#define BUILD_TYPE "Debug"
#endif
#define BUILD_INFO "VER="VERSION_STRING" RUN_IN_PLACE=@RUN_IN_PLACE@ INSTALL_PREFIX=@CMAKE_INSTALL_PREFIX@ BUILD_TYPE="BUILD_TYPE
#define BUILD_INFO "VER="VERSION_STRING" RUN_IN_PLACE=@RUN_IN_PLACE@ USE_GETTEXT=@USE_GETTEXT@ INSTALL_PREFIX=@CMAKE_INSTALL_PREFIX@ BUILD_TYPE="BUILD_TYPE
#endif

View File

@@ -23,7 +23,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define endSceneX(d){d->draw2DLine(v2s32(0,0),v2s32(1,0),\
video::SColor(255,30,30,30));d->endScene();}
#include <irrlicht.h>
#include <irrTypes.h>
#include <vector2d.h>
#include <vector3d.h>
#include <irrMap.h>
#include <irrList.h>
#include <irrArray.h>
#include <aabbox3d.h>
#ifndef SERVER
#include <SColor.h>
#include <IMesh.h>
#include <IImage.h>
#include <IrrlichtDevice.h>
#include <IMeshSceneNode.h>
#include <SMesh.h>
#include <ISceneManager.h>
#include <IMeshBuffer.h>
#include <SMeshBuffer.h>
#include <IGUIElement.h>
#include <IGUIEnvironment.h>
#endif
using namespace irr;
typedef core::vector3df v3f;
typedef core::vector3d<s16> v3s16;

View File

@@ -9,6 +9,8 @@
#ifdef USE_CMAKE_CONFIG_H
#include "cmake_config.h"
#else
#define PROJECT_NAME "minetest"
//#define INSTALL_PREFIX ""
#define VERSION_STRING "unknown"
#ifdef NDEBUG
@@ -21,8 +23,13 @@
#else
#define RUN_IN_PLACE_BOOLSTRING "0"
#endif
#define BUILD_INFO "NON-CMAKE RUN_IN_PLACE="RUN_IN_PLACE_BOOLSTRING" BUILD_TYPE="BUILD_TYPE
#endif
#if USE_GETTEXT
#define USE_GETTEXT_BOOLSTRING "1"
#else
#define USE_GETTEXT_BOOLSTRING "0"
#endif
#define BUILD_INFO "NON-CMAKE RUN_IN_PLACE="RUN_IN_PLACE_BOOLSTRING" USE_GETTEXT="USE_GETTEXT_BOOLSTRING" BUILD_TYPE="BUILD_TYPE
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -319,28 +319,6 @@ struct Channel
{
Channel();
~Channel();
/*
Processes a packet with the basic header stripped out.
Parameters:
packetdata: Data in packet (with no base headers)
con: The connection to which the channel is associated
(used for sending back stuff (ACKs))
peer_id: peer id of the sender of the packet in question
channelnum: channel on which the packet was sent
reliable: true if recursing into a reliable packet
*/
SharedBuffer<u8> ProcessPacket(
SharedBuffer<u8> packetdata,
Connection *con,
u16 peer_id,
u8 channelnum,
bool reliable=false);
// Returns next data from a buffer if possible
// throws a NoIncomingDataException if no data is available
// If found, sets peer_id
SharedBuffer<u8> CheckIncomingBuffers(Connection *con,
u16 &peer_id);
u16 next_outgoing_seqnum;
u16 next_incoming_seqnum;
@@ -412,78 +390,237 @@ class Peer
// with the id we have given to it
bool has_sent_with_id;
float m_sendtime_accu;
float m_max_packets_per_second;
int m_num_sent;
int m_max_num_sent;
private:
};
class Connection
/*
Connection
*/
struct OutgoingPacket
{
u16 peer_id;
u8 channelnum;
SharedBuffer<u8> data;
bool reliable;
OutgoingPacket(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_,
bool reliable_):
peer_id(peer_id_),
channelnum(channelnum_),
data(data_),
reliable(reliable_)
{
}
};
enum ConnectionEventType{
CONNEVENT_NONE,
CONNEVENT_DATA_RECEIVED,
CONNEVENT_PEER_ADDED,
CONNEVENT_PEER_REMOVED,
};
struct ConnectionEvent
{
enum ConnectionEventType type;
u16 peer_id;
SharedBuffer<u8> data;
bool timeout;
Address address;
ConnectionEvent(): type(CONNEVENT_NONE) {}
std::string describe()
{
switch(type){
case CONNEVENT_NONE:
return "CONNEVENT_NONE";
case CONNEVENT_DATA_RECEIVED:
return "CONNEVENT_DATA_RECEIVED";
case CONNEVENT_PEER_ADDED:
return "CONNEVENT_PEER_ADDED";
case CONNEVENT_PEER_REMOVED:
return "CONNEVENT_PEER_REMOVED";
}
return "Invalid ConnectionEvent";
}
void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
{
type = CONNEVENT_DATA_RECEIVED;
peer_id = peer_id_;
data = data_;
}
void peerAdded(u16 peer_id_, Address address_)
{
type = CONNEVENT_PEER_ADDED;
peer_id = peer_id_;
address = address_;
}
void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
{
type = CONNEVENT_PEER_REMOVED;
peer_id = peer_id_;
timeout = timeout_;
address = address_;
}
};
enum ConnectionCommandType{
CONNCMD_NONE,
CONNCMD_SERVE,
CONNCMD_CONNECT,
CONNCMD_DISCONNECT,
CONNCMD_SEND,
CONNCMD_SEND_TO_ALL,
CONNCMD_DELETE_PEER,
};
struct ConnectionCommand
{
enum ConnectionCommandType type;
u16 port;
Address address;
u16 peer_id;
u8 channelnum;
SharedBuffer<u8> data;
bool reliable;
ConnectionCommand(): type(CONNCMD_NONE) {}
void serve(u16 port_)
{
type = CONNCMD_SERVE;
port = port_;
}
void connect(Address address_)
{
type = CONNCMD_CONNECT;
address = address_;
}
void disconnect()
{
type = CONNCMD_DISCONNECT;
}
void send(u16 peer_id_, u8 channelnum_,
SharedBuffer<u8> data_, bool reliable_)
{
type = CONNCMD_SEND;
peer_id = peer_id_;
channelnum = channelnum_;
data = data_;
reliable = reliable_;
}
void sendToAll(u8 channelnum_, SharedBuffer<u8> data_, bool reliable_)
{
type = CONNCMD_SEND_TO_ALL;
channelnum = channelnum_;
data = data_;
reliable = reliable_;
}
void deletePeer(u16 peer_id_)
{
type = CONNCMD_DELETE_PEER;
peer_id = peer_id_;
}
};
class Connection: public SimpleThread
{
public:
Connection(
u32 protocol_id,
u32 max_packet_size,
float timeout,
PeerHandler *peerhandler
);
Connection(u32 protocol_id, u32 max_packet_size, float timeout);
Connection(u32 protocol_id, u32 max_packet_size, float timeout,
PeerHandler *peerhandler);
~Connection();
void setTimeoutMs(int timeout){ m_socket.setTimeoutMs(timeout); }
// Start being a server
void * Thread();
/* Interface */
ConnectionEvent getEvent();
ConnectionEvent waitEvent(u32 timeout_ms);
void putCommand(ConnectionCommand &c);
void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; }
void Serve(unsigned short port);
// Connect to a server
void Connect(Address address);
bool Connected();
void Disconnect();
// Sets peer_id
SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
// The peer_id of sender is stored in peer_id
// Return value: I guess this always throws an exception or
// actually gets data
// May call PeerHandler methods
u32 Receive(u16 &peer_id, u8 *data, u32 datasize);
// These will automatically package the data as an original or split
void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
// Send data as a packet; it will be wrapped in base header and
// optionally to a reliable packet.
void SendAsPacket(u16 peer_id, u8 channelnum,
SharedBuffer<u8> data, bool reliable);
// Sends a raw packet
void RawSend(const BufferedPacket &packet);
// May call PeerHandler methods
void RunTimeouts(float dtime);
// Can throw a PeerNotFoundException
Peer* GetPeer(u16 peer_id);
// returns NULL if failed
Peer* GetPeerNoEx(u16 peer_id);
core::list<Peer*> GetPeers();
// Calls PeerHandler::deletingPeer
// Returns false if peer was not found
bool deletePeer(u16 peer_id, bool timeout);
void SetPeerID(u16 id){ m_peer_id = id; }
void RunTimeouts(float dtime); // dummy
u16 GetPeerID(){ return m_peer_id; }
u32 GetProtocolID(){ return m_protocol_id; }
Address GetPeerAddress(u16 peer_id);
float GetPeerAvgRTT(u16 peer_id);
void DeletePeer(u16 peer_id);
private:
void putEvent(ConnectionEvent &e);
void processCommand(ConnectionCommand &c);
void send(float dtime);
void receive();
void runTimeouts(float dtime);
void serve(u16 port);
void connect(Address address);
void disconnect();
void sendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
void sendAsPacket(u16 peer_id, u8 channelnum,
SharedBuffer<u8> data, bool reliable);
void rawSendAsPacket(u16 peer_id, u8 channelnum,
SharedBuffer<u8> data, bool reliable);
void rawSend(const BufferedPacket &packet);
Peer* getPeer(u16 peer_id);
Peer* getPeerNoEx(u16 peer_id);
core::list<Peer*> getPeers();
bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
// Returns next data from a buffer if possible
// If found, returns true; if not, false.
// If found, sets peer_id and dst
bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
SharedBuffer<u8> &dst);
/*
Processes a packet with the basic header stripped out.
Parameters:
packetdata: Data in packet (with no base headers)
peer_id: peer id of the sender of the packet in question
channelnum: channel on which the packet was sent
reliable: true if recursing into a reliable packet
*/
SharedBuffer<u8> processPacket(Channel *channel,
SharedBuffer<u8> packetdata, u16 peer_id,
u8 channelnum, bool reliable);
bool deletePeer(u16 peer_id, bool timeout);
Queue<OutgoingPacket> m_outgoing_queue;
MutexedQueue<ConnectionEvent> m_event_queue;
MutexedQueue<ConnectionCommand> m_command_queue;
u32 m_protocol_id;
u32 m_max_packet_size;
float m_timeout;
UDPSocket m_socket;
u16 m_peer_id;
core::map<u16, Peer*> m_peers;
JMutex m_peers_mutex;
// For debug printing
// Backwards compatibility
PeerHandler *m_bc_peerhandler;
int m_bc_receive_timeout;
void SetPeerID(u16 id){ m_peer_id = id; }
u32 GetProtocolID(){ return m_protocol_id; }
void PrintInfo(std::ostream &out);
void PrintInfo();
std::string getDesc();
u16 m_indentation;
private:
u32 m_protocol_id;
float m_timeout;
PeerHandler *m_peerhandler;
core::map<u16, Peer*> m_peers;
u16 m_peer_id;
//bool m_waiting_new_peer_id;
u32 m_max_packet_size;
UDPSocket m_socket;
};
} // namespace

View File

@@ -28,13 +28,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//#define HAXMODE 0
#define APPNAME "minetest"
#define DEBUGFILE "debug.txt"
#define WATER_ALPHA 160
//#define WATER_ALPHA 190
// Define for simulating the quirks of sending through internet.
// Causes the socket class to deliberately drop random packets.
// This disables unit testing of socket and connection.
@@ -49,9 +44,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PI 3.14159
// This is the same as in minecraft and everything else
#define FOV_ANGLE (PI/2.5)
// The absolute working limit is (2^15 - viewing_range).
// I really don't want to make every algorithm to check if it's
// going near the limit or not, so this is lower.

View File

@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_cao.h"
#include "tile.h"
#include "environment.h"
#include "settings.h"
#include <ICameraSceneNode.h>
core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
@@ -114,7 +116,7 @@ void TestCAO::step(float dtime, ClientEnvironment *env)
if(m_node)
{
v3f rot = m_node->getRotation();
//dstream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
//infostream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
rot.Y += dtime * 180;
m_node->setRotation(rot);
}
@@ -122,7 +124,7 @@ void TestCAO::step(float dtime, ClientEnvironment *env)
void TestCAO::processMessage(const std::string &data)
{
dstream<<"TestCAO: Got data: "<<data<<std::endl;
infostream<<"TestCAO: Got data: "<<data<<std::endl;
std::istringstream is(data, std::ios::binary);
u16 cmd;
is>>cmd;
@@ -206,6 +208,35 @@ void ItemCAO::addToScene(scene::ISceneManager *smgr)
// This is needed for changing the texture in the future
m_node->setReadOnlyMaterials(true);
updateNodePos();
/*
Update image of node
*/
// Create an inventory item to see what is its image
std::istringstream is(m_inventorystring, std::ios_base::binary);
video::ITexture *texture = NULL;
try{
InventoryItem *item = NULL;
item = InventoryItem::deSerialize(is);
infostream<<__FUNCTION_NAME<<": m_inventorystring=\""
<<m_inventorystring<<"\" -> item="<<item
<<std::endl;
if(item)
{
texture = item->getImage();
delete item;
}
}
catch(SerializationError &e)
{
infostream<<"WARNING: "<<__FUNCTION_NAME
<<": error deSerializing inventorystring \""
<<m_inventorystring<<"\""<<std::endl;
}
// Set meshbuffer texture
buf->getMaterial().setTexture(0, texture);
}
void ItemCAO::removeFromScene()
@@ -224,22 +255,7 @@ void ItemCAO::updateLight(u8 light_at_pos)
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
scene::IMesh *mesh = m_node->getMesh();
if(mesh == NULL)
return;
u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Color = color;
}
}
setMeshVerticesColor(m_node->getMesh(), color);
}
v3s16 ItemCAO::getLightPosition()
@@ -272,7 +288,7 @@ void ItemCAO::step(float dtime, ClientEnvironment *env)
void ItemCAO::processMessage(const std::string &data)
{
dstream<<"ItemCAO: Got message"<<std::endl;
infostream<<"ItemCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
@@ -286,7 +302,7 @@ void ItemCAO::processMessage(const std::string &data)
void ItemCAO::initialize(const std::string &data)
{
dstream<<"ItemCAO: Got init data"<<std::endl;
infostream<<"ItemCAO: Got init data"<<std::endl;
{
std::istringstream is(data, std::ios::binary);
@@ -302,49 +318,6 @@ void ItemCAO::initialize(const std::string &data)
}
updateNodePos();
/*
Update image of node
*/
if(m_node == NULL)
return;
scene::IMesh *mesh = m_node->getMesh();
if(mesh == NULL)
return;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
if(buf == NULL)
return;
// Create an inventory item to see what is its image
std::istringstream is(m_inventorystring, std::ios_base::binary);
video::ITexture *texture = NULL;
try{
InventoryItem *item = NULL;
item = InventoryItem::deSerialize(is);
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
<<m_inventorystring<<"\" -> item="<<item
<<std::endl;
if(item)
{
texture = item->getImage();
delete item;
}
}
catch(SerializationError &e)
{
dstream<<"WARNING: "<<__FUNCTION_NAME
<<": error deSerializing inventorystring \""
<<m_inventorystring<<"\""<<std::endl;
}
// Set meshbuffer texture
buf->getMaterial().setTexture(0, texture);
}
/*
@@ -430,22 +403,7 @@ void RatCAO::updateLight(u8 light_at_pos)
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
scene::IMesh *mesh = m_node->getMesh();
if(mesh == NULL)
return;
u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Color = color;
}
}
setMeshVerticesColor(m_node->getMesh(), color);
}
v3s16 RatCAO::getLightPosition()
@@ -474,7 +432,7 @@ void RatCAO::step(float dtime, ClientEnvironment *env)
void RatCAO::processMessage(const std::string &data)
{
//dstream<<"RatCAO: Got message"<<std::endl;
//infostream<<"RatCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
@@ -491,7 +449,7 @@ void RatCAO::processMessage(const std::string &data)
void RatCAO::initialize(const std::string &data)
{
//dstream<<"RatCAO: Got init data"<<std::endl;
//infostream<<"RatCAO: Got init data"<<std::endl;
{
std::istringstream is(data, std::ios::binary);
@@ -601,22 +559,7 @@ void Oerkki1CAO::updateLight(u8 light_at_pos)
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
scene::IMesh *mesh = m_node->getMesh();
if(mesh == NULL)
return;
u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Color = color;
}
}
setMeshVerticesColor(m_node->getMesh(), color);
}
v3s16 Oerkki1CAO::getLightPosition()
@@ -649,7 +592,7 @@ void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
v2f playerpos_2d(playerpos.X,playerpos.Z);
v2f objectpos_2d(m_position.X,m_position.Z);
if(fabs(m_position.Y - playerpos.Y) < 3.0*BS &&
if(fabs(m_position.Y - playerpos.Y) < 1.5*BS &&
objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
{
if(m_attack_interval.step(dtime, 0.5))
@@ -713,7 +656,7 @@ void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
void Oerkki1CAO::processMessage(const std::string &data)
{
//dstream<<"Oerkki1CAO: Got message"<<std::endl;
//infostream<<"Oerkki1CAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
@@ -728,14 +671,14 @@ void Oerkki1CAO::processMessage(const std::string &data)
}
else if(cmd == 1)
{
u16 damage = readU8(is);
//u16 damage = readU8(is);
m_damage_visual_timer = 1.0;
}
}
void Oerkki1CAO::initialize(const std::string &data)
{
//dstream<<"Oerkki1CAO: Got init data"<<std::endl;
//infostream<<"Oerkki1CAO: Got init data"<<std::endl;
{
std::istringstream is(data, std::ios::binary);
@@ -752,6 +695,18 @@ void Oerkki1CAO::initialize(const std::string &data)
updateNodePos();
}
bool Oerkki1CAO::directReportPunch(const std::string &toolname, v3f dir)
{
m_damage_visual_timer = 1.0;
m_position += dir * BS;
pos_translator.sharpen();
pos_translator.update(m_position);
updateNodePos();
return false;
}
/*
FireflyCAO
*/
@@ -833,22 +788,7 @@ void FireflyCAO::updateLight(u8 light_at_pos)
u8 li = 255;
video::SColor color(255,li,li,li);
scene::IMesh *mesh = m_node->getMesh();
if(mesh == NULL)
return;
u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++)
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
u16 vc = buf->getVertexCount();
for(u16 i=0; i<vc; i++)
{
vertices[i].Color = color;
}
}
setMeshVerticesColor(m_node->getMesh(), color);
}
v3s16 FireflyCAO::getLightPosition()
@@ -877,7 +817,7 @@ void FireflyCAO::step(float dtime, ClientEnvironment *env)
void FireflyCAO::processMessage(const std::string &data)
{
//dstream<<"FireflyCAO: Got message"<<std::endl;
//infostream<<"FireflyCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
@@ -894,7 +834,7 @@ void FireflyCAO::processMessage(const std::string &data)
void FireflyCAO::initialize(const std::string &data)
{
//dstream<<"FireflyCAO: Got init data"<<std::endl;
//infostream<<"FireflyCAO: Got init data"<<std::endl;
{
std::istringstream is(data, std::ios::binary);
@@ -910,3 +850,417 @@ void FireflyCAO::initialize(const std::string &data)
updateNodePos();
}
/*
MobV2CAO
*/
// Prototype
MobV2CAO proto_MobV2CAO;
MobV2CAO::MobV2CAO():
ClientActiveObject(0),
m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
m_node(NULL),
m_position(v3f(0,10*BS,0)),
m_yaw(0),
m_walking(false),
m_walking_unset_timer(0),
m_walk_timer(0),
m_walk_frame(0),
m_damage_visual_timer(0),
m_last_light(0),
m_shooting(0),
m_shooting_unset_timer(0),
m_sprite_size(BS,BS),
m_sprite_y(0),
m_bright_shooting(false),
m_lock_full_brightness(false),
m_player_hit_timer(0)
{
ClientActiveObject::registerType(getType(), create);
m_properties = new Settings;
}
MobV2CAO::~MobV2CAO()
{
delete m_properties;
}
ClientActiveObject* MobV2CAO::create()
{
return new MobV2CAO();
}
void MobV2CAO::addToScene(scene::ISceneManager *smgr)
{
if(m_node != NULL)
return;
/*infostream<<"MobV2CAO::addToScene using texture_name="<<
m_texture_name<<std::endl;*/
std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
texture_string += m_texture_name;
scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
bill->setMaterialTexture(0, g_texturesource->getTextureRaw(texture_string));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
bill->setColor(video::SColor(255,0,0,0));
bill->setVisible(false); /* Set visible when brightness is known */
bill->setSize(m_sprite_size);
if(m_sprite_type == "humanoid_1"){
const float txp = 1./192;
const float txs = txp*32;
const float typ = 1./240;
const float tys = typ*48;
bill->setTCoords(0, v2f(txs*1, tys*1));
bill->setTCoords(1, v2f(txs*1, tys*0));
bill->setTCoords(2, v2f(txs*0, tys*0));
bill->setTCoords(3, v2f(txs*0, tys*1));
} else if(m_sprite_type == "simple"){
const float txs = 1.0;
const float tys = 1.0 / m_simple_anim_frames;
bill->setTCoords(0, v2f(txs*1, tys*1));
bill->setTCoords(1, v2f(txs*1, tys*0));
bill->setTCoords(2, v2f(txs*0, tys*0));
bill->setTCoords(3, v2f(txs*0, tys*1));
} else {
infostream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
<<std::endl;
}
m_node = bill;
updateNodePos();
}
void MobV2CAO::removeFromScene()
{
if(m_node == NULL)
return;
m_node->drop();
m_node->remove();
m_node = NULL;
}
void MobV2CAO::updateLight(u8 light_at_pos)
{
if(m_lock_full_brightness)
light_at_pos = 15;
m_last_light = light_at_pos;
if(m_node == NULL)
return;
if(m_damage_visual_timer > 0)
return;
if(m_shooting && m_bright_shooting)
return;
/*if(light_at_pos <= 2){
m_node->setVisible(false);
return;
}*/
m_node->setVisible(true);
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
m_node->setColor(color);
}
v3s16 MobV2CAO::getLightPosition()
{
return floatToInt(m_position+v3f(0,0,0), BS);
}
void MobV2CAO::updateNodePos()
{
if(m_node == NULL)
return;
m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
}
void MobV2CAO::step(float dtime, ClientEnvironment *env)
{
scene::MyBillboardSceneNode *bill = m_node;
if(!bill)
return;
pos_translator.translate(dtime);
if(m_sprite_type == "humanoid_1"){
scene::ICameraSceneNode* camera = m_node->getSceneManager()->getActiveCamera();
if(!camera)
return;
v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
cam_to_mob.normalize();
int col = 0;
if(cam_to_mob.Y > 0.75)
col = 5;
else if(cam_to_mob.Y < -0.75)
col = 4;
else{
float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / PI * 180.;
float dir = mob_dir - m_yaw;
dir = wrapDegrees_180(dir);
//infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
col = 2;
else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
col = 3;
else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
col = 0;
else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
col = 1;
else
col = 4;
}
int row = 0;
if(m_shooting){
row = 3;
} else if(m_walking){
m_walk_timer += dtime;
if(m_walk_timer >= 0.5){
m_walk_frame = (m_walk_frame + 1) % 2;
m_walk_timer = 0;
}
if(m_walk_frame == 0)
row = 1;
else
row = 2;
}
const float txp = 1./192;
const float txs = txp*32;
const float typ = 1./240;
const float tys = typ*48;
bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
} else if(m_sprite_type == "simple"){
m_walk_timer += dtime;
if(m_walk_timer >= m_simple_anim_frametime){
m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
m_walk_timer = 0;
}
int col = 0;
int row = m_walk_frame;
const float txs = 1.0;
const float tys = 1.0 / m_simple_anim_frames;
bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
} else {
infostream<<"MobV2CAO::step(): Unknown sprite type \""
<<m_sprite_type<<"\""<<std::endl;
}
updateNodePos();
/* Damage local player */
if(m_player_hit_damage && m_player_hit_timer <= 0.0){
LocalPlayer *player = env->getLocalPlayer();
assert(player);
v3f playerpos = player->getPosition();
v2f playerpos_2d(playerpos.X,playerpos.Z);
v2f objectpos_2d(m_position.X,m_position.Z);
if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
{
env->damageLocalPlayer(m_player_hit_damage);
m_player_hit_timer = m_player_hit_interval;
}
}
/* Run timers */
m_player_hit_timer -= dtime;
if(m_damage_visual_timer >= 0){
m_damage_visual_timer -= dtime;
if(m_damage_visual_timer <= 0){
infostream<<"id="<<m_id<<" damage visual ended"<<std::endl;
}
}
m_walking_unset_timer += dtime;
if(m_walking_unset_timer >= 1.0){
m_walking = false;
}
m_shooting_unset_timer -= dtime;
if(m_shooting_unset_timer <= 0.0){
if(m_bright_shooting){
u8 li = decode_light(m_last_light);
video::SColor color(255,li,li,li);
bill->setColor(color);
m_bright_shooting = false;
}
m_shooting = false;
}
}
void MobV2CAO::processMessage(const std::string &data)
{
//infostream<<"MobV2CAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
// Move
if(cmd == 0)
{
// pos
m_position = readV3F1000(is);
pos_translator.update(m_position);
// yaw
m_yaw = readF1000(is);
m_walking = true;
m_walking_unset_timer = 0;
updateNodePos();
}
// Damage
else if(cmd == 1)
{
//u16 damage = readU16(is);
/*u8 li = decode_light(m_last_light);
if(li >= 100)
li = 30;
else
li = 255;*/
/*video::SColor color(255,255,0,0);
m_node->setColor(color);
m_damage_visual_timer = 0.2;*/
}
// Trigger shooting
else if(cmd == 2)
{
// length
m_shooting_unset_timer = readF1000(is);
// bright?
m_bright_shooting = readU8(is);
if(m_bright_shooting){
u8 li = 255;
video::SColor color(255,li,li,li);
m_node->setColor(color);
}
m_shooting = true;
}
}
void MobV2CAO::initialize(const std::string &data)
{
//infostream<<"MobV2CAO: Got init data"<<std::endl;
{
std::istringstream is(data, std::ios::binary);
// version
u8 version = readU8(is);
// check version
if(version != 0){
infostream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
return;
}
std::ostringstream tmp_os(std::ios::binary);
decompressZlib(is, tmp_os);
std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
infostream<<"MobV2CAO::initialize(): got properties:"<<std::endl;
m_properties->writeLines(infostream);
m_properties->setDefault("looks", "dummy_default");
m_properties->setDefault("yaw", "0");
m_properties->setDefault("pos", "(0,0,0)");
m_properties->setDefault("player_hit_damage", "0");
m_properties->setDefault("player_hit_distance", "1.5");
m_properties->setDefault("player_hit_interval", "1.5");
setLooks(m_properties->get("looks"));
m_yaw = m_properties->getFloat("yaw");
m_position = m_properties->getV3F("pos");
m_player_hit_damage = m_properties->getS32("player_hit_damage");
m_player_hit_distance = m_properties->getFloat("player_hit_distance");
m_player_hit_interval = m_properties->getFloat("player_hit_interval");
pos_translator.init(m_position);
}
updateNodePos();
}
bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
{
video::SColor color(255,255,0,0);
m_node->setColor(color);
m_damage_visual_timer = 0.05;
m_position += dir * BS;
pos_translator.sharpen();
pos_translator.update(m_position);
updateNodePos();
return false;
}
void MobV2CAO::setLooks(const std::string &looks)
{
v2f selection_size = v2f(0.4, 0.4) * BS;
float selection_y = 0 * BS;
if(looks == "dungeon_master"){
m_texture_name = "dungeon_master.png";
m_sprite_type = "humanoid_1";
m_sprite_size = v2f(2, 3) * BS;
m_sprite_y = 0.85 * BS;
selection_size = v2f(0.4, 2.6) * BS;
selection_y = -0.4 * BS;
}
else if(looks == "fireball"){
m_texture_name = "fireball.png";
m_sprite_type = "simple";
m_sprite_size = v2f(1, 1) * BS;
m_simple_anim_frames = 3;
m_simple_anim_frametime = 0.1;
m_lock_full_brightness = true;
}
else{
m_texture_name = "stone.png";
m_sprite_type = "simple";
m_sprite_size = v2f(1, 1) * BS;
m_simple_anim_frames = 3;
m_simple_anim_frametime = 0.333;
selection_size = v2f(0.4, 0.4) * BS;
selection_y = 0 * BS;
}
m_selection_box = core::aabbox3d<f32>(
-selection_size.X, selection_y, -selection_size.X,
selection_size.X, selection_y+selection_size.Y,
selection_size.X);
}

View File

@@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientobject.h"
#include "content_object.h"
#include "utility.h" // For IntervalLimiter
class Settings;
#include "MyBillboardSceneNode.h"
/*
SmoothTranslator
@@ -31,19 +33,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct SmoothTranslator
{
v3f vect_old;
v3f vect_show;
v3f vect_aim;
f32 anim_counter;
f32 anim_time;
f32 anim_time_counter;
v3f vect_show;
v3f vect_aim;
SmoothTranslator():
vect_old(0,0,0),
vect_show(0,0,0),
vect_aim(0,0,0),
anim_counter(0),
anim_time(0),
anim_time_counter(0),
vect_show(0,0,0),
vect_aim(0,0,0)
anim_time_counter(0)
{}
void init(v3f vect)
@@ -51,6 +53,14 @@ struct SmoothTranslator
vect_old = vect;
vect_show = vect;
vect_aim = vect;
anim_counter = 0;
anim_time = 0;
anim_time_counter = 0;
}
void sharpen()
{
init(vect_show);
}
void update(v3f vect_new)
@@ -74,11 +84,16 @@ struct SmoothTranslator
if(anim_time > 0.001)
moveratio = anim_time_counter / anim_time;
// Move a bit less than should, to avoid oscillation
moveratio = moveratio * 0.8;
moveratio = moveratio * 0.5;
if(moveratio > 1.5)
moveratio = 1.5;
vect_show = vect_old + vect_move * moveratio;
}
bool is_moving()
{
return ((anim_time_counter / anim_time) < 1.4);
}
};
@@ -233,6 +248,9 @@ class Oerkki1CAO : public ClientActiveObject
{return pos_translator.vect_show;}
//{return m_position;}
// If returns true, punch will not be sent to the server
bool directReportPunch(const std::string &toolname, v3f dir);
private:
IntervalLimiter m_attack_interval;
core::aabbox3d<f32> m_selection_box;
@@ -286,6 +304,78 @@ class FireflyCAO : public ClientActiveObject
SmoothTranslator pos_translator;
};
/*
MobV2CAO
*/
class MobV2CAO : public ClientActiveObject
{
public:
MobV2CAO();
virtual ~MobV2CAO();
u8 getType() const
{
return ACTIVEOBJECT_TYPE_MOBV2;
}
static ClientActiveObject* create();
void addToScene(scene::ISceneManager *smgr);
void removeFromScene();
void updateLight(u8 light_at_pos);
v3s16 getLightPosition();
void updateNodePos();
void step(float dtime, ClientEnvironment *env);
void processMessage(const std::string &data);
void initialize(const std::string &data);
core::aabbox3d<f32>* getSelectionBox()
{return &m_selection_box;}
v3f getPosition()
{return pos_translator.vect_show;}
//{return m_position;}
bool doShowSelectionBox(){return false;}
// If returns true, punch will not be sent to the server
bool directReportPunch(const std::string &toolname, v3f dir);
private:
void setLooks(const std::string &looks);
IntervalLimiter m_attack_interval;
core::aabbox3d<f32> m_selection_box;
scene::MyBillboardSceneNode *m_node;
v3f m_position;
std::string m_texture_name;
float m_yaw;
SmoothTranslator pos_translator;
bool m_walking;
float m_walking_unset_timer;
float m_walk_timer;
int m_walk_frame;
float m_damage_visual_timer;
u8 m_last_light;
bool m_shooting;
float m_shooting_unset_timer;
v2f m_sprite_size;
float m_sprite_y;
bool m_bright_shooting;
std::string m_sprite_type;
int m_simple_anim_frames;
float m_simple_anim_frametime;
bool m_lock_full_brightness;
int m_player_hit_damage;
float m_player_hit_distance;
float m_player_hit_interval;
float m_player_hit_timer;
Settings *m_properties;
};
#endif

View File

@@ -297,6 +297,24 @@ InventoryItem *craft_get_result(InventoryItem **items)
}
}
// Locking Chest
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[4] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
if(checkItemCombination(items, specs))
{
return new MaterialItem(CONTENT_LOCKABLE_CHEST, 1);
}
}
// Furnace
{
ItemSpec specs[9];
@@ -413,6 +431,36 @@ InventoryItem *craft_get_result(InventoryItem **items)
}
}
// Ladder
{
ItemSpec specs[9];
specs[0] = ItemSpec(ITEM_CRAFT, "Stick");
specs[2] = ItemSpec(ITEM_CRAFT, "Stick");
specs[3] = ItemSpec(ITEM_CRAFT, "Stick");
specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
specs[5] = ItemSpec(ITEM_CRAFT, "Stick");
specs[6] = ItemSpec(ITEM_CRAFT, "Stick");
specs[8] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
return new MaterialItem(CONTENT_LADDER, 1);
}
}
// Iron Apple
{
ItemSpec specs[9];
specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[4] = ItemSpec(ITEM_CRAFT, "apple");
specs[5] = ItemSpec(ITEM_CRAFT, "steel_ingot");
specs[7] = ItemSpec(ITEM_CRAFT, "steel_ingot");
if(checkItemCombination(items, specs))
{
return new CraftItem("apple_iron", 1);
}
}
return NULL;
}
@@ -470,6 +518,7 @@ void craft_set_creative_inventory(Player *player)
CONTENT_CHEST,
CONTENT_FURNACE,
CONTENT_SIGN_WALL,
CONTENT_LAVASOURCE,
CONTENT_IGNORE
};

View File

@@ -71,6 +71,10 @@ std::string item_craft_get_image_name(const std::string &subname)
return "scorched_stuff.png";
else if(subname == "firefly")
return "firefly.png";
else if(subname == "apple")
return "apple.png^[forcesingle";
else if(subname == "apple_iron")
return "apple_iron.png";
else
return "cloud.png"; // just something
}
@@ -126,6 +130,10 @@ bool item_craft_is_eatable(const std::string &subname)
{
if(subname == "cooked_rat")
return true;
else if(subname == "apple")
return true;
else if(subname == "apple_iron")
return true;
return false;
}
@@ -133,6 +141,10 @@ s16 item_craft_eat_hp_change(const std::string &subname)
{
if(subname == "cooked_rat")
return 6; // 3 hearts
else if(subname == "apple")
return 4; // 2 hearts
else if(subname == "apple_iron")
return 8; // 4 hearts
return 0;
}

View File

@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h" // For g_settings and g_texturesource
#include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor()
#include "settings.h"
#ifndef SERVER
// Create a cuboid.
@@ -128,32 +129,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Some settings
*/
bool new_style_water = g_settings.getBool("new_style_water");
bool new_style_leaves = g_settings.getBool("new_style_leaves");
//bool smooth_lighting = g_settings.getBool("smooth_lighting");
bool invisible_stone = g_settings.getBool("invisible_stone");
bool new_style_water = g_settings->getBool("new_style_water");
bool new_style_leaves = g_settings->getBool("new_style_leaves");
//bool smooth_lighting = g_settings->getBool("smooth_lighting");
bool invisible_stone = g_settings->getBool("invisible_stone");
float node_water_level = 1.0;
float node_liquid_level = 1.0;
if(new_style_water)
node_water_level = 0.85;
node_liquid_level = 0.85;
v3s16 blockpos_nodes = data->m_blockpos*MAP_BLOCKSIZE;
// Flowing water material
video::SMaterial material_water1;
material_water1.setFlag(video::EMF_LIGHTING, false);
material_water1.setFlag(video::EMF_BACK_FACE_CULLING, false);
material_water1.setFlag(video::EMF_BILINEAR_FILTER, false);
material_water1.setFlag(video::EMF_FOG_ENABLE, true);
material_water1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
AtlasPointer pa_water1 = g_texturesource->getTexture(
g_texturesource->getTextureId("water.png"));
material_water1.setTexture(0, pa_water1.atlas);
// New-style leaves material
video::SMaterial material_leaves1;
material_leaves1.setFlag(video::EMF_LIGHTING, false);
//material_leaves1.setFlag(video::EMF_BACK_FACE_CULLING, false);
material_leaves1.setFlag(video::EMF_BILINEAR_FILTER, false);
material_leaves1.setFlag(video::EMF_FOG_ENABLE, true);
material_leaves1.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
@@ -199,6 +188,28 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer pa_papyrus = g_texturesource->getTexture(
g_texturesource->getTextureId("papyrus.png"));
material_papyrus.setTexture(0, pa_papyrus.atlas);
// Apple material
video::SMaterial material_apple;
material_apple.setFlag(video::EMF_LIGHTING, false);
material_apple.setFlag(video::EMF_BILINEAR_FILTER, false);
material_apple.setFlag(video::EMF_FOG_ENABLE, true);
material_apple.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
AtlasPointer pa_apple = g_texturesource->getTexture(
g_texturesource->getTextureId("apple.png"));
material_apple.setTexture(0, pa_apple.atlas);
// Sapling material
video::SMaterial material_sapling;
material_sapling.setFlag(video::EMF_LIGHTING, false);
material_sapling.setFlag(video::EMF_BILINEAR_FILTER, false);
material_sapling.setFlag(video::EMF_FOG_ENABLE, true);
material_sapling.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
AtlasPointer pa_sapling = g_texturesource->getTexture(
g_texturesource->getTextureId("sapling.png"));
material_sapling.setTexture(0, pa_sapling.atlas);
// junglegrass material
video::SMaterial material_junglegrass;
@@ -217,25 +228,54 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 p(x,y,z);
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes+p);
/*
Add torches to mesh
*/
if(n.getContent() == CONTENT_TORCH)
{
v3s16 dir = unpackDir(n.param2);
const char *texturename = "torch.png";
if(dir == v3s16(0,-1,0)){
texturename = "torch_on_floor.png";
} else if(dir == v3s16(0,1,0)){
texturename = "torch_on_ceiling.png";
// For backwards compatibility
} else if(dir == v3s16(0,0,0)){
texturename = "torch_on_floor.png";
} else {
texturename = "torch.png";
}
AtlasPointer ap = g_texturesource->getTexture(texturename);
// Set material
video::SMaterial material;
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BACK_FACE_CULLING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setFlag(video::EMF_FOG_ENABLE, true);
//material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0, ap.atlas);
video::SColor c(255,255,255,255);
// Wall at X+ of node
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,-BS/2,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),
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
ap.x0(), ap.y1()),
video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
ap.x1(), ap.y1()),
video::S3DVertex(BS/2,BS/2,0, 0,0,0, c,
ap.x1(), ap.y0()),
video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c,
ap.x0(), ap.y0()),
};
v3s16 dir = unpackDir(n.param2);
for(s32 i=0; i<4; i++)
{
if(dir == v3s16(1,0,0))
@@ -254,29 +294,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
// Set material
video::SMaterial material;
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BACK_FACE_CULLING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
//material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
if(dir == v3s16(0,-1,0))
material.setTexture(0,
g_texturesource->getTextureRaw("torch_on_floor.png"));
else if(dir == v3s16(0,1,0))
material.setTexture(0,
g_texturesource->getTextureRaw("torch_on_ceiling.png"));
// For backwards compatibility
else if(dir == v3s16(0,0,0))
material.setTexture(0,
g_texturesource->getTextureRaw("torch_on_floor.png"));
else
material.setTexture(0,
g_texturesource->getTextureRaw("torch.png"));
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material, vertices, 4, indices, 6);
@@ -286,6 +303,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/
else if(n.getContent() == CONTENT_SIGN_WALL)
{
AtlasPointer ap = g_texturesource->getTexture("sign_wall.png");
// Set material
video::SMaterial material;
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BACK_FACE_CULLING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setFlag(video::EMF_FOG_ENABLE, true);
material.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0, ap.atlas);
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c = MapBlock_LightColor(255, l);
@@ -293,10 +322,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// Wall at X+ of node
video::S3DVertex vertices[4] =
{
video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, 1,0),
video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 0,0),
video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c,
ap.x0(), ap.y1()),
video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c,
ap.x1(), ap.y1()),
video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c,
ap.x1(), ap.y0()),
video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c,
ap.x0(), ap.y0()),
};
v3s16 dir = unpackDir(n.param2);
@@ -319,48 +352,45 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
// Set material
video::SMaterial material;
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BACK_FACE_CULLING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setFlag(video::EMF_FOG_ENABLE, true);
//material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0,
g_texturesource->getTextureRaw("sign_wall.png"));
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material, vertices, 4, indices, 6);
}
/*
Add flowing water to mesh
Add flowing liquid to mesh
*/
else if(n.getContent() == CONTENT_WATER)
else if(content_features(n).liquid_type == LIQUID_FLOWING)
{
bool top_is_water = false;
assert(content_features(n).special_material);
video::SMaterial &liquid_material =
*content_features(n).special_material;
assert(content_features(n).special_atlas);
AtlasPointer &pa_liquid1 =
*content_features(n).special_atlas;
bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
if(ntop.getContent() == CONTENT_WATER || ntop.getContent() == CONTENT_WATERSOURCE)
top_is_water = true;
content_t c_flowing = content_features(n).liquid_alternative_flowing;
content_t c_source = content_features(n).liquid_alternative_source;
if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
top_is_same_liquid = true;
u8 l = 0;
// Use the light of the node on top if possible
if(content_features(ntop).param_type == CPT_LIGHT)
l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
// Otherwise use the light of this node (the water)
// Otherwise use the light of this node (the liquid)
else
l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c = MapBlock_LightColor(WATER_ALPHA, l);
video::SColor c = MapBlock_LightColor(
content_features(n).vertex_alpha, l);
// Neighbor water levels (key = relative position)
// Neighbor liquid levels (key = relative position)
// Includes current node
core::map<v3s16, f32> neighbor_levels;
core::map<v3s16, content_t> neighbor_contents;
core::map<v3s16, u8> neighbor_flags;
const u8 neighborflag_top_is_water = 0x01;
const u8 neighborflag_top_is_same_liquid = 0x01;
v3s16 neighbor_dirs[9] = {
v3s16(0,0,0),
v3s16(0,0,1),
@@ -374,7 +404,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
};
for(u32 i=0; i<9; i++)
{
u8 content = CONTENT_AIR;
content_t content = CONTENT_AIR;
float level = -0.5 * BS;
u8 flags = 0;
// Check neighbor
@@ -384,19 +414,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
{
content = n2.getContent();
if(n2.getContent() == CONTENT_WATERSOURCE)
level = (-0.5+node_water_level) * BS;
else if(n2.getContent() == CONTENT_WATER)
level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
* node_water_level) * BS;
if(n2.getContent() == c_source)
level = (-0.5+node_liquid_level) * BS;
else if(n2.getContent() == c_flowing)
level = (-0.5 + ((float)(n2.param2&LIQUID_LEVEL_MASK)
+ 0.5) / 8.0 * node_liquid_level) * BS;
// Check node above neighbor.
// NOTE: This doesn't get executed if neighbor
// doesn't exist
p2.Y += 1;
n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
if(n2.getContent() == CONTENT_WATERSOURCE || n2.getContent() == CONTENT_WATER)
flags |= neighborflag_top_is_water;
if(n2.getContent() == c_source ||
n2.getContent() == c_flowing)
flags |= neighborflag_top_is_same_liquid;
}
neighbor_levels.insert(neighbor_dirs[i], level);
@@ -404,10 +435,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
neighbor_flags.insert(neighbor_dirs[i], flags);
}
//float water_level = (-0.5 + ((float)n.param2 + 0.5) / 8.0) * BS;
//float water_level = neighbor_levels[v3s16(0,0,0)];
// Corner heights (average between four waters)
// Corner heights (average between four liquids)
f32 corner_levels[4];
v3s16 halfdirs[4] = {
@@ -421,29 +449,40 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 cornerdir = halfdirs[i];
float cornerlevel = 0;
u32 valid_count = 0;
u32 air_count = 0;
for(u32 j=0; j<4; j++)
{
v3s16 neighbordir = cornerdir - halfdirs[j];
u8 content = neighbor_contents[neighbordir];
// Special case for source nodes
if(content == CONTENT_WATERSOURCE)
content_t content = neighbor_contents[neighbordir];
// If top is liquid, draw starting from top of node
if(neighbor_flags[neighbordir] &
neighborflag_top_is_same_liquid)
{
cornerlevel = (-0.5+node_water_level)*BS;
cornerlevel = 0.5*BS;
valid_count = 1;
break;
}
else if(content == CONTENT_WATER)
// Source is always the same height
else if(content == c_source)
{
cornerlevel = (-0.5+node_liquid_level)*BS;
valid_count = 1;
break;
}
// Flowing liquid has level information
else if(content == c_flowing)
{
cornerlevel += neighbor_levels[neighbordir];
valid_count++;
}
else if(content == CONTENT_AIR)
{
cornerlevel += -0.5*BS;
valid_count++;
air_count++;
}
}
if(valid_count > 0)
if(air_count >= 2)
cornerlevel = -0.5*BS;
else if(valid_count > 0)
cornerlevel /= valid_count;
corner_levels[i] = cornerlevel;
}
@@ -469,47 +508,46 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 dir = side_dirs[i];
/*
If our topside is water and neighbor's topside
is water, don't draw side face
If our topside is liquid and neighbor's topside
is liquid, don't draw side face
*/
if(top_is_water &&
neighbor_flags[dir] & neighborflag_top_is_water)
if(top_is_same_liquid &&
neighbor_flags[dir] & neighborflag_top_is_same_liquid)
continue;
u8 neighbor_content = neighbor_contents[dir];
content_t neighbor_content = neighbor_contents[dir];
// Don't draw face if neighbor is not air or water
// Don't draw face if neighbor is not air or liquid
if(neighbor_content != CONTENT_AIR
&& neighbor_content != CONTENT_WATER)
&& content_liquid(neighbor_content) == false)
continue;
bool neighbor_is_water = (neighbor_content == CONTENT_WATER);
bool neighbor_is_same_liquid = (neighbor_content == c_source
|| neighbor_content == c_flowing);
// Don't draw any faces if neighbor is water and top is water
if(neighbor_is_water == true && top_is_water == false)
// Don't draw any faces if neighbor same is liquid and top is
// same liquid
if(neighbor_is_same_liquid == true
&& top_is_same_liquid == false)
continue;
video::S3DVertex vertices[4] =
{
/*video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
pa_water1.x0(), pa_water1.y1()),
pa_liquid1.x0(), pa_liquid1.y1()),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
pa_water1.x1(), pa_water1.y1()),
pa_liquid1.x1(), pa_liquid1.y1()),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
pa_water1.x1(), pa_water1.y0()),
pa_liquid1.x1(), pa_liquid1.y0()),
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
pa_water1.x0(), pa_water1.y0()),
pa_liquid1.x0(), pa_liquid1.y0()),
};
/*
If our topside is water, set upper border of face
If our topside is liquid, set upper border of face
at upper border of node
*/
if(top_is_water)
if(top_is_same_liquid)
{
vertices[2].Pos.Y = 0.5*BS;
vertices[3].Pos.Y = 0.5*BS;
@@ -524,16 +562,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
/*
If neighbor is water, lower border of face is corner
water levels
If neighbor is liquid, lower border of face is corner
liquid levels
*/
if(neighbor_is_water)
if(neighbor_is_same_liquid)
{
vertices[0].Pos.Y = corner_levels[side_corners[i][1]];
vertices[1].Pos.Y = corner_levels[side_corners[i][0]];
}
/*
If neighbor is not water, lower border of face is
If neighbor is not liquid, lower border of face is
lower border of node
*/
else
@@ -552,35 +590,38 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
vertices[j].Pos.rotateXZBy(90);
if(dir == v3s16(1,0,-0))
vertices[j].Pos.rotateXZBy(-90);
// Do this to not cause glitches when two liquids are
// side-by-side
if(neighbor_is_same_liquid == false){
vertices[j].Pos.X *= 0.98;
vertices[j].Pos.Z *= 0.98;
}
vertices[j].Pos += intToFloat(p + blockpos_nodes, BS);
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_water1, vertices, 4, indices, 6);
collector.append(liquid_material, vertices, 4, indices, 6);
}
/*
Generate top side, if appropriate
*/
if(top_is_water == false)
if(top_is_same_liquid == false)
{
video::S3DVertex vertices[4] =
{
/*video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
pa_water1.x0(), pa_water1.y1()),
pa_liquid1.x0(), pa_liquid1.y1()),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
pa_water1.x1(), pa_water1.y1()),
pa_liquid1.x1(), pa_liquid1.y1()),
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
pa_water1.x1(), pa_water1.y0()),
pa_liquid1.x1(), pa_liquid1.y0()),
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
pa_water1.x0(), pa_water1.y0()),
pa_liquid1.x0(), pa_liquid1.y0()),
};
// This fixes a strange bug
@@ -588,7 +629,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
for(s32 i=0; i<4; i++)
{
//vertices[i].Pos.Y += water_level;
//vertices[i].Pos.Y += liquid_level;
//vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)];
s32 j = corner_resolve[i];
vertices[i].Pos.Y += corner_levels[j];
@@ -597,55 +638,55 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_water1, vertices, 4, indices, 6);
collector.append(liquid_material, vertices, 4, indices, 6);
}
}
/*
Add water sources to mesh if using new style
*/
else if(n.getContent() == CONTENT_WATERSOURCE && new_style_water)
else if(content_features(n).liquid_type == LIQUID_SOURCE
&& new_style_water)
{
//bool top_is_water = false;
assert(content_features(n).special_material);
video::SMaterial &liquid_material =
*content_features(n).special_material;
assert(content_features(n).special_atlas);
AtlasPointer &pa_liquid1 =
*content_features(n).special_atlas;
bool top_is_air = false;
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
/*if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
top_is_water = true;*/
if(n.getContent() == CONTENT_AIR)
top_is_air = true;
/*if(top_is_water == true)
continue;*/
if(top_is_air == false)
continue;
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c = MapBlock_LightColor(WATER_ALPHA, l);
video::SColor c = MapBlock_LightColor(
content_features(n).vertex_alpha, l);
video::S3DVertex vertices[4] =
{
/*video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
pa_water1.x0(), pa_water1.y1()),
pa_liquid1.x0(), pa_liquid1.y1()),
video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
pa_water1.x1(), pa_water1.y1()),
pa_liquid1.x1(), pa_liquid1.y1()),
video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
pa_water1.x1(), pa_water1.y0()),
pa_liquid1.x1(), pa_liquid1.y0()),
video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
pa_water1.x0(), pa_water1.y0()),
pa_liquid1.x0(), pa_liquid1.y0()),
};
for(s32 i=0; i<4; i++)
{
vertices[i].Pos.Y += (-0.5+node_water_level)*BS;
vertices[i].Pos.Y += (-0.5+node_liquid_level)*BS;
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_water1, vertices, 4, indices, 6);
collector.append(liquid_material, vertices, 4, indices, 6);
}
/*
Add leaves if using new style
@@ -660,10 +701,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
{
video::S3DVertex vertices[4] =
{
/*video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, 0,0),*/
video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
pa_leaves1.x0(), pa_leaves1.y1()),
video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
@@ -882,10 +919,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
video::S3DVertex vertices[4] =
{
/*video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, 0,0),*/
video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
ap.x0(), ap.y1()),
video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
@@ -989,13 +1022,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
pa_papyrus.x0(), pa_papyrus.y1()),
pa_junglegrass.x0(), pa_junglegrass.y1()),
video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
pa_papyrus.x1(), pa_papyrus.y1()),
pa_junglegrass.x1(), pa_junglegrass.y1()),
video::S3DVertex(BS/2,BS/1,0, 0,0,0, c,
pa_papyrus.x1(), pa_papyrus.y0()),
pa_junglegrass.x1(), pa_junglegrass.y0()),
video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c,
pa_papyrus.x0(), pa_papyrus.y0()),
pa_junglegrass.x0(), pa_junglegrass.y0()),
};
if(j == 0)
@@ -1032,9 +1065,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
else if(n.getContent() == CONTENT_RAIL)
{
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c = MapBlock_LightColor(255, l);
bool is_rail_x [] = { false, false }; /* x-1, x+1 */
bool is_rail_z [] = { false, false }; /* z-1, z+1 */
@@ -1052,18 +1082,25 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
if(n_plus_z.getContent() == CONTENT_RAIL)
is_rail_z[1] = true;
float d = (float)BS/16;
video::S3DVertex vertices[4] =
int adjacencies = is_rail_x[0] + is_rail_x[1] + is_rail_z[0] + is_rail_z[1];
// Assign textures
const char *texturename = "rail.png";
if(adjacencies < 2)
texturename = "rail.png";
else if(adjacencies == 2)
{
video::S3DVertex(-BS/2,-BS/2+d,-BS/2, 0,0,0, c,
0, 1),
video::S3DVertex(BS/2,-BS/2+d,-BS/2, 0,0,0, c,
1, 1),
video::S3DVertex(BS/2,-BS/2+d,BS/2, 0,0,0, c,
1, 0),
video::S3DVertex(-BS/2,-BS/2+d,BS/2, 0,0,0, c,
0, 0),
};
if((is_rail_x[0] && is_rail_x[1]) || (is_rail_z[0] && is_rail_z[1]))
texturename = "rail.png";
else
texturename = "rail_curved.png";
}
else if(adjacencies == 3)
texturename = "rail_t_junction.png";
else if(adjacencies == 4)
texturename = "rail_crossing.png";
AtlasPointer ap = g_texturesource->getTexture(texturename);
video::SMaterial material_rail;
material_rail.setFlag(video::EMF_LIGHTING, false);
@@ -1072,23 +1109,23 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
material_rail.setFlag(video::EMF_FOG_ENABLE, true);
material_rail.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_rail.setTexture(0, ap.atlas);
int adjacencies = is_rail_x[0] + is_rail_x[1] + is_rail_z[0] + is_rail_z[1];
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c = MapBlock_LightColor(255, l);
// Assign textures
if(adjacencies < 2)
material_rail.setTexture(0, g_texturesource->getTextureRaw("rail.png"));
else if(adjacencies == 2)
float d = (float)BS/16;
video::S3DVertex vertices[4] =
{
if((is_rail_x[0] && is_rail_x[1]) || (is_rail_z[0] && is_rail_z[1]))
material_rail.setTexture(0, g_texturesource->getTextureRaw("rail.png"));
else
material_rail.setTexture(0, g_texturesource->getTextureRaw("rail_curved.png"));
}
else if(adjacencies == 3)
material_rail.setTexture(0, g_texturesource->getTextureRaw("rail_t_junction.png"));
else if(adjacencies == 4)
material_rail.setTexture(0, g_texturesource->getTextureRaw("rail_crossing.png"));
video::S3DVertex(-BS/2,-BS/2+d,-BS/2, 0,0,0, c,
ap.x0(), ap.y1()),
video::S3DVertex(BS/2,-BS/2+d,-BS/2, 0,0,0, c,
ap.x1(), ap.y1()),
video::S3DVertex(BS/2,-BS/2+d,BS/2, 0,0,0, c,
ap.x1(), ap.y0()),
video::S3DVertex(-BS/2,-BS/2+d,BS/2, 0,0,0, c,
ap.x0(), ap.y0()),
};
// Rotate textures
int angle = 0;
@@ -1134,6 +1171,159 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
u16 indices[] = {0,1,2,2,3,0};
collector.append(material_rail, vertices, 4, indices, 6);
}
else if (n.getContent() == CONTENT_LADDER) {
AtlasPointer ap = g_texturesource->getTexture("ladder.png");
// Set material
video::SMaterial material_ladder;
material_ladder.setFlag(video::EMF_LIGHTING, false);
material_ladder.setFlag(video::EMF_BACK_FACE_CULLING, false);
material_ladder.setFlag(video::EMF_BILINEAR_FILTER, false);
material_ladder.setFlag(video::EMF_FOG_ENABLE, true);
material_ladder.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_ladder.setTexture(0, ap.atlas);
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(255,l,l,l);
float d = (float)BS/16;
// Assume wall is at X+
video::S3DVertex vertices[4] =
{
video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c,
ap.x0(), ap.y1()),
video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c,
ap.x1(), ap.y1()),
video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c,
ap.x1(), ap.y0()),
video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c,
ap.x0(), ap.y0()),
};
v3s16 dir = unpackDir(n.param2);
for(s32 i=0; i<4; i++)
{
if(dir == v3s16(1,0,0))
vertices[i].Pos.rotateXZBy(0);
if(dir == v3s16(-1,0,0))
vertices[i].Pos.rotateXZBy(180);
if(dir == v3s16(0,0,1))
vertices[i].Pos.rotateXZBy(90);
if(dir == v3s16(0,0,-1))
vertices[i].Pos.rotateXZBy(-90);
if(dir == v3s16(0,-1,0))
vertices[i].Pos.rotateXYBy(-90);
if(dir == v3s16(0,1,0))
vertices[i].Pos.rotateXYBy(90);
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_ladder, vertices, 4, indices, 6);
}
else if(n.getContent() == CONTENT_APPLE)
{
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
{
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
pa_apple.x0(), pa_apple.y1()),
video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
pa_apple.x1(), pa_apple.y1()),
video::S3DVertex(BS/2,BS/2,0, 0,0,0, c,
pa_apple.x1(), pa_apple.y0()),
video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c,
pa_apple.x0(), pa_apple.y0()),
};
if(j == 0)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(45);
}
else if(j == 1)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(-45);
}
else if(j == 2)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(135);
}
else if(j == 3)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(-135);
}
for(u16 i=0; i<4; i++)
{
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_apple, vertices, 4, indices, 6);
}
}
else if(n.getContent() == CONTENT_SAPLING) {
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
{
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
pa_sapling.x0(), pa_sapling.y1()),
video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
pa_sapling.x1(), pa_sapling.y1()),
video::S3DVertex(BS/2,BS/1,0, 0,0,0, c,
pa_sapling.x1(), pa_sapling.y0()),
video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c,
pa_sapling.x0(), pa_sapling.y0()),
};
if(j == 0)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(45);
}
else if(j == 1)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(-45);
}
else if(j == 2)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(135);
}
else if(j == 3)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(-135);
}
for(u16 i=0; i<4; i++)
{
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_sapling, vertices, 4, indices, 6);
}
}
}
}
#endif

View File

@@ -23,6 +23,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_mapnode.h"
#include "mapnode.h"
#include "content_nodemeta.h"
#include "settings.h"
#define WATER_ALPHA 160
#define WATER_VISC 1
#define LAVA_VISC 7
// TODO: Get rid of these and set up some attributes like toughness,
// fluffyness, and a funciton to calculate time and durability loss
@@ -31,6 +37,11 @@ void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness)
void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
void setWoodLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
/*
A conversion table for backwards compatibility.
Maps <=v19 content types to current ones.
Should never be touched.
*/
content_t trans_table_19[21][2] = {
{CONTENT_GRASS, 1},
{CONTENT_TREE, 4},
@@ -93,9 +104,9 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
void content_mapnode_init()
{
// Read some settings
bool new_style_water = g_settings.getBool("new_style_water");
bool new_style_leaves = g_settings.getBool("new_style_leaves");
bool invisible_stone = g_settings.getBool("invisible_stone");
bool new_style_water = g_settings->getBool("new_style_water");
bool new_style_leaves = g_settings->getBool("new_style_leaves");
bool invisible_stone = g_settings->getBool("invisible_stone");
content_t i;
ContentFeatures *f = NULL;
@@ -106,6 +117,7 @@ void content_mapnode_init()
f->setInventoryTextureCube("stone.png", "stone.png", "stone.png");
f->param_type = CPT_MINERAL;
f->is_ground_content = true;
f->often_contains_mineral = true;
f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1";
setStoneLikeDiggingProperties(f->digging_properties, 1.0);
if(invisible_stone)
@@ -208,6 +220,7 @@ void content_mapnode_init()
i = CONTENT_JUNGLEGRASS;
f = &content_features(i);
f->setInventoryTexture("junglegrass.png");
f->used_texturenames["junglegrass.png"] = true;
f->light_propagates = true;
f->param_type = CPT_LIGHT;
//f->is_ground_content = true;
@@ -226,12 +239,16 @@ void content_mapnode_init()
if(new_style_leaves)
{
f->solidness = 0; // drawn separately, makes no faces
f->visual_solidness = 1;
f->setAllTextures("leaves.png");
f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png");
}
else
{
f->setAllTextures("[noalpha:leaves.png");
}
f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1";
f->extra_dug_item_rarity = 20;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
setWoodLikeDiggingProperties(f->digging_properties, 0.15);
@@ -249,6 +266,7 @@ void content_mapnode_init()
i = CONTENT_PAPYRUS;
f = &content_features(i);
f->setInventoryTexture("papyrus.png");
f->used_texturenames["papyrus.png"] = true;
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
@@ -277,6 +295,8 @@ void content_mapnode_init()
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->solidness = 0; // drawn separately, makes no faces
f->visual_solidness = 1;
f->setAllTextures("glass.png");
f->setInventoryTextureCube("glass.png", "glass.png", "glass.png");
setWoodLikeDiggingProperties(f->digging_properties, 0.15);
@@ -288,12 +308,14 @@ void content_mapnode_init()
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->solidness = 0; // drawn separately, makes no faces
f->air_equivalent = true; // grass grows underneath
f->setInventoryTexture("item_fence.png");
f->setInventoryTexture("fence.png");
f->used_texturenames["fence.png"] = true;
setWoodLikeDiggingProperties(f->digging_properties, 0.75);
i = CONTENT_RAIL;
f = &content_features(i);
f->setInventoryTexture("rail.png");
f->used_texturenames["rail.png"] = true;
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
@@ -303,6 +325,21 @@ void content_mapnode_init()
f->walkable = false;
setDirtLikeDiggingProperties(f->digging_properties, 0.75);
i = CONTENT_LADDER;
f = &content_features(i);
f->setInventoryTexture("ladder.png");
f->used_texturenames["ladder.png"] = true;
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
f->wall_mounted = true;
f->solidness = 0;
f->air_equivalent = true;
f->walkable = false;
f->climbable = true;
setWoodLikeDiggingProperties(f->digging_properties, 0.5);
// Deprecated
i = CONTENT_COALSTONE;
f = &content_features(i);
@@ -351,6 +388,7 @@ void content_mapnode_init()
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->solidness = 0; // Drawn separately, makes no faces
f->visual_solidness = 1;
f->walkable = false;
f->pointable = false;
f->diggable = false;
@@ -358,6 +396,25 @@ void content_mapnode_init()
f->liquid_type = LIQUID_FLOWING;
f->liquid_alternative_flowing = CONTENT_WATER;
f->liquid_alternative_source = CONTENT_WATERSOURCE;
f->liquid_viscosity = WATER_VISC;
#ifndef SERVER
f->vertex_alpha = WATER_ALPHA;
f->post_effect_color = video::SColor(64, 100, 100, 200);
if(f->special_material == NULL && g_texturesource)
{
// Flowing water material
f->special_material = new video::SMaterial;
f->special_material->setFlag(video::EMF_LIGHTING, false);
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
g_texturesource->getTextureId("water.png")));
f->special_material->setTexture(0, pa_water1->atlas);
f->special_atlas = pa_water1;
}
#endif
i = CONTENT_WATERSOURCE;
f = &content_features(i);
@@ -370,7 +427,7 @@ void content_mapnode_init()
else // old style
{
f->solidness = 1;
#ifndef SERVER
TileSpec t;
if(g_texturesource)
t.texture = g_texturesource->getTexture("water.png");
@@ -379,6 +436,7 @@ void content_mapnode_init()
t.material_type = MATERIAL_ALPHA_VERTEX;
t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
f->setAllTiles(t);
#endif
}
f->param_type = CPT_LIGHT;
f->light_propagates = true;
@@ -390,10 +448,124 @@ void content_mapnode_init()
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->liquid_alternative_flowing = CONTENT_WATER;
f->liquid_alternative_source = CONTENT_WATERSOURCE;
f->liquid_viscosity = WATER_VISC;
#ifndef SERVER
f->vertex_alpha = WATER_ALPHA;
f->post_effect_color = video::SColor(64, 100, 100, 200);
if(f->special_material == NULL && g_texturesource)
{
// Flowing water material
f->special_material = new video::SMaterial;
f->special_material->setFlag(video::EMF_LIGHTING, false);
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
g_texturesource->getTextureId("water.png")));
f->special_material->setTexture(0, pa_water1->atlas);
f->special_atlas = pa_water1;
}
#endif
i = CONTENT_LAVA;
f = &content_features(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png");
f->used_texturenames["lava.png"] = true;
f->param_type = CPT_LIGHT;
f->light_propagates = false;
f->light_source = LIGHT_MAX-1;
f->solidness = 0; // Drawn separately, makes no faces
f->visual_solidness = 2;
f->walkable = false;
f->pointable = false;
f->diggable = false;
f->buildable_to = true;
f->liquid_type = LIQUID_FLOWING;
f->liquid_alternative_flowing = CONTENT_LAVA;
f->liquid_alternative_source = CONTENT_LAVASOURCE;
f->liquid_viscosity = LAVA_VISC;
f->damage_per_second = 4*2;
#ifndef SERVER
f->post_effect_color = video::SColor(192, 255, 64, 0);
if(f->special_material == NULL && g_texturesource)
{
// Flowing lava material
f->special_material = new video::SMaterial;
f->special_material->setFlag(video::EMF_LIGHTING, false);
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
AtlasPointer *pa_lava1 = new AtlasPointer(
g_texturesource->getTexture(
g_texturesource->getTextureId("lava.png")));
f->special_material->setTexture(0, pa_lava1->atlas);
f->special_atlas = pa_lava1;
}
#endif
i = CONTENT_LAVASOURCE;
f = &content_features(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png");
f->used_texturenames["ladder.png"] = true;
if(new_style_water)
{
f->solidness = 0; // drawn separately, makes no faces
}
else // old style
{
f->solidness = 2;
#ifndef SERVER
TileSpec t;
if(g_texturesource)
t.texture = g_texturesource->getTexture("lava.png");
//t.alpha = 255;
//t.material_type = MATERIAL_ALPHA_VERTEX;
//t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
f->setAllTiles(t);
#endif
}
f->param_type = CPT_LIGHT;
f->light_propagates = false;
f->light_source = LIGHT_MAX-1;
f->walkable = false;
f->pointable = false;
f->diggable = false;
f->buildable_to = true;
f->liquid_type = LIQUID_SOURCE;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->liquid_alternative_flowing = CONTENT_LAVA;
f->liquid_alternative_source = CONTENT_LAVASOURCE;
f->liquid_viscosity = LAVA_VISC;
f->damage_per_second = 4*2;
#ifndef SERVER
f->post_effect_color = video::SColor(192, 255, 64, 0);
if(f->special_material == NULL && g_texturesource)
{
// Flowing lava material
f->special_material = new video::SMaterial;
f->special_material->setFlag(video::EMF_LIGHTING, false);
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
AtlasPointer *pa_lava1 = new AtlasPointer(
g_texturesource->getTexture(
g_texturesource->getTextureId("lava.png")));
f->special_material->setTexture(0, pa_lava1->atlas);
f->special_atlas = pa_lava1;
}
#endif
i = CONTENT_TORCH;
f = &content_features(i);
f->setInventoryTexture("torch_on_floor.png");
f->used_texturenames["torch_on_floor.png"] = true;
f->used_texturenames["torch_on_ceiling.png"] = true;
f->used_texturenames["torch_on_floor.png"] = true;
f->used_texturenames["torch.png"] = true;
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
@@ -408,6 +580,7 @@ void content_mapnode_init()
i = CONTENT_SIGN_WALL;
f = &content_features(i);
f->setInventoryTexture("sign_wall.png");
f->used_texturenames["sign_wall.png"] = true;
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
@@ -434,6 +607,20 @@ void content_mapnode_init()
f->initial_metadata = new ChestNodeMetadata();
setWoodLikeDiggingProperties(f->digging_properties, 1.0);
i = CONTENT_LOCKABLE_CHEST;
f = &content_features(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures("chest_side.png");
f->setTexture(0, "chest_top.png");
f->setTexture(1, "chest_top.png");
f->setTexture(5, "chest_lock.png"); // Z-
f->setInventoryTexture("chest_lock.png");
//f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png");
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
if(f->initial_metadata == NULL)
f->initial_metadata = new LockingChestNodeMetadata();
setWoodLikeDiggingProperties(f->digging_properties, 1.0);
i = CONTENT_FURNACE;
f = &content_features(i);
f->param_type = CPT_FACEDIR_SIMPLE;
@@ -490,6 +677,32 @@ void content_mapnode_init()
f->setInventoryTexture("nc_rb.png");
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
setStoneLikeDiggingProperties(f->digging_properties, 3.0);
i = CONTENT_SAPLING;
f = &content_features(i);
f->param_type = CPT_LIGHT;
f->setAllTextures("sapling.png");
f->setInventoryTexture("sapling.png");
f->used_texturenames["sapling.png"] = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->light_propagates = true;
f->air_equivalent = false;
f->solidness = 0; // drawn separately, makes no faces
f->walkable = false;
f->digging_properties.set("", DiggingProperties(true, 0.0, 0));
i = CONTENT_APPLE;
f = &content_features(i);
f->setInventoryTexture("apple.png");
f->used_texturenames["apple.png"] = true;
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
f->solidness = 0; // drawn separately, makes no faces
f->walkable = false;
f->air_equivalent = true;
f->dug_item = std::string("CraftItem apple 1");
f->digging_properties.set("", DiggingProperties(true, 0.0, 0));
// NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp

View File

@@ -37,15 +37,25 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
// 0x000...0x07f (0...127): param2 is fully usable
// 126 and 127 are reserved.
// Use these sparingly, only when the extra space in param2 might be needed.
// Add a space when there is unused space between numbers.
#define CONTENT_STONE 0
#define CONTENT_WATER 2
#define CONTENT_TORCH 3
#define CONTENT_WATERSOURCE 9
#define CONTENT_SIGN_WALL 14
#define CONTENT_CHEST 15
#define CONTENT_FURNACE 16
#define CONTENT_LOCKABLE_CHEST 17
#define CONTENT_FENCE 21
#define CONTENT_RAIL 30
#define CONTENT_LADDER 31
#define CONTENT_LAVA 32
#define CONTENT_LAVASOURCE 33
// 0x800...0xfff (2048...4095): higher 4 bytes of param2 are not usable
#define CONTENT_GRASS 0x800 //1
@@ -74,7 +84,8 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
#define CONTENT_JUNGLEGRASS 0x816
#define CONTENT_NC 0x817
#define CONTENT_NC_RB 0x818
#define CONTENT_APPLE 0x819
#define CONTENT_SAPLING 0x820
#endif

View File

@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_nodemeta.h"
#include "inventory.h"
#include "content_mapnode.h"
#include "log.h"
/*
SignNodeMetadata
@@ -117,6 +118,70 @@ std::string ChestNodeMetadata::getInventoryDrawSpecString()
"list[current_player;main;0,5;8,4;]";
}
/*
LockingChestNodeMetadata
*/
// Prototype
LockingChestNodeMetadata proto_LockingChestNodeMetadata;
LockingChestNodeMetadata::LockingChestNodeMetadata()
{
NodeMetadata::registerType(typeId(), create);
m_inventory = new Inventory();
m_inventory->addList("0", 8*4);
}
LockingChestNodeMetadata::~LockingChestNodeMetadata()
{
delete m_inventory;
}
u16 LockingChestNodeMetadata::typeId() const
{
return CONTENT_LOCKABLE_CHEST;
}
NodeMetadata* LockingChestNodeMetadata::create(std::istream &is)
{
LockingChestNodeMetadata *d = new LockingChestNodeMetadata();
d->setOwner(deSerializeString(is));
d->m_inventory->deSerialize(is);
return d;
}
NodeMetadata* LockingChestNodeMetadata::clone()
{
LockingChestNodeMetadata *d = new LockingChestNodeMetadata();
*d->m_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
*/
@@ -178,31 +243,57 @@ std::string FurnaceNodeMetadata::infoText()
//return "Furnace";
if(m_fuel_time >= m_fuel_totaltime)
{
InventoryList *src_list = m_inventory->getList("src");
const InventoryList *src_list = m_inventory->getList("src");
assert(src_list);
InventoryItem *src_item = src_list->getItem(0);
const InventoryItem *src_item = src_list->getItem(0);
if(src_item)
if(src_item && src_item->isCookable()) {
InventoryList *dst_list = m_inventory->getList("dst");
if(!dst_list->roomForCookedItem(src_item))
return "Furnace is overloaded";
return "Furnace is out of fuel";
}
else
return "Furnace is inactive";
}
else
{
std::string s = "Furnace is active (";
s += itos(m_fuel_time/m_fuel_totaltime*100);
s += "%)";
std::string s = "Furnace is active";
// Do this so it doesn't always show (0%) for weak fuel
if(m_fuel_totaltime > 3) {
s += " (";
s += itos(m_fuel_time/m_fuel_totaltime*100);
s += "%)";
}
return s;
}
}
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()
{
dstream<<"Furnace inventory modification callback"<<std::endl;
infostream<<"Furnace inventory modification callback"<<std::endl;
}
bool FurnaceNodeMetadata::step(float dtime)
{
if(dtime > 60.0)
dstream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
@@ -212,7 +303,7 @@ bool FurnaceNodeMetadata::step(float dtime)
m_step_accumulator -= interval;
dtime = interval;
//dstream<<"Furnace step dtime="<<dtime<<std::endl;
//infostream<<"Furnace step dtime="<<dtime<<std::endl;
InventoryList *dst_list = m_inventory->getList("dst");
assert(dst_list);
@@ -221,9 +312,14 @@ bool FurnaceNodeMetadata::step(float dtime)
assert(src_list);
InventoryItem *src_item = src_list->getItem(0);
bool room_available = false;
if(src_item && src_item->isCookable())
room_available = dst_list->roomForCookedItem(src_item);
// Start only if there are free slots in dst, so that it can
// accomodate any result item
if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable())
if(room_available)
{
m_src_totaltime = 3;
}
@@ -239,7 +335,7 @@ bool FurnaceNodeMetadata::step(float dtime)
*/
if(m_fuel_time < m_fuel_totaltime)
{
//dstream<<"Furnace is active"<<std::endl;
//infostream<<"Furnace is active"<<std::endl;
m_fuel_time += dtime;
m_src_time += dtime;
if(m_src_time >= m_src_totaltime && m_src_totaltime > 0.001
@@ -252,23 +348,33 @@ bool FurnaceNodeMetadata::step(float dtime)
m_src_totaltime = 0;
}
changed = true;
continue;
// If the fuel was not used up this step, just keep burning it
if(m_fuel_time < m_fuel_totaltime)
continue;
}
/*
If there is no source item or source item is not cookable, stop loop.
Get the source again in case it has all burned
*/
if(src_item == NULL || m_src_totaltime < 0.001)
src_item = src_list->getItem(0);
/*
If there is no source item, or the source item is not cookable,
or the furnace is still cooking, or the furnace became overloaded, stop loop.
*/
if(src_item == NULL || !room_available || m_fuel_time < m_fuel_totaltime ||
dst_list->roomForCookedItem(src_item) == false)
{
m_step_accumulator = 0;
break;
}
//dstream<<"Furnace is out of fuel"<<std::endl;
//infostream<<"Furnace is out of fuel"<<std::endl;
InventoryList *fuel_list = m_inventory->getList("fuel");
assert(fuel_list);
InventoryItem *fuel_item = fuel_list->getItem(0);
const InventoryItem *fuel_item = fuel_list->getItem(0);
if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item))
{
@@ -349,7 +455,7 @@ bool FurnaceNodeMetadata::step(float dtime)
}
else
{
//dstream<<"No fuel found"<<std::endl;
//infostream<<"No fuel found"<<std::endl;
// No fuel, stop loop.
m_step_accumulator = 0;
break;

View File

@@ -62,6 +62,29 @@ class ChestNodeMetadata : public NodeMetadata
Inventory *m_inventory;
};
class LockingChestNodeMetadata : public NodeMetadata
{
public:
LockingChestNodeMetadata();
~LockingChestNodeMetadata();
virtual u16 typeId() const;
static NodeMetadata* create(std::istream &is);
virtual NodeMetadata* clone();
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:
@@ -76,6 +99,7 @@ class FurnaceNodeMetadata : public NodeMetadata
virtual Inventory* getInventory() {return m_inventory;}
virtual void inventoryModified();
virtual bool step(float dtime);
virtual bool nodeRemovalDisabled();
virtual std::string getInventoryDrawSpecString();
private:

View File

@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define ACTIVEOBJECT_TYPE_RAT 3
#define ACTIVEOBJECT_TYPE_OERKKI1 4
#define ACTIVEOBJECT_TYPE_FIREFLY 5
#define ACTIVEOBJECT_TYPE_MOBV2 6
#endif

View File

@@ -20,9 +20,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_sao.h"
#include "collision.h"
#include "environment.h"
#include "settings.h"
#include "profiler.h"
core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
/* Some helper functions */
// Y is copied, X and Z change is limited
void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase)
{
v3f d_wanted = target_speed - speed;
d_wanted.Y = 0;
f32 dl_wanted = d_wanted.getLength();
f32 dl = dl_wanted;
if(dl > max_increase)
dl = max_increase;
v3f d = d_wanted.normalize() * dl;
speed.X += d.X;
speed.Z += d.Z;
speed.Y = target_speed.Y;
}
/*
TestSAO
*/
@@ -64,7 +85,6 @@ void TestSAO::step(float dtime, bool send_recommended)
if(m_timer1 < 0.0)
{
m_timer1 += 0.125;
//dstream<<"TestSAO: id="<<getId()<<" sending data"<<std::endl;
std::string data;
@@ -111,13 +131,15 @@ ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
if(version != 0)
return NULL;
std::string inventorystring = deSerializeString(is);
dstream<<"ItemSAO::create(): Creating item \""
infostream<<"ItemSAO::create(): Creating item \""
<<inventorystring<<"\""<<std::endl;
return new ItemSAO(env, id, pos, inventorystring);
}
void ItemSAO::step(float dtime, bool send_recommended)
{
ScopeProfiler sp2(g_profiler, "ItemSAO::step avg", SPT_AVG);
assert(m_env);
const float interval = 0.2;
@@ -186,7 +208,7 @@ std::string ItemSAO::getClientInitializationData()
std::string ItemSAO::getStaticData()
{
dstream<<__FUNCTION_NAME<<std::endl;
infostream<<__FUNCTION_NAME<<std::endl;
std::ostringstream os(std::ios::binary);
char buf[1];
// version
@@ -202,14 +224,14 @@ InventoryItem * ItemSAO::createInventoryItem()
try{
std::istringstream is(m_inventorystring, std::ios_base::binary);
InventoryItem *item = InventoryItem::deSerialize(is);
dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
infostream<<__FUNCTION_NAME<<": m_inventorystring=\""
<<m_inventorystring<<"\" -> item="<<item
<<std::endl;
return item;
}
catch(SerializationError &e)
{
dstream<<__FUNCTION_NAME<<": serialization error: "
infostream<<__FUNCTION_NAME<<": serialization error: "
<<"m_inventorystring=\""<<m_inventorystring<<"\""<<std::endl;
return NULL;
}
@@ -217,7 +239,7 @@ InventoryItem * ItemSAO::createInventoryItem()
void ItemSAO::rightClick(Player *player)
{
dstream<<__FUNCTION_NAME<<std::endl;
infostream<<__FUNCTION_NAME<<std::endl;
InventoryItem *item = createInventoryItem();
if(item == NULL)
return;
@@ -226,6 +248,11 @@ void ItemSAO::rightClick(Player *player)
if(to_be_deleted)
m_removed = true;
else
// Reflect changes to the item here
m_inventorystring = item->getItemString();
delete item;
}
/*
@@ -267,6 +294,8 @@ ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
void RatSAO::step(float dtime, bool send_recommended)
{
ScopeProfiler sp2(g_profiler, "RatSAO::step avg", SPT_AVG);
assert(m_env);
if(m_is_active == false)
@@ -399,7 +428,7 @@ std::string RatSAO::getClientInitializationData()
std::string RatSAO::getStaticData()
{
//dstream<<__FUNCTION_NAME<<std::endl;
//infostream<<__FUNCTION_NAME<<std::endl;
std::ostringstream os(std::ios::binary);
// version
writeU8(os, 0);
@@ -417,23 +446,6 @@ InventoryItem* RatSAO::createPickedUpItem()
Oerkki1SAO
*/
// Y is copied, X and Z change is limited
void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase)
{
v3f d_wanted = target_speed - speed;
d_wanted.Y = 0;
f32 dl_wanted = d_wanted.getLength();
f32 dl = dl_wanted;
if(dl > max_increase)
dl = max_increase;
v3f d = d_wanted.normalize() * dl;
speed.X += d.X;
speed.Z += d.Z;
speed.Y = target_speed.Y;
}
// Prototype
Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0));
@@ -473,6 +485,8 @@ ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
void Oerkki1SAO::step(float dtime, bool send_recommended)
{
ScopeProfiler sp2(g_profiler, "Oerkki1SAO::step avg", SPT_AVG);
assert(m_env);
if(m_is_active == false)
@@ -515,13 +529,14 @@ void Oerkki1SAO::step(float dtime, bool send_recommended)
Player *player = *i;
v3f playerpos = player->getPosition();
f32 dist = m_base_position.getDistanceFrom(playerpos);
if(dist < BS*1.45)
if(dist < BS*0.6)
{
m_removed = true;
return;
player_is_too_close = true;
near_player_pos = playerpos;
break;
}
else if(dist < BS*15.0)
else if(dist < BS*15.0 && !player_is_too_close)
{
player_is_close = true;
near_player_pos = playerpos;
@@ -612,7 +627,7 @@ void Oerkki1SAO::step(float dtime, bool send_recommended)
m_touching_ground = moveresult.touching_ground;
// Do collision damage
float tolerance = BS*12;
float tolerance = BS*30;
float factor = BS*0.5;
v3f speed_diff = old_speed - m_speed_f;
// Increase effect in X and Z
@@ -660,7 +675,7 @@ std::string Oerkki1SAO::getClientInitializationData()
std::string Oerkki1SAO::getStaticData()
{
//dstream<<__FUNCTION_NAME<<std::endl;
//infostream<<__FUNCTION_NAME<<std::endl;
std::ostringstream os(std::ios::binary);
// version
writeU8(os, 0);
@@ -669,18 +684,32 @@ std::string Oerkki1SAO::getStaticData()
return os.str();
}
u16 Oerkki1SAO::punch(const std::string &toolname, v3f dir)
u16 Oerkki1SAO::punch(const std::string &toolname, v3f dir,
const std::string &playername)
{
m_speed_f += dir*12*BS;
u16 amount = 5;
/* See tool names in inventory.h */
if(toolname == "WSword")
amount = 10;
if(toolname == "STSword")
amount = 12;
if(toolname == "SteelSword")
amount = 16;
if(toolname == "STAxe")
amount = 7;
if(toolname == "SteelAxe")
amount = 9;
if(toolname == "SteelPick")
amount = 7;
doDamage(amount);
return 65536/100;
}
void Oerkki1SAO::doDamage(u16 d)
{
dstream<<"oerkki damage: "<<d<<std::endl;
infostream<<"oerkki damage: "<<d<<std::endl;
if(d < m_hp)
{
@@ -744,6 +773,8 @@ ServerActiveObject* FireflySAO::create(ServerEnvironment *env, u16 id, v3f pos,
void FireflySAO::step(float dtime, bool send_recommended)
{
ScopeProfiler sp2(g_profiler, "FireflySAO::step avg", SPT_AVG);
assert(m_env);
if(m_is_active == false)
@@ -868,7 +899,7 @@ std::string FireflySAO::getClientInitializationData()
std::string FireflySAO::getStaticData()
{
//dstream<<__FUNCTION_NAME<<std::endl;
//infostream<<__FUNCTION_NAME<<std::endl;
std::ostringstream os(std::ios::binary);
// version
writeU8(os, 0);
@@ -881,3 +912,581 @@ InventoryItem* FireflySAO::createPickedUpItem()
InventoryItem *item = InventoryItem::deSerialize(is);
return item;
}
/*
MobV2SAO
*/
// Prototype
MobV2SAO proto_MobV2SAO(NULL, 0, v3f(0,0,0), NULL);
MobV2SAO::MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
Settings *init_properties):
ServerActiveObject(env, id, pos),
m_move_type("ground_nodes"),
m_speed(0,0,0),
m_last_sent_position(0,0,0),
m_oldpos(0,0,0),
m_yaw(0),
m_counter1(0),
m_counter2(0),
m_age(0),
m_touching_ground(false),
m_hp(10),
m_walk_around(false),
m_walk_around_timer(0),
m_next_pos_exists(false),
m_shoot_reload_timer(0),
m_shooting(false),
m_shooting_timer(0),
m_falling(false),
m_disturb_timer(100000),
m_random_disturb_timer(0),
m_shoot_y(0)
{
ServerActiveObject::registerType(getType(), create);
m_properties = new Settings();
if(init_properties)
m_properties->update(*init_properties);
m_properties->setV3F("pos", pos);
setPropertyDefaults();
readProperties();
}
MobV2SAO::~MobV2SAO()
{
delete m_properties;
}
ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, u16 id, v3f pos,
const std::string &data)
{
std::istringstream is(data, std::ios::binary);
Settings properties;
properties.parseConfigLines(is, "MobArgsEnd");
MobV2SAO *o = new MobV2SAO(env, id, pos, &properties);
return o;
}
std::string MobV2SAO::getStaticData()
{
updateProperties();
std::ostringstream os(std::ios::binary);
m_properties->writeLines(os);
return os.str();
}
std::string MobV2SAO::getClientInitializationData()
{
//infostream<<__FUNCTION_NAME<<std::endl;
updateProperties();
std::ostringstream os(std::ios::binary);
// version
writeU8(os, 0);
Settings client_properties;
/*client_properties.set("version", "0");
client_properties.updateValue(*m_properties, "pos");
client_properties.updateValue(*m_properties, "yaw");
client_properties.updateValue(*m_properties, "hp");*/
// Just send everything for simplicity
client_properties.update(*m_properties);
std::ostringstream os2(std::ios::binary);
client_properties.writeLines(os2);
compressZlib(os2.str(), os);
return os.str();
}
bool checkFreePosition(Map *map, v3s16 p0, v3s16 size)
{
for(int dx=0; dx<size.X; dx++)
for(int dy=0; dy<size.Y; dy++)
for(int dz=0; dz<size.Z; dz++){
v3s16 dp(dx, dy, dz);
v3s16 p = p0 + dp;
MapNode n = map->getNodeNoEx(p);
if(n.getContent() != CONTENT_AIR)
return false;
}
return true;
}
bool checkWalkablePosition(Map *map, v3s16 p0)
{
v3s16 p = p0 + v3s16(0,-1,0);
MapNode n = map->getNodeNoEx(p);
if(n.getContent() != CONTENT_AIR)
return true;
return false;
}
bool checkFreeAndWalkablePosition(Map *map, v3s16 p0, v3s16 size)
{
if(!checkFreePosition(map, p0, size))
return false;
if(!checkWalkablePosition(map, p0))
return false;
return true;
}
static void get_random_u32_array(u32 a[], u32 len)
{
u32 i, n;
for(i=0; i<len; i++)
a[i] = i;
n = len;
while(n > 1){
u32 k = myrand() % n;
n--;
u32 temp = a[n];
a[n] = a[k];
a[k] = temp;
}
}
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
static void explodeSquare(Map *map, v3s16 p0, v3s16 size)
{
core::map<v3s16, MapBlock*> modified_blocks;
for(int dx=0; dx<size.X; dx++)
for(int dy=0; dy<size.Y; dy++)
for(int dz=0; dz<size.Z; dz++){
v3s16 dp(dx - size.X/2, dy - size.Y/2, dz - size.Z/2);
v3s16 p = p0 + dp;
MapNode n = map->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE)
continue;
//map->removeNodeWithEvent(p);
map->removeNodeAndUpdate(p, modified_blocks);
}
// Send a MEET_OTHER event
MapEditEvent event;
event.type = MEET_OTHER;
for(core::map<v3s16, MapBlock*>::Iterator
i = modified_blocks.getIterator();
i.atEnd() == false; i++)
{
v3s16 p = i.getNode()->getKey();
event.modified_blocks.insert(p, true);
}
map->dispatchEvent(&event);
}
void MobV2SAO::step(float dtime, bool send_recommended)
{
ScopeProfiler sp2(g_profiler, "MobV2SAO::step avg", SPT_AVG);
assert(m_env);
Map *map = &m_env->getMap();
m_age += dtime;
if(m_die_age >= 0.0 && m_age >= m_die_age){
m_removed = true;
return;
}
m_random_disturb_timer += dtime;
if(m_random_disturb_timer >= 5.0)
{
m_random_disturb_timer = 0;
// Check connected players
core::list<Player*> players = m_env->getPlayers(true);
core::list<Player*>::Iterator i;
for(i = players.begin();
i != players.end(); i++)
{
Player *player = *i;
v3f playerpos = player->getPosition();
f32 dist = m_base_position.getDistanceFrom(playerpos);
if(dist < BS*16)
{
if(myrand_range(0,3) == 0){
actionstream<<"Mob id="<<m_id<<" at "
<<PP(m_base_position/BS)
<<" got randomly disturbed by "
<<player->getName()<<std::endl;
m_disturbing_player = player->getName();
m_disturb_timer = 0;
break;
}
}
}
}
Player *disturbing_player =
m_env->getPlayer(m_disturbing_player.c_str());
v3f disturbing_player_off = v3f(0,1,0);
v3f disturbing_player_norm = v3f(0,1,0);
float disturbing_player_distance = 1000000;
float disturbing_player_dir = 0;
if(disturbing_player){
disturbing_player_off =
disturbing_player->getPosition() - m_base_position;
disturbing_player_distance = disturbing_player_off.getLength();
disturbing_player_norm = disturbing_player_off;
disturbing_player_norm.normalize();
disturbing_player_dir = 180./PI*atan2(disturbing_player_norm.Z,
disturbing_player_norm.X);
}
m_disturb_timer += dtime;
if(!m_falling)
{
m_shooting_timer -= dtime;
if(m_shooting_timer <= 0.0 && m_shooting){
m_shooting = false;
std::string shoot_type = m_properties->get("shoot_type");
v3f shoot_pos(0,0,0);
shoot_pos.Y += m_properties->getFloat("shoot_y") * BS;
if(shoot_type == "fireball"){
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
dir.Y = m_shoot_y;
dir.normalize();
v3f speed = dir * BS * 10.0;
v3f pos = m_base_position + shoot_pos;
infostream<<__FUNCTION_NAME<<": Mob id="<<m_id
<<" shooting fireball from "<<PP(pos)
<<" at speed "<<PP(speed)<<std::endl;
Settings properties;
properties.set("looks", "fireball");
properties.setV3F("speed", speed);
properties.setFloat("die_age", 5.0);
properties.set("move_type", "constant_speed");
properties.setFloat("hp", 1000);
properties.set("lock_full_brightness", "true");
properties.set("player_hit_damage", "9");
properties.set("player_hit_distance", "2");
properties.set("player_hit_interval", "1");
ServerActiveObject *obj = new MobV2SAO(m_env, 0,
pos, &properties);
//m_env->addActiveObjectAsStatic(obj);
m_env->addActiveObject(obj);
} else {
infostream<<__FUNCTION_NAME<<": Mob id="<<m_id
<<": Unknown shoot_type="<<shoot_type
<<std::endl;
}
}
m_shoot_reload_timer += dtime;
float reload_time = 15.0;
if(m_disturb_timer <= 15.0)
reload_time = 3.0;
bool shoot_without_player = false;
if(m_properties->getBool("mindless_rage"))
shoot_without_player = true;
if(!m_shooting && m_shoot_reload_timer >= reload_time &&
!m_next_pos_exists &&
(m_disturb_timer <= 60.0 || shoot_without_player))
{
m_shoot_y = 0;
if(m_disturb_timer < 60.0 && disturbing_player &&
disturbing_player_distance < 16*BS &&
fabs(disturbing_player_norm.Y) < 0.8){
m_yaw = disturbing_player_dir;
sendPosition();
m_shoot_y += disturbing_player_norm.Y;
} else {
m_shoot_y = 0.01 * myrand_range(-30,10);
}
m_shoot_reload_timer = 0.0;
m_shooting = true;
m_shooting_timer = 1.5;
{
std::ostringstream os(std::ios::binary);
// command (2 = shooting)
writeU8(os, 2);
// time
writeF1000(os, m_shooting_timer + 0.1);
// bright?
writeU8(os, true);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
}
}
}
if(m_move_type == "ground_nodes")
{
if(!m_shooting){
m_walk_around_timer -= dtime;
if(m_walk_around_timer <= 0.0){
m_walk_around = !m_walk_around;
if(m_walk_around)
m_walk_around_timer = 0.1*myrand_range(10,50);
else
m_walk_around_timer = 0.1*myrand_range(30,70);
}
}
/* Move */
if(m_next_pos_exists){
v3f pos_f = m_base_position;
v3f next_pos_f = intToFloat(m_next_pos_i, BS);
v3f v = next_pos_f - pos_f;
m_yaw = atan2(v.Z, v.X) / PI * 180;
v3f diff = next_pos_f - pos_f;
v3f dir = diff;
dir.normalize();
float speed = BS * 0.5;
if(m_falling)
speed = BS * 3.0;
dir *= dtime * speed;
bool arrived = false;
if(dir.getLength() > diff.getLength()){
dir = diff;
arrived = true;
}
pos_f += dir;
m_base_position = pos_f;
if((pos_f - next_pos_f).getLength() < 0.1 || arrived){
m_next_pos_exists = false;
}
}
v3s16 pos_i = floatToInt(m_base_position, BS);
v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
v3s16 pos_size_off(0,0,0);
if(m_size.X >= 2.5){
pos_size_off.X = -1;
pos_size_off.Y = -1;
}
if(!m_next_pos_exists){
/* Check whether to drop down */
if(checkFreePosition(map,
pos_i + pos_size_off + v3s16(0,-1,0), size_blocks)){
m_next_pos_i = pos_i + v3s16(0,-1,0);
m_next_pos_exists = true;
m_falling = true;
} else {
m_falling = false;
}
}
if(m_walk_around)
{
if(!m_next_pos_exists){
/* Find some position where to go next */
v3s16 dps[3*3*3];
int num_dps = 0;
for(int dx=-1; dx<=1; dx++)
for(int dy=-1; dy<=1; dy++)
for(int dz=-1; dz<=1; dz++){
if(dx == 0 && dy == 0)
continue;
if(dx != 0 && dz != 0 && dy != 0)
continue;
dps[num_dps++] = v3s16(dx,dy,dz);
}
u32 order[3*3*3];
get_random_u32_array(order, num_dps);
for(int i=0; i<num_dps; i++){
v3s16 p = dps[order[i]] + pos_i;
bool is_free = checkFreeAndWalkablePosition(map,
p + pos_size_off, size_blocks);
if(!is_free)
continue;
m_next_pos_i = p;
m_next_pos_exists = true;
break;
}
}
}
}
else if(m_move_type == "constant_speed")
{
m_base_position += m_speed * dtime;
v3s16 pos_i = floatToInt(m_base_position, BS);
v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
v3s16 pos_size_off(0,0,0);
if(m_size.X >= 2.5){
pos_size_off.X = -1;
pos_size_off.Y = -1;
}
bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks);
if(!free){
explodeSquare(map, pos_i, v3s16(3,3,3));
m_removed = true;
return;
}
}
else
{
errorstream<<"MobV2SAO::step(): id="<<m_id<<" unknown move_type=\""
<<m_move_type<<"\""<<std::endl;
}
if(send_recommended == false)
return;
if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS)
{
sendPosition();
}
}
u16 MobV2SAO::punch(const std::string &toolname, v3f dir,
const std::string &playername)
{
assert(m_env);
Map *map = &m_env->getMap();
actionstream<<playername<<" punches mob id="<<m_id
<<" with a \""<<toolname<<"\" at "
<<PP(m_base_position/BS)<<std::endl;
m_disturb_timer = 0;
m_disturbing_player = playername;
m_next_pos_exists = false; // Cancel moving immediately
m_yaw = wrapDegrees_180(180./PI*atan2(dir.Z, dir.X) + 180.);
v3f new_base_position = m_base_position + dir * BS;
{
v3s16 pos_i = floatToInt(new_base_position, BS);
v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
v3s16 pos_size_off(0,0,0);
if(m_size.X >= 2.5){
pos_size_off.X = -1;
pos_size_off.Y = -1;
}
bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks);
if(free)
m_base_position = new_base_position;
}
sendPosition();
u16 amount = 2;
/* See tool names in inventory.h */
if(toolname == "WSword")
amount = 4;
if(toolname == "STSword")
amount = 6;
if(toolname == "SteelSword")
amount = 8;
if(toolname == "STAxe")
amount = 3;
if(toolname == "SteelAxe")
amount = 4;
if(toolname == "SteelPick")
amount = 3;
doDamage(amount);
return 65536/100;
}
bool MobV2SAO::isPeaceful()
{
return m_properties->getBool("is_peaceful");
}
void MobV2SAO::sendPosition()
{
m_last_sent_position = m_base_position;
std::ostringstream os(std::ios::binary);
// command (0 = update position)
writeU8(os, 0);
// pos
writeV3F1000(os, m_base_position);
// yaw
writeF1000(os, m_yaw);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
}
void MobV2SAO::setPropertyDefaults()
{
m_properties->setDefault("is_peaceful", "false");
m_properties->setDefault("move_type", "ground_nodes");
m_properties->setDefault("speed", "(0,0,0)");
m_properties->setDefault("age", "0");
m_properties->setDefault("yaw", "0");
m_properties->setDefault("pos", "(0,0,0)");
m_properties->setDefault("hp", "0");
m_properties->setDefault("die_age", "-1");
m_properties->setDefault("size", "(1,2)");
m_properties->setDefault("shoot_type", "fireball");
m_properties->setDefault("shoot_y", "0");
m_properties->setDefault("mindless_rage", "false");
}
void MobV2SAO::readProperties()
{
m_move_type = m_properties->get("move_type");
m_speed = m_properties->getV3F("speed");
m_age = m_properties->getFloat("age");
m_yaw = m_properties->getFloat("yaw");
m_base_position = m_properties->getV3F("pos");
m_hp = m_properties->getS32("hp");
m_die_age = m_properties->getFloat("die_age");
m_size = m_properties->getV2F("size");
}
void MobV2SAO::updateProperties()
{
m_properties->set("move_type", m_move_type);
m_properties->setV3F("speed", m_speed);
m_properties->setFloat("age", m_age);
m_properties->setFloat("yaw", m_yaw);
m_properties->setV3F("pos", m_base_position);
m_properties->setS32("hp", m_hp);
m_properties->setFloat("die_age", m_die_age);
m_properties->setV2F("size", m_size);
m_properties->setS32("version", 0);
}
void MobV2SAO::doDamage(u16 d)
{
infostream<<"MobV2 hp="<<m_hp<<" damage="<<d<<std::endl;
if(d < m_hp)
{
m_hp -= d;
}
else
{
actionstream<<"A "<<(isPeaceful()?"peaceful":"non-peaceful")
<<" mob id="<<m_id<<" dies at "<<PP(m_base_position)<<std::endl;
// Die
m_hp = 0;
m_removed = true;
}
{
std::ostringstream os(std::ios::binary);
// command (1 = damage)
writeU8(os, 1);
// amount
writeU16(os, d);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
}
}

View File

@@ -96,7 +96,9 @@ class Oerkki1SAO : public ServerActiveObject
std::string getClientInitializationData();
std::string getStaticData();
InventoryItem* createPickedUpItem(){return NULL;}
u16 punch(const std::string &toolname, v3f dir);
u16 punch(const std::string &toolname, v3f dir,
const std::string &playername);
bool isPeaceful(){return false;}
private:
void doDamage(u16 d);
@@ -139,5 +141,59 @@ class FireflySAO : public ServerActiveObject
bool m_touching_ground;
};
class Settings;
class MobV2SAO : public ServerActiveObject
{
public:
MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
Settings *init_properties);
virtual ~MobV2SAO();
u8 getType() const
{return ACTIVEOBJECT_TYPE_MOBV2;}
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
const std::string &data);
std::string getStaticData();
std::string getClientInitializationData();
void step(float dtime, bool send_recommended);
InventoryItem* createPickedUpItem(){return NULL;}
u16 punch(const std::string &toolname, v3f dir,
const std::string &playername);
bool isPeaceful();
private:
void sendPosition();
void setPropertyDefaults();
void readProperties();
void updateProperties();
void doDamage(u16 d);
std::string m_move_type;
v3f m_speed;
v3f m_last_sent_position;
v3f m_oldpos;
float m_yaw;
float m_counter1;
float m_counter2;
float m_age;
bool m_touching_ground;
int m_hp;
bool m_walk_around;
float m_walk_around_timer;
bool m_next_pos_exists;
v3s16 m_next_pos_i;
float m_shoot_reload_timer;
bool m_shooting;
float m_shooting_timer;
float m_die_age;
v2f m_size;
bool m_falling;
float m_disturb_timer;
std::string m_disturbing_player;
float m_random_disturb_timer;
float m_shoot_y;
Settings *m_properties;
};
#endif

View File

@@ -68,9 +68,9 @@ Nullstream dummyout;
void assert_fail(const char *assertion, const char *file,
unsigned int line, const char *function)
{
DEBUGPRINT("\nIn thread %x:\n"
DEBUGPRINT("\nIn thread %lx:\n"
"%s:%d: %s: Assertion '%s' failed.\n",
(unsigned int)get_current_thread_id(),
(unsigned long)get_current_thread_id(),
file, line, function, assertion);
debug_stacks_print();
@@ -95,8 +95,8 @@ DebugStack::DebugStack(threadid_t id)
void DebugStack::print(FILE *file, bool everything)
{
fprintf(file, "DEBUG STACK FOR THREAD %x:\n",
(unsigned int)threadid);
fprintf(file, "DEBUG STACK FOR THREAD %lx:\n",
(unsigned long)threadid);
for(int i=0; i<stack_max_i; i++)
{

View File

@@ -85,7 +85,7 @@ class Debugbuf : public std::streambuf
return c;
}
int xsputn(const char *s, int n)
std::streamsize xsputn(const char *s, std::streamsize n)
{
for(int i=0; i<DEBUGSTREAM_COUNT; i++)
{
@@ -235,10 +235,9 @@ class PacketCounter
#if CATCH_UNHANDLED_EXCEPTIONS == 1
#define BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER try{
#define END_PORTABLE_DEBUG_EXCEPTION_HANDLER\
#define END_PORTABLE_DEBUG_EXCEPTION_HANDLER(logstream)\
}catch(std::exception &e){\
dstream<<std::endl<<DTIME\
<<"ERROR: An unhandled exception occurred: "\
logstream<<"ERROR: An unhandled exception occurred: "\
<<e.what()<<std::endl;\
assert(0);\
}
@@ -257,24 +256,24 @@ class FatalSystemException : public BaseException
BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER\
_set_se_translator(se_trans_func);
#define END_DEBUG_EXCEPTION_HANDLER \
END_PORTABLE_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER(logstream) \
END_PORTABLE_DEBUG_EXCEPTION_HANDLER(logstream)
#else // Probably mingw
#define BEGIN_DEBUG_EXCEPTION_HANDLER\
BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER\
END_PORTABLE_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER(logstream)\
END_PORTABLE_DEBUG_EXCEPTION_HANDLER(logstream)
#endif
#else // Posix
#define BEGIN_DEBUG_EXCEPTION_HANDLER\
BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER\
END_PORTABLE_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER(logstream)\
END_PORTABLE_DEBUG_EXCEPTION_HANDLER(logstream)
#endif
#else
// Dummy ones
#define BEGIN_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER
#define END_DEBUG_EXCEPTION_HANDLER(logstream)
#endif
#endif // DEBUG_HEADER

View File

@@ -17,89 +17,97 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "utility.h"
#include "settings.h"
extern Settings g_settings;
void set_default_settings()
void set_default_settings(Settings *settings)
{
// Client and server
g_settings.setDefault("port", "");
g_settings.setDefault("name", "");
g_settings.setDefault("footprints", "false");
settings->setDefault("port", "");
settings->setDefault("name", "");
settings->setDefault("footprints", "false");
// Client stuff
g_settings.setDefault("keymap_forward", "KEY_KEY_W");
g_settings.setDefault("keymap_backward", "KEY_KEY_S");
g_settings.setDefault("keymap_left", "KEY_KEY_A");
g_settings.setDefault("keymap_right", "KEY_KEY_D");
g_settings.setDefault("keymap_jump", "KEY_SPACE");
g_settings.setDefault("keymap_sneak", "KEY_LSHIFT");
g_settings.setDefault("keymap_inventory", "KEY_KEY_I");
g_settings.setDefault("keymap_chat", "KEY_KEY_T");
g_settings.setDefault("keymap_rangeselect", "KEY_KEY_R");
g_settings.setDefault("keymap_freemove", "KEY_KEY_K");
g_settings.setDefault("keymap_fastmove", "KEY_KEY_J");
g_settings.setDefault("keymap_frametime_graph", "KEY_F1");
g_settings.setDefault("keymap_screenshot", "KEY_F12");
settings->setDefault("keymap_forward", "KEY_KEY_W");
settings->setDefault("keymap_backward", "KEY_KEY_S");
settings->setDefault("keymap_left", "KEY_KEY_A");
settings->setDefault("keymap_right", "KEY_KEY_D");
settings->setDefault("keymap_jump", "KEY_SPACE");
settings->setDefault("keymap_sneak", "KEY_LSHIFT");
settings->setDefault("keymap_inventory", "KEY_KEY_I");
settings->setDefault("keymap_special1", "KEY_KEY_E");
settings->setDefault("keymap_chat", "KEY_KEY_T");
settings->setDefault("keymap_cmd", "/");
settings->setDefault("keymap_rangeselect", "KEY_KEY_R");
settings->setDefault("keymap_freemove", "KEY_KEY_K");
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
settings->setDefault("keymap_frametime_graph", "KEY_F1");
settings->setDefault("keymap_screenshot", "KEY_F12");
settings->setDefault("keymap_toggle_profiler", "KEY_F2");
settings->setDefault("keymap_toggle_force_fog_off", "KEY_F3");
// Some (temporary) keys for debugging
g_settings.setDefault("keymap_special1", "KEY_KEY_E");
g_settings.setDefault("keymap_print_debug_stacks", "KEY_KEY_P");
settings->setDefault("keymap_print_debug_stacks", "KEY_KEY_P");
g_settings.setDefault("wanted_fps", "30");
g_settings.setDefault("fps_max", "60");
g_settings.setDefault("viewing_range_nodes_max", "300");
g_settings.setDefault("viewing_range_nodes_min", "15");
g_settings.setDefault("screenW", "800");
g_settings.setDefault("screenH", "600");
g_settings.setDefault("address", "");
g_settings.setDefault("random_input", "false");
g_settings.setDefault("client_unload_unused_data_timeout", "600");
g_settings.setDefault("enable_fog", "true");
g_settings.setDefault("new_style_water", "false");
g_settings.setDefault("new_style_leaves", "true");
g_settings.setDefault("smooth_lighting", "true");
g_settings.setDefault("frametime_graph", "false");
g_settings.setDefault("enable_texture_atlas", "true");
g_settings.setDefault("texture_path", "");
g_settings.setDefault("video_driver", "opengl");
g_settings.setDefault("free_move", "false");
g_settings.setDefault("continuous_forward", "false");
g_settings.setDefault("fast_move", "false");
g_settings.setDefault("invert_mouse", "false");
g_settings.setDefault("enable_farmesh", "false");
g_settings.setDefault("farmesh_trees", "true");
g_settings.setDefault("farmesh_distance", "40");
g_settings.setDefault("enable_clouds", "true");
g_settings.setDefault("invisible_stone", "false");
g_settings.setDefault("screenshot_path", ".");
settings->setDefault("wanted_fps", "30");
settings->setDefault("fps_max", "60");
settings->setDefault("viewing_range_nodes_max", "300");
settings->setDefault("viewing_range_nodes_min", "15");
settings->setDefault("screenW", "800");
settings->setDefault("screenH", "600");
settings->setDefault("address", "");
settings->setDefault("random_input", "false");
settings->setDefault("client_unload_unused_data_timeout", "600");
settings->setDefault("enable_fog", "true");
settings->setDefault("fov", "72");
settings->setDefault("view_bobbing", "true");
settings->setDefault("new_style_water", "false");
settings->setDefault("new_style_leaves", "true");
settings->setDefault("smooth_lighting", "true");
settings->setDefault("frametime_graph", "false");
settings->setDefault("enable_texture_atlas", "true");
settings->setDefault("texture_path", "");
settings->setDefault("video_driver", "opengl");
settings->setDefault("free_move", "false");
settings->setDefault("continuous_forward", "false");
settings->setDefault("fast_move", "false");
settings->setDefault("invert_mouse", "false");
settings->setDefault("enable_farmesh", "false");
settings->setDefault("enable_clouds", "true");
settings->setDefault("invisible_stone", "false");
settings->setDefault("screenshot_path", ".");
settings->setDefault("view_bobbing_amount", "1.0");
settings->setDefault("enable_2d_clouds", "false");
// Server stuff
g_settings.setDefault("motd", "");
g_settings.setDefault("enable_experimental", "false");
g_settings.setDefault("creative_mode", "false");
g_settings.setDefault("enable_damage", "true");
g_settings.setDefault("give_initial_stuff", "false");
g_settings.setDefault("default_password", "");
g_settings.setDefault("default_privs", "build, shout");
g_settings.setDefault("profiler_print_interval", "0");
g_settings.setDefault("enable_mapgen_debug_info", "false");
// "map-dir" doesn't exist by default.
settings->setDefault("motd", "");
settings->setDefault("max_users", "20");
settings->setDefault("strict_protocol_version_checking", "true");
settings->setDefault("creative_mode", "false");
settings->setDefault("enable_damage", "true");
settings->setDefault("only_peaceful_mobs", "false");
settings->setDefault("fixed_map_seed", "");
settings->setDefault("give_initial_stuff", "false");
settings->setDefault("default_password", "");
settings->setDefault("default_privs", "build, shout");
g_settings.setDefault("objectdata_interval", "0.2");
g_settings.setDefault("active_object_range", "2");
//g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
settings->setDefault("profiler_print_interval", "0");
settings->setDefault("enable_mapgen_debug_info", "false");
settings->setDefault("objectdata_interval", "0.2");
settings->setDefault("active_object_send_range_blocks", "3");
settings->setDefault("active_block_range", "2");
//settings->setDefault("max_simultaneous_block_sends_per_client", "1");
// This causes frametime jitter on client side, or does it?
g_settings.setDefault("max_simultaneous_block_sends_per_client", "2");
g_settings.setDefault("max_simultaneous_block_sends_server_total", "8");
g_settings.setDefault("max_block_send_distance", "8");
g_settings.setDefault("max_block_generate_distance", "8");
g_settings.setDefault("time_send_interval", "20");
g_settings.setDefault("time_speed", "96");
g_settings.setDefault("server_unload_unused_data_timeout", "60");
g_settings.setDefault("server_map_save_interval", "60");
g_settings.setDefault("full_block_send_enable_min_time_from_building", "2.0");
//g_settings.setDefault("dungeon_rarity", "0.025");
settings->setDefault("max_simultaneous_block_sends_per_client", "2");
settings->setDefault("max_simultaneous_block_sends_server_total", "8");
settings->setDefault("max_block_send_distance", "7");
settings->setDefault("max_block_generate_distance", "5");
settings->setDefault("time_send_interval", "20");
settings->setDefault("time_speed", "96");
settings->setDefault("server_unload_unused_data_timeout", "60");
settings->setDefault("server_map_save_interval", "10");
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
settings->setDefault("enable_experimental", "false");
}

28
src/defaultsettings.h Normal file
View File

@@ -0,0 +1,28 @@
/*
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 DEFAULTSETTINGS_HEADER
#define DEFAULTSETTINGS_HEADER
class Settings;
void set_default_settings(Settings *settings);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -175,6 +175,14 @@ class ServerEnvironment : public Environment
*/
u16 addActiveObject(ServerActiveObject *object);
/*
Add an active object as a static object to the corresponding
MapBlock.
Caller allocates memory, ServerEnvironment frees memory.
Return value: true if succeeded, false if failed.
*/
bool addActiveObjectAsStatic(ServerActiveObject *object);
/*
Find out what new objects have been added to
inside a radius around a position
@@ -210,6 +218,11 @@ class ServerEnvironment : public Environment
void addActiveBlockModifier(ActiveBlockModifier *abm);
/* Other stuff */
// Clear all objects, loading and going through every MapBlock
void clearAllObjects();
private:
/*
@@ -406,9 +419,6 @@ class ClientEnvironment : public Environment
// Get event from queue. CEE_NONE is returned if queue is empty.
ClientEnvEvent getClientEvent();
// Post effects
void drawPostFx(video::IVideoDriver* driver, v3f camera_pos);
private:
ClientMap *m_map;
@@ -416,6 +426,7 @@ class ClientEnvironment : public Environment
core::map<u16, ClientActiveObject*> m_active_objects;
Queue<ClientEnvEvent> m_client_event_queue;
IntervalLimiter m_active_object_light_update_interval;
IntervalLimiter m_lava_hurt_interval;
};
#endif

View File

@@ -70,7 +70,6 @@ FarMesh::FarMesh(
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*31000,-BS*1000000,
BS*1000000,BS*31000,BS*1000000);
trees = g_settings.getBool("farmesh_trees");
}
FarMesh::~FarMesh()
@@ -314,11 +313,12 @@ void FarMesh::render()
}
else
{
// Trees if there are over 0.01 trees per MapNode
if(trees && tree_amount_avg > 0.01)
/*// Trees if there are over 0.01 trees per MapNode
if(tree_amount_avg > 0.01)
c = video::SColor(255,50,128,50);
else
c = video::SColor(255,107,134,51);
c = video::SColor(255,107,134,51);*/
c = video::SColor(255,107,134,51);
ground_is_mud = true;
}
}
@@ -351,7 +351,7 @@ void FarMesh::render()
video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
// Add some trees if appropriate
if(trees && tree_amount_avg >= 0.0065 && steepness < 1.4
if(tree_amount_avg >= 0.0065 && steepness < 1.4
&& ground_is_mud == true)
{
driver->setMaterial(m_materials[1]);
@@ -404,11 +404,11 @@ void FarMesh::step(float dtime)
m_time += dtime;
}
void FarMesh::update(v2f camera_p, float brightness)
void FarMesh::update(v2f camera_p, float brightness, s16 render_range)
{
m_camera_pos = camera_p;
m_brightness = brightness;
m_render_range = g_settings.getS16("farmesh_distance")*10;
m_render_range = render_range;
}

View File

@@ -67,7 +67,7 @@ class FarMesh : public scene::ISceneNode
void step(float dtime);
void update(v2f camera_p, float brightness);
void update(v2f camera_p, float brightness, s16 render_range);
private:
video::SMaterial m_materials[FARMESH_MATERIAL_COUNT];
@@ -79,7 +79,6 @@ class FarMesh : public scene::ISceneNode
float m_time;
Client *m_client;
s16 m_render_range;
bool trees;
};
#endif

View File

@@ -28,7 +28,7 @@ namespace fs
#ifdef _WIN32 // WINDOWS
#define _WIN32_WINNT 0x0501
#include <Windows.h>
#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include <tchar.h>
@@ -254,7 +254,7 @@ bool RecursiveDelete(std::string path)
execv(argv[0], argv);
// Execv shouldn't return. Failed.
return false;
_exit(1);
}
else
{
@@ -279,7 +279,7 @@ bool RecursiveDeleteContent(std::string path)
{
if(trim(list[i].name) == "." || trim(list[i].name) == "..")
continue;
std::string childpath = path + "/" + list[i].name;
std::string childpath = path + DIR_DELIM + list[i].name;
bool r = RecursiveDelete(childpath);
if(r == false)
{
@@ -299,7 +299,7 @@ bool CreateAllDirs(std::string path)
while(!PathExists(basepath))
{
tocreate.push_back(basepath);
pos = basepath.rfind('/');
pos = basepath.rfind(DIR_DELIM_C);
if(pos == std::string::npos)
return false;
basepath = basepath.substr(0,pos);

View File

@@ -24,6 +24,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <vector>
#include "exceptions.h"
#ifdef _WIN32 // WINDOWS
#define DIR_DELIM "\\"
#define DIR_DELIM_C '\\'
#else // POSIX
#define DIR_DELIM "/"
#define DIR_DELIM_C '/'
#endif
namespace fs
{

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,69 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h"
#include <string>
#include "keycode.h"
class KeyList : protected core::list<KeyPress>
{
typedef core::list<KeyPress> super;
typedef super::Iterator Iterator;
typedef super::ConstIterator ConstIterator;
virtual ConstIterator find(const KeyPress &key) const
{
ConstIterator f(begin());
ConstIterator e(end());
while (f!=e) {
if (*f == key)
return f;
++f;
}
return e;
}
virtual Iterator find(const KeyPress &key)
{
Iterator f(begin());
Iterator e(end());
while (f!=e) {
if (*f == key)
return f;
++f;
}
return e;
}
public:
void clear() { super::clear(); }
void set(const KeyPress &key)
{
if (find(key) == end())
push_back(key);
}
void unset(const KeyPress &key)
{
Iterator p(find(key));
if (p != end())
erase(p);
}
void toggle(const KeyPress &key)
{
Iterator p(this->find(key));
if (p != end())
erase(p);
else
push_back(key);
}
bool operator[](const KeyPress &key) const
{
return find(key) != end();
}
};
class InputHandler
{
public:
@@ -33,8 +96,8 @@ class InputHandler
{
}
virtual bool isKeyDown(EKEY_CODE keyCode) = 0;
virtual bool wasKeyDown(EKEY_CODE keyCode) = 0;
virtual bool isKeyDown(const KeyPress &keyCode) = 0;
virtual bool wasKeyDown(const KeyPress &keyCode) = 0;
virtual v2s32 getMousePos() = 0;
virtual void setMousePos(s32 x, s32 y) = 0;

View File

@@ -1,4 +1,8 @@
#ifdef USE_GETTEXT
#ifndef GETTEXT_HEADER
#include "config.h" // for USE_GETTEXT
#include <iostream>
#if USE_GETTEXT
#include <libintl.h>
#else
#define gettext(String) String
@@ -8,6 +12,17 @@
#define gettext_noop(String) String
#define N_(String) gettext_noop (String)
inline void init_gettext(const char *path) {
#if USE_GETTEXT
// don't do this if MSVC compiler is used, it gives an assertion fail
#ifndef _MSC_VER
setlocale(LC_MESSAGES, "");
#endif
bindtextdomain(PROJECT_NAME, path);
textdomain(PROJECT_NAME);
#endif
}
inline wchar_t* chartowchar_t(const char *str)
{
size_t l = strlen(str)+1;
@@ -15,3 +30,20 @@ inline wchar_t* chartowchar_t(const char *str)
mbstowcs(nstr, str, l);
return nstr;
}
inline wchar_t* wgettext(const char *str)
{
return chartowchar_t(gettext(str));
}
inline void changeCtype(const char *l)
{
char *ret = NULL;
ret = setlocale(LC_CTYPE, l);
if(ret == NULL)
std::cout<<"locale could not be set"<<std::endl;
else
std::cout<<"locale has been set to:"<<ret<<std::endl;
}
#define GETTEXT_HEADER
#endif

179
src/guiDeathScreen.cpp Normal file
View File

@@ -0,0 +1,179 @@
/*
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 "guiDeathScreen.h"
#include "debug.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "gettext.h"
#include "client.h"
GUIDeathScreen::GUIDeathScreen(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr, IRespawnInitiator *respawner
):
GUIModalMenu(env, parent, id, menumgr),
m_respawner(respawner),
m_screensize(1,1)
{
}
GUIDeathScreen::~GUIDeathScreen()
{
removeChildren();
delete m_respawner;
}
void GUIDeathScreen::removeChildren()
{
const core::list<gui::IGUIElement*> &children = getChildren();
core::list<gui::IGUIElement*> children_copy;
for(core::list<gui::IGUIElement*>::ConstIterator
i = children.begin(); i != children.end(); i++)
{
children_copy.push_back(*i);
}
for(core::list<gui::IGUIElement*>::Iterator
i = children_copy.begin();
i != children_copy.end(); i++)
{
(*i)->remove();
}
}
void GUIDeathScreen::regenerateGui(v2u32 screensize)
{
m_screensize = screensize;
/*
Remove stuff
*/
removeChildren();
/*
Calculate new sizes and positions
*/
core::rect<s32> rect(
screensize.X/2 - 500/2,
screensize.Y/2 - 200/2,
screensize.X/2 + 500/2,
screensize.Y/2 + 200/2
);
DesiredRect = rect;
recalculateAbsolutePosition(false);
v2s32 size = rect.getSize();
/*
Add stuff
*/
changeCtype("");
{
core::rect<s32> rect(0, 0, 400, 50);
rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25);
Environment->addStaticText(wgettext("You died."), rect, false,
true, this, 256);
}
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
gui::IGUIElement *e =
Environment->addButton(rect, this, 257,
wgettext("Respawn"));
Environment->setFocus(e);
}
changeCtype("C");
}
void GUIDeathScreen::drawMenu()
{
gui::IGUISkin* skin = Environment->getSkin();
if (!skin)
return;
video::IVideoDriver* driver = Environment->getVideoDriver();
{
video::SColor color(180,50,0,0);
driver->draw2DRectangle(color,
core::rect<s32>(0,0,m_screensize.X,m_screensize.Y), NULL);
}
{
video::SColor bgcolor(50,0,0,0);
driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
}
gui::IGUIElement::draw();
}
bool GUIDeathScreen::OnEvent(const SEvent& event)
{
if(event.EventType==EET_KEY_INPUT_EVENT)
{
if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
{
respawn();
quitMenu();
return true;
}
if(event.KeyInput.Key==KEY_RETURN && event.KeyInput.PressedDown)
{
respawn();
quitMenu();
return true;
}
}
if(event.EventType==EET_GUI_EVENT)
{
if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
&& isVisible())
{
if(!canTakeFocus(event.GUIEvent.Element))
{
dstream<<"GUIDeathScreen: Not allowing focus change."
<<std::endl;
// Returning true disables focus change
return true;
}
}
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
{
switch(event.GUIEvent.Caller->getID())
{
case 257:
respawn();
quitMenu();
return true;
}
}
}
return Parent ? Parent->OnEvent(event) : false;
}
void GUIDeathScreen::respawn()
{
m_respawner->respawn();
}

60
src/guiDeathScreen.h Normal file
View File

@@ -0,0 +1,60 @@
/*
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 GUIMESSAGEMENU_HEADER
#define GUIMESSAGEMENU_HEADER
#include "common_irrlicht.h"
#include "modalMenu.h"
#include "utility.h"
#include <string>
class IRespawnInitiator
{
public:
virtual void respawn() = 0;
};
class GUIDeathScreen : public GUIModalMenu
{
public:
GUIDeathScreen(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr, IRespawnInitiator *respawner);
~GUIDeathScreen();
void removeChildren();
/*
Remove and re-add (or reposition) stuff
*/
void regenerateGui(v2u32 screensize);
void drawMenu();
bool OnEvent(const SEvent& event);
void respawn();
private:
IRespawnInitiator *m_respawner;
v2u32 m_screensize;
};
#endif

View File

@@ -22,6 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "constants.h"
#include "keycode.h"
#include "strfnd.h"
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "log.h"
void drawInventoryItem(video::IVideoDriver *driver,
gui::IGUIFont *font,
@@ -41,7 +47,7 @@ void drawInventoryItem(video::IVideoDriver *driver,
driver->draw2DImage(texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
clip, colors, false);
clip, colors, true);
}
else
{
@@ -241,22 +247,31 @@ void GUIInventoryMenu::drawList(const ListDrawSpec &s)
if(m_selected_item != NULL && m_selected_item->listname == s.listname
&& m_selected_item->i == i)
{
/*s32 border = imgsize.X/12;
driver->draw2DRectangle(video::SColor(255,192,192,192),
core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*border,
rect.LowerRightCorner + v2s32(1,1)*border),
NULL);
driver->draw2DRectangle(video::SColor(255,0,0,0),
core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*((border+1)/2),
rect.LowerRightCorner + v2s32(1,1)*((border+1)/2)),
NULL);*/
s32 border = 2;
driver->draw2DRectangle(video::SColor(255,255,0,0),
core::rect<s32>(rect.UpperLeftCorner - v2s32(2,2),
rect.LowerRightCorner + v2s32(2,2)),
core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*border,
rect.LowerRightCorner + v2s32(1,1)*border),
&AbsoluteClippingRect);
}
video::SColor bgcolor(255,128,128,128);
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
if(item)
{
drawInventoryItem(driver, font, item,
rect, &AbsoluteClippingRect);
}
else
{
video::SColor bgcolor(255,128,128,128);
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
}
}
}
@@ -290,12 +305,9 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
{
if(event.EventType==EET_KEY_INPUT_EVENT)
{
if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown)
{
quitMenu();
return true;
}
if(event.KeyInput.Key==getKeySetting("keymap_inventory") && event.KeyInput.PressedDown)
KeyPress kp(event.KeyInput);
if (event.KeyInput.PressedDown && (kp == EscapeKey ||
kp == getKeySetting("keymap_inventory")))
{
quitMenu();
return true;
@@ -303,16 +315,23 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
}
if(event.EventType==EET_MOUSE_INPUT_EVENT)
{
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN
|| event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
char amount = -1;
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
amount = 0;
else if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
amount = 1;
else if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN)
amount = 10;
if(amount >= 0)
{
bool right = (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN);
v2s32 p(event.MouseInput.X, event.MouseInput.Y);
//dstream<<"Mouse down at p=("<<p.X<<","<<p.Y<<")"<<std::endl;
//infostream<<"Mouse down at p=("<<p.X<<","<<p.Y<<")"<<std::endl;
ItemSpec s = getItemAtPos(p);
if(s.isValid())
{
dstream<<"Mouse down on "<<s.inventoryname
infostream<<"Mouse down on "<<s.inventoryname
<<"/"<<s.listname<<" "<<s.i<<std::endl;
if(m_selected_item)
{
@@ -327,17 +346,17 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
InventoryList *list_to =
inv_to->getList(s.listname);
if(list_from == NULL)
dstream<<"from list doesn't exist"<<std::endl;
infostream<<"from list doesn't exist"<<std::endl;
if(list_to == NULL)
dstream<<"to list doesn't exist"<<std::endl;
infostream<<"to list doesn't exist"<<std::endl;
// Indicates whether source slot completely empties
bool source_empties = false;
if(list_from && list_to
&& list_from->getItem(m_selected_item->i) != NULL)
{
dstream<<"Handing IACTION_MOVE to manager"<<std::endl;
infostream<<"Handing IACTION_MOVE to manager"<<std::endl;
IMoveAction *a = new IMoveAction();
a->count = right ? 1 : 0;
a->count = amount;
a->from_inv = m_selected_item->inventoryname;
a->from_list = m_selected_item->listname;
a->from_i = m_selected_item->i;
@@ -352,7 +371,7 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
}
// Remove selection if target was left-clicked or source
// slot was emptied
if(right == false || source_empties)
if(amount == 0 || source_empties)
{
delete m_selected_item;
m_selected_item = NULL;
@@ -390,7 +409,7 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
{
if(!canTakeFocus(event.GUIEvent.Element))
{
dstream<<"GUIInventoryMenu: Not allowing focus change."
infostream<<"GUIInventoryMenu: Not allowing focus change."
<<std::endl;
// Returning true disables focus change
return true;
@@ -456,7 +475,7 @@ v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString(
while(f.atend() == false)
{
std::string type = trim(f.next("["));
//dstream<<"type="<<type<<std::endl;
//infostream<<"type="<<type<<std::endl;
if(type == "list")
{
std::string name = f.next(";");
@@ -467,7 +486,7 @@ v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString(
s32 pos_y = stoi(f.next(";"));
s32 geom_x = stoi(f.next(","));
s32 geom_y = stoi(f.next(";"));
dstream<<"list name="<<name<<", subname="<<subname
infostream<<"list name="<<name<<", subname="<<subname
<<", pos=("<<pos_x<<","<<pos_y<<")"
<<", geom=("<<geom_x<<","<<geom_y<<")"
<<std::endl;
@@ -480,14 +499,14 @@ v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString(
{
invsize.X = stoi(f.next(","));
invsize.Y = stoi(f.next(";"));
dstream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
infostream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
f.next("]");
}
else
{
// Ignore others
std::string ts = f.next("]");
dstream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\""
infostream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\""
<<std::endl;
}
}

View File

@@ -22,9 +22,14 @@
#include "guiKeyChangeMenu.h"
#include "debug.h"
#include "serialization.h"
#include "keycode.h"
#include "main.h"
#include <string>
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "settings.h"
GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
@@ -76,13 +81,13 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
recalculateAbsolutePosition(false);
v2s32 topleft(0, 0);
changeCtype("");
{
core::rect < s32 > rect(0, 0, 125, 20);
rect += topleft + v2s32(25, 3);
const wchar_t *text = L"KEYBINDINGS";
//gui::IGUIStaticText *t =
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("KEYBINDINGS"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
v2s32 offset(25, 40);
@@ -91,8 +96,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Forward";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Forward"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -101,15 +106,15 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->forward = Environment->addButton(rect, this,
GUI_ID_KEY_FORWARD_BUTTON,
narrow_to_wide(KeyNames[key_forward]).c_str());
wgettext(key_forward.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Backward";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Backward"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -118,14 +123,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->backward = Environment->addButton(rect, this,
GUI_ID_KEY_BACKWARD_BUTTON,
narrow_to_wide(KeyNames[key_backward]).c_str());
wgettext(key_backward.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Left";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Left"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -133,14 +138,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->left = Environment->addButton(rect, this, GUI_ID_KEY_LEFT_BUTTON,
narrow_to_wide(KeyNames[key_left]).c_str());
wgettext(key_left.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Right";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Right"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -149,14 +154,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->right = Environment->addButton(rect, this,
GUI_ID_KEY_RIGHT_BUTTON,
narrow_to_wide(KeyNames[key_right]).c_str());
wgettext(key_right.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Use";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Use"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -164,14 +169,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->use = Environment->addButton(rect, this, GUI_ID_KEY_USE_BUTTON,
narrow_to_wide(KeyNames[key_use]).c_str());
wgettext(key_use.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Sneak";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Sneak"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -180,14 +185,13 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->sneak = Environment->addButton(rect, this,
GUI_ID_KEY_SNEAK_BUTTON,
narrow_to_wide(KeyNames[key_sneak]).c_str());
wgettext(key_sneak.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Jump";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Jump"), rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -195,15 +199,15 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->jump = Environment->addButton(rect, this, GUI_ID_KEY_JUMP_BUTTON,
narrow_to_wide(KeyNames[key_jump]).c_str());
wgettext(key_jump.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Inventory";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Inventory"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -212,14 +216,13 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->inventory = Environment->addButton(rect, this,
GUI_ID_KEY_INVENTORY_BUTTON,
narrow_to_wide(KeyNames[key_inventory]).c_str());
wgettext(key_inventory.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Chat";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Chat"), rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -227,16 +230,31 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->chat = Environment->addButton(rect, this, GUI_ID_KEY_CHAT_BUTTON,
narrow_to_wide(KeyNames[key_chat]).c_str());
wgettext(key_chat.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
Environment->addStaticText(wgettext("Command"), rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
{
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->cmd = Environment->addButton(rect, this, GUI_ID_KEY_CMD_BUTTON,
wgettext(key_cmd.name()));
}
//next col
offset = v2s32(250, 40);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Toggle fly";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Toggle fly"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -244,14 +262,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->fly = Environment->addButton(rect, this, GUI_ID_KEY_FLY_BUTTON,
narrow_to_wide(KeyNames[key_fly]).c_str());
wgettext(key_fly.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Toggle fast";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Toggle fast"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -259,14 +277,14 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->fast = Environment->addButton(rect, this, GUI_ID_KEY_FAST_BUTTON,
narrow_to_wide(KeyNames[key_fast]).c_str());
wgettext(key_fast.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Range select";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Range select"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -275,15 +293,15 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->range = Environment->addButton(rect, this,
GUI_ID_KEY_RANGE_BUTTON,
narrow_to_wide(KeyNames[key_range]).c_str());
wgettext(key_range.name()));
}
offset += v2s32(0, 25);
{
core::rect < s32 > rect(0, 0, 100, 20);
rect += topleft + v2s32(offset.X, offset.Y);
const wchar_t *text = L"Print stacks";
Environment->addStaticText(text, rect, false, true, this, -1);
Environment->addStaticText(wgettext("Print stacks"),
rect, false, true, this, -1);
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
}
@@ -291,18 +309,21 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
this->dump = Environment->addButton(rect, this, GUI_ID_KEY_DUMP_BUTTON,
narrow_to_wide(KeyNames[key_dump]).c_str());
wgettext(key_dump.name()));
}
{
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
Environment->addButton(rect, this, GUI_ID_BACK_BUTTON, L"Save");
Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
wgettext("Save"));
}
{
core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON, L"Cancel");
Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
wgettext("Cancel"));
}
changeCtype("C");
}
void GUIKeyChangeMenu::drawMenu()
@@ -325,19 +346,20 @@ void GUIKeyChangeMenu::drawMenu()
bool GUIKeyChangeMenu::acceptInput()
{
g_settings.set("keymap_forward", keycode_to_keyname(key_forward));
g_settings.set("keymap_backward", keycode_to_keyname(key_backward));
g_settings.set("keymap_left", keycode_to_keyname(key_left));
g_settings.set("keymap_right", keycode_to_keyname(key_right));
g_settings.set("keymap_jump", keycode_to_keyname(key_jump));
g_settings.set("keymap_sneak", keycode_to_keyname(key_sneak));
g_settings.set("keymap_inventory", keycode_to_keyname(key_inventory));
g_settings.set("keymap_chat", keycode_to_keyname(key_chat));
g_settings.set("keymap_rangeselect", keycode_to_keyname(key_range));
g_settings.set("keymap_freemove", keycode_to_keyname(key_fly));
g_settings.set("keymap_fastmove", keycode_to_keyname(key_fast));
g_settings.set("keymap_special1", keycode_to_keyname(key_use));
g_settings.set("keymap_print_debug_stacks", keycode_to_keyname(key_dump));
g_settings->set("keymap_forward", key_forward.sym());
g_settings->set("keymap_backward", key_backward.sym());
g_settings->set("keymap_left", key_left.sym());
g_settings->set("keymap_right", key_right.sym());
g_settings->set("keymap_jump", key_jump.sym());
g_settings->set("keymap_sneak", key_sneak.sym());
g_settings->set("keymap_inventory", key_inventory.sym());
g_settings->set("keymap_chat", key_chat.sym());
g_settings->set("keymap_cmd", key_cmd.sym());
g_settings->set("keymap_rangeselect", key_range.sym());
g_settings->set("keymap_freemove", key_fly.sym());
g_settings->set("keymap_fastmove", key_fast.sym());
g_settings->set("keymap_special1", key_use.sym());
g_settings->set("keymap_print_debug_stacks", key_dump.sym());
clearKeyCache();
return true;
}
@@ -351,6 +373,7 @@ void GUIKeyChangeMenu::init_keys()
key_sneak = getKeySetting("keymap_sneak");
key_inventory = getKeySetting("keymap_inventory");
key_chat = getKeySetting("keymap_chat");
key_cmd = getKeySetting("keymap_cmd");
key_range = getKeySetting("keymap_rangeselect");
key_fly = getKeySetting("keymap_freemove");
key_fast = getKeySetting("keymap_fastmove");
@@ -366,45 +389,48 @@ bool GUIKeyChangeMenu::resetMenu()
{
case GUI_ID_KEY_FORWARD_BUTTON:
this->forward->setText(
narrow_to_wide(KeyNames[key_forward]).c_str());
wgettext(key_forward.name()));
break;
case GUI_ID_KEY_BACKWARD_BUTTON:
this->backward->setText(
narrow_to_wide(KeyNames[key_backward]).c_str());
wgettext(key_backward.name()));
break;
case GUI_ID_KEY_LEFT_BUTTON:
this->left->setText(narrow_to_wide(KeyNames[key_left]).c_str());
this->left->setText(wgettext(key_left.name()));
break;
case GUI_ID_KEY_RIGHT_BUTTON:
this->right->setText(narrow_to_wide(KeyNames[key_right]).c_str());
this->right->setText(wgettext(key_right.name()));
break;
case GUI_ID_KEY_JUMP_BUTTON:
this->jump->setText(narrow_to_wide(KeyNames[key_jump]).c_str());
this->jump->setText(wgettext(key_jump.name()));
break;
case GUI_ID_KEY_SNEAK_BUTTON:
this->sneak->setText(narrow_to_wide(KeyNames[key_sneak]).c_str());
this->sneak->setText(wgettext(key_sneak.name()));
break;
case GUI_ID_KEY_INVENTORY_BUTTON:
this->inventory->setText(
narrow_to_wide(KeyNames[key_inventory]).c_str());
wgettext(key_inventory.name()));
break;
case GUI_ID_KEY_CHAT_BUTTON:
this->chat->setText(narrow_to_wide(KeyNames[key_chat]).c_str());
this->chat->setText(wgettext(key_chat.name()));
break;
case GUI_ID_KEY_CMD_BUTTON:
this->cmd->setText(wgettext(key_cmd.name()));
break;
case GUI_ID_KEY_RANGE_BUTTON:
this->range->setText(narrow_to_wide(KeyNames[key_range]).c_str());
this->range->setText(wgettext(key_range.name()));
break;
case GUI_ID_KEY_FLY_BUTTON:
this->fly->setText(narrow_to_wide(KeyNames[key_fly]).c_str());
this->fly->setText(wgettext(key_fly.name()));
break;
case GUI_ID_KEY_FAST_BUTTON:
this->fast->setText(narrow_to_wide(KeyNames[key_fast]).c_str());
this->fast->setText(wgettext(key_fast.name()));
break;
case GUI_ID_KEY_USE_BUTTON:
this->use->setText(narrow_to_wide(KeyNames[key_use]).c_str());
this->use->setText(wgettext(key_use.name()));
break;
case GUI_ID_KEY_DUMP_BUTTON:
this->dump->setText(narrow_to_wide(KeyNames[key_dump]).c_str());
this->dump->setText(wgettext(key_dump.name()));
break;
}
activeKey = -1;
@@ -417,85 +443,80 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
&& event.KeyInput.PressedDown)
{
changeCtype("");
KeyPress kp(event.KeyInput);
if (activeKey == GUI_ID_KEY_FORWARD_BUTTON)
{
this->forward->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_forward = event.KeyInput.Key;
this->forward->setText(wgettext(kp.name()));
this->key_forward = kp;
}
else if (activeKey == GUI_ID_KEY_BACKWARD_BUTTON)
{
this->backward->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_backward = event.KeyInput.Key;
this->backward->setText(wgettext(kp.name()));
this->key_backward = kp;
}
else if (activeKey == GUI_ID_KEY_LEFT_BUTTON)
{
this->left->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_left = event.KeyInput.Key;
this->left->setText(wgettext(kp.name()));
this->key_left = kp;
}
else if (activeKey == GUI_ID_KEY_RIGHT_BUTTON)
{
this->right->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_right = event.KeyInput.Key;
this->right->setText(wgettext(kp.name()));
this->key_right = kp;
}
else if (activeKey == GUI_ID_KEY_JUMP_BUTTON)
{
this->jump->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_jump = event.KeyInput.Key;
this->jump->setText(wgettext(kp.name()));
this->key_jump = kp;
}
else if (activeKey == GUI_ID_KEY_SNEAK_BUTTON)
{
this->sneak->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_sneak = event.KeyInput.Key;
this->sneak->setText(wgettext(kp.name()));
this->key_sneak = kp;
}
else if (activeKey == GUI_ID_KEY_INVENTORY_BUTTON)
{
this->inventory->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_inventory = event.KeyInput.Key;
this->inventory->setText(wgettext(kp.name()));
this->key_inventory = kp;
}
else if (activeKey == GUI_ID_KEY_CHAT_BUTTON)
{
this->chat->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_chat = event.KeyInput.Key;
this->chat->setText(wgettext(kp.name()));
this->key_chat = kp;
}
else if (activeKey == GUI_ID_KEY_CMD_BUTTON)
{
this->cmd->setText(wgettext(kp.name()));
this->key_cmd = kp;
}
else if (activeKey == GUI_ID_KEY_RANGE_BUTTON)
{
this->range->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_range = event.KeyInput.Key;
this->range->setText(wgettext(kp.name()));
this->key_range = kp;
}
else if (activeKey == GUI_ID_KEY_FLY_BUTTON)
{
this->fly->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_fly = event.KeyInput.Key;
this->fly->setText(wgettext(kp.name()));
this->key_fly = kp;
}
else if (activeKey == GUI_ID_KEY_FAST_BUTTON)
{
this->fast->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_fast = event.KeyInput.Key;
this->fast->setText(wgettext(kp.name()));
this->key_fast = kp;
}
else if (activeKey == GUI_ID_KEY_USE_BUTTON)
{
this->use->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_use = event.KeyInput.Key;
this->use->setText(wgettext(kp.name()));
this->key_use = kp;
}
else if (activeKey == GUI_ID_KEY_DUMP_BUTTON)
{
this->dump->setText(
narrow_to_wide(KeyNames[event.KeyInput.Key]).c_str());
this->key_dump = event.KeyInput.Key;
this->dump->setText(wgettext(kp.name()));
this->key_dump = kp;
}
changeCtype("C");
activeKey = -1;
return true;
}
@@ -514,6 +535,12 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
}
if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
{
if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
{
changeCtype("");
}
switch (event.GUIEvent.Caller->getID())
{
case GUI_ID_BACK_BUTTON: //back
@@ -526,70 +553,76 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
case GUI_ID_KEY_FORWARD_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->forward->setText(L"press Key");
this->forward->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_BACKWARD_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->backward->setText(L"press Key");
this->backward->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_LEFT_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->left->setText(L"press Key");
this->left->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_RIGHT_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->right->setText(L"press Key");
this->right->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_USE_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->use->setText(L"press Key");
this->use->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_FLY_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->fly->setText(L"press Key");
this->fly->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_FAST_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->fast->setText(L"press Key");
this->fast->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_JUMP_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->jump->setText(L"press Key");
this->jump->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_CHAT_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->chat->setText(L"press Key");
this->chat->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_CMD_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->cmd->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_SNEAK_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->sneak->setText(L"press Key");
this->sneak->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_INVENTORY_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->inventory->setText(L"press Key");
this->inventory->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_DUMP_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->dump->setText(L"press Key");
this->dump->setText(wgettext("press Key"));
break;
case GUI_ID_KEY_RANGE_BUTTON:
resetMenu();
activeKey = event.GUIEvent.Caller->getID();
this->range->setText(L"press Key");
this->range->setText(wgettext("press Key"));
break;
}
//Buttons
changeCtype("C");
}
}

View File

@@ -26,53 +26,29 @@
#include "utility.h"
#include "modalMenu.h"
#include "client.h"
#include "gettext.h"
#include "keycode.h"
#include <string>
static const char *KeyNames[] =
{ "-", "Left Button", "Right Button", "Cancel", "Middle Button", "X Button 1",
"X Button 2", "-", "Back", "Tab", "-", "-", "Clear", "Return", "-",
"-", "Shift", "Control", "Menu", "Pause", "Capital", "Kana", "-",
"Junja", "Final", "Kanji", "-", "Escape", "Convert", "Nonconvert",
"Accept", "Mode Change", "Space", "Priot", "Next", "End", "Home",
"Left", "Up", "Right", "Down", "Select", "Print", "Execute",
"Snapshot", "Insert", "Delete", "Help", "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "-", "-", "-", "-", "-", "-", "-", "A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Left Windows",
"Right Windows", "Apps", "-", "Sleep", "Numpad 0", "Numpad 1",
"Numpad 2", "Numpad 3", "Numpad 4", "Numpad 5", "Numpad 6", "Numpad 7",
"Numpad 8", "Numpad 9", "Numpad *", "Numpad +", "Numpad /", "Numpad -",
"Numpad .", "Numpad /", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
"F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18",
"F19", "F20", "F21", "F22", "F23", "F24", "-", "-", "-", "-", "-", "-",
"-", "-", "Num Lock", "Scroll Lock", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "Left Shift", "Right Shight",
"Left Control", "Right Control", "Left Menu", "Right Menu", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "Plus", "Comma", "Minus", "Period", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "Attn", "CrSel",
"ExSel", "Erase OEF", "Play", "Zoom", "PA1", "OEM Clear", "-" };
enum
{
GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
//buttons
GUI_ID_KEY_FORWARD_BUTTON,
GUI_ID_KEY_BACKWARD_BUTTON,
GUI_ID_KEY_LEFT_BUTTON,
GUI_ID_KEY_RIGHT_BUTTON,
GUI_ID_KEY_USE_BUTTON,
GUI_ID_KEY_FLY_BUTTON,
GUI_ID_KEY_FAST_BUTTON,
GUI_ID_KEY_JUMP_BUTTON,
GUI_ID_KEY_CHAT_BUTTON,
GUI_ID_KEY_SNEAK_BUTTON,
GUI_ID_KEY_INVENTORY_BUTTON,
GUI_ID_KEY_DUMP_BUTTON,
GUI_ID_KEY_RANGE_BUTTON
};
enum
{
GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
//buttons
GUI_ID_KEY_FORWARD_BUTTON,
GUI_ID_KEY_BACKWARD_BUTTON,
GUI_ID_KEY_LEFT_BUTTON,
GUI_ID_KEY_RIGHT_BUTTON,
GUI_ID_KEY_USE_BUTTON,
GUI_ID_KEY_FLY_BUTTON,
GUI_ID_KEY_FAST_BUTTON,
GUI_ID_KEY_JUMP_BUTTON,
GUI_ID_KEY_CHAT_BUTTON,
GUI_ID_KEY_CMD_BUTTON,
GUI_ID_KEY_SNEAK_BUTTON,
GUI_ID_KEY_INVENTORY_BUTTON,
GUI_ID_KEY_DUMP_BUTTON,
GUI_ID_KEY_RANGE_BUTTON
};
class GUIKeyChangeMenu: public GUIModalMenu
{
@@ -112,21 +88,23 @@ class GUIKeyChangeMenu: public GUIModalMenu
gui::IGUIButton *range;
gui::IGUIButton *dump;
gui::IGUIButton *chat;
gui::IGUIButton *cmd;
u32 activeKey;
u32 key_forward;
u32 key_backward;
u32 key_left;
u32 key_right;
u32 key_use;
u32 key_sneak;
u32 key_jump;
u32 key_inventory;
u32 key_fly;
u32 key_fast;
u32 key_range;
u32 key_chat;
u32 key_dump;
s32 activeKey;
KeyPress key_forward;
KeyPress key_backward;
KeyPress key_left;
KeyPress key_right;
KeyPress key_use;
KeyPress key_sneak;
KeyPress key_jump;
KeyPress key_inventory;
KeyPress key_fly;
KeyPress key_fast;
KeyPress key_range;
KeyPress key_chat;
KeyPress key_cmd;
KeyPress key_dump;
};
#endif

View File

@@ -22,7 +22,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "gettext.h"
@@ -164,6 +168,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
v2s32 topleft_client(40, 0);
v2s32 size_client = size - v2s32(40, 0);
changeCtype("");
{
core::rect<s32> rect(0, 0, 20, 125);
rect += topleft_client + v2s32(-15, 60);
@@ -177,9 +182,10 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, 50+6);
Environment->addStaticText(chartowchar_t(gettext("Name/Password")),
Environment->addStaticText(wgettext("Name/Password"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, 50);
@@ -194,21 +200,25 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
gui::IGUIEditBox *e =
Environment->addEditBox(L"", rect, true, this, 264);
e->setPasswordBox(true);
if(text_name != L"" && text_address != L"")
Environment->setFocus(e);
}
changeCtype("");
// Address + port
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, 100+6);
Environment->addStaticText(chartowchar_t(gettext("Address/Port")),
Environment->addStaticText(wgettext("Address/Port"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, 100);
gui::IGUIElement *e =
Environment->addEditBox(text_address.c_str(), rect, true, this, GUI_ID_ADDRESS_INPUT);
if(text_name != L"")
if(text_name != L"" && text_address == L"")
Environment->setFocus(e);
}
{
@@ -217,23 +227,24 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
rect += topleft_client + v2s32(size_client.X-60-100, 100);
Environment->addEditBox(text_port.c_str(), rect, true, this, GUI_ID_PORT_INPUT);
}
changeCtype("");
{
core::rect<s32> rect(0, 0, 400, 20);
rect += topleft_client + v2s32(160, 100+35);
Environment->addStaticText(chartowchar_t(gettext("Leave address blank to start a local server.")),
Environment->addStaticText(wgettext("Leave address blank to start a local server."),
rect, false, true, this, -1);
}
{
core::rect<s32> rect(0, 0, 250, 30);
rect += topleft_client + v2s32(35, 150);
Environment->addCheckBox(fancy_trees, rect, this, GUI_ID_FANCYTREE_CB,
chartowchar_t(gettext("Fancy trees")));
wgettext("Fancy trees"));
}
{
core::rect<s32> rect(0, 0, 250, 30);
rect += topleft_client + v2s32(35, 150+30);
Environment->addCheckBox(smooth_lighting, rect, this, GUI_ID_SMOOTH_LIGHTING_CB,
chartowchar_t(gettext("Smooth Lighting")));
wgettext("Smooth Lighting"));
}
// Start game button
{
@@ -241,7 +252,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
//rect += topleft_client + v2s32(size_client.X/2-180/2, 225-30/2);
rect += topleft_client + v2s32(size_client.X-180-40, 150+25);
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
chartowchar_t(gettext("Start Game / Connect")));
wgettext("Start Game / Connect"));
}
// Key change button
@@ -250,7 +261,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
//rect += topleft_client + v2s32(size_client.X/2-180/2, 225-30/2);
rect += topleft_client + v2s32(size_client.X-180-40-100-20, 150+25);
Environment->addButton(rect, this, GUI_ID_CHANGE_KEYS_BUTTON,
chartowchar_t(gettext("Change keys")));
wgettext("Change keys"));
}
/*
Server section
@@ -273,13 +284,13 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 250, 30);
rect += topleft_server + v2s32(35, 30);
Environment->addCheckBox(creative_mode, rect, this, GUI_ID_CREATIVE_CB,
chartowchar_t(gettext("Creative Mode")));
wgettext("Creative Mode"));
}
{
core::rect<s32> rect(0, 0, 250, 30);
rect += topleft_server + v2s32(35, 60);
Environment->addCheckBox(enable_damage, rect, this, GUI_ID_DAMAGE_CB,
chartowchar_t(gettext("Enable Damage")));
wgettext("Enable Damage"));
}
// Map delete button
{
@@ -287,8 +298,9 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
//rect += topleft_server + v2s32(size_server.X-40-130, 100+25);
rect += topleft_server + v2s32(40, 100+25);
Environment->addButton(rect, this, GUI_ID_DELETE_MAP_BUTTON,
chartowchar_t(gettext("Delete map")));
wgettext("Delete map"));
}
changeCtype("C");
}
void GUIMainMenu::drawMenu()

View File

@@ -21,6 +21,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "gettext.h"
@@ -85,14 +90,16 @@ void GUIMessageMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(m_message_text.c_str(), rect, false,
true, this, 256);
}
changeCtype("");
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
gui::IGUIElement *e =
Environment->addButton(rect, this, 257,
chartowchar_t(gettext("Proceed")));
wgettext("Proceed"));
Environment->setFocus(e);
}
changeCtype("C");
}
void GUIMessageMenu::drawMenu()

View File

@@ -20,6 +20,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "debug.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "gettext.h"
@@ -96,12 +101,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
Add stuff
*/
s32 ypos = 50;
changeCtype("");
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(chartowchar_t(gettext("Old Password")),
Environment->addStaticText(wgettext("Old Password"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, ypos);
@@ -111,12 +118,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
e->setPasswordBox(true);
}
ypos += 50;
changeCtype("");
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(chartowchar_t(gettext("New Password")),
Environment->addStaticText(wgettext("New Password"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, ypos);
@@ -125,12 +134,14 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
e->setPasswordBox(true);
}
ypos += 50;
changeCtype("");
{
core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(chartowchar_t(gettext("Confirm Password")),
Environment->addStaticText(wgettext("Confirm Password"),
rect, false, true, this, -1);
}
changeCtype("C");
{
core::rect<s32> rect(0, 0, 230, 30);
rect += topleft_client + v2s32(160, ypos);
@@ -140,10 +151,11 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
}
ypos += 50;
changeCtype("");
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, ypos);
Environment->addButton(rect, this, ID_change, chartowchar_t(gettext("Change")));
Environment->addButton(rect, this, ID_change, wgettext("Change"));
}
ypos += 50;
@@ -152,10 +164,11 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
rect += topleft_client + v2s32(35, ypos);
IGUIElement *e =
Environment->addStaticText(
chartowchar_t(gettext("Passwords do not match!")),
wgettext("Passwords do not match!"),
rect, false, true, this, ID_message);
e->setVisible(false);
}
changeCtype("C");
}

View File

@@ -23,6 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "porting.h"
#include "config.h"
#include "main.h"
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "gettext.h"
@@ -103,32 +108,33 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
const s32 btn_gap = 20;
const s32 btn_num = 4;
s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
changeCtype("");
{
core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y);
Environment->addButton(rect, this, 256,
chartowchar_t(gettext("Continue")));
wgettext("Continue"));
}
btn_y += btn_height + btn_gap;
{
core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y);
Environment->addButton(rect, this, 261,
chartowchar_t(gettext("Change Password")));
wgettext("Change Password"));
}
btn_y += btn_height + btn_gap;
{
core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y);
Environment->addButton(rect, this, 260,
chartowchar_t(gettext("Disconnect")));
wgettext("Disconnect"));
}
btn_y += btn_height + btn_gap;
{
core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y);
Environment->addButton(rect, this, 257,
chartowchar_t(gettext("Exit to OS")));
wgettext("Exit to OS"));
}
{
@@ -172,7 +178,7 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
);*/
std::ostringstream os;
os<<"Minetest-c55\n";
os<<"Minetest\n";
os<<"by Perttu Ahola and contributors\n";
os<<"celeron55@gmail.com\n";
os<<BUILD_INFO<<"\n";
@@ -180,6 +186,7 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
}
changeCtype("C");
}
void GUIPauseMenu::drawMenu()

View File

@@ -21,6 +21,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h"
#include "serialization.h"
#include <string>
#include <IGUICheckBox.h>
#include <IGUIEditBox.h>
#include <IGUIButton.h>
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "gettext.h"
@@ -103,13 +108,21 @@ void GUITextInputMenu::regenerateGui(v2u32 screensize)
gui::IGUIElement *e =
Environment->addEditBox(text.c_str(), rect, true, this, 256);
Environment->setFocus(e);
irr::SEvent evt;
evt.EventType = EET_KEY_INPUT_EVENT;
evt.KeyInput.Key = KEY_END;
evt.KeyInput.PressedDown = true;
e->OnEvent(evt);
}
changeCtype("");
{
core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
Environment->addButton(rect, this, 257,
chartowchar_t(gettext("Proceed")));
wgettext("Proceed"));
}
changeCtype("C");
}
void GUITextInputMenu::drawMenu()

View File

@@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_inventory.h"
#include "content_sao.h"
#include "player.h"
#include "log.h"
/*
InventoryItem
@@ -97,7 +98,7 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
{
std::string inventorystring;
std::getline(is, inventorystring, '|');
return new MapBlockObjectItem(inventorystring);
throw SerializationError("MBOItem not supported anymore");
}
else if(name == "CraftItem")
{
@@ -117,21 +118,25 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
}
else
{
dstream<<"Unknown InventoryItem name=\""<<name<<"\""<<std::endl;
infostream<<"Unknown InventoryItem name=\""<<name<<"\""<<std::endl;
throw SerializationError("Unknown InventoryItem name");
}
}
std::string InventoryItem::getItemString() {
// Get item string
std::ostringstream os(std::ios_base::binary);
serialize(os);
return os.str();
}
ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f pos)
{
/*
Create an ItemSAO
*/
// Get item string
std::ostringstream os(std::ios_base::binary);
serialize(os);
// Create object
ServerActiveObject *obj = new ItemSAO(env, 0, pos, os.str());
ServerActiveObject *obj = new ItemSAO(env, 0, pos, getItemString());
return obj;
}
@@ -139,12 +144,12 @@ ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f
MaterialItem
*/
bool MaterialItem::isCookable()
bool MaterialItem::isCookable() const
{
return item_material_is_cookable(m_content);
}
InventoryItem *MaterialItem::createCookResult()
InventoryItem *MaterialItem::createCookResult() const
{
return item_material_create_cook_result(m_content);
}
@@ -154,7 +159,7 @@ InventoryItem *MaterialItem::createCookResult()
*/
#ifndef SERVER
video::ITexture * CraftItem::getImage()
video::ITexture * CraftItem::getImage() const
{
if(g_texturesource == NULL)
return NULL;
@@ -176,7 +181,7 @@ ServerActiveObject* CraftItem::createSAO(ServerEnvironment *env, u16 id, v3f pos
return InventoryItem::createSAO(env, id, pos);
}
u16 CraftItem::getDropCount()
u16 CraftItem::getDropCount() const
{
// Special cases
s16 dc = item_craft_get_drop_count(m_subname);
@@ -186,12 +191,12 @@ u16 CraftItem::getDropCount()
return InventoryItem::getDropCount();
}
bool CraftItem::isCookable()
bool CraftItem::isCookable() const
{
return item_craft_is_cookable(m_subname);
}
InventoryItem *CraftItem::createCookResult()
InventoryItem *CraftItem::createCookResult() const
{
return item_craft_create_cook_result(m_subname);
}
@@ -200,87 +205,21 @@ bool CraftItem::use(ServerEnvironment *env, Player *player)
{
if(item_craft_is_eatable(m_subname))
{
u16 result_count = getCount() - 1; // Eat one at a time
s16 hp_change = item_craft_eat_hp_change(m_subname);
if(player->hp + hp_change > 20)
player->hp = 20;
else
player->hp += hp_change;
return true;
if(result_count < 1)
return true;
else
setCount(result_count);
}
return false;
}
/*
MapBlockObjectItem DEPRECATED
TODO: Remove
*/
#ifndef SERVER
video::ITexture * MapBlockObjectItem::getImage()
{
if(m_inventorystring.substr(0,3) == "Rat")
return g_texturesource->getTextureRaw("rat.png");
if(m_inventorystring.substr(0,4) == "Sign")
return g_texturesource->getTextureRaw("sign.png");
return NULL;
}
#endif
std::string MapBlockObjectItem::getText()
{
if(m_inventorystring.substr(0,3) == "Rat")
return "";
if(m_inventorystring.substr(0,4) == "Sign")
return "";
return "obj";
}
MapBlockObject * MapBlockObjectItem::createObject
(v3f pos, f32 player_yaw, f32 player_pitch)
{
std::istringstream is(m_inventorystring);
std::string name;
std::getline(is, name, ' ');
if(name == "None")
{
return NULL;
}
else if(name == "Sign")
{
std::string text;
std::getline(is, text, '|');
SignObject *obj = new SignObject(NULL, -1, pos);
obj->setText(text);
obj->setYaw(-player_yaw);
return obj;
}
else if(name == "Rat")
{
RatObject *obj = new RatObject(NULL, -1, pos);
return obj;
}
else if(name == "ItemObj")
{
/*
Now we are an inventory item containing the serialization
string of an object that contains the serialization
string of an inventory item. Fuck this.
*/
//assert(0);
dstream<<__FUNCTION_NAME<<": WARNING: Ignoring ItemObj "
<<"because an item-object should never be inside "
<<"an object-item."<<std::endl;
return NULL;
}
else
{
return NULL;
}
}
/*
Inventory
*/
@@ -320,7 +259,7 @@ void InventoryList::clearItems()
//setDirty(true);
}
void InventoryList::serialize(std::ostream &os)
void InventoryList::serialize(std::ostream &os) const
{
//os.imbue(std::locale("C"));
@@ -416,7 +355,7 @@ InventoryList & InventoryList::operator = (const InventoryList &other)
return *this;
}
std::string InventoryList::getName()
const std::string &InventoryList::getName() const
{
return m_name;
}
@@ -443,6 +382,13 @@ u32 InventoryList::getFreeSlots()
return getSize() - getUsedSlots();
}
const InventoryItem * InventoryList::getItem(u32 i) const
{
if(i > m_items.size() - 1)
return NULL;
return m_items[i];
}
InventoryItem * InventoryList::getItem(u32 i)
{
if(i > m_items.size() - 1)
@@ -542,20 +488,20 @@ InventoryItem * InventoryList::addItem(u32 i, InventoryItem *newitem)
}
}
bool InventoryList::itemFits(u32 i, InventoryItem *newitem)
bool InventoryList::itemFits(const u32 i, const InventoryItem *newitem)
{
// If it is an empty position, it's an easy job.
InventoryItem *to_item = getItem(i);
const InventoryItem *to_item = getItem(i);
if(to_item == NULL)
{
return true;
}
// If not addable, return the item
// If not addable, fail
if(newitem->addableTo(to_item) == false)
return false;
// If the item fits fully in the slot, add counter and delete it
// If the item fits fully in the slot, pass
if(newitem->getCount() <= to_item->freeSpace())
{
return true;
@@ -564,6 +510,26 @@ bool InventoryList::itemFits(u32 i, InventoryItem *newitem)
return false;
}
bool InventoryList::roomForItem(const InventoryItem *item)
{
for(u32 i=0; i<m_items.size(); i++)
if(itemFits(i, item))
return true;
return false;
}
bool InventoryList::roomForCookedItem(const InventoryItem *item)
{
if(!item)
return false;
const InventoryItem *cook = item->createCookResult();
if(!cook)
return false;
bool room = roomForItem(cook);
delete cook;
return room;
}
InventoryItem * InventoryList::takeItem(u32 i, u32 count)
{
if(count == 0)
@@ -654,7 +620,7 @@ Inventory & Inventory::operator = (const Inventory &other)
return *this;
}
void Inventory::serialize(std::ostream &os)
void Inventory::serialize(std::ostream &os) const
{
for(u32 i=0; i<m_lists.size(); i++)
{
@@ -736,7 +702,15 @@ InventoryList * Inventory::getList(const std::string &name)
return m_lists[i];
}
s32 Inventory::getListIndex(const std::string &name)
const InventoryList * Inventory::getList(const std::string &name) const
{
s32 i = getListIndex(name);
if(i == -1)
return NULL;
return m_lists[i];
}
const s32 Inventory::getListIndex(const std::string &name) const
{
for(u32 i=0; i<m_lists.size(); i++)
{
@@ -765,51 +739,56 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
return a;
}
static std::string describeC(const struct InventoryContext *c)
{
if(c->current_player == NULL)
return "current_player=NULL";
else
return std::string("current_player=") + c->current_player->getName();
}
void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
{
#if 1
/*dstream<<"from_inv="<<from_inv<<" to_inv="<<to_inv<<std::endl;
dstream<<"from_list="<<from_list<<" to_list="<<to_list<<std::endl;
dstream<<"from_i="<<from_i<<" to_i="<<to_i<<std::endl;*/
Inventory *inv_from = mgr->getInventory(c, from_inv);
Inventory *inv_to = mgr->getInventory(c, to_inv);
if(!inv_from || !inv_to)
{
dstream<<__FUNCTION_NAME<<": Operation not allowed "
<<"(inventories not found)"<<std::endl;
if(!inv_from){
infostream<<"IMoveAction::apply(): FAIL: source inventory not found: "
<<"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""
<<", to_inv=\""<<to_inv<<"\""<<std::endl;
return;
}
if(!inv_to){
infostream<<"IMoveAction::apply(): FAIL: destination inventory not found: "
"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""
<<", to_inv=\""<<to_inv<<"\""<<std::endl;
return;
}
InventoryList *list_from = inv_from->getList(from_list);
InventoryList *list_to = inv_to->getList(to_list);
/*dstream<<"list_from="<<list_from<<" list_to="<<list_to
<<std::endl;*/
/*if(list_from)
dstream<<" list_from->getItem(from_i)="<<list_from->getItem(from_i)
<<std::endl;
if(list_to)
dstream<<" list_to->getItem(to_i)="<<list_to->getItem(to_i)
<<std::endl;*/
/*
If a list doesn't exist or the source item doesn't exist
*/
if(!list_from || !list_to)
{
dstream<<__FUNCTION_NAME<<": Operation not allowed "
<<"(a list doesn't exist)"
<<std::endl;
if(!list_from){
infostream<<"IMoveAction::apply(): FAIL: source list not found: "
<<"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""
<<", from_list=\""<<from_list<<"\""<<std::endl;
return;
}
if(!list_to){
infostream<<"IMoveAction::apply(): FAIL: destination list not found: "
<<"context=["<<describeC(c)<<"], to_inv=\""<<to_inv<<"\""
<<", to_list=\""<<to_list<<"\""<<std::endl;
return;
}
if(list_from->getItem(from_i) == NULL)
{
dstream<<__FUNCTION_NAME<<": Operation not allowed "
<<"(the source item doesn't exist)"
<<std::endl;
infostream<<"IMoveAction::apply(): FAIL: source item not found: "
<<"context=["<<describeC(c)<<"], from_inv=\""<<from_inv<<"\""
<<", from_list=\""<<from_list<<"\""
<<" from_i="<<from_i<<std::endl;
return;
}
/*
@@ -817,8 +796,9 @@ void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
*/
if(inv_from == inv_to && list_from == list_to && from_i == to_i)
{
dstream<<__FUNCTION_NAME<<": Operation not allowed "
<<"(source and the destination slots are the same)"<<std::endl;
infostream<<"IMoveAction::apply(): FAIL: source and destination slots "
<<"are the same: inv=\""<<from_inv<<"\" list=\""<<from_list
<<"\" i="<<from_i<<std::endl;
return;
}
@@ -859,14 +839,23 @@ void IMoveAction::apply(InventoryContext *c, InventoryManager *mgr)
mgr->inventoryModified(c, from_inv);
if(from_inv != to_inv)
mgr->inventoryModified(c, to_inv);
#endif
infostream<<"IMoveAction::apply(): moved at "
<<"["<<describeC(c)<<"]"
<<" from inv=\""<<from_inv<<"\""
<<" list=\""<<from_list<<"\""
<<" i="<<from_i
<<" to inv=\""<<to_inv<<"\""
<<" list=\""<<to_list<<"\""
<<" i="<<to_i
<<std::endl;
}
/*
Craft checking system
*/
bool ItemSpec::checkItem(InventoryItem *item)
bool ItemSpec::checkItem(const InventoryItem *item) const
{
if(type == ITEM_NONE)
{
@@ -916,7 +905,7 @@ bool ItemSpec::checkItem(InventoryItem *item)
return true;
}
bool checkItemCombination(InventoryItem **items, ItemSpec *specs)
bool checkItemCombination(InventoryItem const * const *items, const ItemSpec *specs)
{
u16 items_min_x = 100;
u16 items_max_x = 100;
@@ -979,8 +968,8 @@ bool checkItemCombination(InventoryItem **items, ItemSpec *specs)
u16 items_y = items_min_y + y;
u16 specs_x = specs_min_x + x;
u16 specs_y = specs_min_y + y;
InventoryItem *item = items[items_y * 3 + items_x];
ItemSpec &spec = specs[specs_y * 3 + specs_x];
const InventoryItem *item = items[items_y * 3 + items_x];
const ItemSpec &spec = specs[specs_y * 3 + specs_x];
if(spec.checkItem(item) == false)
return false;

View File

@@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string>
#include "common_irrlicht.h"
#include "debug.h"
#include "mapblockobject.h"
#include "main.h" // For g_materials
#include "mapnode.h" // For content_t
@@ -49,31 +48,37 @@ class InventoryItem
virtual const char* getName() const = 0;
// Shall write the name and the parameters
virtual void serialize(std::ostream &os) = 0;
virtual void serialize(std::ostream &os) const = 0;
// Shall make an exact clone of the item
virtual InventoryItem* clone() = 0;
#ifndef SERVER
// Shall return an image to show in the GUI (or NULL)
virtual video::ITexture * getImage() { return NULL; }
// Return the name of the image for this item
virtual std::string getBasename() const { return ""; }
// Shall return an image of the item (or NULL)
virtual video::ITexture * getImage() const { return NULL; }
// Shall return an image of the item without embellishments (or NULL)
virtual video::ITexture * getImageRaw() const { return getImage(); }
#endif
// Shall return a text to show in the GUI
virtual std::string getText() { return ""; }
// Returns the string used for inventory
virtual std::string getItemString();
// Creates an object from the item, to be placed in the world.
virtual ServerActiveObject* createSAO(ServerEnvironment *env, u16 id, v3f pos);
// Gets amount of items that dropping one SAO will decrement
virtual u16 getDropCount(){ return getCount(); }
virtual u16 getDropCount() const { return getCount(); }
/*
Quantity methods
*/
// Shall return true if the item can be add()ed to the other
virtual bool addableTo(InventoryItem *other)
virtual bool addableTo(const InventoryItem *other) const
{
return false;
}
u16 getCount()
u16 getCount() const
{
return m_count;
}
@@ -82,7 +87,7 @@ class InventoryItem
m_count = count;
}
// This should return something else for stackable items
virtual u16 freeSpace()
virtual u16 freeSpace() const
{
return 0;
}
@@ -102,11 +107,11 @@ class InventoryItem
*/
// Whether it can be cooked
virtual bool isCookable(){return false;}
virtual bool isCookable() const {return false;}
// Time of cooking
virtual float getCookTime(){return 3.0;}
// Result of cooking (can randomize)
virtual InventoryItem *createCookResult(){return NULL;}
virtual InventoryItem *createCookResult() const {return NULL;}
// Eat, press, activate, whatever.
// Called when item is right-clicked when lying on ground.
@@ -133,7 +138,7 @@ class MaterialItem : public InventoryItem
{
return "MaterialItem";
}
virtual void serialize(std::ostream &os)
virtual void serialize(std::ostream &os) const
{
//os.imbue(std::locale("C"));
os<<"MaterialItem2";
@@ -147,10 +152,9 @@ class MaterialItem : public InventoryItem
return new MaterialItem(m_content, m_count);
}
#ifndef SERVER
video::ITexture * getImage()
video::ITexture * getImage() const
{
return content_features(m_content).inventory_texture;
return NULL;
}
#endif
std::string getText()
@@ -160,7 +164,7 @@ class MaterialItem : public InventoryItem
return os.str();
}
virtual bool addableTo(InventoryItem *other)
virtual bool addableTo(const InventoryItem *other) const
{
if(std::string(other->getName()) != "MaterialItem")
return false;
@@ -169,7 +173,7 @@ class MaterialItem : public InventoryItem
return false;
return true;
}
u16 freeSpace()
u16 freeSpace() const
{
if(m_count > QUANTITY_ITEM_MAX_COUNT)
return 0;
@@ -178,8 +182,8 @@ class MaterialItem : public InventoryItem
/*
Other properties
*/
bool isCookable();
InventoryItem *createCookResult();
bool isCookable() const;
InventoryItem *createCookResult() const;
/*
Special methods
*/
@@ -191,61 +195,6 @@ class MaterialItem : public InventoryItem
content_t m_content;
};
//TODO: Remove
class MapBlockObjectItem : public InventoryItem
{
public:
MapBlockObjectItem(std::string inventorystring):
InventoryItem(1)
{
m_inventorystring = inventorystring;
}
/*
Implementation interface
*/
virtual const char* getName() const
{
return "MBOItem";
}
virtual void serialize(std::ostream &os)
{
for(;;)
{
size_t t = m_inventorystring.find('|');
if(t == std::string::npos)
break;
m_inventorystring[t] = '?';
}
os<<getName();
os<<" ";
os<<m_inventorystring;
os<<"|";
}
virtual InventoryItem* clone()
{
return new MapBlockObjectItem(m_inventorystring);
}
#ifndef SERVER
video::ITexture * getImage();
#endif
std::string getText();
/*
Special methods
*/
std::string getInventoryString()
{
return m_inventorystring;
}
MapBlockObject * createObject(v3f pos, f32 player_yaw, f32 player_pitch);
private:
std::string m_inventorystring;
};
/*
An item that is used as a mid-product when crafting.
Subnames:
@@ -266,7 +215,7 @@ class CraftItem : public InventoryItem
{
return "CraftItem";
}
virtual void serialize(std::ostream &os)
virtual void serialize(std::ostream &os) const
{
os<<getName();
os<<" ";
@@ -279,7 +228,7 @@ class CraftItem : public InventoryItem
return new CraftItem(m_subname, m_count);
}
#ifndef SERVER
video::ITexture * getImage();
video::ITexture * getImage() const;
#endif
std::string getText()
{
@@ -289,9 +238,9 @@ class CraftItem : public InventoryItem
}
ServerActiveObject* createSAO(ServerEnvironment *env, u16 id, v3f pos);
u16 getDropCount();
u16 getDropCount() const;
virtual bool addableTo(InventoryItem *other)
virtual bool addableTo(const InventoryItem *other) const
{
if(std::string(other->getName()) != "CraftItem")
return false;
@@ -300,7 +249,7 @@ class CraftItem : public InventoryItem
return false;
return true;
}
u16 freeSpace()
u16 freeSpace() const
{
if(m_count > QUANTITY_ITEM_MAX_COUNT)
return 0;
@@ -311,8 +260,8 @@ class CraftItem : public InventoryItem
Other properties
*/
bool isCookable();
InventoryItem *createCookResult();
bool isCookable() const;
InventoryItem *createCookResult() const;
bool use(ServerEnvironment *env, Player *player);
@@ -343,7 +292,7 @@ class ToolItem : public InventoryItem
{
return "ToolItem";
}
virtual void serialize(std::ostream &os)
virtual void serialize(std::ostream &os) const
{
os<<getName();
os<<" ";
@@ -356,40 +305,43 @@ class ToolItem : public InventoryItem
return new ToolItem(m_toolname, m_wear);
}
#ifndef SERVER
video::ITexture * getImage()
std::string getBasename() const {
if(m_toolname == "WPick")
return "tool_woodpick.png";
else if(m_toolname == "STPick")
return "tool_stonepick.png";
else if(m_toolname == "SteelPick")
return "tool_steelpick.png";
else if(m_toolname == "MesePick")
return "tool_mesepick.png";
else if(m_toolname == "WShovel")
return "tool_woodshovel.png";
else if(m_toolname == "STShovel")
return "tool_stoneshovel.png";
else if(m_toolname == "SteelShovel")
return "tool_steelshovel.png";
else if(m_toolname == "WAxe")
return "tool_woodaxe.png";
else if(m_toolname == "STAxe")
return "tool_stoneaxe.png";
else if(m_toolname == "SteelAxe")
return "tool_steelaxe.png";
else if(m_toolname == "WSword")
return "tool_woodsword.png";
else if(m_toolname == "STSword")
return "tool_stonesword.png";
else if(m_toolname == "SteelSword")
return "tool_steelsword.png";
else
return "cloud.png";
}
video::ITexture * getImage() const
{
if(g_texturesource == NULL)
return NULL;
std::string basename;
if(m_toolname == "WPick")
basename = "tool_woodpick.png";
else if(m_toolname == "STPick")
basename = "tool_stonepick.png";
else if(m_toolname == "SteelPick")
basename = "tool_steelpick.png";
else if(m_toolname == "MesePick")
basename = "tool_mesepick.png";
else if(m_toolname == "WShovel")
basename = "tool_woodshovel.png";
else if(m_toolname == "STShovel")
basename = "tool_stoneshovel.png";
else if(m_toolname == "SteelShovel")
basename = "tool_steelshovel.png";
else if(m_toolname == "WAxe")
basename = "tool_woodaxe.png";
else if(m_toolname == "STAxe")
basename = "tool_stoneaxe.png";
else if(m_toolname == "SteelAxe")
basename = "tool_steelaxe.png";
else if(m_toolname == "WSword")
basename = "tool_woodsword.png";
else if(m_toolname == "STSword")
basename = "tool_stonesword.png";
else if(m_toolname == "SteelSword")
basename = "tool_steelsword.png";
else
basename = "cloud.png";
std::string basename = getBasename();
/*
Calculate a progress value with sane amount of
@@ -404,6 +356,14 @@ class ToolItem : public InventoryItem
return g_texturesource->getTextureRaw(os.str());
}
video::ITexture * getImageRaw() const
{
if(g_texturesource == NULL)
return NULL;
return g_texturesource->getTextureRaw(getBasename());
}
#endif
std::string getText()
{
@@ -461,13 +421,13 @@ class InventoryList
InventoryList(std::string name, u32 size);
~InventoryList();
void clearItems();
void serialize(std::ostream &os);
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
InventoryList(const InventoryList &other);
InventoryList & operator = (const InventoryList &other);
std::string getName();
const std::string &getName() const;
u32 getSize();
// Count used slots
u32 getUsedSlots();
@@ -477,6 +437,7 @@ class InventoryList
void setDirty(bool dirty=true){ m_dirty = dirty; }*/
// Get pointer to item
const InventoryItem * getItem(u32 i) const;
InventoryItem * getItem(u32 i);
// Returns old item (or NULL). Parameter can be NULL.
InventoryItem * changeItem(u32 i, InventoryItem *newitem);
@@ -494,7 +455,13 @@ class InventoryList
InventoryItem * addItem(u32 i, InventoryItem *newitem);
// Checks whether the item could be added to the given slot
bool itemFits(u32 i, InventoryItem *newitem);
bool itemFits(const u32 i, const InventoryItem *newitem);
// Checks whether there is room for a given item
bool roomForItem(const InventoryItem *item);
// Checks whether there is room for a given item aftr it has been cooked
bool roomForCookedItem(const InventoryItem *item);
// Takes some items from a slot.
// If there are not enough, takes as many as it can.
@@ -524,11 +491,12 @@ class Inventory
Inventory(const Inventory &other);
Inventory & operator = (const Inventory &other);
void serialize(std::ostream &os);
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
InventoryList * addList(const std::string &name, u32 size);
InventoryList * getList(const std::string &name);
const InventoryList * getList(const std::string &name) const;
bool deleteList(const std::string &name);
// A shorthand for adding items.
// Returns NULL if the item was fully added, leftover otherwise.
@@ -542,7 +510,7 @@ class Inventory
private:
// -1 if not found
s32 getListIndex(const std::string &name);
const s32 getListIndex(const std::string &name) const;
core::array<InventoryList*> m_lists;
};
@@ -558,7 +526,7 @@ struct InventoryContext
{}
};
class InventoryAction;
struct InventoryAction;
class InventoryManager
{
@@ -589,7 +557,7 @@ struct InventoryAction
static InventoryAction * deSerialize(std::istream &is);
virtual u16 getType() const = 0;
virtual void serialize(std::ostream &os) = 0;
virtual void serialize(std::ostream &os) const = 0;
virtual void apply(InventoryContext *c, InventoryManager *mgr) = 0;
};
@@ -637,7 +605,7 @@ struct IMoveAction : public InventoryAction
return IACTION_MOVE;
}
void serialize(std::ostream &os)
void serialize(std::ostream &os) const
{
os<<"Move ";
os<<count<<" ";
@@ -689,14 +657,14 @@ struct ItemSpec
{
}
bool checkItem(InventoryItem *item);
bool checkItem(const InventoryItem *item) const;
};
/*
items: a pointer to an array of 9 pointers to items
specs: a pointer to an array of 9 ItemSpecs
*/
bool checkItemCombination(InventoryItem **items, ItemSpec *specs);
bool checkItemCombination(const InventoryItem * const*items, const ItemSpec *specs);
#endif

View File

@@ -19,6 +19,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "keycode.h"
#include "main.h" // For g_settings
#include "exceptions.h"
#include "settings.h"
class UnknownKeycode : public BaseException
{
public:
UnknownKeycode(const char *s) :
BaseException(s) {};
};
#define CHECKKEY(x){if(strcmp(name, #x)==0) return irr::x;}
@@ -168,7 +177,7 @@ irr::EKEY_CODE keyname_to_keycode(const char *name)
CHECKKEY(KEY_PA1)
CHECKKEY(KEY_OEM_CLEAR)
return irr::KEY_KEY_CODES_COUNT;
throw UnknownKeycode(name);
}
static const char *KeyNames[] =
@@ -206,31 +215,131 @@ static const char *KeyNames[] =
"-", "-", "-", "-", "-", "-", "-", "-", "Attn", "CrSel", "ExSel",
"Erase OEF", "Play", "Zoom", "PA1", "OEM Clear", "-" };
std::string keycode_to_keyname(s32 keycode)
#define N_(text) text
static const char *KeyNamesLang[] =
{ "-", N_("Left Button"), N_("Right Button"), N_("Cancel"), N_("Middle Button"), N_("X Button 1"),
N_("X Button 2"), "-", N_("Back"), N_("Tab"), "-", "-", N_("Clear"), N_("Return"), "-",
"-", N_("Shift"), N_("Control"), N_("Menu"), N_("Pause"), N_("Capital"), N_("Kana"), "-",
N_("Junja"), N_("Final"), N_("Kanji"), "-", N_("Escape"), N_("Convert"), N_("Nonconvert"),
N_("Accept"), N_("Mode Change"), N_("Space"), N_("Prior"), N_("Next"), N_("End"), N_("Home"),
N_("Left"), N_("Up"), N_("Right"), N_("Down"), N_("Select"), N_("Print"), N_("Execute"),
N_("Snapshot"), N_("Insert"), N_("Delete"), N_("Help"), "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "-", "-", "-", "-", "-", "-", "-", "A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z", N_("Left Windows"),
N_("Right Windows"), N_("Apps"), "-", N_("Sleep"), N_("Numpad 0"), N_("Numpad 1"),
N_("Numpad 2"), N_("Numpad 3"), N_("Numpad 4"), N_("Numpad 5"), N_("Numpad 6"), N_("Numpad 7"),
N_("Numpad 8"), N_("Numpad 9"), N_("Numpad *"), N_("Numpad +"), N_("Numpad /"), N_("Numpad -"),
"Numpad .", "Numpad /", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
"F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18",
"F19", "F20", "F21", "F22", "F23", "F24", "-", "-", "-", "-", "-", "-",
"-", "-", N_("Num Lock"), N_("Scroll Lock"), "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", N_("Left Shift"), N_("Right Shift"),
N_("Left Control"), N_("Right Control"), N_("Left Menu"), N_("Right Menu"), "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", N_("Plus"), N_("Comma"), N_("Minus"), N_("Period"), "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", N_("Attn"), N_("CrSel"),
N_("ExSel"), N_("Erase OEF"), N_("Play"), N_("Zoom"), N_("PA1"), N_("OEM Clear"), "-" };
#undef N_
KeyPress::KeyPress() :
Key(irr::KEY_KEY_CODES_COUNT),
Char(L'\0')
{}
KeyPress::KeyPress(const char *name)
{
return KeyNames[keycode];
if (strlen(name) > 4) {
try {
Key = keyname_to_keycode(name);
m_name = name;
if (strlen(name) > 8)
mbtowc(&Char, name + 8, 1);
else
Char = L'\0';
return;
} catch (UnknownKeycode &e) {};
} else {
// see if we can set it up as a KEY_KEY_something
m_name = "KEY_KEY_";
m_name += name;
try {
Key = keyname_to_keycode(m_name.c_str());
mbtowc(&Char, name, 1);
return;
} catch (UnknownKeycode &e) {};
}
// it's not a (known) key, just take the first char and use that
Key = irr::KEY_KEY_CODES_COUNT;
mbtowc(&Char, name, 1);
m_name = name[0];
}
KeyPress::KeyPress(const irr::SEvent::SKeyInput &in)
{
Key = in.Key;
Char = in.Char;
if (valid_kcode(Key)) {
m_name = KeyNames[Key];
} else {
size_t maxlen = wctomb(NULL, Char);
m_name.resize(maxlen+1, '\0');
wctomb(&m_name[0], Char);
}
}
const char *KeyPress::sym() const
{
if (Key && Key < irr::KEY_KEY_CODES_COUNT)
return KeyNames[Key];
else {
return m_name.c_str();
}
}
const char *KeyPress::name() const
{
if (Key && Key < irr::KEY_KEY_CODES_COUNT)
return KeyNamesLang[Key];
else {
return m_name.c_str();
}
}
const KeyPress EscapeKey("KEY_ESCAPE");
const KeyPress NumberKey[] = {
KeyPress("KEY_KEY_0"), KeyPress("KEY_KEY_1"), KeyPress("KEY_KEY_2"),
KeyPress("KEY_KEY_3"), KeyPress("KEY_KEY_4"), KeyPress("KEY_KEY_5"),
KeyPress("KEY_KEY_6"), KeyPress("KEY_KEY_7"), KeyPress("KEY_KEY_8"),
KeyPress("KEY_KEY_9")};
/*
Key config
*/
// A simple cache for quicker lookup
core::map<std::string, irr::EKEY_CODE> g_key_setting_cache;
core::map<std::string, KeyPress> g_key_setting_cache;
irr::EKEY_CODE getKeySetting(const char *settingname)
KeyPress getKeySetting(const char *settingname)
{
core::map<std::string, irr::EKEY_CODE>::Node *n;
core::map<std::string, KeyPress>::Node *n;
n = g_key_setting_cache.find(settingname);
if(n)
return n->getValue();
irr::EKEY_CODE c = keyname_to_keycode(g_settings.get(settingname).c_str());
g_key_setting_cache.insert(settingname, c);
return c;
g_key_setting_cache.insert(settingname,
g_settings->get(settingname).c_str());
return g_key_setting_cache.find(settingname)->getValue();
}
void clearKeyCache()
{
g_key_setting_cache.clear();
}

View File

@@ -23,11 +23,42 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h"
#include <string>
irr::EKEY_CODE keyname_to_keycode(const char *name);
std::string keycode_to_keyname(s32 keycode);
/* A key press, consisting of either an Irrlicht keycode
or an actual char */
class KeyPress
{
public:
KeyPress();
KeyPress(const char *name);
KeyPress(const irr::SEvent::SKeyInput &in);
bool operator==(const KeyPress &o) const
{
return valid_kcode(Key) ? Key == o.Key : Char == o.Char;
}
const char *sym() const;
const char *name() const;
std::string debug() const;
protected:
static bool valid_kcode(irr::EKEY_CODE k)
{
return k > 0 && k < irr::KEY_KEY_CODES_COUNT;
}
irr::EKEY_CODE Key;
wchar_t Char;
std::string m_name;
};
extern const KeyPress EscapeKey;
extern const KeyPress NumberKey[10];
// Key configuration getter
irr::EKEY_CODE getKeySetting(const char *settingname);
KeyPress getKeySetting(const char *settingname);
// Clear fast lookup cache
void clearKeyCache();

144
src/log.cpp Normal file
View File

@@ -0,0 +1,144 @@
/*
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 "log.h"
#include <map>
#include <list>
#include <sstream>
#include "threads.h"
#include "debug.h"
#include "gettime.h"
std::list<ILogOutput*> log_outputs[LMT_NUM_VALUES];
std::map<threadid_t, std::string> log_threadnames;
void log_add_output(ILogOutput *out, enum LogMessageLevel lev)
{
log_outputs[lev].push_back(out);
}
void log_add_output_maxlev(ILogOutput *out, enum LogMessageLevel lev)
{
for(int i=0; i<=lev; i++)
log_outputs[i].push_back(out);
}
void log_add_output_all_levs(ILogOutput *out)
{
for(int i=0; i<LMT_NUM_VALUES; i++)
log_outputs[i].push_back(out);
}
void log_register_thread(const std::string &name)
{
threadid_t id = get_current_thread_id();
log_threadnames[id] = name;
}
static std::string get_lev_string(enum LogMessageLevel lev)
{
switch(lev){
case LMT_ERROR:
return "ERROR";
case LMT_ACTION:
return "ACTION";
case LMT_INFO:
return "INFO";
case LMT_VERBOSE:
return "VERBOSE";
case LMT_NUM_VALUES:
break;
}
return "(unknown level)";
}
void log_printline(enum LogMessageLevel lev, const std::string &text)
{
std::string threadname = "(unknown thread)";
std::map<threadid_t, std::string>::const_iterator i;
i = log_threadnames.find(get_current_thread_id());
if(i != log_threadnames.end())
threadname = i->second;
std::string levelname = get_lev_string(lev);
std::ostringstream os(std::ios_base::binary);
os<<getTimestamp()<<": "<<levelname<<"["<<threadname<<"]: "<<text;
for(std::list<ILogOutput*>::iterator i = log_outputs[lev].begin();
i != log_outputs[lev].end(); i++){
ILogOutput *out = *i;
out->printLog(os.str());
out->printLog(lev, text);
}
}
class Logbuf : public std::streambuf
{
public:
Logbuf(enum LogMessageLevel lev):
m_lev(lev)
{
}
~Logbuf()
{
}
int overflow(int c)
{
bufchar(c);
return c;
}
std::streamsize xsputn(const char *s, std::streamsize n)
{
for(int i=0; i<n; i++)
bufchar(s[i]);
return n;
}
void printbuf()
{
log_printline(m_lev, m_buf);
}
void bufchar(char c)
{
if(c == '\n' || c == '\r'){
if(m_buf != "")
printbuf();
m_buf = "";
return;
}
m_buf += c;
}
private:
enum LogMessageLevel m_lev;
std::string m_buf;
};
Logbuf errorbuf(LMT_ERROR);
Logbuf actionbuf(LMT_ACTION);
Logbuf infobuf(LMT_INFO);
Logbuf verbosebuf(LMT_VERBOSE);
std::ostream errorstream(&errorbuf);
std::ostream actionstream(&actionbuf);
std::ostream infostream(&infobuf);
std::ostream verbosestream(&verbosebuf);

69
src/log.h Normal file
View File

@@ -0,0 +1,69 @@
/*
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 LOG_HEADER
#define LOG_HEADER
#include <string>
/*
Use this for logging everything.
If you need to explicitly print something, use dstream or cout or cerr.
*/
enum LogMessageLevel {
LMT_ERROR, /* Something failed ("invalid map data on disk, block (2,2,1)") */
LMT_ACTION, /* In-game actions ("celeron55 placed block at (12,4,-5)") */
LMT_INFO, /* More deep info ("saving map on disk (only_modified=true)") */
LMT_VERBOSE, /* Flood-style ("loaded block (2,2,2) from disk") */
LMT_NUM_VALUES,
};
class ILogOutput
{
public:
/* line: Full line with timestamp, level and thread */
virtual void printLog(const std::string &line){};
/* line: Only actual printed text */
virtual void printLog(enum LogMessageLevel lev, const std::string &line){};
};
void log_add_output(ILogOutput *out, enum LogMessageLevel lev);
void log_add_output_maxlev(ILogOutput *out, enum LogMessageLevel lev);
void log_add_output_all_levs(ILogOutput *out);
void log_register_thread(const std::string &name);
void log_printline(enum LogMessageLevel lev, const std::string &text);
#define LOGLINEF(lev, ...)\
{\
char buf[10000];\
snprintf(buf, 10000, __VA_ARGS__);\
log_printline(lev, buf);\
}
extern std::ostream errorstream;
extern std::ostream actionstream;
extern std::ostream infostream;
extern std::ostream verbosestream;
#endif

View File

@@ -367,6 +367,9 @@ TODO: Merge bahamada's audio stuff (clean patch available)
TODO: Move content_features to mapnode_content_features.{h,cpp} or so
TODO: Fix item use() stuff; dropping a stack of cooked rats and eating
it gives 3 hearts and consumes all the rats.
Making it more portable:
------------------------
@@ -408,10 +411,13 @@ Doing currently:
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
#include "irrlicht.h" // createDevice
#include "main.h"
#include "mainmenumanager.h"
#include <iostream>
#include <fstream>
#include <locale.h>
#include "main.h"
#include "common_irrlicht.h"
#include "debug.h"
#include "test.h"
@@ -428,8 +434,11 @@ Doing currently:
#include "game.h"
#include "keycode.h"
#include "tile.h"
#include "defaultsettings.h"
#include "gettext.h"
#include "settings.h"
#include "profiler.h"
#include "log.h"
// This makes textures
ITextureSource *g_texturesource = NULL;
@@ -438,25 +447,23 @@ ITextureSource *g_texturesource = NULL;
Settings.
These are loaded from the config file.
*/
Settings g_settings;
// This is located in defaultsettings.cpp
extern void set_default_settings();
Settings main_settings;
Settings *g_settings = &main_settings;
// Global profiler
Profiler g_profiler;
Profiler main_profiler;
Profiler *g_profiler = &main_profiler;
/*
Random stuff
*/
/*
GUI Stuff
mainmenumanager.h
*/
gui::IGUIEnvironment* guienv = NULL;
gui::IGUIStaticText *guiroot = NULL;
MainMenuManager g_menumgr;
bool noMenuActive()
@@ -465,7 +472,6 @@ bool noMenuActive()
}
// Passed to menus to allow disconnecting and exiting
MainGameCallback *g_gamecallback = NULL;
/*
@@ -474,19 +480,17 @@ MainGameCallback *g_gamecallback = NULL;
// Connection
std::ostream *dout_con_ptr = &dummyout;
std::ostream *derr_con_ptr = &dstream_no_stderr;
//std::ostream *dout_con_ptr = &dstream_no_stderr;
//std::ostream *derr_con_ptr = &dstream_no_stderr;
//std::ostream *dout_con_ptr = &dstream;
//std::ostream *derr_con_ptr = &dstream;
std::ostream *derr_con_ptr = &verbosestream;
//std::ostream *dout_con_ptr = &infostream;
//std::ostream *derr_con_ptr = &errorstream;
// Server
std::ostream *dout_server_ptr = &dstream;
std::ostream *derr_server_ptr = &dstream;
std::ostream *dout_server_ptr = &infostream;
std::ostream *derr_server_ptr = &errorstream;
// Client
std::ostream *dout_client_ptr = &dstream;
std::ostream *derr_client_ptr = &dstream;
std::ostream *dout_client_ptr = &infostream;
std::ostream *derr_client_ptr = &errorstream;
/*
gettime.h implementation
@@ -560,10 +564,12 @@ class MyEventReceiver : public IEventReceiver
// Remember whether each key is down or up
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
keyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
if(event.KeyInput.PressedDown)
keyWasDown[event.KeyInput.Key] = true;
if(event.KeyInput.PressedDown) {
keyIsDown.set(event.KeyInput);
keyWasDown.set(event.KeyInput);
} else {
keyIsDown.unset(event.KeyInput);
}
}
if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
@@ -576,7 +582,6 @@ class MyEventReceiver : public IEventReceiver
}
else
{
//dstream<<"MyEventReceiver: mouse input"<<std::endl;
left_active = event.MouseInput.isLeftPressed();
middle_active = event.MouseInput.isMiddlePressed();
right_active = event.MouseInput.isRightPressed();
@@ -607,16 +612,17 @@ class MyEventReceiver : public IEventReceiver
return false;
}
bool IsKeyDown(EKEY_CODE keyCode) const
bool IsKeyDown(const KeyPress &keyCode) const
{
return keyIsDown[keyCode];
}
// Checks whether a key was down and resets the state
bool WasKeyDown(EKEY_CODE keyCode)
bool WasKeyDown(const KeyPress &keyCode)
{
bool b = keyWasDown[keyCode];
keyWasDown[keyCode] = false;
if (b)
keyWasDown.unset(keyCode);
return b;
}
@@ -629,12 +635,9 @@ class MyEventReceiver : public IEventReceiver
void clearInput()
{
for(u32 i=0; i<KEY_KEY_CODES_COUNT; i++)
{
keyIsDown[i] = false;
keyWasDown[i] = false;
}
keyIsDown.clear();
keyWasDown.clear();
leftclicked = false;
rightclicked = false;
leftreleased = false;
@@ -667,9 +670,9 @@ class MyEventReceiver : public IEventReceiver
IrrlichtDevice *m_device;
// The current state of keys
bool keyIsDown[KEY_KEY_CODES_COUNT];
KeyList keyIsDown;
// Whether a key has been pressed or not
bool keyWasDown[KEY_KEY_CODES_COUNT];
KeyList keyWasDown;
};
/*
@@ -684,11 +687,11 @@ class RealInputHandler : public InputHandler
m_receiver(receiver)
{
}
virtual bool isKeyDown(EKEY_CODE keyCode)
virtual bool isKeyDown(const KeyPress &keyCode)
{
return m_receiver->IsKeyDown(keyCode);
}
virtual bool wasKeyDown(EKEY_CODE keyCode)
virtual bool wasKeyDown(const KeyPress &keyCode)
{
return m_receiver->WasKeyDown(keyCode);
}
@@ -769,14 +772,13 @@ class RandomInputHandler : public InputHandler
rightclicked = false;
leftreleased = false;
rightreleased = false;
for(u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
keydown[i] = false;
keydown.clear();
}
virtual bool isKeyDown(EKEY_CODE keyCode)
virtual bool isKeyDown(const KeyPress &keyCode)
{
return keydown[keyCode];
}
virtual bool wasKeyDown(EKEY_CODE keyCode)
virtual bool wasKeyDown(const KeyPress &keyCode)
{
return false;
}
@@ -845,8 +847,7 @@ class RandomInputHandler : public InputHandler
if(counter1 < 0.0)
{
counter1 = 0.1*Rand(1, 40);
keydown[getKeySetting("keymap_jump")] =
!keydown[getKeySetting("keymap_jump")];
keydown.toggle(getKeySetting("keymap_jump"));
}
}
{
@@ -855,8 +856,7 @@ class RandomInputHandler : public InputHandler
if(counter1 < 0.0)
{
counter1 = 0.1*Rand(1, 40);
keydown[getKeySetting("keymap_special1")] =
!keydown[getKeySetting("keymap_special1")];
keydown.toggle(getKeySetting("keymap_special1"));
}
}
{
@@ -865,8 +865,7 @@ class RandomInputHandler : public InputHandler
if(counter1 < 0.0)
{
counter1 = 0.1*Rand(1, 40);
keydown[getKeySetting("keymap_forward")] =
!keydown[getKeySetting("keymap_forward")];
keydown.toggle(getKeySetting("keymap_forward"));
}
}
{
@@ -875,8 +874,7 @@ class RandomInputHandler : public InputHandler
if(counter1 < 0.0)
{
counter1 = 0.1*Rand(1, 40);
keydown[getKeySetting("keymap_left")] =
!keydown[getKeySetting("keymap_left")];
keydown.toggle(getKeySetting("keymap_left"));
}
}
{
@@ -922,7 +920,7 @@ class RandomInputHandler : public InputHandler
return (myrand()%(max-min+1))+min;
}
private:
bool keydown[KEY_KEY_CODES_COUNT];
KeyList keydown;
v2s32 mousepos;
v2s32 mousespeed;
bool leftdown;
@@ -1026,7 +1024,7 @@ void SpeedTests()
u32 dtime = timer.stop();
u32 per_ms = n / dtime;
std::cout<<"Done. "<<dtime<<"ms, "
dstream<<"Done. "<<dtime<<"ms, "
<<per_ms<<"/ms"<<std::endl;
}
}
@@ -1078,12 +1076,37 @@ void drawMenuBackground(video::IVideoDriver* driver)
}
}
class StderrLogOutput: public ILogOutput
{
public:
/* line: Full line with timestamp, level and thread */
void printLog(const std::string &line)
{
std::cerr<<line<<std::endl;
}
} main_stderr_log_out;
class DstreamNoStderrLogOutput: public ILogOutput
{
public:
/* line: Full line with timestamp, level and thread */
void printLog(const std::string &line)
{
dstream_no_stderr<<line<<std::endl;
}
} main_dstream_no_stderr_log_out;
int main(int argc, char *argv[])
{
/*
Initialization
*/
log_add_output_maxlev(&main_stderr_log_out, LMT_ACTION);
log_add_output_all_levs(&main_dstream_no_stderr_log_out);
log_register_thread("main");
// Set locale. This is for forcing '.' as the decimal point.
std::locale::global(std::locale("C"));
// This enables printing all characters in bitmap font
@@ -1110,6 +1133,7 @@ int main(int argc, char *argv[])
allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG));
#endif
allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG));
allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG));
Settings cmd_args;
@@ -1151,6 +1175,9 @@ int main(int argc, char *argv[])
if(cmd_args.getFlag("dstream-on-stderr") == false)
disable_stderr = true;
#endif
if(cmd_args.getFlag("info-on-stderr"))
log_add_output(&main_stderr_log_out, LMT_INFO);
porting::signal_handler_init();
bool &kill = *porting::signal_handler_killstatus();
@@ -1161,17 +1188,13 @@ int main(int argc, char *argv[])
// Create user data directory
fs::CreateDir(porting::path_userdata);
#ifdef USE_GETTEXT
setlocale(LC_MESSAGES, "");
bindtextdomain("minetest", (porting::path_userdata+"/locale").c_str());
textdomain("minetest");
#endif
init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
// Initialize debug streams
#ifdef RUN_IN_PLACE
std::string debugfile = DEBUGFILE;
#else
std::string debugfile = porting::path_userdata+"/"+DEBUGFILE;
std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
#endif
debugstreams_init(disable_stderr, debugfile.c_str());
// Initialize debug stacks
@@ -1186,7 +1209,7 @@ int main(int argc, char *argv[])
BEGIN_DEBUG_EXCEPTION_HANDLER
// Print startup message
dstream<<DTIME<<"minetest-c55"
actionstream<<PROJECT_NAME<<
" with SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
<<", "<<BUILD_INFO
<<std::endl;
@@ -1196,7 +1219,7 @@ int main(int argc, char *argv[])
*/
// Initialize default settings
set_default_settings();
set_default_settings(g_settings);
// Initialize sockets
sockets_init();
@@ -1211,10 +1234,10 @@ int main(int argc, char *argv[])
if(cmd_args.exists("config"))
{
bool r = g_settings.readConfigFile(cmd_args.get("config").c_str());
bool r = g_settings->readConfigFile(cmd_args.get("config").c_str());
if(r == false)
{
dstream<<"Could not read configuration from \""
errorstream<<"Could not read configuration from \""
<<cmd_args.get("config")<<"\""<<std::endl;
return 1;
}
@@ -1223,14 +1246,16 @@ int main(int argc, char *argv[])
else
{
core::array<std::string> filenames;
filenames.push_back(porting::path_userdata + "/minetest.conf");
filenames.push_back(porting::path_userdata +
DIR_DELIM + "minetest.conf");
#ifdef RUN_IN_PLACE
filenames.push_back(porting::path_userdata + "/../minetest.conf");
filenames.push_back(porting::path_userdata +
DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif
for(u32 i=0; i<filenames.size(); i++)
{
bool r = g_settings.readConfigFile(filenames[i].c_str());
bool r = g_settings->readConfigFile(filenames[i].c_str());
if(r)
{
configpath = filenames[i];
@@ -1255,6 +1280,9 @@ int main(int argc, char *argv[])
// Initial call with g_texturesource not set.
init_mapnode();
// Must be called before g_texturesource is created
// (for texture atlas making)
init_mineral();
/*
Run unit tests
@@ -1281,17 +1309,17 @@ int main(int argc, char *argv[])
u16 port = 30000;
if(cmd_args.exists("port"))
port = cmd_args.getU16("port");
else if(g_settings.exists("port"))
port = g_settings.getU16("port");
else if(g_settings->exists("port"))
port = g_settings->getU16("port");
if(port == 0)
port = 30000;
// Map directory
std::string map_dir = porting::path_userdata+"/world";
std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
if(cmd_args.exists("map-dir"))
map_dir = cmd_args.get("map-dir");
else if(g_settings.exists("map-dir"))
map_dir = g_settings.get("map-dir");
else if(g_settings->exists("map-dir"))
map_dir = g_settings->get("map-dir");
// Run dedicated server if asked to
if(cmd_args.getFlag("server"))
@@ -1325,10 +1353,10 @@ int main(int argc, char *argv[])
}
else
{
address = g_settings.get("address");
address = g_settings->get("address");
}
std::string playername = g_settings.get("name");
std::string playername = g_settings->get("name");
/*
Device initialization
@@ -1337,14 +1365,14 @@ int main(int argc, char *argv[])
// Resolution selection
bool fullscreen = false;
u16 screenW = g_settings.getU16("screenW");
u16 screenH = g_settings.getU16("screenH");
u16 screenW = g_settings->getU16("screenW");
u16 screenH = g_settings->getU16("screenH");
// Determine driver
video::E_DRIVER_TYPE driverType;
std::string driverstring = g_settings.get("video_driver");
std::string driverstring = g_settings->get("video_driver");
if(driverstring == "null")
driverType = video::EDT_NULL;
@@ -1360,7 +1388,7 @@ int main(int argc, char *argv[])
driverType = video::EDT_OPENGL;
else
{
dstream<<"WARNING: Invalid video_driver specified; defaulting "
errorstream<<"WARNING: Invalid video_driver specified; defaulting "
"to opengl"<<std::endl;
driverType = video::EDT_OPENGL;
}
@@ -1379,9 +1407,6 @@ int main(int argc, char *argv[])
if (device == 0)
return 1; // could not create selected driver.
// Set device in game parameters
device = device;
// Set the window caption
device->setWindowCaption(L"Minetest [Main Menu]");
@@ -1406,7 +1431,7 @@ int main(int argc, char *argv[])
device->setResizable(true);
bool random_input = g_settings.getBool("random_input")
bool random_input = g_settings->getBool("random_input")
|| cmd_args.getFlag("random-input");
InputHandler *input = NULL;
if(random_input)
@@ -1434,14 +1459,14 @@ int main(int argc, char *argv[])
if(font)
skin->setFont(font);
else
dstream<<"WARNING: Font file was not found."
errorstream<<"WARNING: Font file was not found."
" Using default font."<<std::endl;
// If font was not found, this will get us one
font = skin->getFont();
assert(font);
u32 text_height = font->getDimension(L"Hello, world!").Height;
dstream<<"text_height="<<text_height<<std::endl;
infostream<<"text_height="<<text_height<<std::endl;
//skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,0,0,0));
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255,255,255,255));
@@ -1455,7 +1480,6 @@ int main(int argc, char *argv[])
*/
init_mapnode(); // Second call with g_texturesource set
init_mineral();
/*
GUI stuff
@@ -1517,10 +1541,10 @@ int main(int argc, char *argv[])
menudata.address = narrow_to_wide(address);
menudata.name = narrow_to_wide(playername);
menudata.port = narrow_to_wide(itos(port));
menudata.fancy_trees = g_settings.getBool("new_style_leaves");
menudata.smooth_lighting = g_settings.getBool("smooth_lighting");
menudata.creative_mode = g_settings.getBool("creative_mode");
menudata.enable_damage = g_settings.getBool("enable_damage");
menudata.fancy_trees = g_settings->getBool("new_style_leaves");
menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
menudata.creative_mode = g_settings->getBool("creative_mode");
menudata.enable_damage = g_settings->getBool("enable_damage");
GUIMainMenu *menu =
new GUIMainMenu(guienv, guiroot, -1,
@@ -1529,7 +1553,7 @@ int main(int argc, char *argv[])
if(error_message != L"")
{
dstream<<"WARNING: error_message = "
errorstream<<"error_message = "
<<wide_to_narrow(error_message)<<std::endl;
GUIMessageMenu *menu2 =
@@ -1541,7 +1565,7 @@ int main(int argc, char *argv[])
video::IVideoDriver* driver = device->getVideoDriver();
dstream<<"Created main menu"<<std::endl;
infostream<<"Created main menu"<<std::endl;
while(device->run() && kill == false)
{
@@ -1566,7 +1590,7 @@ int main(int argc, char *argv[])
if(device->run() == false || kill == true)
break;
dstream<<"Dropping main menu"<<std::endl;
infostream<<"Dropping main menu"<<std::endl;
menu->drop();
@@ -1583,16 +1607,16 @@ int main(int argc, char *argv[])
password = translatePassword(playername, menudata.password);
//dstream<<"Main: password hash: '"<<password<<"'"<<std::endl;
//infostream<<"Main: password hash: '"<<password<<"'"<<std::endl;
address = wide_to_narrow(menudata.address);
int newport = stoi(wide_to_narrow(menudata.port));
if(newport != 0)
port = newport;
g_settings.set("new_style_leaves", itos(menudata.fancy_trees));
g_settings.set("smooth_lighting", itos(menudata.smooth_lighting));
g_settings.set("creative_mode", itos(menudata.creative_mode));
g_settings.set("enable_damage", itos(menudata.enable_damage));
g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
g_settings->set("creative_mode", itos(menudata.creative_mode));
g_settings->set("enable_damage", itos(menudata.enable_damage));
// NOTE: These are now checked server side; no need to do it
// here, so let's not do it here.
@@ -1611,12 +1635,12 @@ int main(int argc, char *argv[])
}*/
// Save settings
g_settings.set("name", playername);
g_settings.set("address", address);
g_settings.set("port", itos(port));
g_settings->set("name", playername);
g_settings->set("address", address);
g_settings->set("port", itos(port));
// Update configuration file
if(configpath != "")
g_settings.updateConfigFile(configpath.c_str());
g_settings->updateConfigFile(configpath.c_str());
// Continue to game
break;
@@ -1650,12 +1674,12 @@ int main(int argc, char *argv[])
} //try
catch(con::PeerNotFoundException &e)
{
dstream<<DTIME<<"Connection error (timed out?)"<<std::endl;
errorstream<<"Connection error (timed out?)"<<std::endl;
error_message = L"Connection error (timed out?)";
}
catch(SocketException &e)
{
dstream<<DTIME<<"Socket error (port already in use?)"<<std::endl;
errorstream<<"Socket error (port already in use?)"<<std::endl;
error_message = L"Socket error (port already in use?)";
}
#ifdef NDEBUG
@@ -1664,7 +1688,7 @@ int main(int argc, char *argv[])
std::string narrow_message = "Some exception, what()=\"";
narrow_message += e.what();
narrow_message += "\"";
dstream<<DTIME<<narrow_message<<std::endl;
errorstream<<narrow_message<<std::endl;
error_message = narrow_to_wide(narrow_message);
}
#endif
@@ -1678,7 +1702,7 @@ int main(int argc, char *argv[])
*/
device->drop();
END_DEBUG_EXCEPTION_HANDLER
END_DEBUG_EXCEPTION_HANDLER(errorstream)
debugstreams_deinit();

View File

@@ -21,16 +21,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MAIN_HEADER
// Settings
#include "utility.h"
extern Settings g_settings;
class Settings;
extern Settings *g_settings;
// This makes and maps textures
class ITextureSource;
extern ITextureSource *g_texturesource;
// Global profiler
#include "profiler.h"
extern Profiler g_profiler;
class Profiler;
extern Profiler *g_profiler;
// Debug streams
@@ -50,105 +50,5 @@ extern std::ostream *derr_server_ptr;
#define dout_server (*dout_server_ptr)
#define derr_server (*derr_server_ptr)
/*
All kinds of stuff that needs to be exposed from main.cpp
*/
#include "modalMenu.h"
#include "guiPauseMenu.h" //For IGameCallback
extern gui::IGUIEnvironment* guienv;
extern gui::IGUIStaticText *guiroot;
// Handler for the modal menus
class MainMenuManager : public IMenuManager
{
public:
virtual void createdMenu(GUIModalMenu *menu)
{
for(core::list<GUIModalMenu*>::Iterator
i = m_stack.begin();
i != m_stack.end(); i++)
{
assert(*i != menu);
}
if(m_stack.size() != 0)
(*m_stack.getLast())->setVisible(false);
m_stack.push_back(menu);
}
virtual void deletingMenu(GUIModalMenu *menu)
{
// Remove all entries if there are duplicates
bool removed_entry;
do{
removed_entry = false;
for(core::list<GUIModalMenu*>::Iterator
i = m_stack.begin();
i != m_stack.end(); i++)
{
if(*i == menu)
{
m_stack.erase(i);
removed_entry = true;
break;
}
}
}while(removed_entry);
/*core::list<GUIModalMenu*>::Iterator i = m_stack.getLast();
assert(*i == menu);
m_stack.erase(i);*/
if(m_stack.size() != 0)
(*m_stack.getLast())->setVisible(true);
}
u32 menuCount()
{
return m_stack.size();
}
core::list<GUIModalMenu*> m_stack;
};
extern MainMenuManager g_menumgr;
extern bool noMenuActive();
class MainGameCallback : public IGameCallback
{
public:
MainGameCallback(IrrlichtDevice *a_device):
disconnect_requested(false),
changepassword_requested(false),
device(a_device)
{
}
virtual void exitToOS()
{
device->closeDevice();
}
virtual void disconnect()
{
disconnect_requested = true;
}
virtual void changePassword()
{
changepassword_requested = true;
}
bool disconnect_requested;
bool changepassword_requested;
IrrlichtDevice *device;
};
extern MainGameCallback *g_gamecallback;
#endif

124
src/mainmenumanager.h Normal file
View File

@@ -0,0 +1,124 @@
/*
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
(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 MAINMENUMANAGER_HEADER
#define MAINMENUMANAGER_HEADER
/*
All kinds of stuff that needs to be exposed from main.cpp
*/
#include "debug.h" // assert
#include "modalMenu.h"
#include "guiPauseMenu.h" //For IGameCallback
extern gui::IGUIEnvironment* guienv;
extern gui::IGUIStaticText *guiroot;
// Handler for the modal menus
class MainMenuManager : public IMenuManager
{
public:
virtual void createdMenu(GUIModalMenu *menu)
{
for(core::list<GUIModalMenu*>::Iterator
i = m_stack.begin();
i != m_stack.end(); i++)
{
assert(*i != menu);
}
if(m_stack.size() != 0)
(*m_stack.getLast())->setVisible(false);
m_stack.push_back(menu);
}
virtual void deletingMenu(GUIModalMenu *menu)
{
// Remove all entries if there are duplicates
bool removed_entry;
do{
removed_entry = false;
for(core::list<GUIModalMenu*>::Iterator
i = m_stack.begin();
i != m_stack.end(); i++)
{
if(*i == menu)
{
m_stack.erase(i);
removed_entry = true;
break;
}
}
}while(removed_entry);
/*core::list<GUIModalMenu*>::Iterator i = m_stack.getLast();
assert(*i == menu);
m_stack.erase(i);*/
if(m_stack.size() != 0)
(*m_stack.getLast())->setVisible(true);
}
u32 menuCount()
{
return m_stack.size();
}
core::list<GUIModalMenu*> m_stack;
};
extern MainMenuManager g_menumgr;
extern bool noMenuActive();
class MainGameCallback : public IGameCallback
{
public:
MainGameCallback(IrrlichtDevice *a_device):
disconnect_requested(false),
changepassword_requested(false),
device(a_device)
{
}
virtual void exitToOS()
{
device->closeDevice();
}
virtual void disconnect()
{
disconnect_requested = true;
}
virtual void changePassword()
{
changepassword_requested = true;
}
bool disconnect_requested;
bool changepassword_requested;
IrrlichtDevice *device;
};
extern MainGameCallback *g_gamecallback;
#endif

File diff suppressed because it is too large Load Diff

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