Merge branch 'master' of https://github.com/erlehmann/minetest-delta.git into upstrea...
authorSebastian Rühl <bahamada_basti@yahoo.de>
Sun, 26 Jun 2011 10:24:32 +0000 (12:24 +0200)
committerSebastian Rühl <bahamada_basti@yahoo.de>
Sun, 26 Jun 2011 10:24:32 +0000 (12:24 +0200)
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>
44 files changed:
.gitignore
.hgtags
CMakeLists.txt
README [new file with mode: 0644]
data/book.png [new file with mode: 0644]
data/bookshelf.png [new file with mode: 0644]
data/brick.png [new file with mode: 0644]
data/cactus_side.png [new file with mode: 0644]
data/cactus_top.png [new file with mode: 0644]
data/clay.png [new file with mode: 0644]
data/clay_brick.png [new file with mode: 0644]
data/fence.png [new file with mode: 0644]
data/glass.png
data/lump_of_clay.png [new file with mode: 0644]
data/menulogo.png
data/oerkki1.png
data/paper.png [new file with mode: 0644]
data/papyrus.png [new file with mode: 0644]
data/player.png
data/player_back.png
data/rail.png [new file with mode: 0644]
data/rail_crossing.png [new file with mode: 0644]
data/rail_curved.png [new file with mode: 0644]
data/rail_t_junction.png [new file with mode: 0644]
data/rat.png
data/sandstone.png [new file with mode: 0644]
genmap.py [new file with mode: 0755]
heart.png [new file with mode: 0644]
minetestmapper/colors.txt [new file with mode: 0644]
minetestmapper/minetestmapper2.py [new file with mode: 0755]
pnoise.py [new file with mode: 0644]
src/CMakeLists.txt
src/client.cpp
src/content_craft.cpp
src/content_inventory.cpp
src/content_mapblock.cpp
src/content_mapnode.cpp
src/content_mapnode.h
src/environment.cpp
src/game.cpp
src/guiMainMenu.cpp
src/guiMainMenu.h
src/keycode.cpp
src/keycode.h

index ce00d585ed9ee5194fd8b81b0a99ab1f4ede0d19..f0c372ab7785cc160eeee597a15285a4b0ed26dc 100644 (file)
@@ -19,4 +19,4 @@ cmake_install.cmake
 src/jthread/libjthread.a
 debug.txt
 bin/debug.txt
-
+minetestmapper/map.png
diff --git a/.hgtags b/.hgtags
index a124357b7bb1cacd1fcf218d393921e40425cf7b..95bda33a868aa0ef86b5a9aa028931078bf479dd 100644 (file)
--- a/.hgtags
+++ b/.hgtags
@@ -1,13 +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
index 516778995621b2dbde7cc9a4c5dce994f5d6e85b..854c4b48dca6b11d38deee68aae42be342b7d7d1 100644 (file)
@@ -59,7 +59,7 @@ elseif(UNIX) # Linux, BSD etc
        set(EXAMPLE_CONF_DIR "share/doc/minetest")
 endif()
 
-install(FILES "README.txt" DESTINATION "${DOCDIR}")
+install(FILES "doc/README.txt" DESTINATION "${DOCDIR}")
 install(FILES "minetest.conf.example" DESTINATION "${DOCDIR}")
 
 #
@@ -104,7 +104,7 @@ elseif(APPLE)
        set(CPACK_BUNDLE_ICON "")
        set(CPACK_BUNDLE_PLIST "")
        set(CPACK_BUNDLE_STARTUP_COMMAND "Contents/MacOS/minetest")
