forked from Vogtinator/crafti
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tntrenderer.cpp
66 lines (54 loc) · 2.5 KB
/
tntrenderer.cpp
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
#include <cstdlib>
#include "world.h"
#include "tntrenderer.h"
void TNTRenderer::tick(const BLOCK_WDATA /*block*/, int local_x, int local_y, int local_z, Chunk &c)
{
if(c.isBlockPowered(local_x, local_y, local_z))
explode(local_x, local_y, local_z, c);
}
void TNTRenderer::explode(const int local_x, const int local_y, const int local_z, Chunk &c)
{
c.setGlobalBlockRelative(local_x, local_y, local_z, BLOCK_AIR);
Particle p;
p.size = 14;
p.tae = terrain_atlas[1][1].current;
// Use the center quarter of the texture
const int tex_width = p.tae.right - p.tae.left,
tex_height = p.tae.bottom - p.tae.top;
p.tae.left += tex_width / 4;
p.tae.right -= tex_width / 4;
p.tae.top += tex_height / 4;
p.tae.bottom -= tex_height / 4;
// Random value between 0 and max (not including max)
const auto randMax = [](GLFix max) { return max * (rand() & 0xFF) / 0xFF; };
// Get the center of the block contents (chunk relative coordinates)
const auto aabb = global_block_renderer.getAABB(getBLOCK(c.getGlobalBlockRelative(local_x, local_y, local_z)), local_x * BLOCK_SIZE, local_y * BLOCK_SIZE, local_z * BLOCK_SIZE);
auto center = VECTOR3{(aabb.low_x + aabb.high_x) / 2, (aabb.low_y + aabb.high_y) / 2, (aabb.low_z + aabb.high_z) / 2};
// Spawn four particles at the center with random velocity and offset
for(int i = 0; i < 4; ++i)
{
p.vel = {randMax(10) - 5, randMax(5), randMax(10) - 5};
p.pos = center;
p.pos.x += randMax(100) - 50;
p.pos.y += randMax(100) - 50;
p.pos.z += randMax(100) - 50;
c.addParticle(p);
}
// Destroy everything in a sphere with a 3 block radius
const int dist = 3;
for(int x = -dist; x <= dist; ++x)
for(int y = -dist; y <= dist; ++y)
for(int z = -dist; z <= dist; ++z)
{
if(local_y + y + Chunk::SIZE * c.y < 1 || local_y + y + Chunk::SIZE * c.y >= World::HEIGHT*Chunk::SIZE)
continue;
if(x*x + y*y + z*z > dist*dist)
continue;
//Explode other TNT blocks
auto block = getBLOCK(c.getGlobalBlockRelative(local_x + x, local_y + y, local_z + z));
if(block == BLOCK_TNT)
explode(local_x + x, local_y + y, local_z + z, c);
else if(block != BLOCK_BEDROCK && block != BLOCK_AIR)
c.changeGlobalBlockRelative(local_x + x, local_y + y, local_z + z, BLOCK_AIR);
}
}