]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Add items
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 19 Apr 2022 21:30:07 +0000 (23:30 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 19 Apr 2022 21:31:26 +0000 (23:31 +0200)
63 files changed:
deps/protogen
meshes/axe.gox [new file with mode: 0644]
meshes/axe.txt [new file with mode: 0644]
meshes/pickaxe.gox [new file with mode: 0644]
meshes/pickaxe.txt [new file with mode: 0644]
meshes/unknown.gox [new file with mode: 0644]
meshes/unknown.txt [new file with mode: 0644]
models/player.txt
shaders/3d/entity/fragment.glsl
shaders/3d/entity/vertex.glsl
shaders/3d/item/fragment.glsl [new file with mode: 0755]
shaders/3d/item/vertex.glsl [new file with mode: 0755]
shaders/3d/terrain/fragment.glsl
shaders/3d/terrain/vertex.glsl
src/CMakeLists.txt
src/client/camera.c
src/client/camera.h
src/client/client.c
src/client/client_entity.c
src/client/client_entity.h
src/client/client_inventory.c [new file with mode: 0644]
src/client/client_inventory.h [new file with mode: 0644]
src/client/client_item.c [new file with mode: 0644]
src/client/client_item.h [new file with mode: 0644]
src/client/client_node.c
src/client/client_node.h
src/client/client_player.c
src/client/client_player.h
src/client/client_terrain.c
src/client/debug_menu.c
src/client/debug_menu.h
src/client/game.c
src/client/game.h
src/client/gui.c
src/client/gui.h
src/client/input.c
src/client/interact.c
src/client/interact.h
src/client/mesh.c
src/client/mesh.h
src/client/model.c
src/client/model.h
src/client/raycast.c
src/client/screenshot.c [new file with mode: 0644]
src/client/screenshot.h [new file with mode: 0644]
src/client/shader.c
src/client/shader.h
src/client/terrain_gfx.c
src/client/window.h
src/item.c [new file with mode: 0644]
src/item.h [new file with mode: 0644]
src/node.c
src/node.h
src/physics.c
src/server/server.c
src/server/server_player.c
src/server/server_player.h
src/server/server_terrain.c
src/server/terrain_gen.c
src/server/trees.c
src/server/trees.h
src/terrain.c
src/types.def

index 45b691209c95e5a758536a32564c329683550dca..97963be1d8fbc53dce1b116f1d62340dee83383c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 45b691209c95e5a758536a32564c329683550dca
+Subproject commit 97963be1d8fbc53dce1b116f1d62340dee83383c
diff --git a/meshes/axe.gox b/meshes/axe.gox
new file mode 100644 (file)
index 0000000..08bb09a
Binary files /dev/null and b/meshes/axe.gox differ
diff --git a/meshes/axe.txt b/meshes/axe.txt
new file mode 100644 (file)
index 0000000..1e29a2a
--- /dev/null
@@ -0,0 +1,39 @@
+# Goxel 0.10.6
+# One line per voxel
+# X Y Z RRGGBB
+0 -1 9 a5a5a5
+0 -1 10 a0a0a0
+0 0 0 503612
+0 0 1 503612
+0 0 2 584120
+0 0 3 43351e
+0 0 4 503612
+0 0 5 503612
+0 0 6 4a3312
+0 0 7 5c421a
+0 3 7 a0a0a0
+0 4 7 9e9e9e
+0 0 8 5a380e
+0 2 8 9e9e9e
+0 3 8 a1a1a1
+0 4 8 a1a1a1
+0 0 9 a1a1a1
+1 0 9 a0a0a0
+0 1 9 9e9e9e
+0 2 9 9e9e9e
+0 3 9 a1a1a1
+0 4 9 9e9e9e
+0 0 10 989898
+1 0 10 a0a0a0
+0 1 10 a0a0a0
+0 2 10 9e9e9e
+0 3 10 9e9e9e
+0 4 10 9e9e9e
+0 0 11 5c421a
+0 2 11 a0a0a0
+0 3 11 9e9e9e
+0 4 11 a1a1a1
+0 3 12 9e9e9e
+0 4 12 9e9e9e
+-1 0 9 a0a0a0
+-1 0 10 a0a0a0
diff --git a/meshes/pickaxe.gox b/meshes/pickaxe.gox
new file mode 100644 (file)
index 0000000..95e9c21
Binary files /dev/null and b/meshes/pickaxe.gox differ
diff --git a/meshes/pickaxe.txt b/meshes/pickaxe.txt
new file mode 100644 (file)
index 0000000..c14d78e
--- /dev/null
@@ -0,0 +1,31 @@
+# Goxel 0.10.6
+# One line per voxel
+# X Y Z RRGGBB
+0 -4 7 a0a0a0
+0 -4 8 a0a0a0
+0 -3 8 999999
+0 -3 9 a0a0a0
+0 -2 9 a0a0a0
+0 -1 9 8b8b8b
+0 -2 10 a0a0a0
+0 -1 10 a9a9a9
+0 0 0 503612
+0 0 1 503612
+0 0 2 584120
+0 0 3 43351e
+0 0 4 503612
+0 0 5 503612
+0 0 6 4a3312
+0 0 7 5c421a
+0 4 7 999999
+0 0 8 5a380e
+0 3 8 999999
+0 4 8 a0a0a0
+0 0 9 a0a0a0
+0 1 9 a9a9a9
+0 2 9 a0a0a0
+0 3 9 a0a0a0
+0 0 10 a9a9a9
+0 1 10 8b8b8b
+0 2 10 a0a0a0
+0 0 11 a0a0a0
diff --git a/meshes/unknown.gox b/meshes/unknown.gox
new file mode 100644 (file)
index 0000000..61584af
Binary files /dev/null and b/meshes/unknown.gox differ
diff --git a/meshes/unknown.txt b/meshes/unknown.txt
new file mode 100644 (file)
index 0000000..78bbd97
--- /dev/null
@@ -0,0 +1,732 @@
+# Goxel 0.10.6
+# One line per voxel
+# X Y Z RRGGBB
+0 0 0 920088
+1 0 0 920088
+2 0 0 920088
+3 0 0 920088
+4 0 0 920088
+5 0 0 920088
+6 0 0 920088
+7 0 0 920088
+8 0 0 920088
+0 1 0 920088
+1 1 0 c400bc
+2 1 0 c400bc
+3 1 0 c400bc
+4 1 0 c400bc
+5 1 0 c400bc
+6 1 0 c400bc
+7 1 0 c400bc
+8 1 0 920088
+0 2 0 920088
+1 2 0 c400bc
+2 2 0 c400bc
+3 2 0 cdd300
+4 2 0 cdd300
+5 2 0 cdd300
+6 2 0 c400bc
+7 2 0 c400bc
+8 2 0 920088
+0 3 0 920088
+1 3 0 c400bc
+2 3 0 cdd300
+3 3 0 c400bc
+4 3 0 c400bc
+5 3 0 c400bc
+6 3 0 cdd300
+7 3 0 c400bc
+8 3 0 920088
+0 4 0 920088
+1 4 0 c400bc
+2 4 0 c400bc
+3 4 0 c400bc
+4 4 0 cdd300
+5 4 0 cdd300
+6 4 0 c400bc
+7 4 0 c400bc
+8 4 0 920088
+0 5 0 920088
+1 5 0 c400bc
+2 5 0 c400bc
+3 5 0 c400bc
+4 5 0 c400bc
+5 5 0 c400bc
+6 5 0 c400bc
+7 5 0 c400bc
+8 5 0 920088
+0 6 0 920088
+1 6 0 c400bc
+2 6 0 c400bc
+3 6 0 c400bc
+4 6 0 cdd300
+5 6 0 c400bc
+6 6 0 c400bc
+7 6 0 c400bc
+8 6 0 920088
+0 7 0 920088
+1 7 0 c400bc
+2 7 0 c400bc
+3 7 0 c400bc
+4 7 0 c400bc
+5 7 0 c400bc
+6 7 0 c400bc
+7 7 0 c400bc
+8 7 0 920088
+0 8 0 920088
+1 8 0 920088
+2 8 0 920088
+3 8 0 920088
+4 8 0 920088
+5 8 0 920088
+6 8 0 920088
+7 8 0 920088
+8 8 0 920088
+0 0 1 920088
+1 0 1 c400bc
+2 0 1 c400bc
+3 0 1 c400bc
+4 0 1 c400bc
+5 0 1 c400bc
+6 0 1 c400bc
+7 0 1 c400bc
+8 0 1 920088
+0 1 1 c400bc
+1 1 1 ffffff
+2 1 1 ffffff
+3 1 1 ffffff
+4 1 1 ffffff
+5 1 1 ffffff
+6 1 1 ffffff
+7 1 1 ffffff
+8 1 1 c400bc
+0 2 1 c400bc
+1 2 1 ffffff
+2 2 1 ffffff
+3 2 1 ffffff
+4 2 1 ffffff
+5 2 1 ffffff
+6 2 1 ffffff
+7 2 1 ffffff
+8 2 1 c400bc
+0 3 1 c400bc
+1 3 1 ffffff
+2 3 1 ffffff
+3 3 1 ffffff
+4 3 1 ffffff
+5 3 1 ffffff
+6 3 1 ffffff
+7 3 1 ffffff
+8 3 1 c400bc
+0 4 1 c400bc
+1 4 1 ffffff
+2 4 1 ffffff
+3 4 1 ffffff
+4 4 1 ffffff
+5 4 1 ffffff
+6 4 1 ffffff
+7 4 1 ffffff
+8 4 1 c400bc
+0 5 1 c400bc
+1 5 1 ffffff
+2 5 1 ffffff
+3 5 1 ffffff
+4 5 1 ffffff
+5 5 1 ffffff
+6 5 1 ffffff
+7 5 1 ffffff
+8 5 1 c400bc
+0 6 1 c400bc
+1 6 1 ffffff
+2 6 1 ffffff
+3 6 1 ffffff
+4 6 1 ffffff
+5 6 1 ffffff
+6 6 1 ffffff
+7 6 1 ffffff
+8 6 1 c400bc
+0 7 1 c400bc
+1 7 1 ffffff
+2 7 1 ffffff
+3 7 1 ffffff
+4 7 1 ffffff
+5 7 1 ffffff
+6 7 1 ffffff
+7 7 1 ffffff
+8 7 1 c400bc
+0 8 1 920088
+1 8 1 c400bc
+2 8 1 c400bc
+3 8 1 c400bc
+4 8 1 c400bc
+5 8 1 c400bc
+6 8 1 c400bc
+7 8 1 c400bc
+8 8 1 920088
+0 0 2 920088
+1 0 2 c400bc
+2 0 2 c400bc
+3 0 2 c400bc
+4 0 2 cdd300
+5 0 2 c400bc
+6 0 2 c400bc
+7 0 2 c400bc
+8 0 2 920088
+0 1 2 c400bc
+1 1 2 ffffff
+2 1 2 ffffff
+3 1 2 ffffff
+4 1 2 ffffff
+5 1 2 ffffff
+6 1 2 ffffff
+7 1 2 ffffff
+8 1 2 c400bc
+0 2 2 c400bc
+1 2 2 ffffff
+2 2 2 ffffff
+3 2 2 ffffff
+4 2 2 ffffff
+5 2 2 ffffff
+6 2 2 ffffff
+7 2 2 ffffff
+8 2 2 c400bc
+0 3 2 c400bc
+1 3 2 ffffff
+2 3 2 ffffff
+3 3 2 ffffff
+4 3 2 ffffff
+5 3 2 ffffff
+6 3 2 ffffff
+7 3 2 ffffff
+8 3 2 c400bc
+0 4 2 cdd300
+1 4 2 ffffff
+2 4 2 ffffff
+3 4 2 ffffff
+4 4 2 ffffff
+5 4 2 ffffff
+6 4 2 ffffff
+7 4 2 ffffff
+8 4 2 cdd300
+0 5 2 c400bc
+1 5 2 ffffff
+2 5 2 ffffff
+3 5 2 ffffff
+4 5 2 ffffff
+5 5 2 ffffff
+6 5 2 ffffff
+7 5 2 ffffff
+8 5 2 c400bc
+0 6 2 c400bc
+1 6 2 ffffff
+2 6 2 ffffff
+3 6 2 ffffff
+4 6 2 ffffff
+5 6 2 ffffff
+6 6 2 ffffff
+7 6 2 ffffff
+8 6 2 c400bc
+0 7 2 c400bc
+1 7 2 ffffff
+2 7 2 ffffff
+3 7 2 ffffff
+4 7 2 ffffff
+5 7 2 ffffff
+6 7 2 ffffff
+7 7 2 ffffff
+8 7 2 c400bc
+0 8 2 920088
+1 8 2 c400bc
+2 8 2 c400bc
+3 8 2 c400bc
+4 8 2 cdd300
+5 8 2 c400bc
+6 8 2 c400bc
+7 8 2 c400bc
+8 8 2 920088
+0 0 3 920088
+1 0 3 c400bc
+2 0 3 c400bc
+3 0 3 c400bc
+4 0 3 c400bc
+5 0 3 c400bc
+6 0 3 c400bc
+7 0 3 c400bc
+8 0 3 920088
+0 1 3 c400bc
+1 1 3 ffffff
+2 1 3 c400bc
+3 1 3 c400bc
+4 1 3 ffffff
+5 1 3 ffffff
+6 1 3 ffffff
+7 1 3 ffffff
+8 1 3 c400bc
+0 2 3 c400bc
+1 2 3 c400bc
+2 2 3 c400bc
+3 2 3 ffffff
+4 2 3 ffffff
+5 2 3 ffffff
+6 2 3 ffffff
+7 2 3 ffffff
+8 2 3 c400bc
+0 3 3 c400bc
+1 3 3 ffffff
+2 3 3 ffffff
+3 3 3 ffffff
+4 3 3 ffffff
+5 3 3 ffffff
+6 3 3 ffffff
+7 3 3 ffffff
+8 3 3 c400bc
+0 4 3 c400bc
+1 4 3 ffffff
+2 4 3 ffffff
+3 4 3 ffffff
+4 4 3 ffffff
+5 4 3 ffffff
+6 4 3 ffffff
+7 4 3 ffffff
+8 4 3 c400bc
+0 5 3 c400bc
+1 5 3 ffffff
+2 5 3 ffffff
+3 5 3 ffffff
+4 5 3 ffffff
+5 5 3 ffffff
+6 5 3 ffffff
+7 5 3 ffffff
+8 5 3 c400bc
+0 6 3 c400bc
+1 6 3 ffffff
+2 6 3 ffffff
+3 6 3 ffffff
+4 6 3 ffffff
+5 6 3 ffffff
+6 6 3 ffffff
+7 6 3 ffffff
+8 6 3 c400bc
+0 7 3 c400bc
+1 7 3 ffffff
+2 7 3 ffffff
+3 7 3 ffffff
+4 7 3 ffffff
+5 7 3 ffffff
+6 7 3 ffffff
+7 7 3 ffffff
+8 7 3 c400bc
+0 8 3 920088
+1 8 3 c400bc
+2 8 3 c400bc
+3 8 3 c400bc
+4 8 3 c400bc
+5 8 3 c400bc
+6 8 3 c400bc
+7 8 3 c400bc
+8 8 3 920088
+0 0 4 920088
+1 0 4 c400bc
+2 0 4 c400bc
+3 0 4 c400bc
+4 0 4 cdd300
+5 0 4 cdd300
+6 0 4 c400bc
+7 0 4 c400bc
+8 0 4 920088
+0 1 4 c400bc
+1 1 4 c400bc
+2 1 4 c400bc
+3 1 4 ffffff
+4 1 4 ffffff
+5 1 4 ffffff
+6 1 4 ffffff
+7 1 4 ffffff
+8 1 4 c400bc
+0 2 4 c400bc
+1 2 4 c400bc
+2 2 4 ffffff
+3 2 4 ffffff
+4 2 4 ffffff
+5 2 4 ffffff
+6 2 4 ffffff
+7 2 4 ffffff
+8 2 4 c400bc
+0 3 4 cdd300
+1 3 4 ffffff
+2 3 4 ffffff
+3 3 4 ffffff
+4 3 4 ffffff
+5 3 4 ffffff
+6 3 4 ffffff
+7 3 4 ffffff
+8 3 4 c400bc
+0 4 4 cdd300
+1 4 4 ffffff
+2 4 4 ffffff
+3 4 4 ffffff
+4 4 4 ffffff
+5 4 4 ffffff
+6 4 4 ffffff
+7 4 4 ffffff
+8 4 4 cdd300
+0 5 4 c400bc
+1 5 4 ffffff
+2 5 4 ffffff
+3 5 4 ffffff
+4 5 4 ffffff
+5 5 4 ffffff
+6 5 4 ffffff
+7 5 4 ffffff
+8 5 4 cdd300
+0 6 4 c400bc
+1 6 4 ffffff
+2 6 4 ffffff
+3 6 4 ffffff
+4 6 4 ffffff
+5 6 4 ffffff
+6 6 4 ffffff
+7 6 4 ffffff
+8 6 4 c400bc
+0 7 4 c400bc
+1 7 4 ffffff
+2 7 4 ffffff
+3 7 4 ffffff
+4 7 4 ffffff
+5 7 4 ffffff
+6 7 4 ffffff
+7 7 4 ffffff
+8 7 4 c400bc
+0 8 4 920088
+1 8 4 c400bc
+2 8 4 c400bc
+3 8 4 cdd300
+4 8 4 cdd300
+5 8 4 c400bc
+6 8 4 c400bc
+7 8 4 c400bc
+8 8 4 920088
+0 0 5 920088
+1 0 5 c400bc
+2 0 5 cdd300
+3 0 5 c400bc
+4 0 5 c400bc
+5 0 5 c400bc
+6 0 5 cdd300
+7 0 5 c400bc
+8 0 5 920088
+0 1 5 c400bc
+1 1 5 c400bc
+2 1 5 ffffff
+3 1 5 ffffff
+4 1 5 ffffff
+5 1 5 ffffff
+6 1 5 ffffff
+7 1 5 ffffff
+8 1 5 c400bc
+0 2 5 cdd300
+1 2 5 ffffff
+2 2 5 ffffff
+3 2 5 ffffff
+4 2 5 ffffff
+5 2 5 ffffff
+6 2 5 ffffff
+7 2 5 ffffff
+8 2 5 cdd300
+0 3 5 c400bc
+1 3 5 ffffff
+2 3 5 ffffff
+3 3 5 ffffff
+4 3 5 ffffff
+5 3 5 ffffff
+6 3 5 ffffff
+7 3 5 ffffff
+8 3 5 c400bc
+0 4 5 c400bc
+1 4 5 ffffff
+2 4 5 ffffff
+3 4 5 ffffff
+4 4 5 ffffff
+5 4 5 ffffff
+6 4 5 ffffff
+7 4 5 ffffff
+8 4 5 c400bc
+0 5 5 c400bc
+1 5 5 ffffff
+2 5 5 ffffff
+3 5 5 ffffff
+4 5 5 ffffff
+5 5 5 ffffff
+6 5 5 ffffff
+7 5 5 ffffff
+8 5 5 c400bc
+0 6 5 cdd300
+1 6 5 ffffff
+2 6 5 ffffff
+3 6 5 ffffff
+4 6 5 ffffff
+5 6 5 ffffff
+6 6 5 ffffff
+7 6 5 ffffff
+8 6 5 cdd300
+0 7 5 c400bc
+1 7 5 ffffff
+2 7 5 ffffff
+3 7 5 ffffff
+4 7 5 ffffff
+5 7 5 ffffff
+6 7 5 ffffff
+7 7 5 ffffff
+8 7 5 c400bc
+0 8 5 920088
+1 8 5 c400bc
+2 8 5 cdd300
+3 8 5 c400bc
+4 8 5 c400bc
+5 8 5 c400bc
+6 8 5 cdd300
+7 8 5 c400bc
+8 8 5 920088
+0 0 6 920088
+1 0 6 c400bc
+2 0 6 c400bc
+3 0 6 cdd300
+4 0 6 cdd300
+5 0 6 cdd300
+6 0 6 c400bc
+7 0 6 c400bc
+8 0 6 920088
+0 1 6 c400bc
+1 1 6 c400bc
+2 1 6 c400bc
+3 1 6 c400bc
+4 1 6 ffffff
+5 1 6 ffffff
+6 1 6 c400bc
+7 1 6 c400bc
+8 1 6 c400bc
+0 2 6 c400bc
+1 2 6 c400bc
+2 2 6 ffffff
+3 2 6 ffffff
+4 2 6 ffffff
+5 2 6 ffffff
+6 2 6 ffffff
+7 2 6 ffffff
+8 2 6 c400bc
+0 3 6 cdd300
+1 3 6 ffffff
+2 3 6 ffffff
+3 3 6 ffffff
+4 3 6 ffffff
+5 3 6 ffffff
+6 3 6 ffffff
+7 3 6 ffffff
+8 3 6 cdd300
+0 4 6 cdd300
+1 4 6 ffffff
+2 4 6 ffffff
+3 4 6 ffffff
+4 4 6 ffffff
+5 4 6 ffffff
+6 4 6 ffffff
+7 4 6 ffffff
+8 4 6 cdd300
+0 5 6 cdd300
+1 5 6 ffffff
+2 5 6 ffffff
+3 5 6 ffffff
+4 5 6 ffffff
+5 5 6 ffffff
+6 5 6 ffffff
+7 5 6 ffffff
+8 5 6 cdd300
+0 6 6 c400bc
+1 6 6 ffffff
+2 6 6 ffffff
+3 6 6 ffffff
+4 6 6 ffffff
+5 6 6 ffffff
+6 6 6 ffffff
+7 6 6 ffffff
+8 6 6 c400bc
+0 7 6 c400bc
+1 7 6 ffffff
+2 7 6 ffffff
+3 7 6 ffffff
+4 7 6 ffffff
+5 7 6 ffffff
+6 7 6 ffffff
+7 7 6 ffffff
+8 7 6 c400bc
+0 8 6 920088
+1 8 6 c400bc
+2 8 6 c400bc
+3 8 6 cdd300
+4 8 6 cdd300
+5 8 6 cdd300
+6 8 6 c400bc
+7 8 6 c400bc
+8 8 6 920088
+0 0 7 920088
+1 0 7 c400bc
+2 0 7 c400bc
+3 0 7 c400bc
+4 0 7 c400bc
+5 0 7 c400bc
+6 0 7 c400bc
+7 0 7 c400bc
+8 0 7 920088
+0 1 7 c400bc
+1 1 7 ffffff
+2 1 7 c400bc
+3 1 7 ffffff
+4 1 7 ffffff
+5 1 7 ffffff
+6 1 7 ffffff
+7 1 7 c400bc
+8 1 7 c400bc
+0 2 7 c400bc
+1 2 7 c400bc
+2 2 7 c400bc
+3 2 7 c400bc
+4 2 7 ffffff
+5 2 7 c400bc
+6 2 7 c400bc
+7 2 7 c400bc
+8 2 7 c400bc
+0 3 7 c400bc
+1 3 7 c400bc
+2 3 7 ffffff
+3 3 7 ffffff
+4 3 7 c400bc
+5 3 7 c400bc
+6 3 7 c400bc
+7 3 7 ffffff
+8 3 7 c400bc
+0 4 7 c400bc
+1 4 7 ffffff
+2 4 7 ffffff
+3 4 7 ffffff
+4 4 7 ffffff
+5 4 7 ffffff
+6 4 7 ffffff
+7 4 7 ffffff
+8 4 7 c400bc
+0 5 7 c400bc
+1 5 7 ffffff
+2 5 7 ffffff
+3 5 7 ffffff
+4 5 7 ffffff
+5 5 7 ffffff
+6 5 7 ffffff
+7 5 7 ffffff
+8 5 7 c400bc
+0 6 7 c400bc
+1 6 7 ffffff
+2 6 7 ffffff
+3 6 7 ffffff
+4 6 7 ffffff
+5 6 7 ffffff
+6 6 7 ffffff
+7 6 7 ffffff
+8 6 7 c400bc
+0 7 7 c400bc
+1 7 7 ffffff
+2 7 7 ffffff
+3 7 7 ffffff
+4 7 7 ffffff
+5 7 7 ffffff
+6 7 7 ffffff
+7 7 7 ffffff
+8 7 7 c400bc
+0 8 7 920088
+1 8 7 c400bc
+2 8 7 c400bc
+3 8 7 c400bc
+4 8 7 c400bc
+5 8 7 c400bc
+6 8 7 c400bc
+7 8 7 c400bc
+8 8 7 920088
+0 0 8 920088
+1 0 8 920088
+2 0 8 920088
+3 0 8 920088
+4 0 8 920088
+5 0 8 920088
+6 0 8 920088
+7 0 8 920088
+8 0 8 920088
+0 1 8 920088
+1 1 8 c400bc
+2 1 8 c400bc
+3 1 8 c400bc
+4 1 8 c400bc
+5 1 8 c400bc
+6 1 8 c400bc
+7 1 8 c400bc
+8 1 8 920088
+0 2 8 920088
+1 2 8 c400bc
+2 2 8 c400bc
+3 2 8 c400bc
+4 2 8 cdd300
+5 2 8 c400bc
+6 2 8 c400bc
+7 2 8 c400bc
+8 2 8 920088
+0 3 8 920088
+1 3 8 c400bc
+2 3 8 c400bc
+3 3 8 c400bc
+4 3 8 c400bc
+5 3 8 c400bc
+6 3 8 c400bc
+7 3 8 c400bc
+8 3 8 920088
+0 4 8 920088
+1 4 8 c400bc
+2 4 8 c400bc
+3 4 8 c400bc
+4 4 8 cdd300
+5 4 8 cdd300
+6 4 8 c400bc
+7 4 8 c400bc
+8 4 8 920088
+0 5 8 920088
+1 5 8 c400bc
+2 5 8 cdd300
+3 5 8 c400bc
+4 5 8 c400bc
+5 5 8 c400bc
+6 5 8 cdd300
+7 5 8 c400bc
+8 5 8 920088
+0 6 8 920088
+1 6 8 c400bc
+2 6 8 c400bc
+3 6 8 cdd300
+4 6 8 cdd300
+5 6 8 cdd300
+6 6 8 c400bc
+7 6 8 c400bc
+8 6 8 920088
+0 7 8 920088
+1 7 8 c400bc
+2 7 8 c400bc
+3 7 8 c400bc
+4 7 8 c400bc
+5 7 8 c400bc
+6 7 8 c400bc
+7 7 8 c400bc
+8 7 8 920088
+0 8 8 920088
+1 8 8 920088
+2 8 8 920088
+3 8 8 920088
+4 8 8 920088
+5 8 8 920088
+6 8 8 920088
+7 8 8 920088
+8 8 8 920088
index ee482f86fd28ba931f07e730d051ad4485b03008..e67a0e9093d0dc9c00addc60259f88b3bc865f67 100644 (file)
@@ -1,19 +1,15 @@
-name player scale 1 1.8 1
-       name nametag pos 0 1.1 0
-       name neck pos 0 0.75 0 scale 0.45 0.25 0.45
-               name head pos 0 +0.5 0 cube head
-                       name eyes pos 0 0 +0.5
-       name body scale 0.48 0.75 0.225
-               name upper pos 0 1.0 0 scale 1 0.5 1
-                       name chest pos 0 -0.5 0 cube chest
-                       name shoulders scale 0.5 1 1
-                               name left pos -1.5 0 0
-                                       name arm pos 0 -0.5 0 cube arm
-                               name right pos +1.5 0 0
-                                       name arm pos 0 -0.5 0 cube arm
-               name lower pos 0 0.5 0 scale 1 0.5 1
-                       name hips scale 0.5 1 1
-                               name left pos -0.5 0 0
-                                       name leg pos 0 -0.5 0 cube leg
-                               name right pos +0.5 0 0
-                                       name leg pos 0 -0.5 0 cube leg
+name nametag pos 0 2 0
+name neck pos 0 1.35 0
+       name head pos 0 0.225 0 scale 0.45 0.45 0.45 cube head
+               name eyes pos 0 0 +0.5
+name chest pos 0 1.0125 0 scale 0.48 0.675 0.225 cube chest
+name arm_left pos -0.36 1.35 0 scale -1 1 1 clockwise
+       pos 0 -0.3375 0 scale 0.24 0.675 0.225 cube arm
+       name hand pos 0 -0.585 0 scale 0.0625 0.0625 0.0625 rot 90 0 0
+name arm_right pos +0.36 1.35 0
+       pos 0 -0.3375 0 scale 0.24 0.675 0.225 cube arm
+       name hand pos 0 -0.585 0 scale 0.0625 0.0625 0.0625 rot 90 0 0
+name leg_left pos -0.12 0.675 0 scale -1 1 1 clockwise
+       pos 0 -0.3375 0 scale 0.24 0.675 0.225 cube leg
+name leg_right pos +0.12 0.675 0
+       pos 0 -0.3375 0 scale 0.24 0.675 0.225 cube leg
index 2cd47682322ead9b213f79f681441a9090acfa79..d74e86a0d3103982b92e10dd5b1dc992bcbc90f4 100755 (executable)
@@ -1,5 +1,4 @@
 in vec3 fragmentPosition;
-in vec3 fragmentNormal;
 in vec3 fragmentTextureCoordinates;
 in float fragmentLight;
 
index ca8684a22e34671ebd93e5c1e22f20b38cd30fef..a53f950549202299b36aa88050621e5e644ef104 100755 (executable)
@@ -2,7 +2,6 @@ layout(location = 0) in vec3 vertexPosition;
 layout(location = 1) in vec3 vertexNormal;
 
 out vec3 fragmentPosition;
-out vec3 fragmentNormal;
 out vec3 fragmentTextureCoordinates;
 out float fragmentLight;
 
@@ -18,9 +17,9 @@ void main()
        gl_Position = VP * worldSpace;
 
        fragmentPosition = worldSpace.xyz;
-       fragmentNormal = vertexNormal;
        fragmentTextureCoordinates = vertexPosition;
 
-       float diffuseLight = 0.3 * daylight * clamp(dot(normalize(fragmentNormal), normalize(lightDir)), 0.0, 1.0);
-       fragmentLight = ambientLight + diffuseLight;
+       mat3 normalMatrix = transpose(inverse(mat3(model)));
+       vec3 normal = normalize(normalMatrix * vertexNormal);
+       fragmentLight = ambientLight + 0.3 * daylight * clamp(dot(normal, normalize(lightDir)), 0.0, 1.0);
 }