-       set(CPACK_GENERATOR Bundle)
+       set(CPACK_GENERATOR "Bundle")
 else()
        set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-linux")
        set(CPACK_GENERATOR TGZ)
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9b1f54e
--- /dev/null
+++ b/README
@@ -0,0 +1,29 @@
+Minetest Δ (“Minetest Delta”) is a fork of Minetest-c55 <http://celeron.55.lt/~celeron55/minetest/>, incorporating experimental features that are not (yet) included in Minetest-c55.
+
+New features:
+* Submenu for key assignment (changes apply after restart)
+
+New bricks:
+* Sandstone (crafted from 4 sand, yields sand)
+* Cactus (plant that grows on sand)
+* Clay (found in sand at sea level, yields 4 lumps of clay)
+* Brick (made from 4 clay bricks, yields 4 clay bricks)
+* Papyrus (plant that grows in shallow water, yields paper)
+* Book shelf (made from 6 wood and 3 books, sandwhiched)
+* Rail (made from 6 iron ingots and 3 sticks, vertically sandwhiched)
+
+New materials:
+* Lump of clay
+* Clay brick (made from lumps of clay in the furnace)
+* Paper
+* Book (made from 3 paper)
+
+Alternate graphics:
+* Player
+* Omsk birds (instead of Oerkki ghosts)
+* Rat
+* Glass
+
+Building on GNU/Linux or OS X:
+    cmake . -DRUN_IN_PLACE=1
+    make -j2
diff --git a/data/book.png b/data/book.png
new file mode 100644 (file)
index 0000000..176fb6a
Binary files /dev/null and b/data/book.png differ
diff --git a/data/bookshelf.png b/data/bookshelf.png
new file mode 100644 (file)
index 0000000..5ecc50f
Binary files /dev/null and b/data/bookshelf.png differ
diff --git a/data/brick.png b/data/brick.png
new file mode 100644 (file)
index 0000000..32d77f3
Binary files /dev/null and b/data/brick.png differ
diff --git a/data/cactus_side.png b/data/cactus_side.png
new file mode 100644 (file)
index 0000000..fc479fd
Binary files /dev/null and b/data/cactus_side.png differ
diff --git a/data/cactus_top.png b/data/cactus_top.png
new file mode 100644 (file)
index 0000000..f9e68df
Binary files /dev/null and b/data/cactus_top.png differ
diff --git a/data/clay.png b/data/clay.png
new file mode 100644 (file)
index 0000000..3557429
Binary files /dev/null and b/data/clay.png differ
diff --git a/data/clay_brick.png b/data/clay_brick.png
new file mode 100644 (file)
index 0000000..e36648e
Binary files /dev/null and b/data/clay_brick.png differ
diff --git a/data/fence.png b/data/fence.png
new file mode 100644 (file)
index 0000000..0b99f0e
Binary files /dev/null and b/data/fence.png differ
index 8598ce670f502802f166eb4b8d07a871b564d263..35ea596d54c5b3e0b55adb0081b71464f665b846 100644 (file)
Binary files a/data/glass.png and b/data/glass.png differ
diff --git a/data/lump_of_clay.png b/data/lump_of_clay.png
new file mode 100644 (file)
index 0000000..be0bab9
Binary files /dev/null and b/data/lump_of_clay.png differ
index 76595c48dc78e626365261633ec9f13b5e5eeaac..cb6983e5c6c2db4b98b810a236cb9df1f9680e4a 100644 (file)
Binary files a/data/menulogo.png and b/data/menulogo.png differ
index c32fb99dbc9381cba551ef0c96482624ec72792a..aad2ddb41faada144601bfaaf02cdd814ad4bb97 100644 (file)
Binary files a/data/oerkki1.png and b/data/oerkki1.png differ
diff --git a/data/paper.png b/data/paper.png
new file mode 100644 (file)
index 0000000..ae5c06b
Binary files /dev/null and b/data/paper.png differ
diff --git a/data/papyrus.png b/data/papyrus.png
new file mode 100644 (file)
index 0000000..bf0dec7
Binary files /dev/null and b/data/papyrus.png differ
index 90adf97476ecd3442dcd435201658ebfaef9d7ab..60ac4854ba00dc30c692e4fafdd6a0810d0806fb 100644 (file)
Binary files a/data/player.png and b/data/player.png differ
index 530aa7519b95a650ce4fea2612b2dced58becdbc..447c1fd8f149788f85f9aa350f27361d5e8459d8 100644 (file)
Binary files a/data/player_back.png and b/data/player_back.png differ
diff --git a/data/rail.png b/data/rail.png
new file mode 100644 (file)
index 0000000..18176d9
Binary files /dev/null and b/data/rail.png differ
diff --git a/data/rail_crossing.png b/data/rail_crossing.png
new file mode 100644 (file)
index 0000000..9846405
Binary files /dev/null and b/data/rail_crossing.png differ
diff --git a/data/rail_curved.png b/data/rail_curved.png
new file mode 100644 (file)
index 0000000..62afa3d
Binary files /dev/null and b/data/rail_curved.png differ
diff --git a/data/rail_t_junction.png b/data/rail_t_junction.png
new file mode 100644 (file)
index 0000000..9985f63
Binary files /dev/null and b/data/rail_t_junction.png differ
index d1a0e2ae26ad41a751c99ea84e79f45e58c1970b..96d44c3fae171d9d1e59d8137315f0d61697abd5 100644 (file)
Binary files a/data/rat.png and b/data/rat.png differ
diff --git a/data/sandstone.png b/data/sandstone.png
new file mode 100644 (file)
index 0000000..c4759b4
Binary files /dev/null and b/data/sandstone.png differ
diff --git a/genmap.py b/genmap.py
new file mode 100755 (executable)
index 0000000..a605094
--- /dev/null
+++ b/genmap.py
@@ -0,0 +1,271 @@
+#!/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
diff --git a/heart.png b/heart.png
new file mode 100644 (file)
index 0000000..bea1aef
Binary files /dev/null and b/heart.png differ
diff --git a/minetestmapper/colors.txt b/minetestmapper/colors.txt
new file mode 100644 (file)
index 0000000..e70f56e
--- /dev/null
@@ -0,0 +1,25 @@
+0 128 128 128\r
+1 107 134 51\r
+2 39 66 106\r
+3 255 255 0\r
+4 86 58 31\r
+5 48 95 8\r
+6 102 129 38\r
+7 178 178 0\r
+8 101 84 36\r
+9 39 66 106\r
+12 104 78 42\r
+13 210 194 156\r
+14 117 86 41\r
+15 128 79 0\r
+16 118 118 118\r
+18 123 123 123\r
+19 199 199 199\r
+20 183 183 222\r
+21 103 78 42\r
+22 219 202 178\r
+23 78 154 6\r
+24 204 0 0\r
+25 211 215 207\r
+26 138 226 52\r
+27 104 78 42\r
diff --git a/minetestmapper/minetestmapper2.py b/minetestmapper/minetestmapper2.py
new file mode 100755 (executable)
index 0000000..8dc3de2
--- /dev/null
@@ -0,0 +1,275 @@
+#!/usr/bin/env python\r
+# -*- coding: utf-8 -*-\r
+\r
+# Made by j0gge, modified by celeron55\r
+\r
+# This program is free software. It comes without any warranty, to\r
+# the extent permitted by applicable law. You can redistribute it\r
+# and/or modify it under the terms of the Do What The Fuck You Want\r
+# To Public License, Version 2, as published by Sam Hocevar. See\r
+# http://sam.zoy.org/wtfpl/COPYING for more details.\r
+\r
+# Requires Python Imaging Library: http://www.pythonware.com/products/pil/\r
+\r
+# Some speed-up: ...lol, actually it slows it down.\r
+#import psyco ; psyco.full()\r
+#from psyco.classes import *\r
+\r
+import zlib\r
+import Image, ImageDraw\r
+import os\r
+import string\r
+import time\r
+\r
+def hex_to_int(h):\r
+    i = int(h,16)\r
+    if(i > 2047):\r
+        i-=4096\r
+    return i\r
+\r
+def hex4_to_int(h):\r
+    i = int(h,16)\r
+    if(i > 32767):\r
+        i-=65536\r
+    return i\r
+\r
+def int_to_hex3(i):\r
+    if(i < 0):\r
+        return "%03X" % (i + 4096)\r
+    else:\r
+        return "%03X" % i\r
+\r
+def int_to_hex4(i):\r
+    if(i < 0):\r
+        return "%04X" % (i + 65536)\r
+    else:\r
+        return "%04X" % i\r
+\r
+def limit(i,l,h):\r
+    if(i>h):\r
+        i=h\r
+    if(i<l):\r
+        i=l\r
+    return i\r
+\r
+# Fix these!\r
+path="../map/"\r
+output="map.png"\r
+\r
+sector_xmin = -1000/16\r
+sector_xmax = 1000/16\r
+sector_zmin = -1000/16\r
+sector_zmax = 1000/16\r
+\r
+# Load color information for the blocks.\r
+colors = {}\r
+f = file("colors.txt")\r
+for line in f:\r
+    values = string.split(line)\r
+    colors[int(values[0])] = (int(values[1]), int(values[2]), int(values[3]))\r
+f.close()\r
+\r
+xlist = []\r
+zlist = []\r
+\r
+# List all sectors to memory and calculate the width and heigth of the resulting picture.\r
+if os.path.exists(path + "sectors2"):\r
+    for filename in os.listdir(path + "sectors2"):\r
+        for filename2 in os.listdir(path + "sectors2/" + filename):\r
+            x = hex_to_int(filename)\r
+            z = hex_to_int(filename2)\r
+            if x < sector_xmin or x > sector_xmax:\r
+                continue\r
+            if z < sector_zmin or z > sector_zmax:\r
+                continue\r
+            xlist.append(x)\r
+            zlist.append(z)\r
+\r
+if os.path.exists(path + "sectors"):\r
+    for filename in os.listdir(path + "sectors"):\r
+        x = hex4_to_int(filename[:4])\r
+        z = hex4_to_int(filename[-4:])\r
+        if x < sector_xmin or x > sector_xmax:\r
+            continue\r
+        if z < sector_zmin or z > sector_zmax:\r
+            continue\r
+        xlist.append(x)\r
+        zlist.append(z)\r
+\r
+w = (max(xlist) - min(xlist)) * 16 + 16\r
+h = (max(zlist) - min(zlist)) * 16 + 16\r
+\r
+print "w="+str(w)+" h="+str(h)\r
+\r
+im = Image.new("RGB", (w, h), "white")\r
+impix = im.load()\r
+\r
+stuff={}\r
+\r
+starttime = time.time()\r
+\r
+# Go through all sectors.\r
+for n in range(len(xlist)):\r
+    #if n > 500:\r
+    #   break\r
+    if n % 200 == 0:\r
+        nowtime = time.time()\r
+        dtime = nowtime - starttime\r
+        n_per_second = 1.0 * n / dtime\r
+        if n_per_second != 0:\r
+            seconds_per_n = 1.0 / n_per_second\r
+            time_guess = seconds_per_n * len(xlist)\r
+            remaining_s = time_guess - dtime\r
+            remaining_minutes = int(remaining_s / 60)\r
+            remaining_s -= remaining_minutes * 60;\r
+            print("Processing sector "+str(n)+" of "+str(len(xlist))\r
+                    +" ("+str(round(100.0*n/len(xlist), 1))+"%)"\r
+                    +" (ETA: "+str(remaining_minutes)+"m "\r
+                    +str(int(remaining_s))+"s)")\r
+\r
+    xpos = xlist[n]\r
+    zpos = zlist[n]\r
+\r
+    xhex = int_to_hex3(xpos)\r
+    zhex = int_to_hex3(zpos)\r
+    xhex4 = int_to_hex4(xpos)\r
+    zhex4 = int_to_hex4(zpos)\r
+\r
+    sector1 = xhex4.lower() + zhex4.lower()\r
+    sector2 = xhex.lower() + "/" + zhex.lower()\r
+\r
+    ylist=[]\r
+\r
+    sectortype = ""\r
+\r
+    try:\r
+        for filename in os.listdir(path + "sectors/" + sector1):\r
+            if(filename != "meta"):\r
+                pos = int(filename,16)\r
+                if(pos > 32767):\r
+                    pos-=65536\r
+                ylist.append(pos)\r
+                sectortype = "old"\r
+    except OSError:\r
+        pass\r
+\r
+    if sectortype != "old":\r
+        try:\r
+            for filename in os.listdir(path + "sectors2/" + sector2):\r
+                if(filename != "meta"):\r
+                    pos = int(filename,16)\r
+                    if(pos > 32767):\r
+                        pos-=65536\r
+                    ylist.append(pos)\r
+                    sectortype = "new"\r
+        except OSError:\r
+            pass\r
+\r
+    if sectortype == "":\r
+        continue\r
+\r
+    ylist.sort()\r
+\r
+    # Make a list of pixels of the sector that are to be looked for.\r
+    pixellist = []\r
+    for x in range(16):\r
+        for y in range(16):\r
+            pixellist.append((x,y))\r
+\r
+    # Go through the Y axis from top to bottom.\r
+    for ypos in reversed(ylist):\r
+\r
+        yhex = int_to_hex4(ypos)\r
+\r
+        filename = ""\r
+        if sectortype == "old":\r
+            filename = path + "sectors/" + sector1 + "/" + yhex.lower()\r
+        else:\r
+            filename = path + "sectors2/" + sector2 + "/" + yhex.lower()\r
+\r
+        f = file(filename, "rb")\r
+\r
+        # Let's just memorize these even though it's not really necessary.\r
+        version = f.read(1)\r
+        flags = f.read(1)\r
+\r
+        dec_o = zlib.decompressobj()\r
+        try:\r
+            mapdata = dec_o.decompress(f.read())\r
+        except:\r
+            mapdata = []\r
+\r
+        f.close()\r
+\r
+        if(len(mapdata)<4096):\r
+            print "bad: " + xhex+zhex+"/"+yhex + " " + len(mapdata)\r
+        else:\r
+            chunkxpos=xpos*16\r
+            chunkypos=ypos*16\r
+            chunkzpos=zpos*16\r
+            for (x,z) in reversed(pixellist):\r
+                for y in reversed(range(16)):\r
+                    datapos=x+y*16+z*256\r
+                    if(ord(mapdata[datapos])!=254):\r
+                        try:\r
+                            pixellist.remove((x,z))\r
+                            # Memorize information on the type and height of the block and for drawing the picture.\r
+                            stuff[(chunkxpos+x,chunkzpos+z)]=(chunkypos+y,ord(mapdata[datapos]))\r
+                            break\r
+                        except:\r
+                            print "strange block: " + xhex+zhex+"/"+yhex + " x: " + str(x) + " y: " + str(y) + " z: " + str(z) + " block: " + str(ord(mapdata[datapos]))\r
+\r
+        # After finding all the pixeld in the sector, we can move on to the next sector without having to continue the Y axis.\r
+        if(len(pixellist)==0):\r
+            break\r
+\r
+print "Drawing image"\r
+# Drawing the picture\r
+starttime = time.time()\r
+n = 0\r
+minx = min(xlist)\r
+minz = min(zlist)\r
+for (x,z) in stuff.iterkeys():\r
+    if n % 500000 == 0:\r
+        nowtime = time.time()\r
+        dtime = nowtime - starttime\r
+        n_per_second = 1.0 * n / dtime\r
+        if n_per_second != 0:\r
+            listlen = len(stuff)\r
+            seconds_per_n = 1.0 / n_per_second\r
+            time_guess = seconds_per_n * listlen\r
+            remaining_s = time_guess - dtime\r
+            remaining_minutes = int(remaining_s / 60)\r
+            remaining_s -= remaining_minutes * 60;\r
+            print("Drawing pixel "+str(n)+" of "+str(listlen)\r
+                    +" ("+str(round(100.0*n/listlen, 1))+"%)"\r
+                    +" (ETA: "+str(remaining_minutes)+"m "\r
+                    +str(int(remaining_s))+"s)")\r
+    n += 1\r
+\r
+    (r,g,b)=colors[stuff[(x,z)][1]]\r
+\r
+    # Comparing heights of a couple of adjacent blocks and changing brightness accordingly.\r
+    try:\r
+        y1=stuff[(x-1,z)][0]\r
+        y2=stuff[(x,z-1)][0]\r
+        y=stuff[(x,z)][0]\r
+\r
+        d=(y-y1+y-y2)*12\r
+\r
+        if(d>36):\r
+            d=36\r
+\r
+        r=limit(r+d,0,255)\r
+        g=limit(g+d,0,255)\r
+        b=limit(b+d,0,255)\r
+    except:\r
+        pass\r
+    #impix[w-1-(x-minx*16),h-1-(z-minz*16)]=(r,g,b)\r
+    impix[x-minx*16,h-1-(z-minz*16)]=(r,g,b)\r
+\r
+# Flip the picture to make it right and save.\r
+#print "Transposing"\r
+#im=im.transpose(Image.FLIP_TOP_BOTTOM)\r
+print "Saving"\r
+im.save(output)\r
diff --git a/pnoise.py b/pnoise.py
new file mode 100644 (file)
index 0000000..fcab5ac
--- /dev/null
+++ b/pnoise.py
@@ -0,0 +1,102 @@
+#
+# A python perlin noise implementation, from
+# http://www.fundza.com/c4serious/noise/perlin/perlin.html
+#
+# This is used for testing how to create maps with a python script.
+#
+
+import math
+p = (
+151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,
+30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,
+62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,
+125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,
+83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,
+143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,
+196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,
+250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,
+58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,
+221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,
+224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,
+12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,
+199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,
+205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
+151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,
+30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,
+62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,
+125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,
+83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,
+143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,
+196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,
+250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,
+58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,
+221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,
+224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,
+12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,
+199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,
+205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180)
+  
+def lerp(t, a, b):
+    return a + t * (b - a)
+  
+def fade(t):
+    return t * t * t * (t * (t * 6 - 15) + 10)
+  
+def grad(hash, x, y, z):
+    h = hash & 15
+    if h < 8:
+        u = x
+    else:
+        u = y
+    if h < 4:
+        v = y
+    elif h == 12 or h == 14:
+        v = x
+    else:
+        v = z
+    if h & 1 != 0:
+        u = -u
+    if h & 2 != 0:
+        v = -v
+    return u + v
+  
+def pnoise(x, y, z):
+    global p
+    X = int(math.floor(x)) & 255
+    Y = int(math.floor(y)) & 255
+    Z = int(math.floor(z)) & 255
+    x -= math.floor(x)
+    y -= math.floor(y)
+    z -= math.floor(z)
+    
+    u = fade(x)
+    v = fade(y)
+    w = fade(z)
+    
+    A =  p[X] + Y
+    AA = p[A] + Z
+    AB = p[A + 1] + Z
+    B =  p[X + 1] + Y
+    BA = p[B] + Z
+    BB = p[B + 1] + Z
+    
+    pAA = p[AA]
+    pAB = p[AB]
+    pBA = p[BA]
+    pBB = p[BB]
+    pAA1 = p[AA + 1]
+    pBA1 = p[BA + 1]
+    pAB1 = p[AB + 1]
+    pBB1 = p[BB + 1]
+    
+    gradAA =  grad(pAA, x,   y,   z)
+    gradBA =  grad(pBA, x-1, y,   z)
+    gradAB =  grad(pAB, x,   y-1, z)
+    gradBB =  grad(pBB, x-1, y-1, z)
+    gradAA1 = grad(pAA1,x,   y,   z-1)
+    gradBA1 = grad(pBA1,x-1, y,   z-1)
+    gradAB1 = grad(pAB1,x,   y-1, z-1)
+    gradBB1 = grad(pBB1,x-1, y-1, z-1)
+    return lerp(w, 
+    lerp(v, lerp(u, gradAA, gradBA), lerp(u, gradAB, gradBB)),
+    lerp(v, lerp(u, gradAA1,gradBA1),lerp(u, gradAB1,gradBB1)))    
index 73a960ecc64b6a3e70dc9b7715c2719b9b89fae3..f62a8626bef71ca8030934f285262eaaaf2b304f 100644 (file)
@@ -108,6 +108,7 @@ set(minetest_SRCS
        clouds.cpp
        clientobject.cpp
        guiMainMenu.cpp
+       guiKeyChangeMenu.cpp
        guiMessageMenu.cpp
        guiTextInputMenu.cpp
        guiInventoryMenu.cpp
index abc05650541e5bb7e9ceae557085131ef5b44bd4..e86b3a4f85ad0fafd9575022c46300372e65a193 100644 (file)
@@ -722,6 +722,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                */
                                //dstream<<"Updating"<<std::endl;
                                block->deSerialize(istr, ser_version);
+                               //block->setChangedFlag();
                        }
                        catch(InvalidPositionException &e)
                        {
@@ -732,6 +733,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                block = new MapBlock(&m_env.getMap(), p);
                                block->deSerialize(istr, ser_version);
                                sector->insertBlock(block);
+                               //block->setChangedFlag();
 
                                //DEBUG
                                /*NodeMod mod;
@@ -742,6 +744,27 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                block->setTempMod(v3s16(8,8,8), mod);
                                block->setTempMod(v3s16(8,7,8), mod);
                                block->setTempMod(v3s16(8,6,8), mod);*/
+#if 0
+                               /*
+                                       Add some coulds
+                                       Well, this is a dumb way to do it, they should just
+                                       be drawn as separate objects. But the looks of them
+                                       can be tested this way.
+                               */
+                               if(p.Y == 3)
+                               {
+                                       NodeMod mod;
+                                       mod.type = NODEMOD_CHANGECONTENT;
+                                       mod.param = CONTENT_CLOUD;
+                                       v3s16 p2;
+                                       p2.Y = 8;
+                                       for(p2.X=3; p2.X<=13; p2.X++)
+                                       for(p2.Z=3; p2.Z<=13; p2.Z++)
+                                       {
+                                               block->setTempMod(p2, mod);
+                                       }
+                               }
+#endif
                        }
                } //envlock
 
