summaryrefslogtreecommitdiff
path: root/server/block_def.go
blob: a5adb4071df294d611d6dd753151ab5f07b3f3c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package server

import (
	"iter"
	"git.citrons.xyz/metronode/classic"
)

type blockType int16

const (
	walkThrough = classic.WalkThrough
	swimThrough = classic.SwimThrough
	solid = classic.Solid
	partiallySlippery = classic.PartiallySlippery
	fullySlippery = classic.FullySlippery
	water = classic.Water
	lava = classic.Lava
	rope = classic.Rope
)
type blockSolidity byte

const (
	noSound = classic.NoSound
	woodSound = classic.WoodSound
	gravelSound = classic.GravelSound
	grassSound = classic.GrassSound
	stoneSound = classic.StoneSound
	metalSound = classic.MetalSound
	glassSound = classic.GlassSound
	woolSound = classic.WoolSound
	sandSound = classic.SandSound
	snowSound = classic.SnowSound
)
type blockSound byte

const (
	opaque = classic.Opaque
	transparentGlass = classic.TransparentGlass
	transparentLeaves = classic.TransparentLeaves
	translucent = classic.Translucent
	invisible = classic.Invisible
)
type blockOpacity byte

const (
	cubeShape = iota
	spriteShape
	cuboidShape
)
type blockShape byte

type textureId int
const fillTextures = -1

type blockDef struct {
	Name string
	Solidity blockSolidity
	MovementSpeed byte
	Textures [6]textureId
	TransmitsLight bool
	WalkSound blockSound
	FullBright bool
	Shape blockShape
	Min [3]byte
	Max [3]byte
	Opacity blockOpacity
	FogDensity byte
	FogColor [3]byte
	Variants map[any]blockType
}

type rotateVariant int

var rotationNames = []string {"-N", "-E", "-S", "-W"}
func makeRotations(block blockType) {
	var variants = make(map[any]blockType)
	oldDef := blockDefinitions[block]
	for i := 0; i < 4; i++ {
		newBlock := block + blockType(i)
		if _, ok := blockDefinitions[newBlock]; i != 0 && ok {
			panic("variant would override existing block")
		}
		newDef := oldDef
		for j := 0; j < 4; j++ {
			k := (j + i) % 4
			newDef.Textures[j + 1] = oldDef.Textures[k + 1]
		}
		var minX, minZ, maxX, maxZ byte
		switch i {
		case 1:
			minX = oldDef.Min[2]
			minZ = 16 - oldDef.Min[0]
			maxX = oldDef.Max[2]
			maxZ = 16 - oldDef.Max[0]
		case 2:
			minX = 16 - oldDef.Min[0]
			minZ = 16 - oldDef.Min[2]
			maxX = 16 - oldDef.Max[0]
			maxZ = 16 - oldDef.Max[2]
		case 3:
			minX = oldDef.Min[2]
			minZ = 16 - oldDef.Min[0]
			maxX = oldDef.Max[2]
			maxZ = 16 - oldDef.Max[0]
		}
		newDef.Min = [3]byte {byte(minX), oldDef.Min[1], byte(minZ)}
		newDef.Max = [3]byte {byte(maxX), oldDef.Max[1], byte(maxZ)}
		newDef.Name = newDef.Name + rotationNames[i]
		newDef.Variants = variants
		blockDefinitions[newBlock] = newDef
	}
}

func getBlockDefPackets() iter.Seq[classic.Packet] {
	return func(yield func(classic.Packet) bool) {
		for id, def := range blockDefinitions { 
			var packet classic.Packet
			var (
				transmitsLight byte
				fullBright byte
			)
			if def.TransmitsLight {
				transmitsLight = 1
			}
			if def.FullBright {
				fullBright = 1
			}
			if def.Shape != spriteShape {
				var (i int; texture textureId)
				for i, texture = range def.Textures {
					if texture == fillTextures {
						break
					}
				}
				if texture == fillTextures {
					for i = i; i < len(def.Textures); i++ {
						def.Textures[i] = def.Textures[i - 1]
					}
				}
				if def.Shape == cubeShape {
					def.Min = [3]byte {0, 0, 0}
					def.Max = [3]byte {16, 16, 16}
				}
				packet = &classic.DefineBlockExt {
					BlockId: byte(id),
					Name: classic.PadString(def.Name),
					Solidity: byte(def.Solidity),
					MovementSpeed: def.MovementSpeed,
					TopTextureId: byte(def.Textures[0]),
					LeftTextureId: byte(def.Textures[4]),
					RightTextureId: byte(def.Textures[2]),
					FrontTextureId: byte(def.Textures[3]),
					BackTextureId: byte(def.Textures[1]),
					BottomTextureId: byte(def.Textures[5]),
					TransmitsLight: transmitsLight,
					WalkSound: byte(def.WalkSound),
					FullBright: fullBright,
					Min: def.Min,
					Max: def.Max,
					BlockDraw: byte(def.Opacity),
					FogDensity: def.FogDensity,
					FogColor: def.FogColor,
				}
			} else {
				packet = &classic.DefineBlock {
					BlockId: byte(id),
					Name: classic.PadString(def.Name),
					Solidity: byte(def.Solidity),
					MovementSpeed: def.MovementSpeed,
					SideTextureId: byte(def.Textures[1]),
					TransmitsLight: transmitsLight,
					WalkSound: byte(def.WalkSound),
					FullBright: fullBright,
					Shape: 0,
					BlockDraw: byte(def.Opacity),
					FogDensity: def.FogDensity,
					FogColor: def.FogColor,
				}
			}
			if !yield(packet) {
				return
			}
		}
	}
}