diff --git a/shaders/3d/item/fragment.glsl b/shaders/3d/item/fragment.glsl
new file mode 100755 (executable)
index 0000000..102b9a5
--- /dev/null
@@ -0,0 +1,16 @@
+in vec3 fragmentPosition;
+in vec3 fragmentColor;
+
+out vec4 outColor;
+
+uniform vec3 fogColor;
+uniform vec3 cameraPos;
+
+void main()
+{
+       outColor = vec4(fragmentColor, 1.0);
+       outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / VIEW_DISTANCE, 0.0, 1.0));
+
+       if (outColor.a == 0.0)
+               discard;
+}
diff --git a/shaders/3d/item/vertex.glsl b/shaders/3d/item/vertex.glsl
new file mode 100755 (executable)
index 0000000..9aabdcc
--- /dev/null
@@ -0,0 +1,25 @@
+layout(location = 0) in vec3 vertexPosition;
+layout(location = 1) in vec3 vertexNormal;
+layout(location = 2) in vec3 vertexColor;
+
+out vec3 fragmentPosition;
+out vec3 fragmentColor;
+
+uniform mat4 model;
+uniform mat4 VP;
+uniform float daylight;
+uniform float ambientLight;
+uniform vec3 lightDir;
+
+void main()
+{
+       vec4 worldSpace = model * vec4(vertexPosition, 1.0);
+       gl_Position = VP * worldSpace;
+
+       fragmentPosition = worldSpace.xyz;
+       fragmentColor = vertexColor;
+
+       mat3 normalMatrix = transpose(inverse(mat3(model)));
+       vec3 normal = normalize(normalMatrix * vertexNormal);
+       fragmentColor *= ambientLight + 0.3 * daylight * clamp(dot(normal, normalize(lightDir)), 0.0, 1.0);
+}
index 62ee89b1fbee5f96b498ce059f5f2434e735893b..37bc56746cc76a2bf182f9e7a0b5bca60e40f59f 100755 (executable)
@@ -1,5 +1,4 @@
 in vec3 fragmentPosition;