@@ -772,7 +795,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                */
 
                //m_env.getClientMap().updateMeshes(block->getPos(), getDayNightRatio());
-               
                /*
                        Add it to mesh update queue and set it to be acknowledged after update.
                */
index 32d2e6d489b6f4d5cdff8ff952463a6e77822268..069e68300b9bdf412c082a84b7aaa2fdc250c19e 100644 (file)
@@ -261,6 +261,24 @@ InventoryItem *craft_get_result(InventoryItem **items)
                }
        }
 
+       // Rail
+       {
+               ItemSpec specs[9];
+               specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot");
+               specs[1] = ItemSpec(ITEM_CRAFT, "Stick");
+               specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot");
+               specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot");
+               specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
+               specs[5] = ItemSpec(ITEM_CRAFT, "steel_ingot");
+               specs[6] = ItemSpec(ITEM_CRAFT, "steel_ingot");
+               specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
+               specs[8] = ItemSpec(ITEM_CRAFT, "steel_ingot");
+               if(checkItemCombination(items, specs))
+               {
+                       return new MaterialItem(CONTENT_RAIL, 15);
+               }
+       }
+
        // Chest
        {
                ItemSpec specs[9];
@@ -313,6 +331,87 @@ InventoryItem *craft_get_result(InventoryItem **items)
                }
        }
 
