1 #include "ChunkTest.hpp"
3 #include "world/BlockType.hpp"
4 #include "world/Chunk.hpp"
8 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::ChunkTest);
10 using std::unique_ptr;
16 void ChunkTest::setUp() {
17 types = BlockTypeRegistry();
20 obstacle.name = "obstacle";
21 obstacle.visible = true;
22 obstacle.block_light = true;
23 types.Add(std::move(obstacle));
26 source.name = "source";
27 source.visible = true;
28 source.luminosity = 5;
29 source.block_light = true;
30 types.Add(std::move(source));
33 void ChunkTest::tearDown() {
37 void ChunkTest::testBounds() {
38 CPPUNIT_ASSERT_MESSAGE(
39 "valid position out of bounds",
40 Chunk::InBounds(RoughLocation::Fine(0, 0, 0))
42 CPPUNIT_ASSERT_MESSAGE(
43 "valid position out of bounds",
44 Chunk::InBounds(RoughLocation::Fine(15, 0, 0))
46 CPPUNIT_ASSERT_MESSAGE(
47 "valid position out of bounds",
48 Chunk::InBounds(RoughLocation::Fine(0, 15, 0))
50 CPPUNIT_ASSERT_MESSAGE(
51 "valid position out of bounds",
52 Chunk::InBounds(RoughLocation::Fine(0, 0, 15))
54 CPPUNIT_ASSERT_MESSAGE(
55 "valid position out of bounds",
56 Chunk::InBounds(RoughLocation::Fine(15, 15, 15))
58 CPPUNIT_ASSERT_MESSAGE(
59 "invalid position in bounds",
60 !Chunk::InBounds(RoughLocation::Fine(-1, -1, -1))
62 CPPUNIT_ASSERT_MESSAGE(
63 "invalid position in bounds",
64 !Chunk::InBounds(RoughLocation::Fine(-1, 1, 0))
66 CPPUNIT_ASSERT_MESSAGE(
67 "invalid position in bounds",
68 !Chunk::InBounds(RoughLocation::Fine(16, -16, 0))
70 CPPUNIT_ASSERT_MESSAGE(
71 "invalid position in bounds",
72 !Chunk::InBounds(RoughLocation::Fine(16, 16, 16))
76 void ChunkTest::testBorder() {
77 CPPUNIT_ASSERT_MESSAGE(
78 "position not border",
79 Chunk::IsBorder(RoughLocation::Fine(0, 0, 0))
81 CPPUNIT_ASSERT_MESSAGE(
82 "position not border",
83 Chunk::IsBorder(RoughLocation::Fine(0, 0, 8))
85 CPPUNIT_ASSERT_MESSAGE(
86 "position not border",
87 Chunk::IsBorder(RoughLocation::Fine(0, 0, 15))
89 CPPUNIT_ASSERT_MESSAGE(
90 "position not border",
91 Chunk::IsBorder(RoughLocation::Fine(0, 8, 0))
93 CPPUNIT_ASSERT_MESSAGE(
94 "position not border",
95 Chunk::IsBorder(RoughLocation::Fine(0, 8, 8))
97 CPPUNIT_ASSERT_MESSAGE(
98 "position not border",
99 Chunk::IsBorder(RoughLocation::Fine(0, 8, 15))
101 CPPUNIT_ASSERT_MESSAGE(
102 "position not border",
103 Chunk::IsBorder(RoughLocation::Fine(0, 15, 0))
105 CPPUNIT_ASSERT_MESSAGE(
106 "position not border",
107 Chunk::IsBorder(RoughLocation::Fine(0, 15, 8))
109 CPPUNIT_ASSERT_MESSAGE(
110 "position not border",
111 Chunk::IsBorder(RoughLocation::Fine(0, 15, 15))
113 CPPUNIT_ASSERT_MESSAGE(
114 "position not border",
115 Chunk::IsBorder(RoughLocation::Fine(8, 0, 0))
117 CPPUNIT_ASSERT_MESSAGE(
118 "position not border",
119 Chunk::IsBorder(RoughLocation::Fine(8, 0, 8))
121 CPPUNIT_ASSERT_MESSAGE(
122 "position not border",
123 Chunk::IsBorder(RoughLocation::Fine(8, 0, 15))
125 CPPUNIT_ASSERT_MESSAGE(
126 "position not border",
127 Chunk::IsBorder(RoughLocation::Fine(8, 8, 0))
129 CPPUNIT_ASSERT_MESSAGE(
130 "position is border",
131 !Chunk::IsBorder(RoughLocation::Fine(8, 8, 8))
133 CPPUNIT_ASSERT_MESSAGE(
134 "position not border",
135 Chunk::IsBorder(RoughLocation::Fine(8, 8, 15))
137 CPPUNIT_ASSERT_MESSAGE(
138 "position not border",
139 Chunk::IsBorder(RoughLocation::Fine(8, 15, 0))
141 CPPUNIT_ASSERT_MESSAGE(
142 "position not border",
143 Chunk::IsBorder(RoughLocation::Fine(8, 15, 8))
145 CPPUNIT_ASSERT_MESSAGE(
146 "position not border",
147 Chunk::IsBorder(RoughLocation::Fine(8, 15, 15))
149 CPPUNIT_ASSERT_MESSAGE(
150 "position not border",
151 Chunk::IsBorder(RoughLocation::Fine(15, 0, 0))
153 CPPUNIT_ASSERT_MESSAGE(
154 "position not border",
155 Chunk::IsBorder(RoughLocation::Fine(15, 0, 8))
157 CPPUNIT_ASSERT_MESSAGE(
158 "position not border",
159 Chunk::IsBorder(RoughLocation::Fine(15, 0, 15))
161 CPPUNIT_ASSERT_MESSAGE(
162 "position not border",
163 Chunk::IsBorder(RoughLocation::Fine(15, 8, 0))
165 CPPUNIT_ASSERT_MESSAGE(
166 "position not border",
167 Chunk::IsBorder(RoughLocation::Fine(15, 8, 8))
169 CPPUNIT_ASSERT_MESSAGE(
170 "position not border",
171 Chunk::IsBorder(RoughLocation::Fine(15, 8, 15))
173 CPPUNIT_ASSERT_MESSAGE(
174 "position not border",
175 Chunk::IsBorder(RoughLocation::Fine(15, 15, 0))
177 CPPUNIT_ASSERT_MESSAGE(
178 "position not border",
179 Chunk::IsBorder(RoughLocation::Fine(15, 15, 8))
181 CPPUNIT_ASSERT_MESSAGE(
182 "position not border",
183 Chunk::IsBorder(RoughLocation::Fine(15, 15, 15))
186 CPPUNIT_ASSERT_MESSAGE(
187 "position not border",
188 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 0, 0)))
190 CPPUNIT_ASSERT_MESSAGE(
191 "position not border",
192 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 0, 8)))
194 CPPUNIT_ASSERT_MESSAGE(
195 "position not border",
196 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 0, 15)))
198 CPPUNIT_ASSERT_MESSAGE(
199 "position not border",
200 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 8, 0)))
202 CPPUNIT_ASSERT_MESSAGE(
203 "position not border",
204 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 8, 8)))
206 CPPUNIT_ASSERT_MESSAGE(
207 "position not border",
208 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 8, 15)))
210 CPPUNIT_ASSERT_MESSAGE(
211 "position not border",
212 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 15, 0)))
214 CPPUNIT_ASSERT_MESSAGE(
215 "position not border",
216 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 15, 8)))
218 CPPUNIT_ASSERT_MESSAGE(
219 "position not border",
220 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(0, 15, 15)))
222 CPPUNIT_ASSERT_MESSAGE(
223 "position not border",
224 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 0, 0)))
226 CPPUNIT_ASSERT_MESSAGE(
227 "position not border",
228 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 0, 8)))
230 CPPUNIT_ASSERT_MESSAGE(
231 "position not border",
232 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 0, 15)))
234 CPPUNIT_ASSERT_MESSAGE(
235 "position not border",
236 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 8, 0)))
238 CPPUNIT_ASSERT_MESSAGE(
239 "position is border",
240 !Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 8, 8)))
242 CPPUNIT_ASSERT_MESSAGE(
243 "position not border",
244 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 8, 15)))
246 CPPUNIT_ASSERT_MESSAGE(
247 "position not border",
248 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 15, 0)))
250 CPPUNIT_ASSERT_MESSAGE(
251 "position not border",
252 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 15, 8)))
254 CPPUNIT_ASSERT_MESSAGE(
255 "position not border",
256 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(8, 15, 15)))
258 CPPUNIT_ASSERT_MESSAGE(
259 "position not border",
260 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 0, 0)))
262 CPPUNIT_ASSERT_MESSAGE(
263 "position not border",
264 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 0, 8)))
266 CPPUNIT_ASSERT_MESSAGE(
267 "position not border",
268 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 0, 15)))
270 CPPUNIT_ASSERT_MESSAGE(
271 "position not border",
272 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 8, 0)))
274 CPPUNIT_ASSERT_MESSAGE(
275 "position not border",
276 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 8, 8)))
278 CPPUNIT_ASSERT_MESSAGE(
279 "position not border",
280 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 8, 15)))
282 CPPUNIT_ASSERT_MESSAGE(
283 "position not border",
284 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 15, 0)))
286 CPPUNIT_ASSERT_MESSAGE(
287 "position not border",
288 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 15, 8)))
290 CPPUNIT_ASSERT_MESSAGE(
291 "position not border",
292 Chunk::IsBorder(Chunk::ToIndex(RoughLocation::Fine(15, 15, 15)))
296 void ChunkTest::testNeighbor() {
297 unique_ptr<Chunk> chunk(new Chunk(types));
298 chunk->Position({0, 0, 0});
299 for (int i = 0; i < Block::FACE_COUNT; ++i) {
300 CPPUNIT_ASSERT_MESSAGE(
301 "sole chunk has neighbor",
302 !chunk->HasNeighbor(Block::Face(i))
306 unique_ptr<Chunk> neighbor(new Chunk(types));
307 for (int i = 0; i < Block::FACE_COUNT; ++i) {
308 Block::Face face = Block::Face(i);
309 neighbor->Position(Block::FaceNormal(face));
310 chunk->SetNeighbor(face, *neighbor);
311 CPPUNIT_ASSERT_MESSAGE(
312 "chunk did not link right neighbor",
313 chunk->HasNeighbor(face)
315 CPPUNIT_ASSERT_MESSAGE(
316 "chunk did not link right neighbor",
317 neighbor->HasNeighbor(Block::Opposite(face))
319 CPPUNIT_ASSERT_EQUAL_MESSAGE(
320 "chunk did not link correct neighbor",
321 &*neighbor, &chunk->GetNeighbor(face)
323 CPPUNIT_ASSERT_EQUAL_MESSAGE(
324 "chunk did not link correct neighbor",
325 &*chunk, &neighbor->GetNeighbor(Block::Opposite(face))
332 void ChunkTest::testBlock() {
333 unique_ptr<Chunk> chunk(new Chunk(types));
335 for (int index = 0; index < Chunk::size; ++index) {
336 CPPUNIT_ASSERT_EQUAL_MESSAGE(
337 "default chunk has non-default block",
338 Block(), chunk->BlockAt(index)
342 Block block(1, Block::FACE_LEFT, Block::TURN_RIGHT);
343 chunk->SetBlock(0, block);
344 CPPUNIT_ASSERT_EQUAL_MESSAGE(
345 "wrong type on set block",
346 block.type, chunk->BlockAt(0).type
348 CPPUNIT_ASSERT_EQUAL_MESSAGE(
349 "wrong orientation on set block",
350 block.orient, chunk->BlockAt(0).orient
352 for (int index = 1; index < Chunk::size; ++index) {
353 CPPUNIT_ASSERT_EQUAL_MESSAGE(
354 "changing block at index 0 affected some other block",
355 Block(), chunk->BlockAt(index)
360 void ChunkTest::testLight() {
361 unique_ptr<Chunk> chunk(new Chunk(types));
363 for (int index = 0; index < Chunk::size; ++index) {
364 CPPUNIT_ASSERT_EQUAL_MESSAGE(
365 "default chunk has non-zero light level",
366 0, chunk->GetLight(index)
370 chunk->SetLight(0, 15);
371 CPPUNIT_ASSERT_EQUAL_MESSAGE(
372 "wrong light level on set index",
373 15, chunk->GetLight(0)
375 for (int index = 1; index < Chunk::size; ++index) {
376 CPPUNIT_ASSERT_EQUAL_MESSAGE(
377 "changing light at index 0 affected some other index",
378 0, chunk->GetLight(index)
383 void ChunkTest::testLightPropagation() {
384 unique_ptr<Chunk> chunk(new Chunk(types));
385 // this is required to make the chunk do lighting propagation at all
388 // 0 air, 1 solid, 2 solid and emits light level of 5
389 chunk->SetBlock(RoughLocation::Fine(7, 7, 7), Block(2));
390 CPPUNIT_ASSERT_EQUAL_MESSAGE(
391 "adding luminant block did not set correct light level",
392 5, chunk->GetLight(RoughLocation::Fine(7, 7, 7))
395 CPPUNIT_ASSERT_EQUAL_MESSAGE(
396 "light did not propagate correctly in +X",
397 4, chunk->GetLight(RoughLocation::Fine(8, 7, 7))
399 CPPUNIT_ASSERT_EQUAL_MESSAGE(
400 "light did not propagate correctly in -X",
401 4, chunk->GetLight(RoughLocation::Fine(6, 7, 7))
403 CPPUNIT_ASSERT_EQUAL_MESSAGE(
404 "light did not propagate correctly in +Y",
405 4, chunk->GetLight(RoughLocation::Fine(7, 8, 7))
407 CPPUNIT_ASSERT_EQUAL_MESSAGE(
408 "light did not propagate correctly in -Y",
409 4, chunk->GetLight(RoughLocation::Fine(7, 6, 7))
411 CPPUNIT_ASSERT_EQUAL_MESSAGE(
412 "light did not propagate correctly in +Z",
413 4, chunk->GetLight(RoughLocation::Fine(7, 7, 8))
415 CPPUNIT_ASSERT_EQUAL_MESSAGE(
416 "light did not propagate correctly in -Z",
417 4, chunk->GetLight(RoughLocation::Fine(7, 7, 6))
420 CPPUNIT_ASSERT_EQUAL_MESSAGE(
421 "light did not propagate correctly in 2D diagonal",
422 3, chunk->GetLight(RoughLocation::Fine(8, 8, 7))
424 CPPUNIT_ASSERT_EQUAL_MESSAGE(
425 "light did not propagate correctly in 2D diagonal",
426 3, chunk->GetLight(RoughLocation::Fine(7, 6, 8))
428 CPPUNIT_ASSERT_EQUAL_MESSAGE(
429 "light did not propagate correctly in 2D diagonal",
430 3, chunk->GetLight(RoughLocation::Fine(6, 7, 8))
433 CPPUNIT_ASSERT_EQUAL_MESSAGE(
434 "light did not propagate correctly in 3D diagonal",
435 2, chunk->GetLight(RoughLocation::Fine(8, 6, 6))
437 CPPUNIT_ASSERT_EQUAL_MESSAGE(
438 "light did not propagate correctly in 3D diagonal",
439 2, chunk->GetLight(RoughLocation::Fine(6, 6, 8))
441 CPPUNIT_ASSERT_EQUAL_MESSAGE(
442 "light did not propagate correctly in 3D diagonal",
443 2, chunk->GetLight(RoughLocation::Fine(6, 8, 8))
446 // now block the light to the left
447 chunk->SetBlock(RoughLocation::Fine(6, 7, 7), Block(1));
448 CPPUNIT_ASSERT_EQUAL_MESSAGE(
449 "adding obstacle affected unrelated index",
450 5, chunk->GetLight(RoughLocation::Fine(7, 7, 7))
452 CPPUNIT_ASSERT_EQUAL_MESSAGE(
453 "adding obstacle affected unrelated index",
454 4, chunk->GetLight(RoughLocation::Fine(8, 7, 7))
456 CPPUNIT_ASSERT_EQUAL_MESSAGE(
457 "adding obstacle affected unrelated index",
458 4, chunk->GetLight(RoughLocation::Fine(7, 8, 7))
460 CPPUNIT_ASSERT_EQUAL_MESSAGE(
461 "adding obstacle affected unrelated index",
462 4, chunk->GetLight(RoughLocation::Fine(7, 6, 7))
464 CPPUNIT_ASSERT_EQUAL_MESSAGE(
465 "adding obstacle affected unrelated index",
466 4, chunk->GetLight(RoughLocation::Fine(7, 7, 8))
468 CPPUNIT_ASSERT_EQUAL_MESSAGE(
469 "adding obstacle affected unrelated index",
470 4, chunk->GetLight(RoughLocation::Fine(7, 7, 6))
472 CPPUNIT_ASSERT_EQUAL_MESSAGE(
473 "adding obstacle affected unrelated index",
474 3, chunk->GetLight(RoughLocation::Fine(6, 6, 7))
476 CPPUNIT_ASSERT_EQUAL_MESSAGE(
477 "adding obstacle affected unrelated index",
478 3, chunk->GetLight(RoughLocation::Fine(6, 8, 7))
480 CPPUNIT_ASSERT_EQUAL_MESSAGE(
481 "adding obstacle affected unrelated index",
482 3, chunk->GetLight(RoughLocation::Fine(6, 7, 6))
484 CPPUNIT_ASSERT_EQUAL_MESSAGE(
485 "adding obstacle affected unrelated index",
486 3, chunk->GetLight(RoughLocation::Fine(6, 7, 6))
488 CPPUNIT_ASSERT_EQUAL_MESSAGE(
489 "adding obstacle affected unrelated index",
490 2, chunk->GetLight(RoughLocation::Fine(5, 6, 7))
492 CPPUNIT_ASSERT_EQUAL_MESSAGE(
493 "adding obstacle affected unrelated index",
494 2, chunk->GetLight(RoughLocation::Fine(5, 8, 7))
496 CPPUNIT_ASSERT_EQUAL_MESSAGE(
497 "adding obstacle affected unrelated index",
498 2, chunk->GetLight(RoughLocation::Fine(5, 7, 6))
500 CPPUNIT_ASSERT_EQUAL_MESSAGE(
501 "adding obstacle affected unrelated index",
502 2, chunk->GetLight(RoughLocation::Fine(5, 7, 6))
504 CPPUNIT_ASSERT_EQUAL_MESSAGE(
505 "adding obstacle resulted in unexpected light level behind it",
506 1, chunk->GetLight(RoughLocation::Fine(5, 7, 7))
509 // and remove it again
510 chunk->SetBlock(RoughLocation::Fine(6, 7, 7), Block(0));
511 CPPUNIT_ASSERT_EQUAL_MESSAGE(
512 "removing obstacle did not refill light correctly",
513 4, chunk->GetLight(RoughLocation::Fine(6, 7, 7))
515 CPPUNIT_ASSERT_EQUAL_MESSAGE(
516 "removing obstacle did not refill light correctly",
517 3, chunk->GetLight(RoughLocation::Fine(5, 7, 7))
519 CPPUNIT_ASSERT_EQUAL_MESSAGE(
520 "removing obstacle did not refill light correctly",
521 2, chunk->GetLight(RoughLocation::Fine(4, 7, 7))