-in vec3 fragmentNormal;
 in vec2 fragmentTextureCoordinates;
 in float fragmentTextureIndex;
 in vec3 fragmentColor;
index abef047ebfaa99208a4815080b175a78ce617ee2..2068cdca7a9736c6c57bd8580c8a2bbd31e5d86f 100755 (executable)
@@ -5,7 +5,6 @@ layout(location = 3) in float vertexTextureIndex;
 layout(location = 4) in vec3 vertexColor;
 
 out vec3 fragmentPosition;
-out vec3 fragmentNormal;
 out vec2 fragmentTextureCoordinates;
 out float fragmentTextureIndex;
 out vec3 fragmentColor;
@@ -22,13 +21,9 @@ void main()
        gl_Position = VP * worldSpace;
 
        fragmentPosition = worldSpace.xyz;
-       fragmentNormal = vertexNormal;
        fragmentTextureCoordinates = vertexTextureCoordinates;
        fragmentTextureIndex = vertexTextureIndex;
        fragmentColor = vertexColor;
 
-       float diffuseLight = 0.3 * daylight * clamp(dot(normalize(fragmentNormal), normalize(lightDir)), 0.0, 1.0);
-       float light = ambientLight + diffuseLight;
-
-       fragmentColor *= light;
+       fragmentColor *= ambientLight + 0.3 * daylight * clamp(dot(normalize(vertexNormal), normalize(lightDir)), 0.0, 1.0);
 }
index 4b7cede31fe2637ad84f89329514b12be1aec457..4df3b80b7446aed709f266b102208a115a55e836 100644 (file)
@@ -79,6 +79,7 @@ set(COMMON_SOURCES
        day.c
        environment.c
        interrupt.c
+       item.c
        node.c
        perlin.c
        physics.c
@@ -94,6 +95,8 @@ add_executable(dragonblocks
        client/client_auth.c
        client/client_config.c
        client/client_entity.c
+       client/client_inventory.c
+       client/client_item.c
        client/client_node.c
        client/client_player.c
        client/client_terrain.c
@@ -111,6 +114,7 @@ add_executable(dragonblocks
        client/mesh.c
        client/model.c
        client/raycast.c
+       client/screenshot.c
        client/shader.c
        client/sky.c
        client/terrain_gfx.c
index adb23647884cd1784d5b1a15d4d1dbff7c2c0e9f..8b6a318aeeebcdbcbb126344972f0202e3f13b73 100644 (file)
@@ -1,6 +1,5 @@
 #include <math.h>
 #include "client/camera.h"
-#include "client/client.h"
 
 struct Camera camera;
 
@@ -14,6 +13,12 @@ static void camera_update()
        mat4x4_look_at(camera.view, camera.eye, center, camera.up);
 }
 
+void camera_init()
+{
+       camera_set_position((v3f32) {0.0f, 0.0f, 0.0f});
+       camera_set_angle(0.0f, 0.0f);
+}
+
 void camera_set_position(v3f32 pos)
 {
        camera.eye[0] = pos.x;
index abe7d8f0a83fd3cc8b242f60a02896a39e3759f4..3e3d517c2e8f6f8574ba9fd88c8a5f106f5dd572 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _CAMERA_H_
 #define _CAMERA_H_
 
-#include <GL/glew.h>
-#include <GLFW/glfw3.h>
 #include <linmath.h/linmath.h>
 #include "types.h"
 
@@ -16,8 +14,8 @@ extern struct Camera {
        } movement_dirs;
 } camera;
 
+void camera_init();
 void camera_set_position(v3f32 pos);
 void camera_set_angle(f32 yaw, f32 pitch);
-void camera_on_resize(int width, int height);
 
 #endif // _CAMERA_H_
index 539392297f3a48dec947b1fcb55b08fb6582dc21..40f58dcfeda681650007e364ac43931126a5ab90 100644 (file)
@@ -7,6 +7,7 @@
 #include <unistd.h>
 #include "client/client.h"
 #include "client/client_auth.h"
+#include "client/client_inventory.h"
 #include "client/client_player.h"
 #include "client/client_terrain.h"
 #include "client/debug_menu.h"
@@ -143,6 +144,7 @@ int main(int argc, char **argv)
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityRemove       ] = (void *) &client_entity_remove;
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityUpdatePosRot ] = (void *) &client_entity_update_pos_rot;
        client->on_recv_type[DRAGONNET_TYPE_ToClientEntityUpdateNametag] = (void *) &client_entity_update_nametag;
+       client->on_recv_type[DRAGONNET_TYPE_ToClientPlayerInventory    ] = (void *) &client_inventory_update_player;
 
        flag_ini(&finish);
        flag_ini(&gfx_init);