+       // Sandstone
+       {
+               ItemSpec specs[9];
+               specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_SAND);
+               specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_SAND);
+               specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_SAND);
+               specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_SAND);
+               if(checkItemCombination(items, specs))
+               {
+                       return new MaterialItem(CONTENT_SANDSTONE, 1);
+               }
+       }
+
+       // Clay
+       {
+               ItemSpec specs[9];
+               specs[3] = ItemSpec(ITEM_CRAFT, "lump_of_clay");
+               specs[4] = ItemSpec(ITEM_CRAFT, "lump_of_clay");
+               specs[6] = ItemSpec(ITEM_CRAFT, "lump_of_clay");
+               specs[7] = ItemSpec(ITEM_CRAFT, "lump_of_clay");
+               if(checkItemCombination(items, specs))
+               {
+                       return new MaterialItem(CONTENT_CLAY, 1);
+               }
+       }
+
+       // Brick
+       {
+               ItemSpec specs[9];
+               specs[3] = ItemSpec(ITEM_CRAFT, "clay_brick");
+               specs[4] = ItemSpec(ITEM_CRAFT, "clay_brick");
+               specs[6] = ItemSpec(ITEM_CRAFT, "clay_brick");
+               specs[7] = ItemSpec(ITEM_CRAFT, "clay_brick");
+               if(checkItemCombination(items, specs))
+               {
+                       return new MaterialItem(CONTENT_BRICK, 1);
+               }
+       }
+
+       // Paper
+       {
+               ItemSpec specs[9];
+               specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_PAPYRUS);
+               specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_PAPYRUS);
+               specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_PAPYRUS);
+               if(checkItemCombination(items, specs))
+               {
+                       return new CraftItem("paper", 1);
+               }
+       }
+
+       // Book
+       {
+               ItemSpec specs[9];
+               specs[1] = ItemSpec(ITEM_CRAFT, "paper");
+               specs[4] = ItemSpec(ITEM_CRAFT, "paper");
+               specs[7] = ItemSpec(ITEM_CRAFT, "paper");
+               if(checkItemCombination(items, specs))
+               {
+                       return new CraftItem("book", 1);
+               }
+       }
+
+       // Book shelf
+       {
+               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_CRAFT, "book");
+               specs[4] = ItemSpec(ITEM_CRAFT, "book");
+               specs[5] = ItemSpec(ITEM_CRAFT, "book");
+               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_BOOKSHELF, 1);
+               }
+       }
+
        return NULL;
 }
 
@@ -353,10 +452,17 @@ void craft_set_creative_inventory(Player *player)
                CONTENT_MUD,
                CONTENT_STONE,
                CONTENT_SAND,
+               CONTENT_SANDSTONE,
+               CONTENT_CLAY,
+               CONTENT_BRICK,
                CONTENT_TREE,
                CONTENT_LEAVES,
+               CONTENT_CACTUS,
+               CONTENT_PAPYRUS,
+               CONTENT_BOOKSHELF,
                CONTENT_GLASS,
                CONTENT_FENCE,
+               CONTENT_RAIL,
                CONTENT_MESE,
                CONTENT_WATERSOURCE,
                CONTENT_CLOUD,
