From: Elias Fleckenstein Date: Tue, 19 Apr 2022 21:30:07 +0000 (+0200) Subject: Add items X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;ds=sidebyside;h=dde805203b320dd008718099b965f7275c04d1cd;p=dragonblocks_alpha.git Add items --- diff --git a/deps/protogen b/deps/protogen index 45b6912..97963be 160000 --- a/deps/protogen +++ b/deps/protogen @@ -1 +1 @@ -Subproject commit 45b691209c95e5a758536a32564c329683550dca +Subproject commit 97963be1d8fbc53dce1b116f1d62340dee83383c diff --git a/meshes/axe.gox b/meshes/axe.gox new file mode 100644 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 index 0000000..1e29a2a --- /dev/null +++ b/meshes/axe.txt @@ -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 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 index 0000000..c14d78e --- /dev/null +++ b/meshes/pickaxe.txt @@ -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 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 index 0000000..78bbd97 --- /dev/null +++ b/meshes/unknown.txt @@ -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 diff --git a/models/player.txt b/models/player.txt index ee482f8..e67a0e9 100644 --- a/models/player.txt +++ b/models/player.txt @@ -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 diff --git a/shaders/3d/entity/fragment.glsl b/shaders/3d/entity/fragment.glsl index 2cd4768..d74e86a 100755 --- a/shaders/3d/entity/fragment.glsl +++ b/shaders/3d/entity/fragment.glsl @@ -1,5 +1,4 @@ in vec3 fragmentPosition; -in vec3 fragmentNormal; in vec3 fragmentTextureCoordinates; in float fragmentLight; diff --git a/shaders/3d/entity/vertex.glsl b/shaders/3d/entity/vertex.glsl index ca8684a..a53f950 100755 --- a/shaders/3d/entity/vertex.glsl +++ b/shaders/3d/entity/vertex.glsl @@ -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 index 0000000..102b9a5 --- /dev/null +++ b/shaders/3d/item/fragment.glsl @@ -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 index 0000000..9aabdcc --- /dev/null +++ b/shaders/3d/item/vertex.glsl @@ -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); +} diff --git a/shaders/3d/terrain/fragment.glsl b/shaders/3d/terrain/fragment.glsl index 62ee89b..37bc567 100755 --- a/shaders/3d/terrain/fragment.glsl +++ b/shaders/3d/terrain/fragment.glsl @@ -1,5 +1,4 @@ in vec3 fragmentPosition; -in vec3 fragmentNormal; in vec2 fragmentTextureCoordinates; in float fragmentTextureIndex; in vec3 fragmentColor; diff --git a/shaders/3d/terrain/vertex.glsl b/shaders/3d/terrain/vertex.glsl index abef047..2068cdc 100755 --- a/shaders/3d/terrain/vertex.glsl +++ b/shaders/3d/terrain/vertex.glsl @@ -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); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b7cede..4df3b80 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/client/camera.c b/src/client/camera.c index adb2364..8b6a318 100644 --- a/src/client/camera.c +++ b/src/client/camera.c @@ -1,6 +1,5 @@ #include #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; diff --git a/src/client/camera.h b/src/client/camera.h index abe7d8f..3e3d517 100644 --- a/src/client/camera.h +++ b/src/client/camera.h @@ -1,8 +1,6 @@ #ifndef _CAMERA_H_ #define _CAMERA_H_ -#include -#include #include #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_ diff --git a/src/client/client.c b/src/client/client.c index 5393922..40f58dc 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -7,6 +7,7 @@ #include #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); diff --git a/src/client/client_entity.c b/src/client/client_entity.c index 97173e8..2bc3253 100644 --- a/src/client/client_entity.c +++ b/src/client/client_entity.c @@ -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); diff --git a/src/client/client_entity.h b/src/client/client_entity.h index 53125db..03238a6 100644 --- a/src/client/client_entity.h +++ b/src/client/client_entity.h @@ -1,12 +1,12 @@ #ifndef _CLIENT_ENTITY_H_ #define _CLIENT_ENTITY_H_ -#include #include #include #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 index 0000000..4ae916b --- /dev/null +++ b/src/client/client_inventory.c @@ -0,0 +1,109 @@ +#include +#include +#include +#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 index 0000000..3b09789 --- /dev/null +++ b/src/client/client_inventory.h @@ -0,0 +1,16 @@ +#ifndef _CLIENT_INVENTORY_H_ +#define _CLIENT_INVENTORY_H_ + +#include +#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 index 0000000..923fd74 --- /dev/null +++ b/src/client/client_item.c @@ -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 index 0000000..0105abf --- /dev/null +++ b/src/client/client_item.h @@ -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_ diff --git a/src/client/client_node.c b/src/client/client_node.c index 956e18f..56c646e 100644 --- a/src/client/client_node.c +++ b/src/client/client_node.c @@ -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]; diff --git a/src/client/client_node.h b/src/client/client_node.h index 7edcf66..57ae625 100644 --- a/src/client/client_node.h +++ b/src/client/client_node.h @@ -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_ diff --git a/src/client/client_player.c b/src/client/client_player.c index 326ab53..ccbd059 100644 --- a/src/client/client_player.c +++ b/src/client/client_player.c @@ -2,6 +2,7 @@ #include #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" @@ -10,16 +11,6 @@ #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; diff --git a/src/client/client_player.h b/src/client/client_player.h index 5ddefa0..1028955 100644 --- a/src/client/client_player.h +++ b/src/client/client_player.h @@ -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 diff --git a/src/client/client_terrain.c b/src/client/client_terrain.c index c9c0ff1..148c084 100644 --- a/src/client/client_terrain.c +++ b/src/client/client_terrain.c @@ -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); diff --git a/src/client/debug_menu.c b/src/client/debug_menu.c index 8e60bdb..e3f1a9c 100644 --- a/src/client/debug_menu.c +++ b/src/client/debug_menu.c @@ -6,12 +6,14 @@ #include #include #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}, diff --git a/src/client/debug_menu.h b/src/client/debug_menu.h index 3b1b7de..74f23ac 100644 --- a/src/client/debug_menu.h +++ b/src/client/debug_menu.h @@ -5,6 +5,7 @@ typedef enum { ENTRY_VERSION, ENTRY_FPS, ENTRY_POS, + ENTRY_POINTED, ENTRY_YAW, ENTRY_PITCH, ENTRY_TIME, diff --git a/src/client/game.c b/src/client/game.c index c0554eb..8891b18 100644 --- a/src/client/game.c +++ b/src/client/game.c @@ -1,13 +1,13 @@ -#define STB_IMAGE_WRITE_IMPLEMENTATION #include #include #include -#include #include #include #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" @@ -26,25 +26,7 @@ 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); -} diff --git a/src/client/game.h b/src/client/game.h index af1d74c..107583a 100644 --- a/src/client/game.h +++ b/src/client/game.h @@ -2,10 +2,11 @@ #define _GAME_H_ #include +#include "types.h" extern int game_fps; bool game(Flag *gfx_init); -char *game_take_screenshot(); +void game_render(f64 dtime); #endif // _GAME_H_ diff --git a/src/client/gui.c b/src/client/gui.c index 4aecb48..05f4fb7 100644 --- a/src/client/gui.c +++ b/src/client/gui.c @@ -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; diff --git a/src/client/gui.h b/src/client/gui.h index ea4b15e..1ce9584 100644 --- a/src/client/gui.h +++ b/src/client/gui.h @@ -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); diff --git a/src/client/input.c b/src/client/input.c index 19dc81c..00ede8a 100644 --- a/src/client/input.c +++ b/src/client/input.c @@ -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; diff --git a/src/client/interact.c b/src/client/interact.c index 728bc29..a4c2251 100644 --- a/src/client/interact.c +++ b/src/client/interact.c @@ -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; diff --git a/src/client/interact.h b/src/client/interact.h index 707bb01..aa3389d 100644 --- a/src/client/interact.h +++ b/src/client/interact.h @@ -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(); diff --git a/src/client/mesh.c b/src/client/mesh.c index 49df506..d778ce1 100644 --- a/src/client/mesh.c +++ b/src/client/mesh.c @@ -1,8 +1,133 @@ +#include #include +#include #include +#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) { diff --git a/src/client/mesh.h b/src/client/mesh.h index 3597043..15c598b 100644 --- a/src/client/mesh.h +++ b/src/client/mesh.h @@ -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); diff --git a/src/client/model.c b/src/client/model.c index 3a8ba6c..8954267 100644 --- a/src/client/model.c +++ b/src/client/model.c @@ -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}; diff --git a/src/client/model.h b/src/client/model.h index 977dbc6..8ca5ed2 100644 --- a/src/client/model.h +++ b/src/client/model.h @@ -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 { diff --git a/src/client/raycast.c b/src/client/raycast.c index fba282d..c1f4a93 100644 --- a/src/client/raycast.c +++ b/src/client/raycast.c @@ -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 index 0000000..0a388f2 --- /dev/null +++ b/src/client/screenshot.c @@ -0,0 +1,73 @@ +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include +#include +#include +#include +#include +#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 index 0000000..06de0df --- /dev/null +++ b/src/client/screenshot.h @@ -0,0 +1,6 @@ +#ifndef _SCREENSHOT_H_ +#define _SCREENSHOT_H_ + +char *screenshot(); + +#endif // _SCREENSHOT_H_ diff --git a/src/client/shader.c b/src/client/shader.c index fcf358a..1a54271 100644 --- a/src/client/shader.c +++ b/src/client/shader.c @@ -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; diff --git a/src/client/shader.h b/src/client/shader.h index eb62941..b53b604 100644 --- a/src/client/shader.h +++ b/src/client/shader.h @@ -5,6 +5,6 @@ #include #include -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_ diff --git a/src/client/terrain_gfx.c b/src/client/terrain_gfx.c index 258a295..52877d9 100644 --- a/src/client/terrain_gfx.c +++ b/src/client/terrain_gfx.c @@ -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; diff --git a/src/client/window.h b/src/client/window.h index 0203510..7f657e3 100644 --- a/src/client/window.h +++ b/src/client/window.h @@ -2,6 +2,9 @@ #define _WINDOW_H_ #include +#include +#include +#include "types.h" extern struct Window { int width, height; diff --git a/src/item.c b/src/item.c new file mode 100644 index 0000000..25a1a2c --- /dev/null +++ b/src/item.c @@ -0,0 +1,98 @@ +#include +#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 index 0000000..accf3ab --- /dev/null +++ b/src/item.h @@ -0,0 +1,40 @@ +#ifndef _ITEM_H_ +#define _ITEM_H_ + +#include +#include +#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_ diff --git a/src/node.c b/src/node.c index 727f81c..c9c2c1c 100644 --- a/src/node.c +++ b/src/node.c @@ -2,7 +2,7 @@ #include "terrain.h" #include "types.h" -NodeDefinition node_definitions[NODE_UNLOADED] = { +NodeDef node_defs[NODE_UNLOADED] = { // unknown { .solid = true, diff --git a/src/node.h b/src/node.h index 3e7e930..b660d17 100644 --- a/src/node.h +++ b/src/node.h @@ -5,8 +5,6 @@ #include #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 diff --git a/src/physics.c b/src/physics.c index 8f117b4..a89e89c 100644 --- a/src/physics.c +++ b/src/physics.c @@ -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) diff --git a/src/server/server.c b/src/server/server.c index 0cbaed3..114f654 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -1,8 +1,9 @@ #define _GNU_SOURCE // don't worry, GNU extensions are only used when available #include +#include #include #include -#include +#include #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; diff --git a/src/server/server_player.c b/src/server/server_player.c index 61b666c..4a41d5e 100644 --- a/src/server/server_player.c +++ b/src/server/server_player.c @@ -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); diff --git a/src/server/server_player.h b/src/server/server_player.h index 1d20a5d..34af225 100644 --- a/src/server/server_player.h +++ b/src/server/server_player.h @@ -5,6 +5,7 @@ #include #include #include +#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(); diff --git a/src/server/server_terrain.c b/src/server/server_terrain.c index f6a22da..77b9475 100644 --- a/src/server/server_terrain.c +++ b/src/server/server_terrain.c @@ -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, diff --git a/src/server/terrain_gen.c b/src/server/terrain_gen.c index b258b1d..6d5a239 100644 --- a/src/server/terrain_gen.c +++ b/src/server/terrain_gen.c @@ -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 diff --git a/src/server/trees.c b/src/server/trees.c index 2d165c2..e013a0d 100644 --- a/src/server/trees.c +++ b/src/server/trees.c @@ -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, diff --git a/src/server/trees.h b/src/server/trees.h index 8084c52..2eeb3f8 100644 --- a/src/server/trees.h +++ b/src/server/trees.h @@ -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_ diff --git a/src/terrain.c b/src/terrain.c index 2e8eec8..b3366c8 100644 --- a/src/terrain.c +++ b/src/terrain.c @@ -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); diff --git a/src/types.def b/src/types.def index 48c572b..8248726 100644 --- a/src/types.def +++ b/src/types.def @@ -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