index 97173e8165c847dfb7e7f985a56cb52f6e4fc2bc..2bc325363bc30ed484207fb11c309e95e49f9a62 100644 (file)
@@ -94,7 +94,7 @@ static void update_nametag(ClientEntity *entity)
                if (!entity->data.nametag)
                        entity->nametag->visible = false;
        } else if (entity->data.nametag) {
-               entity->nametag = gui_add(NULL, (GUIElementDefinition) {
+               entity->nametag = gui_add(NULL, (GUIElementDef) {
                        .pos = {-1.0f, -1.0f},
                        .z_index = 0.1f,
                        .offset = {0, 0},
@@ -233,7 +233,7 @@ void client_entity_transform(ClientEntity *entity)
        model_node_transform(entity->model->root);
 }
 
-void client_entity_add(__attribute__((unused)) DragonnetPeer *peer, ToClientEntityAdd *pkt)
+void client_entity_add(__attribute__((unused)) void *peer, ToClientEntityAdd *pkt)
 {
        if (pkt->type >= COUNT_ENTITY)
                return;
@@ -264,12 +264,12 @@ void client_entity_add(__attribute__((unused)) DragonnetPeer *peer, ToClientEnti
        refcount_drp(&entity->rc);
 }
 
-void client_entity_remove(__attribute__((unused)) DragonnetPeer *peer, ToClientEntityRemove *pkt)
+void client_entity_remove(__attribute__((unused)) void *peer, ToClientEntityRemove *pkt)
 {
        map_del(&entities, &pkt->id, &cmp_entity, &entity_drop, NULL, &refcount_obj);
 }
 
-void client_entity_update_pos_rot(__attribute__((unused)) DragonnetPeer *peer, ToClientEntityUpdatePosRot *pkt)
+void client_entity_update_pos_rot(__attribute__((unused)) void *peer, ToClientEntityUpdatePosRot *pkt)
 {
        ClientEntity *entity = client_entity_grab(pkt->id);
 
@@ -291,7 +291,7 @@ void client_entity_update_pos_rot(__attribute__((unused)) DragonnetPeer *peer, T
        refcount_drp(&entity->rc);
 }
 
-void client_entity_update_nametag(__attribute__((unused)) DragonnetPeer *peer, ToClientEntityUpdateNametag *pkt)
+void client_entity_update_nametag(__attribute__((unused)) void *peer, ToClientEntityUpdateNametag *pkt)
 {
        ClientEntity *entity = client_entity_grab(pkt->id);
 
index 53125dbbfe9a7c3cc212d5b9b323498f23ec2b5e..03238a6032bc5bde468d29d20c91dd237427ddf9 100644 (file)
@@ -1,12 +1,12 @@
 #ifndef _CLIENT_ENTITY_H_
 #define _CLIENT_ENTITY_H_
 
-#include <dragonnet/peer.h>
 #include <dragonstd/refcount.h>
 #include <pthread.h>
 #include "client/gui.h"
 #include "client/model.h"
 #include "entity.h"
+#include "item.h"
 #include "types.h"
 
 typedef struct {
@@ -56,9 +56,9 @@ void client_entity_drop(ClientEntity *entity);
 
 void client_entity_transform(ClientEntity *entity);
 
-void client_entity_add(DragonnetPeer *peer, ToClientEntityAdd *pkt);
-void client_entity_remove(DragonnetPeer *peer, ToClientEntityRemove *pkt);
-void client_entity_update_pos_rot(DragonnetPeer *peer, ToClientEntityUpdatePosRot *pkt);
-void client_entity_update_nametag(DragonnetPeer *peer, ToClientEntityUpdateNametag *pkt);
+void client_entity_add(void *peer, ToClientEntityAdd *pkt);
+void client_entity_remove(void *peer, ToClientEntityRemove *pkt);
+void client_entity_update_pos_rot(void *peer, ToClientEntityUpdatePosRot *pkt);
+void client_entity_update_nametag(void *peer, ToClientEntityUpdateNametag *pkt);
 
 #endif // _CLIENT_ENTITY_H_
diff --git a/src/client/client_inventory.c b/src/client/client_inventory.c
new file mode 100644 (file)
index 0000000..4ae916b
--- /dev/null
@@ -0,0 +1,109 @@
+#include <asprintf/asprintf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "client/client_config.h"
+#include "client/client_inventory.h"
+#include "client/client_item.h"
+#include "client/gl_debug.h"
+#include "client/frustum.h"
+#include "client/light.h"
+#include "client/shader.h"
+
+static GLuint _3d_shader_prog;
+static GLint _3d_loc_VP;
+static ModelShader _3d_model_shader;
+static LightShader _3d_light_shader;
+
+bool client_inventory_init()
+{
+       char *_3d_shader_defs;
+       asprintf(&_3d_shader_defs, "#define VIEW_DISTANCE %lf\n", client_config.view_distance);
+
+       if (!shader_program_create(RESSOURCE_PATH "shaders/3d/item", &_3d_shader_prog, _3d_shader_defs)) {
+               fprintf(stderr, "[error] failed to create 3D item shader program\n");
+               return false;
+       }
+
+       free(_3d_shader_defs);
+
+       _3d_loc_VP = glGetUniformLocation(_3d_shader_prog, "VP");
+
+       _3d_model_shader.prog = _3d_shader_prog;
+       _3d_model_shader.loc_transform = glGetUniformLocation(_3d_shader_prog, "model"); GL_DEBUG
+
+       _3d_light_shader.prog = _3d_shader_prog;
+       light_shader_locate(&_3d_light_shader);
+
+       return true;
+}
+
+void client_inventory_deinit()
+{
+       glDeleteProgram(_3d_shader_prog); GL_DEBUG
+}
+
+void client_inventory_update()
+{
+       glProgramUniformMatrix4fv(_3d_shader_prog, _3d_loc_VP, 1, GL_FALSE, frustum[0]); GL_DEBUG
+       light_shader_update(&_3d_light_shader);
+}
+
+static void wield_init(ModelNode *hand)
+{
+       if (hand)
+               model_node_add_mesh(hand, &(ModelMesh) {
+                       .mesh = NULL,
+                       .textures = NULL,
+                       .num_textures = 0,
+                       .shader = &_3d_model_shader,
+               });
+}
+
+static void wield_update(ModelNode *hand, ModelNode *arm, ItemType item)
+{
+       Mesh *mesh = client_item_mesh(item);
+
+       if (hand)
+               ((ModelMesh *) hand->meshes.ptr)[0].mesh = mesh;
+
+       if (arm) {
+               arm->rot.x = mesh ? -M_PI / 8.0 : 0.0;
+               model_node_transform(arm);              
+       }
+}
+
+void client_inventory_init_player(ClientEntity *entity)
+{
+       ClientPlayerData *data = entity->extra;
+
+       item_stack_initialize(&data->inventory.left);
+       item_stack_initialize(&data->inventory.right);
+
+       wield_init(data->bones.hand_left);
+       wield_init(data->bones.hand_right);
+}
+
+void client_inventory_deinit_player(ClientEntity *entity)
+{
+       ClientPlayerData *data = entity->extra;
+
+       item_stack_destroy(&data->inventory.left);
+       item_stack_destroy(&data->inventory.right);
+}
+
+void client_inventory_update_player(__attribute__((unused)) void *peer, ToClientPlayerInventory *pkt)
+{
+       ClientEntity *entity = client_player_entity(pkt->id);
+       if (!entity)
+               return;
+
+       ClientPlayerData *data = entity->extra;
+
+       item_stack_deserialize(&data->inventory.left, &pkt->left);
+       item_stack_deserialize(&data->inventory.right, &pkt->right);
+
+       wield_update(data->bones.hand_left,  data->bones.arm_left,  data->inventory.left.type);
+       wield_update(data->bones.hand_right, data->bones.arm_right, data->inventory.right.type);
+
+       refcount_drp(&entity->rc);
+}
diff --git a/src/client/client_inventory.h b/src/client/client_inventory.h
new file mode 100644 (file)
index 0000000..3b09789
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _CLIENT_INVENTORY_H_
+#define _CLIENT_INVENTORY_H_
+
+#include <stdbool.h>
+#include "client/client_player.h"
+#include "client/model.h"
+
+bool client_inventory_init();
+void client_inventory_deinit();
+void client_inventory_update();
+
+void client_inventory_init_player(ClientEntity *entity);
+void client_inventory_deinit_player(ClientEntity *entity);
+void client_inventory_update_player(void *peer, ToClientPlayerInventory *pkt);
+
+#endif // _CLIENT_INVENTORY_H_
diff --git a/src/client/client_item.c b/src/client/client_item.c
new file mode 100644 (file)
index 0000000..923fd74
--- /dev/null
@@ -0,0 +1,43 @@
+#include "client/client_item.h"
+
+ClientItemDef client_item_defs[COUNT_ITEM] = {
+       // unknown
+       {
+               .mesh_path = RESSOURCE_PATH "meshes/unknown.txt",
+               .mesh = {0},
+       },
+       // none
+       {
+               .mesh_path = NULL,
+               .mesh = {0},
+       },
+       // pickaxe
+       {
+               .mesh_path = RESSOURCE_PATH "meshes/pickaxe.txt",
+               .mesh = {0},
+       },
+       // axe
+       {
+               .mesh_path = RESSOURCE_PATH "meshes/axe.txt",
+               .mesh = {0},
+       },
+};
+
+void client_item_init()
+{
+       for (ItemType i = 0; i < COUNT_ITEM; i++)
+               if (client_item_defs[i].mesh_path)
+                       mesh_load(&client_item_defs[i].mesh, client_item_defs[i].mesh_path);
+}
+
+void client_item_deinit()
+{
+       for (ItemType i = 0; i < COUNT_ITEM; i++)
+               if (client_item_defs[i].mesh_path)
+                       mesh_destroy(&client_item_defs[i].mesh);
+}
+
+Mesh *client_item_mesh(ItemType type)
+{
+       return client_item_defs[type].mesh_path ? &client_item_defs[type].mesh : NULL;
+}
diff --git a/src/client/client_item.h b/src/client/client_item.h
new file mode 100644 (file)
index 0000000..0105abf
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _CLIENT_ITEM_H_
+#define _CLIENT_ITEM_H_
+
+#include "client/mesh.h"
+#include "item.h"
+
+typedef struct {
+       const char *mesh_path;
+       Mesh mesh;
+} ClientItemDef;
+
+extern ClientItemDef client_item_defs[];
+
+void client_item_init();
+void client_item_deinit();
+Mesh *client_item_mesh(ItemType type);
+
+#endif // _CLIENT_ITEM_H_
index 956e18fa0e49ab128f9e5c6fe01b4583b761c6ae..56c646e3757f711cb0ff16d47f32f92bb6f59c00 100644 (file)
@@ -38,7 +38,7 @@ static void render_color(NodeArgsRender *args)
        args->vertex.color = ((ColorData *) args->node->data)->color;
 }
 
-ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
+ClientNodeDef client_node_defs[NODE_UNLOADED] = {
        // unknown
        {
                .tiles = TILES_SIMPLE(RESSOURCE_PATH "textures/unknown.png"),
@@ -47,6 +47,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Unknown",
        },
        // air
        {
@@ -56,6 +57,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = false,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Air",
        },
        // grass
        {
@@ -65,6 +67,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_grass,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Grass",
        },
        // dirt
        {
@@ -74,6 +77,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Dirt",
        },
        // stone
        {
@@ -83,6 +87,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_stone,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Stone",
        },
        // snow
        {
@@ -92,6 +97,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = true,
                .selection_color = {0.1f, 0.5f, 1.0f},
+               .name = "Snow",
        },
        // oak wood
        {
@@ -105,6 +111,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_color,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Oak Wood",
        },
        // oak leaves
        {
@@ -114,6 +121,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_color,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Oak Leaves",
        },
        // pine wood
        {
@@ -127,6 +135,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_color,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Pine Wood",
        },
        // pine leaves
        {
@@ -136,6 +145,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_color,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Pine Leaves",
        },
        // palm wood
        {
@@ -149,6 +159,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_color,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Palm Wood",
        },
        // palm leaves
        {
@@ -158,6 +169,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = &render_color,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Palm Leaves",
        },
        // sand
        {
@@ -167,6 +179,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Sand",
        },
        // water
        {
@@ -176,6 +189,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = false,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Water",
        },
        // lava
        {
@@ -185,6 +199,7 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = false,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Lava",
        },
        // vulcano_stone
        {
@@ -194,13 +209,14 @@ ClientNodeDefinition client_node_definitions[NODE_UNLOADED] = {
                .render = NULL,
                .pointable = true,
                .selection_color = {1.0f, 1.0f, 1.0f},
+               .name = "Vulcano Stone",
        },
 };
 
 void client_node_init()
 {
-       for (NodeType node = NODE_UNKNOWN; node < NODE_UNLOADED; node++) {
-               ClientNodeDefinition *def = &client_node_definitions[node];
+       for (NodeType node = 0; node < NODE_UNLOADED; node++) {
+               ClientNodeDef *def = &client_node_defs[node];
 
                if (def->visibility != VISIBILITY_NONE) {
                        Texture *textures[6];
index 7edcf661511ec4545b93c114d970d8892eac2921..57ae62567f4e4beb826ed1805d5daf393d6e0b34 100644 (file)
@@ -30,9 +30,10 @@ typedef struct {
        void (*render)(NodeArgsRender *args);
        bool pointable;
        v3f32 selection_color;
-} ClientNodeDefinition;
+       char *name;
+} ClientNodeDef;
 
-extern ClientNodeDefinition client_node_definitions[];
+extern ClientNodeDef client_node_defs[];
 void client_node_init();
 
 #endif // _CLIENT_NODE_H_
index 326ab53948e2033920a06ca1713acc3b34949e3d..ccbd059e0aeb32101ad2202c59e489f353206df2 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include "client/camera.h"
 #include "client/client.h"
+#include "client/client_inventory.h"
 #include "client/client_player.h"
 #include "client/client_terrain.h"
 #include "client/cube.h"
 #include "environment.h"
 #include "physics.h"
 
-typedef struct {
-       ModelNode *nametag;
-       ModelNode *neck;
-       ModelNode *eyes;
-       ModelNode *shoulder_left;
-       ModelNode *shoulder_right;
-       ModelNode *hip_left;
-       ModelNode *hip_right;
-} PlayerModelBones;
-
 struct ClientPlayer client_player;
 
 static ClientEntity *player_entity;
@@ -33,10 +24,10 @@ static void update_camera()
 {
        vec4 dst, src = {0.0f, 0.0f, 0.0f, 1.0f};
 
-       PlayerModelBones *bones = player_entity->extra;
+       ClientPlayerData *data = player_entity->extra;
 
-       if (bones->eyes)
-               mat4x4_mul_vec4(dst, bones->eyes->abs, src);
+       if (data->bones.eyes)
+               mat4x4_mul_vec4(dst, data->bones.eyes->abs, src);
        else
                vec4_dup(dst, src);
 
@@ -88,21 +79,26 @@ static void on_add(ClientEntity *entity)
        entity->model = model_clone(player_model);
        entity->model->extra = refcount_grb(&entity->rc);
 
-       PlayerModelBones *bones = entity->extra = malloc(sizeof *bones);
-       *bones = (PlayerModelBones) {NULL};
-       model_get_bones(entity->model, (ModelBoneMapping[]) {
-               {"player.nametag",                    &bones->nametag       },
-               {"player.neck",                       &bones->neck          },
-               {"player.neck.head.eyes",             &bones->eyes          },
-               {"player.body.upper.shoulders.left",  &bones->shoulder_left },
-               {"player.body.upper.shoulders.right", &bones->shoulder_right},
-               {"player.body.lower.hips.left",       &bones->hip_left      },
-               {"player.body.lower.hips.right",      &bones->hip_right     },
-       }, 7);
-
-       entity->nametag_offset = bones->nametag ? &bones->nametag->abs : NULL;
+       ClientPlayerData *data = entity->extra = malloc(sizeof *data);
+       data->bones = (struct ClientPlayerBones) {NULL};
+
+       model_get_bones(entity->model, (ModelBoneMapping[9]) {
+               {"nametag",        &data->bones.nametag   },
+               {"neck",           &data->bones.neck      },
+               {"neck.head.eyes", &data->bones.eyes      },
+               {"arm_left",       &data->bones.arm_left  },
+               {"arm_right",      &data->bones.arm_right },
+               {"arm_left.hand",  &data->bones.hand_left },
+               {"arm_right.hand", &data->bones.hand_right},
+               {"leg_left",       &data->bones.leg_left  },
+               {"leg_right",      &data->bones.leg_right },
+       }, 9);
+
+       entity->nametag_offset = data->bones.nametag ? &data->bones.nametag->abs : NULL;
        entity->box_collision = (aabb3f32) {{-0.45f, 0.0f, -0.45f}, {0.45f, 1.8f, 0.45f}};
 
+       client_inventory_init_player(entity);
+
        model_scene_add(entity->model);
        client_entity_transform(entity);
 }
@@ -115,18 +111,19 @@ static void on_remove(ClientEntity *entity)
 
 static void on_free(ClientEntity *entity)
 {
+       client_inventory_init_player(entity);
        free(entity->extra);
 }
 
 static void on_transform(ClientEntity *entity)
 {
-       PlayerModelBones *bones = entity->extra;
+       ClientPlayerData *data = entity->extra;
 
        entity->model->root->rot.x = entity->model->root->rot.z = 0.0f;
 
-       if (bones->neck) {
-               bones->neck->rot.x = entity->data.rot.x;
-               model_node_transform(bones->neck);
+       if (data->bones.neck) {
+               data->bones.neck->rot.x = entity->data.rot.x;
+               model_node_transform(data->bones.neck);
        }
 }
 
@@ -174,8 +171,8 @@ static void local_on_update_nametag(ClientEntity *entity)
 
 static void __attribute__((unused)) on_model_step(Model *model, __attribute__((unused)) f64 dtime)
 {
-       PlayerModelBones *bones = ((ClientEntity *) model->extra)->extra;
-       (void) bones;
+       ClientPlayerData *data = ((ClientEntity *) model->extra)->extra;
+       (void) data; // ToDo: animations
 }
 
 static void on_model_delete(Model *model)
@@ -241,7 +238,19 @@ void client_player_gfx_deinit()
        model_delete(player_model);
 }
 
-ClientEntity *client_player_entity()
+ClientEntity *client_player_entity(u64 id)
+{
+       ClientEntity *entity = client_entity_grab(id);
+
+       if (entity->type == &client_entity_types[ENTITY_LOCALPLAYER] 
+                       || entity->type == &client_entity_types[ENTITY_PLAYER])
+               return entity;
+
+       refcount_drp(&entity->rc);
+       return NULL;
+}
+
+ClientEntity *client_player_entity_local()
 {
        ClientEntity *entity = NULL;
 
@@ -280,7 +289,7 @@ void client_player_update_rot(ClientEntity *entity)
 // jump if possible
 void client_player_jump()
 {
-       ClientEntity *entity = client_player_entity();
+       ClientEntity *entity = client_player_entity_local();
        if (!entity)
                return;
 
@@ -305,7 +314,7 @@ void client_player_jump()
 // to be called every frame
 void client_player_tick(f64 dtime)
 {
-       ClientEntity *entity = client_player_entity();
+       ClientEntity *entity = client_player_entity_local();
        if (!entity)
                return;
 
index 5ddefa058e261c870ed8414fef882966d08db70f..1028955f97af29e6145bdc449740f3d12467cd82 100644 (file)
@@ -11,13 +11,32 @@ extern struct ClientPlayer {
        pthread_rwlock_t lock_movement;
 } client_player;
 
+typedef struct {
+       struct {
+               ItemStack left;
+               ItemStack right;
+       } inventory;
+       struct ClientPlayerBones {
+               ModelNode *nametag;
+               ModelNode *neck;
+               ModelNode *eyes;
+               ModelNode *arm_left;
+               ModelNode *arm_right;
+               ModelNode *hand_left;
+               ModelNode *hand_right;
+               ModelNode *leg_left;
+               ModelNode *leg_right;
+       } bones;
+} ClientPlayerData;
+
 void client_player_init();                           // called on startup
 void client_player_deinit();                         // called on shutdown
 
 void client_player_gfx_init();
 void client_player_gfx_deinit();
 
-ClientEntity *client_player_entity();                // grab and return client entity
+ClientEntity *client_player_entity(u64 id);         // grab and return client entity by id
+ClientEntity *client_player_entity_local();         // grab and return local client entity
 
 void client_player_jump();                           // jump if possible
 
index c9c0ff1af0a2448457ba9711294501af54123ba3..148c0844f656b1495f5fdf11ce6eb26db8cc735a 100644 (file)
@@ -63,7 +63,7 @@ static void sync_step()
        static size_t old_num_requests = 0;
 
        v3f64 player_pos;
-       ClientEntity *entity = client_player_entity();
+       ClientEntity *entity = client_player_entity_local();
 
        if (entity) {
                pthread_rwlock_rdlock(&entity->lock_pos_rot);
index 8e60bdbdd29e879d3c23f729a189589576724227..e3f1a9c2f30edd1d8db30be05e87a2349f911fb5 100644 (file)
@@ -6,12 +6,14 @@
 #include <stdlib.h>
 #include <pthread.h>
 #include "client/client_config.h"
+#include "client/client_node.h"
 #include "client/client_player.h"
 #include "client/client_terrain.h"
 #include "client/debug_menu.h"
 #include "client/game.h"
 #include "client/gl_debug.h"
 #include "client/gui.h"
+#include "client/interact.h"
 #include "client/window.h"
 #include "day.h"
 #include "environment.h"
@@ -23,7 +25,7 @@ static bool changed_elements[COUNT_ENTRY] = {false};
 static pthread_mutex_t changed_elements_mtx = PTHREAD_MUTEX_INITIALIZER;
 
 static bool debug_menu_enabled = true;
-static DebugMenuEntry last_always_visible = ENTRY_POS;
+static DebugMenuEntry last_always_visible = ENTRY_POINTED;
 
 static char *get_entry_text(DebugMenuEntry entry)
 {
@@ -33,6 +35,10 @@ static char *get_entry_text(DebugMenuEntry entry)
        int minutes = 0;
        v3f64 pos = {0.0f, 0.0f, 0.0f};
        v3f32 rot = {0.0f, 0.0f, 0.0f};
+       char *pnt_name = NULL;
+
+       // shortcut
+       static struct InteractPointed *pnt = &interact_pointed;
 
        switch (entry) {
                case ENTRY_POS:
@@ -40,7 +46,7 @@ static char *get_entry_text(DebugMenuEntry entry)
                case ENTRY_PITCH:
                case ENTRY_HUMIDITY:
                case ENTRY_TEMPERATURE: {
-                       ClientEntity *entity = client_player_entity();
+                       ClientEntity *entity = client_player_entity_local();
                        if (!entity)
                                return strdup("");
 
@@ -52,6 +58,13 @@ static char *get_entry_text(DebugMenuEntry entry)
                        break;
                }
 
+               case ENTRY_POINTED:
+                       if (!pnt->exists)
+                               return strdup("");
+
+                       pnt_name = client_node_defs[pnt->node].name;
+                       break;
+
                case ENTRY_FLIGHT:
                case ENTRY_COLLISION:
                        pthread_rwlock_rdlock(&client_player.lock_movement);
@@ -78,6 +91,7 @@ static char *get_entry_text(DebugMenuEntry entry)
                case ENTRY_VERSION:       asprintf(&str, "Dragonblocks Alpha %s", VERSION                                    );          break;
                case ENTRY_FPS:           asprintf(&str, "%d FPS", game_fps                                                  );          break;
                case ENTRY_POS:           asprintf(&str, "(%.1f %.1f %.1f)", pos.x, pos.y, pos.z                             );          break;
+               case ENTRY_POINTED:       asprintf(&str, "%s (%d, %d, %d)", pnt_name, pnt->pos.x, pnt->pos.y, pnt->pos.z     );          break;
                case ENTRY_YAW:           asprintf(&str, "yaw = %.1f", 360.0 - rot.y / M_PI * 180.0                          );          break;
                case ENTRY_PITCH:         asprintf(&str, "pitch = %.1f", -rot.x / M_PI * 180.0                               );          break;
                case ENTRY_TIME:          asprintf(&str, "%02d:%02d", hours, minutes                                         );          break;
@@ -106,7 +120,7 @@ void debug_menu_init()
        s32 offset = -16;
 
        for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++) {
-               gui_elements[i] = gui_add(NULL, (GUIElementDefinition) {
+               gui_elements[i] = gui_add(NULL, (GUIElementDef) {
                        .pos = {0.0f, 0.0f},
                        .z_index = 0.1f,
                        .offset = {2, offset += 18},
index 3b1b7de58af00d82700ec6659d80e399ec0ee8e1..74f23acb130f90ec752fbf6d674d5590d9537994 100644 (file)
@@ -5,6 +5,7 @@ typedef enum {
        ENTRY_VERSION,
        ENTRY_FPS,
        ENTRY_POS,
+       ENTRY_POINTED,
        ENTRY_YAW,
        ENTRY_PITCH,
        ENTRY_TIME,
index c0554ebf5a02cc0d0efafa42d1e0fa9e687138c1..8891b187494cbc1c099f7f366228ac96a36b43bf 100644 (file)
@@ -1,13 +1,13 @@
-#define STB_IMAGE_WRITE_IMPLEMENTATION
 #include <GL/glew.h>
 #include <GL/gl.h>
 #include <GLFW/glfw3.h>
-#include <stb/stb_image_write.h>
 #include <stdio.h>
 #include <unistd.h>
 #include "client/camera.h"
 #include "client/client.h"
 #include "client/client_entity.h"
+#include "client/client_inventory.h"
+#include "client/client_item.h"
 #include "client/client_node.h"
 #include "client/client_player.h"
 #include "client/client_terrain.h"
 
 int game_fps = 0;
 
-static void crosshair_init()
-{
-       gui_add(NULL, (GUIElementDefinition) {
-               .pos = {0.5f, 0.5f},
-               .z_index = 0.0f,
-               .offset = {0, 0},
-               .margin = {0, 0},
-               .align = {0.5f, 0.5f},
-               .scale = {1.0f, 1.0f},
-               .scale_type = SCALE_IMAGE,
-               .affect_parent_scale = false,
-               .text = NULL,
-               .image = texture_load(RESSOURCE_PATH "textures/crosshair.png", false),
-               .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
-               .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
-       });
-}
-
-static void render(f64 dtime)
+void game_render(f64 dtime)
 {
        glEnable(GL_DEPTH_TEST); GL_DEBUG
        glEnable(GL_BLEND); GL_DEBUG
@@ -60,6 +42,7 @@ static void render(f64 dtime)
        frustum_update();
        terrain_gfx_update();
        client_entity_gfx_update();
+       client_inventory_update();
 
        sky_render();
        model_scene_render(dtime);
@@ -98,7 +81,7 @@ static void game_loop()
                debug_menu_changed(ENTRY_SUN_ANGLE);
                debug_menu_update();
 
-               render(dtime);
+               game_render(dtime);
 
                glfwSwapBuffers(window.handle);
                glfwPollEvents();
@@ -126,23 +109,27 @@ bool game(Flag *gfx_init)
 
        client_player_gfx_init();
 
-       if (!interact_init())
+       camera_init();
+
+       if (!gui_init())
                return false;
 
-       client_node_init();
-       client_terrain_start();
+       if (!interact_init())
+               return false;
 
-       camera_set_position((v3f32) {0.0f, 0.0f, 0.0f});
-       camera_set_angle(0.0f, 0.0f);
+       client_item_init();
 
-       if (!gui_init())
+       if (!client_inventory_init())
                return false;
 
+       client_node_init();
+       client_terrain_start();
+
        debug_menu_init();
-       crosshair_init();
        input_init();
 
        flag_set(gfx_init);
+
        game_loop();
 
        client_terrain_stop();
@@ -155,70 +142,9 @@ bool game(Flag *gfx_init)
        client_entity_gfx_deinit();
        client_player_gfx_deinit();
        interact_deinit();
+       client_item_deinit();
+       client_inventory_deinit();
 
        return true;
 }
 
-char *game_take_screenshot()
-{
-       // renderbuffer for depth & stencil buffer
-       GLuint rbo;
-       glGenRenderbuffers(1, &rbo); GL_DEBUG
-       glBindRenderbuffer(GL_RENDERBUFFER, rbo); GL_DEBUG
-       glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH24_STENCIL8, window.width, window.height); GL_DEBUG
-
-       // 2 textures, one with AA, one without
-
-       GLuint txos[2];
-       glGenTextures(2, txos); GL_DEBUG
-
-       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, txos[0]); GL_DEBUG
-       glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, window.width, window.height, GL_TRUE); GL_DEBUG
-
-       glBindTexture(GL_TEXTURE_2D, txos[1]); GL_DEBUG
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window.width, window.height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); GL_DEBUG
-
-       // 2 framebuffers, one with AA, one without
-
-       GLuint fbos[2];
-       glGenFramebuffers(2, fbos); GL_DEBUG
-
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
-       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, txos[0], 0); GL_DEBUG
-       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); GL_DEBUG
-
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
-       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, txos[1], 0); GL_DEBUG
-
-       // render scene
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
-       render(0.0);
-       glBindFramebuffer(GL_FRAMEBUFFER, 0); GL_DEBUG
-
-       // blit AA-buffer into no-AA buffer
-       glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); GL_DEBUG
-       glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); GL_DEBUG
-       glBlitFramebuffer(0, 0, window.width, window.height, 0, 0, window.width, window.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_DEBUG
-
-       // read data
-       GLubyte data[window.width * window.height * 3];
-       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
-       glPixelStorei(GL_PACK_ALIGNMENT, 1); GL_DEBUG
-       glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, data); GL_DEBUG
-
-       // create filename
-       char filename[BUFSIZ];
-       time_t timep = time(0);
-       strftime(filename, BUFSIZ, "screenshot-%Y-%m-%d-%H:%M:%S.png", localtime(&timep));
-
-       // save screenshot
-       stbi_flip_vertically_on_write(true);
-       stbi_write_png(filename, window.width, window.height, 3, data, window.width * 3);
-
-       // delete buffers
-       glDeleteRenderbuffers(1, &rbo); GL_DEBUG
-       glDeleteTextures(2, txos); GL_DEBUG
-       glDeleteFramebuffers(2, fbos); GL_DEBUG
-
-       return strdup(filename);
-}
index af1d74ca143c1ead29b6b9d240d6a4d0f434bc39..107583aafd1bc98c7e620873d6c8a5d2dd22b63f 100644 (file)
@@ -2,10 +2,11 @@
 #define _GAME_H_
 
 #include <dragonstd/flag.h>
+#include "types.h"
 
 extern int game_fps;
 
 bool game(Flag *gfx_init);
-char *game_take_screenshot();
+void game_render(f64 dtime);
 
 #endif // _GAME_H_
index 4aecb482527e54cf2fd030a0b6de4ab6af49cfce..05f4fb79df078f15957dcd0fd70697525e5b9ee3 100644 (file)
@@ -327,7 +327,7 @@ void gui_render()
        glEnable(GL_CULL_FACE); GL_DEBUG
 }
 
-GUIElement *gui_add(GUIElement *parent, GUIElementDefinition def)
+GUIElement *gui_add(GUIElement *parent, GUIElementDef def)
 {
        if (parent == NULL)
                parent = &root_element;
index ea4b15e559fab2fbc35a170c595d424cbad0a440..1ce958492bed40f5231c8bc3edf327be1693f68b 100644 (file)
@@ -29,10 +29,10 @@ typedef struct {
        Texture *image;
        v4f32 text_color;
        v4f32 bg_color;
-} GUIElementDefinition;
+} GUIElementDef;
 
 typedef struct GUIElement {
-       GUIElementDefinition def;
+       GUIElementDef def;
        bool visible;
        v2f32 pos;
        v2f32 scale;
@@ -47,7 +47,7 @@ bool gui_init();
 void gui_deinit();
 void gui_update_projection();
 void gui_render();
-GUIElement *gui_add(GUIElement *parent, GUIElementDefinition def);
+GUIElement *gui_add(GUIElement *parent, GUIElementDef def);
 void gui_text(GUIElement *element, const char *text);
 void gui_transform(GUIElement *element);
 
index 19dc81cf65b96da8b6fa3c40b3aae7978b1f98e4..00ede8a173ebe62e6443112f08e64a0308387a19 100644 (file)
@@ -6,9 +6,9 @@
 #include "client/client.h"
 #include "client/client_player.h"
 #include "client/debug_menu.h"
-#include "client/game.h"
 #include "client/gui.h"
 #include "client/input.h"
+#include "client/screenshot.h"
 #include "client/window.h"
 #include "day.h"
 
@@ -72,7 +72,7 @@ static bool key_listener(KeyListener *listener)
 
 void input_init()
 {
-       pause_menu = gui_add(NULL, (GUIElementDefinition) {
+       pause_menu = gui_add(NULL, (GUIElementDef) {
                .pos = {0.0f, 0.0f},
                .z_index = 0.5f,
                .offset = {0, 0},
@@ -87,7 +87,7 @@ void input_init()
                .bg_color = {0.0f, 0.0f, 0.0f, 0.4f},
        });
 
-       status_message = gui_add(NULL, (GUIElementDefinition) {
+       status_message = gui_add(NULL, (GUIElementDef) {
                .pos = {0.5f, 0.25f},
                .z_index = 0.1f,
                .offset = {0, 0},
@@ -165,7 +165,7 @@ void input_tick(f64 dtime)
                        debug_menu_toggle();
 
                if (key_listener(&listener_screenshot)) {
-                       char *screenshot_filename = game_take_screenshot();
+                       char *screenshot_filename = screenshot();
                        SET_STATUS_MESSAGE("Screenshot saved to %s", screenshot_filename)
                        free(screenshot_filename);
                }
@@ -202,7 +202,7 @@ void input_cursor(double current_x, double current_y)
        cursor_last_x = current_x;
        cursor_last_y = current_y;
 
-       ClientEntity *entity = client_player_entity();
+       ClientEntity *entity = client_player_entity_local();
        if (!entity)
                return;
 
index 728bc2934756ff9567dbecf804fd21bc9ace4db3..a4c22514dc5183fbd27c0566ed6a6cb767ebc4f3 100644 (file)
@@ -3,15 +3,17 @@
 #include "client/camera.h"
 #include "client/client_node.h"
 #include "client/cube.h"
+#include "client/debug_menu.h"
 #include "client/frustum.h"
 #include "client/gl_debug.h"
+#include "client/gui.h"
 #include "client/interact.h"
 #include "client/mesh.h"
 #include "client/raycast.h"
 #include "client/shader.h"
 
-static bool pointed;
-static v3s32 node_pos;
+struct InteractPointed interact_pointed;
+
 static GLuint shader_prog;
 static GLint loc_MVP;
 static GLint loc_color;
@@ -53,6 +55,21 @@ bool interact_init()
        selection_mesh.data = vertices;
        mesh_upload(&selection_mesh);
 
+       gui_add(NULL, (GUIElementDef) {
+               .pos = {0.5f, 0.5f},
+               .z_index = 0.0f,
+               .offset = {0, 0},
+               .margin = {0, 0},
+               .align = {0.5f, 0.5f},
+               .scale = {1.0f, 1.0f},
+               .scale_type = SCALE_IMAGE,
+               .affect_parent_scale = false,
+               .text = NULL,
+               .image = texture_load(RESSOURCE_PATH "textures/crosshair.png", false),
+               .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
+               .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
+       });
+
        return true;
 }
 
@@ -64,22 +81,27 @@ void interact_deinit()
 
 void interact_tick()
 {
-       v3s32 old_node_pos = node_pos;
-
-       NodeType node;
-       if ((pointed = raycast(
-                       (v3f64) {camera.eye  [0], camera.eye  [1], camera.eye  [2]}, 
-                       (v3f64) {camera.front[0], camera.front[1], camera.front[2]},
-                       5, &node_pos, &node)) && !v3s32_equals(node_pos, old_node_pos)) {
-               mat4x4_translate(model, node_pos.x, node_pos.y, node_pos.z);
-               v3f32 *color = &client_node_definitions[node].selection_color;
+       bool old_exists = interact_pointed.exists;
+       v3s32 old_pointed = interact_pointed.pos;
+       if ((interact_pointed.exists = raycast(
+                               (v3f64) {camera.eye  [0], camera.eye  [1], camera.eye  [2]}, 
+                               (v3f64) {camera.front[0], camera.front[1], camera.front[2]},
+                               5, &interact_pointed.pos, &interact_pointed.node)) 
+                       && !v3s32_equals(interact_pointed.pos, old_pointed)) {
+               mat4x4_translate(model,
+                       interact_pointed.pos.x, interact_pointed.pos.y, interact_pointed.pos.z);
+               v3f32 *color = &client_node_defs[interact_pointed.node].selection_color;
                glProgramUniform3f(shader_prog, loc_color, color->x, color->y, color->z); GL_DEBUG
+               debug_menu_changed(ENTRY_POINTED);
        }
+
+       if (old_exists && !interact_pointed.exists)
+               debug_menu_changed(ENTRY_POINTED);      
 }
 
 void interact_render()
 {
-       if (!pointed)
+       if (!interact_pointed.exists)
                return;
 
        mat4x4 mvp;
index 707bb0138921052d51f43fc39bda80e5f587a54f..aa3389dbd1411e5b0a860b6de3f257e03455f43b 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef _INTERACT_H_
 #define _INTERACT_H_
 
+extern struct InteractPointed {
+       bool exists;
+       v3s32 pos;
+       NodeType node;
+} interact_pointed;
+
 bool interact_init();
 void interact_deinit();
 void interact_tick();
index 49df5060be3eb97275a50f0264b5647eebec7198..d778ce11a5c0ca5de5b5ccf2e47bb0f8fb90bf2d 100644 (file)
@@ -1,8 +1,133 @@
+#include <dragonstd/tree.h>
 #include <stddef.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include "client/cube.h"
 #include "client/gl_debug.h"
 #include "client/mesh.h"
 
+typedef struct {
+       v3s32 pos;
+       v3f32 color;
+} LoadedVoxel;
+
+typedef struct {
+       Tree voxels;
+       Array vertices;
+} LoadedRenderArgs;
+
+static v3s32 face_dir[6] = {
+       {+0, +0, -1},
+       {+0, +0, +1},
+       {-1, +0, +0},
+       {+1, +0, +0},
+       {+0, -1, +0},
+       {+0, +1, +0},
+};
+
+typedef struct {
+       v3f32 pos;
+       v3f32 normal;
+       v3f32 color;
+} __attribute__((packed)) LoadedVertex;
+static VertexLayout loaded_layout = {
+       .attributes = (VertexAttribute[]) {
+               {GL_FLOAT, 3, sizeof(v3f32)}, // position
+               {GL_FLOAT, 3, sizeof(v3f32)}, // normal
+               {GL_FLOAT, 3, sizeof(v3f32)}, // color
+       },
+       .count = 3,
+       .size = sizeof(LoadedVertex),
+};
+
+static int cmp_loaded_voxel(const LoadedVoxel *voxel, const v3s32 *pos)
+{
+       return v3s32_cmp(&voxel->pos, pos);
+}
+
+static void render_loaded_voxel(LoadedVoxel *voxel, LoadedRenderArgs *args)
+{
+       v3f32 pos = v3s32_to_f32(voxel->pos);
+       for (int f = 0; f < 6; f++) {
+               v3s32 neigh_pos = v3s32_add(voxel->pos, face_dir[f]);
+               if (tree_get(&args->voxels, &neigh_pos, &cmp_loaded_voxel, NULL))
+                       continue;
+
+               for (int v = 0; v < 6; v++)
+                       array_apd(&args->vertices, &(LoadedVertex) {
+                               v3f32_add(cube_vertices[f][v].position, pos),
+                               cube_vertices[f][v].normal,
+                               voxel->color,
+                       });
+       }
+}
+
+void mesh_load(Mesh *mesh, const char *path)
+{
+       mesh->layout = &loaded_layout;
+       mesh->vao = mesh->vbo = 0;
+       mesh->data = NULL;
+       mesh->count = 0;
+       mesh->free_data = true;
+
+       LoadedRenderArgs args;
+       tree_ini(&args.voxels);
+       array_ini(&args.vertices, sizeof(LoadedVertex), 500);
+
+       FILE *file = fopen(path, "r");
+       if (!file) {
+               fprintf(stderr, "[warning] failed to open mesh %s\n", path);
+               return;
+       }
+
+       char *line = NULL;
+       size_t siz = 0;
+       ssize_t length;
+       int count = 0;
+
+       while ((length = getline(&line, &siz, file)) > 0) {
+               count++;
+
+               if (*line == '#')
+                       continue;
+
+               LoadedVoxel *voxel = malloc(sizeof *voxel);
+
+               v3s32 color;
+               if (sscanf(line, "%d %d %d %2x%2x%2x",
+                               &voxel->pos.x, &voxel->pos.z, &voxel->pos.y,
+                               &color.x, &color.y, &color.z) != 6) {
+                       fprintf(stderr, "[warning] syntax error in mesh %s in line %d: %s\n",
+                               path, count, line);
+                       free(voxel);
+                       continue;
+               }
+
+               voxel->color = (v3f32) {
+                       (f32) color.x / 0xFF,
+                       (f32) color.y / 0xFF,
+                       (f32) color.z / 0xFF,
+               };
+
+               if (!tree_add(&args.voxels, &voxel->pos, voxel, &cmp_loaded_voxel, NULL)) {
+                       fprintf(stderr, "[warning] more than one voxel at position (%d, %d, %d) in mesh %s in line %d\n",
+                               voxel->pos.x, voxel->pos.y, voxel->pos.z, path, count);
+                       free(voxel);
+               }
+       }
+
+       if (line)
+               free(line);
+
+       fclose(file);
+
+       tree_trv(&args.voxels, &render_loaded_voxel, &args, NULL, 0);
+       tree_clr(&args.voxels, &free, NULL, NULL, 0);
+
+       mesh->data = args.vertices.ptr;
+       mesh->count = args.vertices.siz;
+}
+
 // upload data to GPU (only done once)
 void mesh_upload(Mesh *mesh)
 {
index 3597043a3c02fc181ab7640c2e4f846a7d3e941f..15c598b1daddc0b46a91f855567f002a6e9b9dad 100644 (file)
@@ -25,6 +25,7 @@ typedef struct {
        bool free_data;
 } Mesh;
 
+void mesh_load(Mesh *mesh, const char *path);
 void mesh_upload(Mesh *mesh);
 void mesh_render(Mesh *mesh);
 void mesh_destroy(Mesh *mesh);
index 3a8ba6c5ea417a097f983571a198be968b1e87c1..89542679c8313d5d7b5b0ffcd2955b2cc1fc8fea 100644 (file)
@@ -55,9 +55,16 @@ static void render_node(ModelNode *node)
        if (!node->visible)
                return;
 
+       if (node->clockwise) {
+               glFrontFace(GL_CW); GL_DEBUG
+       }
+
        for (size_t i = 0; i < node->meshes.siz; i++) {
                ModelMesh *mesh = &((ModelMesh *) node->meshes.ptr)[i];
 
+               if (!mesh->mesh)
+                       continue;
+
                glUseProgram(mesh->shader->prog); GL_DEBUG
                glUniformMatrix4fv(mesh->shader->loc_transform, 1, GL_FALSE, node->abs[0]); GL_DEBUG
 
@@ -70,6 +77,10 @@ static void render_node(ModelNode *node)
        }
 
        list_itr(&node->children, &render_node, NULL, NULL);
+
+       if (node->clockwise) {
+               glFrontFace(GL_CCW); GL_DEBUG
+       }
 }
 
 static void free_node_meshes(ModelNode *node)
@@ -276,11 +287,15 @@ Model *model_load(const char *path, const char *textures_path, Mesh *cube, Model
                                        cursor += n;
                                else
                                        fprintf(stderr, "[warning] invalid value for rot in model %s in line %d\n", path, count);
+
+                               node->rot = v3f32_scale(node->rot, M_PI / 180.0);
                        } else if (strcmp(key, "scale") == 0) {
                                if (sscanf(cursor, "%f %f %f %n", &node->scale.x, &node->scale.y, &node->scale.z, &n) == 3)
                                        cursor += n;
                                else
                                        fprintf(stderr, "[warning] invalid value for scale in model %s in line %d\n", path, count);
+                       } else if (strcmp(key, "clockwise") == 0) {
+                               node->clockwise = 1;
                        } else if (strcmp(key, "cube") == 0) {
                                char texture[length + 1];
 
@@ -372,7 +387,8 @@ ModelNode *model_node_create(ModelNode *parent)
 {
        ModelNode *node = malloc(sizeof *node);
        node->name = NULL;
-       node->visible = true;
+       node->visible = 1;
+       node->clockwise = 0;
        node->pos = (v3f32) {0.0f, 0.0f, 0.0f};
        node->rot = (v3f32) {0.0f, 0.0f, 0.0f};
        node->scale = (v3f32) {1.0f, 1.0f, 1.0f};
index 977dbc6e7c2574c993a40b3eda6d1b07fc1304f8..8ca5ed274b663e3c9cbf36f47f164348c119d367 100644 (file)
@@ -26,12 +26,13 @@ typedef struct {
 
 typedef struct ModelNode {
        char *name;
-       bool visible;
        v3f32 pos, rot, scale;
        mat4x4 abs, rel;
        Array meshes;
        struct ModelNode *parent;
        List children;
+       unsigned int visible: 1;
+       unsigned int clockwise: 1;
 } ModelNode;
 
 typedef struct {
index fba282d7397b2c90db83cb967c8138889aec3043..c1f4a93a385a8ceefbfd02c7b040f4800155534f 100644 (file)
@@ -14,7 +14,7 @@ bool raycast(v3f64 pos, v3f64 dir, f64 len, v3s32 *node_pos, NodeType *node)
                if (*node == NODE_UNLOADED)
                        return false;
 
-               if (client_node_definitions[*node].pointable)
+               if (client_node_defs[*node].pointable)
                        return true;
 
                f64 vpos[3] = {pos.x, pos.y, pos.z};
diff --git a/src/client/screenshot.c b/src/client/screenshot.c
new file mode 100644 (file)
index 0000000..0a388f2
--- /dev/null
@@ -0,0 +1,73 @@
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <stb/stb_image_write.h>
+#include <string.h>
+#include <time.h>
+#include "client/game.h"
+#include "client/gl_debug.h"
+#include "client/window.h"
+
+char *screenshot()
+{
+       // renderbuffer for depth & stencil buffer
+       GLuint rbo;
+       glGenRenderbuffers(1, &rbo); GL_DEBUG
+       glBindRenderbuffer(GL_RENDERBUFFER, rbo); GL_DEBUG
+       glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH24_STENCIL8, window.width, window.height); GL_DEBUG
+
+       // 2 textures, one with AA, one without
+
+       GLuint txos[2];
+       glGenTextures(2, txos); GL_DEBUG
+
+       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, txos[0]); GL_DEBUG
+       glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGB, window.width, window.height, GL_TRUE); GL_DEBUG
+
+       glBindTexture(GL_TEXTURE_2D, txos[1]); GL_DEBUG
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window.width, window.height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); GL_DEBUG
+
+       // 2 framebuffers, one with AA, one without
+
+       GLuint fbos[2];
+       glGenFramebuffers(2, fbos); GL_DEBUG
+
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, txos[0], 0); GL_DEBUG
+       glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); GL_DEBUG
+
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, txos[1], 0); GL_DEBUG
+
+       // render scene
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); GL_DEBUG
+       game_render(0.0);
+       glBindFramebuffer(GL_FRAMEBUFFER, 0); GL_DEBUG
+
+       // blit AA-buffer into no-AA buffer
+       glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); GL_DEBUG
+       glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); GL_DEBUG
+       glBlitFramebuffer(0, 0, window.width, window.height, 0, 0, window.width, window.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_DEBUG
+
+       // read data
+       GLubyte data[window.width * window.height * 3];
+       glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]); GL_DEBUG
+       glPixelStorei(GL_PACK_ALIGNMENT, 1); GL_DEBUG
+       glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, data); GL_DEBUG
+
+       // create filename
+       char filename[BUFSIZ];
+       time_t timep = time(0);
+       strftime(filename, BUFSIZ, "screenshot-%Y-%m-%d-%H:%M:%S.png", localtime(&timep));
+
+       // save screenshot
+       stbi_flip_vertically_on_write(true);
+       stbi_write_png(filename, window.width, window.height, 3, data, window.width * 3);
+
+       // delete buffers
+       glDeleteRenderbuffers(1, &rbo); GL_DEBUG
+       glDeleteTextures(2, txos); GL_DEBUG
+       glDeleteFramebuffers(2, fbos); GL_DEBUG
+
+       return strdup(filename);
+}
diff --git a/src/client/screenshot.h b/src/client/screenshot.h
new file mode 100644 (file)
index 0000000..06de0df
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _SCREENSHOT_H_
+#define _SCREENSHOT_H_
+
+char *screenshot();
+
+#endif // _SCREENSHOT_H_
index fcf358a6b0152938323e45378f5e9648b34c8f72..1a542715ee53c84ae4c385236e8c5c869af5d13b 100644 (file)
@@ -5,7 +5,7 @@
 #include "client/gl_debug.h"
 #include "client/shader.h"
 
-static GLuint compile_shader(GLenum type, const char *path, const char *name, GLuint program, const char *definitions)
+static GLuint compile_shader(GLenum type, const char *path, const char *name, GLuint program, const char *defs)
 {
        char full_path[strlen(path) + 1 + strlen(name) + 1 + 4 + 1];
        sprintf(full_path, "%s/%s.glsl", path, name);
@@ -53,13 +53,13 @@ static GLuint compile_shader(GLenum type, const char *path, const char *name, GL
 
        const char *code_list[3] = {
                version,
-               definitions,
+               defs,
                code,
        };
 
        int size_list[3] = {
                18,
-               strlen(definitions),
+               strlen(defs),
                size,
        };
 
@@ -82,21 +82,21 @@ static GLuint compile_shader(GLenum type, const char *path, const char *name, GL
        return id;
 }
 
-bool shader_program_create(const char *path, GLuint *idptr, const char *definitions)
+bool shader_program_create(const char *path, GLuint *idptr, const char *defs)
 {
        GLuint id = glCreateProgram(); GL_DEBUG
 
-       if (!definitions)
-               definitions = "";
+       if (!defs)
+               defs = "";
 
        GLuint vert, frag;
 
-       if (!(vert = compile_shader(GL_VERTEX_SHADER, path, "vertex", id, definitions))) {
+       if (!(vert = compile_shader(GL_VERTEX_SHADER, path, "vertex", id, defs))) {
                glDeleteProgram(id); GL_DEBUG
                return false;
        }
 
-       if (!(frag = compile_shader(GL_FRAGMENT_SHADER, path, "fragment", id, definitions))) {
+       if (!(frag = compile_shader(GL_FRAGMENT_SHADER, path, "fragment", id, defs))) {
                glDeleteShader(vert); GL_DEBUG
                glDeleteProgram(id); GL_DEBUG
                return false;
index eb62941f565eb90ca8283e1970d6866563e8cf35..b53b604995d90e83ddf5b61e8de269d1ced41c58 100644 (file)
@@ -5,6 +5,6 @@
 #include <GL/gl.h>
 #include <stdbool.h>
 
-bool shader_program_create(const char *path, GLuint *idptr, const char *definitions);
+bool shader_program_create(const char *path, GLuint *idptr, const char *defs);
 
 #endif // _SHADER_H_
index 258a295cdbd028fab836cb56a8283d4f0350c730..52877d9ae54b493ca5ee6176b4a6561d7656b2b0 100644 (file)
@@ -59,7 +59,7 @@ static ModelShader model_shader;
 
 static inline bool cull_face(NodeType self, NodeType nbr)
 {
-       switch (client_node_definitions[self].visibility) {
+       switch (client_node_defs[self].visibility) {
                case VISIBILITY_CLIP:
                        return false;
 
@@ -69,7 +69,7 @@ static inline bool cull_face(NodeType self, NodeType nbr)
 
                case VISIBILITY_SOLID:
                        return nbr == NODE_UNLOADED
-                               || client_node_definitions[nbr].visibility == VISIBILITY_SOLID;
+                               || client_node_defs[nbr].visibility == VISIBILITY_SOLID;
 
                default: // impossible
                        break;
@@ -85,7 +85,7 @@ static inline void render_node(ChunkRenderData *data, v3s32 offset)
 
        args.node = &data->chunk->data[offset.x][offset.y][offset.z];
 
-       ClientNodeDefinition *def = &client_node_definitions[args.node->type];
+       ClientNodeDef *def = &client_node_defs[args.node->type];
        if (def->visibility == VISIBILITY_NONE)
                return;
 
index 0203510a4d6d64e0709c14e1602106c9d8187909..7f657e3d066598b4cf61f0c440eed3a3fc8670d8 100644 (file)
@@ -2,6 +2,9 @@
 #define _WINDOW_H_
 
 #include <GLFW/glfw3.h>
+#include <linmath.h/linmath.h>
+#include <stdbool.h>
+#include "types.h"
 
 extern struct Window {
        int width, height;
diff --git a/src/item.c b/src/item.c
new file mode 100644 (file)
index 0000000..25a1a2c
--- /dev/null
@@ -0,0 +1,98 @@
+#include <stdlib.h>
+#include "item.h"
+
+void item_stack_initialize(ItemStack *stack)
+{
+       stack->type = ITEM_NONE;
+       stack->count = 1;
+       stack->data = NULL;
+
+       if (item_defs[stack->type].create)
+               item_defs[stack->type].create(stack);   
+}
+
+void item_stack_destroy(ItemStack *stack)
+{
+       if (item_defs[stack->type].delete)
+               item_defs[stack->type].delete(stack);   
+
+       if (stack->data) {
+               free(stack->data);
+               stack->data = NULL;
+       }
+}
+
+void item_stack_set(ItemStack *stack, ItemType type, u32 count, Blob buffer)
+{
+       item_stack_destroy(stack);
+
+       stack->type = type;
+       stack->count = count;
+       stack->data = item_defs[stack->type].data_size > 0 ?
+               malloc(item_defs[stack->type].data_size) : NULL;
+
+       if (item_defs[stack->type].create)
+               item_defs[stack->type].create(stack);
+
+       if (item_defs[stack->type].deserialize)
+               item_defs[stack->type].deserialize(&buffer, stack->data);
+}
+
+void item_stack_serialize(ItemStack *stack, SerializedItemStack *serialized)
+{
+       serialized->type = stack->type;
+       serialized->count = stack->count;
+       serialized->data = (Blob) {0, NULL};
+
+       if (item_defs[stack->type].serialize)
+               item_defs[stack->type].serialize(&serialized->data, stack->data);
+}
+
+void item_stack_deserialize(ItemStack *stack, SerializedItemStack *serialized)
+{
+       ItemType type = serialized->type;
+
+       if (type >= COUNT_ITEM)
+               type = ITEM_UNKNOWN;
+       
+       item_stack_set(stack, type, serialized->count, serialized->data);
+}
+
+ItemDef item_defs[COUNT_ITEM] = {
+       // unknown
+       {
+               .stackable = false,
+               .data_size = 0,
+               .create = NULL,
+               .delete = NULL,
+               .serialize = NULL,
+               .deserialize = NULL,
+       },
+       // none
+       {
+               .stackable = false,
+               .data_size = 0,
+               .create = NULL,
+               .delete = NULL,
+               .serialize = NULL,
+               .deserialize = NULL,
+       },
+       // pickaxe
+       {
+               .stackable = false,
+               .data_size = 0,
+               .create = NULL,
+               .delete = NULL,
+               .serialize = NULL,
+               .deserialize = NULL,
+       },
+       // axe
+       {
+               .stackable = false,
+               .data_size = 0,
+               .create = NULL,
+               .delete = NULL,
+               .serialize = NULL,
+               .deserialize = NULL,
+       },
+};
diff --git a/src/item.h b/src/item.h
new file mode 100644 (file)
index 0000000..accf3ab
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _ITEM_H_
+#define _ITEM_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include "types.h"
+
+typedef enum {
+       ITEM_UNKNOWN,
+       ITEM_NONE,
+       ITEM_PICKAXE,
+       ITEM_AXE,
+       COUNT_ITEM,
+} ItemType;
+
+typedef struct {
+       ItemType type;
+       u32 count; // i know future me is going to thank me for making it big
+       void *data;
+} ItemStack;
+
+typedef struct {
+       bool stackable;
+       size_t data_size;
+       void (*create)(ItemStack *stack);
+       void (*delete)(ItemStack *stack);
+       void (*serialize)(Blob *buffer, void *data);
+       void (*deserialize)(Blob *buffer, void *data);
+} ItemDef;
+
+void item_stack_initialize(ItemStack *stack);
+void item_stack_destroy(ItemStack *stack);
+
+void item_stack_set(ItemStack *stack, ItemType type, u32 count, Blob buffer);
+void item_stack_serialize(ItemStack *stack, SerializedItemStack *serialized);
+void item_stack_deserialize(ItemStack *stack, SerializedItemStack *serialized);
+
+extern ItemDef item_defs[];
+
+#endif // _ITEM_H_
index 727f81cf10508fa4c2c04a38af265fe5ca313c90..c9c2c1cf205e6d9b66a469de49ba5b3e93b903fd 100644 (file)
@@ -2,7 +2,7 @@
 #include "terrain.h"
 #include "types.h"
 
-NodeDefinition node_definitions[NODE_UNLOADED] = {
+NodeDef node_defs[NODE_UNLOADED] = {
        // unknown
        {
                .solid = true,
index 3e7e9307fb25202abbec7da37b444054b9e1ab1f..b660d179fe0ba4a5d3cd6378ebc1edf668cde50f 100644 (file)
@@ -5,8 +5,6 @@
 #include <stddef.h>
 #include "types.h"
 
-#define NODE_DEFINITION(type) ((type) < NODE_UNLOADED ? &node_definitions[NODE_UNKNOWN] : &node_definitions[(type)]);
-
 typedef enum {
        NODE_UNKNOWN,       // Used for unknown nodes received from server (caused by outdated clients)
        NODE_AIR,
@@ -36,8 +34,8 @@ typedef struct {
        void (*delete)(struct TerrainNode *node);
        void (*serialize)(Blob *buffer, void *data);
        void (*deserialize)(Blob *buffer, void *data);
-} NodeDefinition;
+} NodeDef;
 
-extern NodeDefinition node_definitions[];
+extern NodeDef node_defs[];
 
 #endif
index 8f117b40d76a292d130794b38e71c4f9a75b718c..a89e89cdec09108abcac254a9551f1faedcf10ac 100644 (file)
@@ -20,7 +20,7 @@ static aabb3s32 round_box(aabb3f64 box)
 static bool is_solid(Terrain *terrain, s32 x, s32 y, s32 z)
 {
        NodeType node = terrain_get_node(terrain, (v3s32) {x, y, z}).type;
-       return node == NODE_UNLOADED || node_definitions[node].solid;
+       return node == NODE_UNLOADED || node_defs[node].solid;
 }
 
 bool physics_ground(Terrain *terrain, bool collide, aabb3f32 box, v3f64 *pos, v3f64 *vel)
index 0cbaed38d8df73a6128db24839866407f21ee763..114f6540489d2b022de508c5973584c20eb05d6c 100644 (file)
@@ -1,8 +1,9 @@
 #define _GNU_SOURCE // don't worry, GNU extensions are only used when available
 #include <dragonnet/addr.h>
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <pthread.h>
+#include <time.h>
 #include "interrupt.h"
 #include "server/database.h"
 #include "server/server.h"
@@ -70,6 +71,8 @@ int main(int argc, char **argv)
        server->on_recv_type[DRAGONNET_TYPE_ToServerPosRot      ] = (void *) &on_ToServerPosRot;
        server->on_recv_type[DRAGONNET_TYPE_ToServerRequestChunk] = (void *) &on_ToServerRequestChunk;
 
+       srand(time(0));
+
        interrupt_init();
        if (!database_init())
                return EXIT_FAILURE;
index 61b666c4728e6094119c44bbfc0ac38223db1e4d..4a41d5e52a7c244a9b4f038390787d8c7a0a6a3e 100644 (file)
@@ -27,32 +27,50 @@ static void send_entity_add(ServerPlayer *player, ServerPlayer *entity)
        });
 }
 
-static void send_entity_remove(ServerPlayer *player, ServerPlayer *entity)
+static void send_entity_remove(ServerPlayer *client, ServerPlayer *entity)
 {
-       dragonnet_peer_send_ToClientEntityRemove(player->peer, &(ToClientEntityRemove) {
+       dragonnet_peer_send_ToClientEntityRemove(client->peer, &(ToClientEntityRemove) {
                .id = entity->id,
        });
 }
 
-static void send_entity_update_pos_rot(ServerPlayer *player, ServerPlayer *entity)
+static void send_entity_update_pos_rot(ServerPlayer *client, ServerPlayer *entity)
 {
-       if (player != entity)
-               dragonnet_peer_send_ToClientEntityUpdatePosRot(player->peer, &(ToClientEntityUpdatePosRot) {
+       if (client != entity)
+               dragonnet_peer_send_ToClientEntityUpdatePosRot(client->peer, &(ToClientEntityUpdatePosRot) {
                        .id = entity->id,
                        .pos = entity->pos,
                        .rot = entity->rot,
                });
 }
 
-static void send_entity_add_existing(ServerPlayer *entity, ServerPlayer *player)
+static void send_entity_add_existing(ServerPlayer *entity, ServerPlayer *client)
 {
-       if (player != entity) {
+       if (client != entity) {
                pthread_rwlock_rdlock(&entity->lock_pos);
-               send_entity_add(player, entity);
+               send_entity_add(client, entity);
                pthread_rwlock_unlock(&entity->lock_pos);
        }
 }
 
+static void send_player_inventory(ServerPlayer *client, ServerPlayer *player)
+{
+       ToClientPlayerInventory pkt;
+       pkt.id = player->id;
+       item_stack_serialize(&player->inventory.left, &pkt.left);
+       item_stack_serialize(&player->inventory.right, &pkt.right);
+       dragonnet_peer_send_ToClientPlayerInventory(client->peer, &pkt);
+}
+
+static void send_player_inventory_existing(ServerPlayer *player, ServerPlayer *client)
+{
+       if (client != player) {
+               pthread_rwlock_rdlock(&player->lock_inv);
+               send_player_inventory(client, player);
+               pthread_rwlock_unlock(&player->lock_inv);
+       }       
+}
+
 // main thread
 // called on server shutdown
 static void player_drop(ServerPlayer *player)
@@ -81,6 +99,10 @@ static void player_delete(ServerPlayer *player)
 
        pthread_rwlock_destroy(&player->lock_pos);
 
+       item_stack_destroy(&player->inventory.left);
+       item_stack_destroy(&player->inventory.right);
+       pthread_rwlock_destroy(&player->lock_inv);
+
        free(player);
 }
 
@@ -95,6 +117,9 @@ static void player_spawn(ServerPlayer *player)
                database_create_player(player->name, player->pos, player->rot);
        }
 
+       item_stack_set(&player->inventory.left, ITEM_NONE + rand() % (ITEM_AXE - ITEM_NONE + 1), 1, (Blob) {0, NULL});
+       item_stack_set(&player->inventory.right, ITEM_NONE + rand() % (ITEM_AXE - ITEM_NONE + 1), 1, (Blob) {0, NULL});
+
        // since this is recv thread, we don't need lock_peer
        dragonnet_peer_send_ToClientInfo(player->peer, &(ToClientInfo) {
                .seed = seed,
@@ -113,6 +138,9 @@ static void player_spawn(ServerPlayer *player)
 
        server_player_iterate(&send_entity_add, player);
        server_player_iterate(&send_entity_add_existing, player);
+
+       server_player_iterate(&send_player_inventory, player);
+       server_player_iterate(&send_player_inventory_existing, player);
 }
 
 // any thread
@@ -170,6 +198,10 @@ void server_player_add(DragonnetPeer *peer)
        player->rot = (v3f32) {0.0f, 0.0f, 0.0f};
        pthread_rwlock_init(&player->lock_pos, NULL);
 
+       item_stack_initialize(&player->inventory.left);
+       item_stack_initialize(&player->inventory.right);
+       pthread_rwlock_init(&player->lock_inv, NULL);
+
        printf("[access] connected %s\n", player->name);
        peer->extra = refcount_grb(&player->rc);
 
index 1d20a5d6fb8efc95560e36c2814e689afc47f9a4..34af22521a17144900d6aef89f56d3228f282a74 100644 (file)
@@ -5,6 +5,7 @@
 #include <dragonstd/refcount.h>
 #include <pthread.h>
 #include <stdbool.h>
+#include "item.h"
 #include "types.h"
 
 typedef struct {
@@ -21,6 +22,12 @@ typedef struct {
        v3f64 pos;                     // player position
        v3f32 rot;                     // you wont guess what this is
        pthread_rwlock_t lock_pos;     // git commit crime
+
+       struct {
+               ItemStack left;
+               ItemStack right;
+       } inventory;
+       pthread_rwlock_t lock_inv;
 } ServerPlayer;
 
 void server_player_init();
index f6a22da591188930cd73b6743abf0aa7f21fadb4..77b947513d3e3daa0ec2b0c4ca6727f7a3530fb1 100644 (file)
@@ -263,7 +263,7 @@ static void generate_spawn_hut()
                                pos.y++;
                        }
 
-                       if (node_definitions[node].solid)
+                       if (node_defs[node].solid)
                                break;
 
                        server_terrain_gen_node(pos,
index b258b1d2208f73ad32120c76c54f1388393e8564..6d5a2398e50e1fa876f01f4875006db31abde50e 100644 (file)
@@ -95,7 +95,7 @@ void terrain_gen_chunk(TerrainChunk *chunk, List *changed_chunks)
                                        node = NODE_SNOW;
 
                                if (generate_args.diff == 1) for (int i = 0; i < NUM_TREES; i++) {
-                                       TreeDef *def = &tree_definitions[i];
+                                       TreeDef *def = &tree_defs[i];
 
                                        if (def->condition(&condition_args)
                                                        && noise2d(condition_args.pos.x, condition_args.pos.z, 0, seed + def->offset) * 0.5 + 0.5 < def->probability
index 2d165c26c1d80f9db098007e82e3e616b0aa14ec..e013a0d1fe0e0de542b0eba291587f0c56daad02 100644 (file)
@@ -201,7 +201,7 @@ static void palm_tree(v3s32 pos, List *changed_chunks)
        voxel_procedural_delete(proc);
 }
 
-TreeDef tree_definitions[NUM_TREES] = {
+TreeDef tree_defs[NUM_TREES] = {
        // oak
        {
                .spread = 64.0f,
index 8084c52d2f242f16b0c16382dfd64aae36ca128b..2eeb3f8739d548462d1def1d4c8a5f0368b3c041 100644 (file)
@@ -30,6 +30,6 @@ typedef struct {
        void (*generate)(v3s32 pos, List *changed_chunks);
 } TreeDef;
 
-extern TreeDef tree_definitions[];
+extern TreeDef tree_defs[];
 
 #endif // _TREES_H_
index 2e8eec888072b94177a7299a6061819dd0813711..b3366c8f483e4bf3b7d05299131dae7d8d86d26b 100644 (file)
@@ -166,7 +166,7 @@ Blob terrain_serialize_chunk(TerrainChunk *chunk)
                        },
                };
 
-               NodeDefinition *def = &node_definitions[node->type];
+               NodeDef *def = &node_defs[node->type];
 
                if (def->serialize)
                        def->serialize(&node_data->data, node->data);
@@ -242,7 +242,7 @@ TerrainNode terrain_node_create(NodeType type, Blob buffer)
        if (type >= NODE_UNLOADED)
                type = NODE_UNKNOWN;
 
-       NodeDefinition *def = &node_definitions[type];
+       NodeDef *def = &node_defs[type];
 
        TerrainNode node;
        node.type = type;
@@ -259,7 +259,7 @@ TerrainNode terrain_node_create(NodeType type, Blob buffer)
 
 void terrain_node_delete(TerrainNode node)
 {
-       NodeDefinition *def = &node_definitions[node.type];
+       NodeDef *def = &node_defs[node.type];
 
        if (def->delete)
                def->delete(&node);
index 48c572b788499793c8361a8cfca7bfaa2a833a41..824872649eda86dc296619e48c28f647a64d95c8 100644 (file)
@@ -25,6 +25,11 @@ EntityData
        v3f32 rot
        String nametag
 
+SerializedItemStack
+       u32 type
+       u32 count
+       Blob data
+
 ; server packets
 
 pkt ToServerAuth
@@ -83,3 +88,8 @@ pkt ToClientEntityUpdatePosRot
 pkt ToClientEntityUpdateNametag
        u64 id
        String nametag
+
+pkt ToClientPlayerInventory
+       u64 id
+       SerializedItemStack left
+       SerializedItemStack right