index 3b72b31f1a21f72def7f4ab39b72b5c69ab29d97..357c8ef26c05d0511b32f1a4653709d37d7c3536 100644 (file)
@@ -48,12 +48,20 @@ std::string item_craft_get_image_name(const std::string &subname)
 {
        if(subname == "Stick")
                return "stick.png";
+       else if(subname == "paper")
+               return "paper.png";
+       else if(subname == "book")
+               return "book.png";
        else if(subname == "lump_of_coal")
                return "lump_of_coal.png";
        else if(subname == "lump_of_iron")
                return "lump_of_iron.png";
+       else if(subname == "lump_of_clay")
+               return "lump_of_clay.png";
        else if(subname == "steel_ingot")
                return "steel_ingot.png";
+       else if(subname == "clay_brick")
+               return "clay_brick.png";
        else if(subname == "rat")
                return "rat.png";
        else
@@ -82,7 +90,7 @@ s16 item_craft_get_drop_count(const std::string &subname)
 
 bool item_craft_is_cookable(const std::string &subname)
 {
-       if(subname == "lump_of_iron")
+       if(subname == "lump_of_iron" || subname == "lump_of_clay")
                return true;
                
        return false;
@@ -92,6 +100,8 @@ InventoryItem* item_craft_create_cook_result(const std::string &subname)
 {
        if(subname == "lump_of_iron")
                return new CraftItem("steel_ingot", 1);
+       else if(subname == "lump_of_clay")
+               return new CraftItem("clay_brick", 1);
 
        return NULL;
 }
index bc701aadf4c32927cd83372daaaf7072a104c736..9ef0599d17911689fbe0682daea707200c84db6a 100644 (file)
@@ -188,6 +188,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
        material_general.setFlag(video::EMF_FOG_ENABLE, true);
        material_general.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
 
+
+       // Papyrus material
+       video::SMaterial material_papyrus;
+       material_papyrus.setFlag(video::EMF_LIGHTING, false);
+       material_papyrus.setFlag(video::EMF_BILINEAR_FILTER, false);
+       material_papyrus.setFlag(video::EMF_FOG_ENABLE, true);
+       material_papyrus.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+       AtlasPointer pa_papyrus = g_texturesource->getTexture(
+                       g_texturesource->getTextureId("papyrus.png"));
+       material_papyrus.setTexture(0, pa_papyrus.atlas);
        for(s16 z=0; z<MAP_BLOCKSIZE; z++)
        for(s16 y=0; y<MAP_BLOCKSIZE; y++)
        for(s16 x=0; x<MAP_BLOCKSIZE; x++)
@@ -857,9 +867,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                TileSpec ts = n.getTile(dir);
                                AtlasPointer ap = ts.texture;
                                material_general.setTexture(0, ap.atlas);
-
                                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),
@@ -895,14 +904,56 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                                vertices[i].Pos.rotateXZBy(90);
                                }
                                else if(j == 4)
+
+                               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_general, vertices, 4, indices, 6);
+                       }
+               }
+#endif
+               else if(n.d == CONTENT_PAPYRUS)
+               {
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       video::SColor c(255,l,l,l);
+
+                       for(u32 j=0; j<4; j++)
+                       {
+                               video::S3DVertex vertices[4] =
+                               {
+                                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
+                                               pa_papyrus.x0(), pa_papyrus.y1()),
+                                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
+                                               pa_papyrus.x1(), pa_papyrus.y1()),
+                                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c,
+                                               pa_papyrus.x1(), pa_papyrus.y0()),
+                                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c,
+                                               pa_papyrus.x0(), pa_papyrus.y0()),
+                               };
+
+                               if(j == 0)
                                {
                                        for(u16 i=0; i<4; i++)
-                                               vertices[i].Pos.rotateYZBy(-90);
+                                               vertices[i].Pos.rotateXZBy(45);
                                }
-                               else if(j == 5)
+                               else if(j == 1)
                                {
                                        for(u16 i=0; i<4; i++)
-                                               vertices[i].Pos.rotateYZBy(90);
+                                               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++)
@@ -912,11 +963,113 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 
                                u16 indices[] = {0,1,2,2,3,0};
                                // Add to mesh collector
-                               collector.append(material_general, vertices, 4, indices, 6);
+                               collector.append(material_papyrus, vertices, 4, indices, 6);
                        }
                }
-#endif
+               else if(n.d == CONTENT_RAIL)
+               {
+                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+                       video::SColor c(255,l,l,l);
+
+                       bool is_rail_x [] = { false, false };  /* x-1, x+1 */
+                       bool is_rail_z [] = { false, false };  /* z-1, z+1 */
+
+                       MapNode n_minus_x = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x-1,y,z));
+                       MapNode n_plus_x = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x+1,y,z));
+                       MapNode n_minus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z-1));
+                       MapNode n_plus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z+1));
+
+                       if(n_minus_x.d == CONTENT_RAIL)
+                               is_rail_x[0] = true;
+                       if(n_plus_x.d == CONTENT_RAIL)
+                               is_rail_x[1] = true;
+                       if(n_minus_z.d == CONTENT_RAIL)
+                               is_rail_z[0] = true;
+                       if(n_plus_z.d == CONTENT_RAIL)
+                               is_rail_z[1] = true;
+
+                       float d = (float)BS/16;
+                       video::S3DVertex vertices[4] =
+                       {
+                               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),
+                       };
+
+                       video::SMaterial material_rail;
+                       material_rail.setFlag(video::EMF_LIGHTING, false);
+                       material_rail.setFlag(video::EMF_BACK_FACE_CULLING, false);
+                       material_rail.setFlag(video::EMF_BILINEAR_FILTER, false);
+                       material_rail.setFlag(video::EMF_FOG_ENABLE, true);
+                       material_rail.MaterialType
+                                       = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+
+                       int adjacencies = is_rail_x[0] + is_rail_x[1] + is_rail_z[0] + is_rail_z[1];
+
+                       // Assign textures
+                       if(adjacencies < 2)
+                               material_rail.setTexture(0, g_texturesource->getTextureRaw("rail.png"));
+                       else if(adjacencies == 2)
+                       {
+                               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"));
 
+                       // Rotate textures
+                       int angle = 0;
+
+                       if(adjacencies == 1)
+                       {
+                               if(is_rail_x[0] || is_rail_x[1])
+                                       angle = 90;
+                       }
+                       else if(adjacencies == 2)
+                       {
+                               if(is_rail_x[0] && is_rail_x[1])
+                                       angle = 90;
+                               else if(is_rail_x[0] && is_rail_z[0])
+                                       angle = 270;
+                               else if(is_rail_x[0] && is_rail_z[1])
+                                       angle = 180;
+                               else if(is_rail_x[1] && is_rail_z[1])
+                                       angle = 90;
+                       }
+                       else if(adjacencies == 3)
+                       {
+                               if(!is_rail_x[0])
+                                       angle=0;
+                               if(!is_rail_x[1])
+                                       angle=180;
+                               if(!is_rail_z[0])
+                                       angle=90;
+                               if(!is_rail_z[1])
+                                       angle=270;
+                       }
+
+                       if(angle != 0) {
+                               for(u16 i=0; i<4; i++)
+                                       vertices[i].Pos.rotateXZBy(angle);
+                       }
+
+                       for(s32 i=0; i<4; i++)
+                       {
+                               vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
+                       }
+
+                       u16 indices[] = {0,1,2,2,3,0};
+                       collector.append(material_rail, vertices, 4, indices, 6);
+               }
        }
 }
 #endif
index 403fb66d398fc86a750e9f5564553e1165ecdf12..2e7a240f308aea55e15639f4ddf20cfe181a67da 100644 (file)
@@ -99,6 +99,33 @@ void content_mapnode_init()
        f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
        setDirtLikeDiggingProperties(f->digging_properties, 1.75);
        
+       i = CONTENT_SANDSTONE;
+       f = &content_features(i);
+       f->setAllTextures("sandstone.png");
+       f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png");
+       f->param_type = CPT_MINERAL;
+       f->is_ground_content = true;
+       f->dug_item = std::string("MaterialItem ")+itos(CONTENT_SAND)+" 1";
+       setDirtLikeDiggingProperties(f->digging_properties, 1.0);
+
+       i = CONTENT_CLAY;
+       f = &content_features(i);
+       f->setAllTextures("clay.png");
+       f->setInventoryTextureCube("clay.png", "clay.png", "clay.png");
+       f->param_type = CPT_MINERAL;
+       f->is_ground_content = true;
+       f->dug_item = std::string("CraftItem lump_of_clay 4");
+       setDirtLikeDiggingProperties(f->digging_properties, 1.0);
+
+       i = CONTENT_BRICK;
+       f = &content_features(i);
+       f->setAllTextures("brick.png");
+       f->setInventoryTextureCube("brick.png", "brick.png", "brick.png");
+       f->param_type = CPT_MINERAL;
+       f->is_ground_content = true;
+       f->dug_item = std::string("CraftItem clay_brick 4");
+       setStoneLikeDiggingProperties(f->digging_properties, 1.0);
+
        i = CONTENT_TREE;
        f = &content_features(i);
        f->setAllTextures("tree.png");
@@ -127,6 +154,40 @@ void content_mapnode_init()
        f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
        setWoodLikeDiggingProperties(f->digging_properties, 0.15);
 
+       i = CONTENT_CACTUS;
+       f = &content_features(i);
+       f->setAllTextures("cactus_side.png");
+       f->setTexture(0, "cactus_top.png");
+       f->setTexture(1, "cactus_top.png");
+       f->setInventoryTextureCube("cactus_top.png", "cactus_side.png", "cactus_side.png");
+       f->param_type = CPT_MINERAL;
+       f->is_ground_content = true;
+       f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+       setWoodLikeDiggingProperties(f->digging_properties, 0.75);
+
+       i = CONTENT_PAPYRUS;
+       f = &content_features(i);
+       f->setInventoryTexture("papyrus.png");
+       f->light_propagates = true;
+       f->param_type = CPT_LIGHT;
+       f->is_ground_content = true;
+       f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+       f->solidness = 0; // drawn separately, makes no faces
+       f->walkable = false;
+       setWoodLikeDiggingProperties(f->digging_properties, 0.25);
+
+       i = CONTENT_BOOKSHELF;
+       f = &content_features(i);
+       f->setAllTextures("bookshelf.png");
+       f->setTexture(0, "wood.png");
+       f->setTexture(1, "wood.png");
+       // FIXME: setInventoryTextureCube() only cares for the first texture
+       f->setInventoryTextureCube("bookshelf.png", "bookshelf.png", "bookshelf.png");
+       //f->setInventoryTextureCube("wood.png", "bookshelf.png", "bookshelf.png");
+       f->param_type = CPT_MINERAL;
+       f->is_ground_content = true;
+       setWoodLikeDiggingProperties(f->digging_properties, 0.75);
+
        i = CONTENT_GLASS;
        f = &content_features(i);
        f->light_propagates = true;
@@ -148,6 +209,18 @@ void content_mapnode_init()
        f->setInventoryTexture("item_fence.png");
        setWoodLikeDiggingProperties(f->digging_properties, 0.75);
 
+       i = CONTENT_RAIL;
+       f = &content_features(i);
+       f->setInventoryTexture("rail.png");
+       f->light_propagates = true;
+       f->param_type = CPT_LIGHT;
+       f->is_ground_content = true;
+       f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+       f->solidness = 0; // drawn separately, makes no faces
+       f->air_equivalent = true; // grass grows underneath
+       f->walkable = false;
+       setDirtLikeDiggingProperties(f->digging_properties, 0.75);
+
        // Deprecated
        i = CONTENT_COALSTONE;
        f = &content_features(i);
index e314807f94dc7c92a37c8871a068a1f1b0b2187c..e53624c21597d5cb19d6e62d1299d387254d253a 100644 (file)
@@ -50,6 +50,13 @@ void content_mapnode_init();
 #define CONTENT_FENCE 21
 #define CONTENT_MOSSYCOBBLE 22
 #define CONTENT_GRAVEL 23
+#define CONTENT_SANDSTONE 24
+#define CONTENT_CACTUS 25
+#define CONTENT_BRICK 26
+#define CONTENT_CLAY 27
+#define CONTENT_PAPYRUS 28
+#define CONTENT_BOOKSHELF 29
+#define CONTENT_RAIL 30
 
 #endif
 
index cd255341f5d8b996c1600e61a14fa2e46d9665ba..e2c704259888323064063c0bf7a4a78b8e7aeab0 100644 (file)
@@ -592,7 +592,7 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
        block->setTimestamp(m_game_time);
 
        //dstream<<"Block is "<<dtime_s<<" seconds old."<<std::endl;
-       
+
        // Activate stored objects
        activateObjects(block);
 
@@ -610,7 +610,7 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
 
        // TODO: Do something
        // TODO: Implement usage of ActiveBlockModifier
-       
+
        // Here's a quick demonstration
        v3s16 p0;
        for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
@@ -754,8 +754,8 @@ void ServerEnvironment::step(float dtime)
                        MapBlock *block = m_map->getBlockNoCreateNoEx(p);
                        if(block==NULL)
                                continue;
-                       
                        // Set current time as timestamp (and let it set ChangedFlag)
+
                        block->setTimestamp(m_game_time);
                }
 
@@ -776,7 +776,75 @@ void ServerEnvironment::step(float dtime)
                        if(block==NULL)
                                continue;
 
-                       activateBlock(block);
+                       // Get time difference
+                       u32 dtime_s = 0;
+                       u32 stamp = block->getTimestamp();
+                       if(m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED)
+                               dtime_s = m_game_time - block->getTimestamp();
+
+                       // Set current time as timestamp (and let it set ChangedFlag)
+                       block->setTimestamp(m_game_time);
+
+                       //dstream<<"Block is "<<dtime_s<<" seconds old."<<std::endl;
+
+                       // Activate stored objects
+                       activateObjects(block);
+
+                       // Run node metadata
+                       bool changed = block->m_node_metadata.step((float)dtime_s);
+                       if(changed)
+                       {
+                               MapEditEvent event;
+                               event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
+                               event.p = p;
+                               m_map->dispatchEvent(&event);
+
+                               block->setChangedFlag();
+                       }
+
+                       // TODO: Do something
+                       // TODO: Implement usage of ActiveBlockModifier
+
+                       // Here's a quick demonstration
+                       v3s16 p0;
+                       for(p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
+                       for(p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++)
+                       for(p0.Z=0; p0.Z<MAP_BLOCKSIZE; p0.Z++)
+                       {
+                               v3s16 p = p0 + block->getPosRelative();
+                               MapNode n = block->getNodeNoEx(p0);
+                               // Test something:
+                               // Convert all mud under proper day lighting to grass
+                               if(n.d == CONTENT_MUD)
+                               {
+                                       if(dtime_s > 300)
+                                       {
+                                               MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
+                                               if(content_features(n_top.d).air_equivalent &&
+                                                               n_top.getLight(LIGHTBANK_DAY) >= 13)
+                                               {
+                                                       n.d = CONTENT_GRASS;
+                                                       m_map->addNodeWithEvent(p, n);
+                                               }
+                                       }
+                               }
+                               /*
+                                       Convert grass into mud if under something else than air
+                               */
+                               else if(n.d == CONTENT_GRASS)
+                               {
+                                       //if(myrand()%20 == 0)
+                                       {
+                                               MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
+                                               if(n_top.d != CONTENT_AIR
+                                                               && n_top.d != CONTENT_IGNORE)
+                                               {
+                                                       n.d = CONTENT_MUD;
+                                                       m_map->addNodeWithEvent(p, n);
+                                               }
+                                       }
+                               }
+                       }
                }
        }
 
@@ -889,8 +957,8 @@ void ServerEnvironment::step(float dtime)
                                                        n.d = CONTENT_MUD;
                                                        m_map->addNodeWithEvent(p, n);
                                                }
+                                               }
                                        }
-                               }
                        }
                }
        }
index f3fac0c84eb5bbdb6e80fbff49bf058ef32efabe..5632c1805ae39c8a47c23b77cec50e876c720a42 100644 (file)
@@ -534,6 +534,43 @@ void getPointedNode(Client *client, v3f player_position,
                                }
                        }
                }
+               else if(n.d == CONTENT_RAIL)
+               {
+                       v3s16 dir = unpackDir(n.dir);
+                       v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
+                       dir_f *= BS/2 - BS/6 - BS/20;
+                       v3f cpf = npf + dir_f;
+                       f32 distance = (cpf - camera_position).getLength();
+
+                       float d = (float)BS/16;
+                       v3f vertices[4] =
+                       {
+                               v3f(BS/2, -BS/2+d, -BS/2),
+                               v3f(-BS/2, -BS/2, BS/2),
+                       };
+
+                       for(s32 i=0; i<2; i++)
+                       {
+                               vertices[i] += npf;
+                       }
+
+                       core::aabbox3d<f32> box;
+
+                       box = core::aabbox3d<f32>(vertices[0]);
+                       box.addInternalPoint(vertices[1]);
+
+                       if(distance < mindistance)
+                       {
+                               if(box.intersectsWithLine(shootline))
+                               {
+                                       nodefound = true;
+                                       nodepos = np;
+                                       neighbourpos = np;
+                                       mindistance = distance;
+                                       nodehilightbox = box;
+                               }
+                       }
+               }
                /*
                        Regular blocks
                */
index ef0a013f14e850403e5be8b65332d0426e01943a..cea32860bc9109d1e15962f11a456fdd0a0bef1b 100644 (file)
@@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "guiMainMenu.h"
+#include "guiKeyChangeMenu.h"
 #include "debug.h"
 #include "serialization.h"
 #include <string>
 
+
+
 GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
                gui::IGUIElement* parent, s32 id,
                IMenuManager *menumgr,
@@ -34,6 +37,10 @@ GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
        m_gamecallback(gamecallback)
 {
        assert(m_data);
+       this->env = env;
+       this->parent = parent;
+       this->id = id;
+       this->menumgr = menumgr;
 }
 
 GUIMainMenu::~GUIMainMenu()
@@ -70,35 +77,35 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
        
        // Client options
        {
-               gui::IGUIElement *e = getElementFromId(258);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
                if(e != NULL)
                        text_name = e->getText();
                else
                        text_name = m_data->name;
        }
        {
-               gui::IGUIElement *e = getElementFromId(256);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
                if(e != NULL)
                        text_address = e->getText();
                else
                        text_address = m_data->address;
        }
        {
-               gui::IGUIElement *e = getElementFromId(257);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
                if(e != NULL)
                        text_port = e->getText();
                else
                        text_port = m_data->port;
        }
        {
-               gui::IGUIElement *e = getElementFromId(263);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
                else
                        fancy_trees = m_data->fancy_trees;
        }
        {
-               gui::IGUIElement *e = getElementFromId(262);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
                else
@@ -107,14 +114,14 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
        
        // Server options
        {
-               gui::IGUIElement *e = getElementFromId(259);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
                else
                        creative_mode = m_data->creative_mode;
        }
        {
-               gui::IGUIElement *e = getElementFromId(261);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
                else
@@ -175,7 +182,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                core::rect<s32> rect(0, 0, 230, 30);
                rect += topleft_client + v2s32(160, 50);
                gui::IGUIElement *e = 
-               Environment->addEditBox(text_name.c_str(), rect, true, this, 258);
+               Environment->addEditBox(text_name.c_str(), rect, true, this, GUI_ID_NAME_INPUT);
                if(text_name == L"")
                        Environment->setFocus(e);
        }
@@ -198,7 +205,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                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, 256);
+               Environment->addEditBox(text_address.c_str(), rect, true, this, GUI_ID_ADDRESS_INPUT);
                if(text_name != L"")
                        Environment->setFocus(e);
        }
@@ -206,7 +213,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                core::rect<s32> rect(0, 0, 120, 30);
                //rect += topleft_client + v2s32(160+250+20, 125);
                rect += topleft_client + v2s32(size_client.X-60-100, 100);
-               Environment->addEditBox(text_port.c_str(), rect, true, this, 257);
+               Environment->addEditBox(text_port.c_str(), rect, true, this, GUI_ID_PORT_INPUT);
        }
        {
                core::rect<s32> rect(0, 0, 400, 20);
@@ -217,13 +224,13 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
        {
                core::rect<s32> rect(0, 0, 250, 30);
                rect += topleft_client + v2s32(35, 150);
-               Environment->addCheckBox(fancy_trees, rect, this, 263,
+               Environment->addCheckBox(fancy_trees, rect, this, GUI_ID_FANCYTREE_CB,
                                L"Fancy trees");
        }
        {
                core::rect<s32> rect(0, 0, 250, 30);
                rect += topleft_client + v2s32(35, 150+30);
-               Environment->addCheckBox(smooth_lighting, rect, this, 262,
+               Environment->addCheckBox(smooth_lighting, rect, this, GUI_ID_SMOOTH_LIGHTING_CB,
                                L"Smooth Lighting");
        }
        // Start game button
@@ -231,9 +238,16 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
                core::rect<s32> rect(0, 0, 180, 30);
                //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, 257, L"Start Game / Connect");
+               Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, L"Start Game / Connect");
        }
 
+       // Key change button
+       {
+               core::rect<s32> rect(0, 0, 100, 30);
+               //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, L"Change keys");
+       }
        /*
                Server section
        */
@@ -254,19 +268,19 @@ 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, 259, L"Creative Mode");
+               Environment->addCheckBox(creative_mode, rect, this, GUI_ID_CREATIVE_CB, L"Creative Mode");
        }
        {
                core::rect<s32> rect(0, 0, 250, 30);
                rect += topleft_server + v2s32(35, 60);
-               Environment->addCheckBox(enable_damage, rect, this, 261, L"Enable Damage");
+               Environment->addCheckBox(enable_damage, rect, this, GUI_ID_DAMAGE_CB, L"Enable Damage");
        }
        // Map delete button
        {
                core::rect<s32> rect(0, 0, 130, 30);
                //rect += topleft_server + v2s32(size_server.X-40-130, 100+25);
                rect += topleft_server + v2s32(40, 100+25);
-               Environment->addButton(rect, this, 260, L"Delete world");
+               Environment->addButton(rect, this, GUI_ID_DELETE_MAP_BUTTON, L"Delete map");
        }
 }
 
@@ -300,7 +314,7 @@ void GUIMainMenu::drawMenu()
 void GUIMainMenu::acceptInput()
 {
        {
-               gui::IGUIElement *e = getElementFromId(258);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_NAME_INPUT);
                if(e != NULL)
                        m_data->name = e->getText();
        }
@@ -310,32 +324,32 @@ void GUIMainMenu::acceptInput()
                        m_data->password = e->getText();
        }
        {
-               gui::IGUIElement *e = getElementFromId(256);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_ADDRESS_INPUT);
                if(e != NULL)
                        m_data->address = e->getText();
        }
        {
-               gui::IGUIElement *e = getElementFromId(257);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_PORT_INPUT);
                if(e != NULL)
                        m_data->port = e->getText();
        }
        {
-               gui::IGUIElement *e = getElementFromId(259);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_CREATIVE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        m_data->creative_mode = ((gui::IGUICheckBox*)e)->isChecked();
        }
        {
-               gui::IGUIElement *e = getElementFromId(261);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_DAMAGE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        m_data->enable_damage = ((gui::IGUICheckBox*)e)->isChecked();
        }
        {
-               gui::IGUIElement *e = getElementFromId(262);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_SMOOTH_LIGHTING_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        m_data->smooth_lighting = ((gui::IGUICheckBox*)e)->isChecked();
        }
        {
-               gui::IGUIElement *e = getElementFromId(263);
+               gui::IGUIElement *e = getElementFromId(GUI_ID_FANCYTREE_CB);
                if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
                        m_data->fancy_trees = ((gui::IGUICheckBox*)e)->isChecked();
        }
@@ -377,11 +391,16 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                {
                        switch(event.GUIEvent.Caller->getID())
                        {
-                       case 257: // Start game
+                       case GUI_ID_JOIN_GAME_BUTTON: // Start game
                                acceptInput();
                                quitMenu();
                                return true;
-                       case 260: // Delete map
+                       case GUI_ID_CHANGE_KEYS_BUTTON: {
+                               GUIKeyChangeMenu *kmenu = new GUIKeyChangeMenu(env, parent, -1,menumgr);
+                               kmenu->drop();
+                               return true;
+                       }
+                       case GUI_ID_DELETE_MAP_BUTTON: // Delete map
                                // Don't accept input data, just set deletion request
                                m_data->delete_map = true;
                                m_accepted = true;
@@ -393,7 +412,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
                {
                        switch(event.GUIEvent.Caller->getID())
                        {
-                               case 256: case 257: case 258: case 264:
+                               case GUI_ID_ADDRESS_INPUT: case GUI_ID_PORT_INPUT: case GUI_ID_NAME_INPUT: case 264:
                                acceptInput();
                                quitMenu();
                                return true;
index edd519024fb6a56879538d6cf144183f92f4c18b..87561f7974fd075dd4bea9c6fc440a5470fffcfb 100644 (file)
@@ -27,6 +27,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 // For IGameCallback
 #include "guiPauseMenu.h"
 
+enum
+{
+       GUI_ID_QUIT_BUTTON = 101,
+       GUI_ID_NAME_INPUT,
+       GUI_ID_ADDRESS_INPUT,
+       GUI_ID_PORT_INPUT,
+       GUI_ID_FANCYTREE_CB,
+       GUI_ID_SMOOTH_LIGHTING_CB,
+       GUI_ID_DAMAGE_CB,
+       GUI_ID_CREATIVE_CB,
+       GUI_ID_JOIN_GAME_BUTTON,
+       GUI_ID_CHANGE_KEYS_BUTTON,
+       GUI_ID_DELETE_MAP_BUTTON
+};
+
 struct MainMenuData
 {
        MainMenuData():
@@ -87,6 +102,11 @@ private:
        MainMenuData *m_data;
        bool m_accepted;
        IGameCallback *m_gamecallback;
+
+       gui::IGUIEnvironment* env;
+       gui::IGUIElement* parent;
+       s32 id;
+       IMenuManager *menumgr;
 };
 
 #endif
index ad3c0b4018bf074dabf120eb5bb18f479fe50fe8..f014914d02a6f27e3070a60aa4693e9affc36a36 100644 (file)
@@ -171,6 +171,46 @@ irr::EKEY_CODE keyname_to_keycode(const char *name)
        return irr::KEY_KEY_CODES_COUNT;
 }
 
+static const char *KeyNames[] =
+{ "-", "KEY_LBUTTON", "KEY_RBUTTON", "Cancel", "Middle Button", "X Button 1",
+               "X Button 2", "-", "Back", "Tab", "-", "-", "Clear", "Return", "-",
+               "-", "KEY_SHIFT", "Control", "Menu", "Pause", "Capital", "Kana", "-",
+               "Junja", "Final", "Kanji", "-", "Escape", "Convert", "Nonconvert",
+               "Accept", "Mode Change", "KEY_SPACE", "Priot", "Next", "KEY_END",
+               "KEY_HOME", "Left", "Up", "Right", "Down", "Select", "KEY_PRINT",
+               "Execute", "Snapshot", "Insert", "Delete", "Help", "KEY_KEY_0",
+               "KEY_KEY_1", "KEY_KEY_2", "KEY_KEY_3", "KEY_KEY_4", "KEY_KEY_5",
+               "KEY_KEY_6", "KEY_KEY_7", "KEY_KEY_8", "KEY_KEY_9", "-", "-", "-", "-",
+               "-", "-", "-", "KEY_KEY_A", "KEY_KEY_B", "KEY_KEY_C", "KEY_KEY_D",
+               "KEY_KEY_E", "KEY_KEY_F", "KEY_KEY_G", "KEY_KEY_H", "KEY_KEY_I",
+               "KEY_KEY_J", "KEY_KEY_K", "KEY_KEY_L", "KEY_KEY_M", "KEY_KEY_N",
+               "KEY_KEY_O", "KEY_KEY_P", "KEY_KEY_Q", "KEY_KEY_R", "KEY_KEY_S",
+               "KEY_KEY_T", "KEY_KEY_U", "KEY_KEY_V", "KEY_KEY_W", "KEY_KEY_X",
+               "KEY_KEY_Y", "KEY_KEY_Z", "Left Windows", "Right Windows", "Apps", "-",
+               "Sleep", "KEY_NUMPAD0", "KEY_NUMPAD1", "KEY_NUMPAD2", "KEY_NUMPAD3",
+               "KEY_NUMPAD4", "KEY_NUMPAD5", "KEY_NUMPAD6", "KEY_NUMPAD7",
+               "KEY_NUMPAD8", "KEY_NUMPAD9", "Numpad *", "Numpad +", "Numpad /",
+               "Numpad -", "Numpad .", "Numpad /", "KEY_F1", "KEY_F2", "KEY_F3",
+               "KEY_F4", "KEY_F5", "KEY_F6", "KEY_F7", "KEY_F8", "KEY_F9", "KEY_F10",
+               "KEY_F11", "KEY_F12", "KEY_F13", "KEY_F14", "KEY_F15", "KEY_F16",
+               "KEY_F17", "KEY_F18", "KEY_F19", "KEY_F20", "KEY_F21", "KEY_F22",
+               "KEY_F23", "KEY_F24", "-", "-", "-", "-", "-", "-", "-", "-",
+               "Num Lock", "Scroll Lock", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+               "-", "-", "-", "-", "-", "KEY_LSHIFT", "KEY_RSHIFT", "Left Control",
+               "Right Control", "Left Menu", "Right Menu", "-", "-", "-", "-", "-",
+               "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+               "-", "-", "Plus", "Comma", "Minus", "Period", "-", "-", "-", "-", "-",
+               "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+               "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+               "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+               "-", "-", "-", "-", "-", "-", "-", "-", "Attn", "CrSel", "ExSel",
+               "Erase OEF", "Play", "Zoom", "PA1", "OEM Clear", "-" };
+
+std::string keycode_to_keyname(s32 keycode)
+{
+       return KeyNames[keycode];
+}
+
 /*
        Key config
 */
@@ -189,4 +229,7 @@ irr::EKEY_CODE getKeySetting(const char *settingname)
        return c;
 }
 
-
+void clearKeyCache()
+{
+       g_key_setting_cache.clear();
+}
index f19fe344282c77c8f999b2ddffe7cbb286a9d38b..9c62004d8f744644185d61ad4ded8bfab9abb4a1 100644 (file)
@@ -21,11 +21,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define KEYCODE_HEADER
 
 #include "common_irrlicht.h"
+#include <string>
 
 irr::EKEY_CODE keyname_to_keycode(const char *name);
 
 // Key configuration getter
 irr::EKEY_CODE getKeySetting(const char *settingname);
+std::string keycode_to_keyname(s32 keycode);
+void clearCache();
 
 #endif