Cuberite
A lightweight, fast and extensible game server for Minecraft
Explodinator.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h"
3 #include "BlockInfo.h"
4 #include "Explodinator.h"
5 #include "Blocks/BlockHandler.h"
7 #include "Chunk.h"
8 #include "ClientHandle.h"
10 #include "LineBlockTracer.h"
12 
13 
14 
15 
16 
17 namespace Explodinator
18 {
19  static const auto StepUnit = 0.3f;
20  static const auto KnockbackFactor = 25U;
21  static const auto StepAttenuation = 0.225f;
22  static const auto TraceCubeSideLength = 16U;
23  static const auto BoundingBoxStepUnit = 0.5;
24 
26  static Vector3f AbsoluteToRelative(const Vector3f a_Position, const cChunkCoords a_ChunkPosition)
27  {
28  return { a_Position.x - a_ChunkPosition.m_ChunkX * cChunkDef::Width, a_Position.y, a_Position.z - a_ChunkPosition.m_ChunkZ * cChunkDef::Width };
29  }
30 
32  static Vector3f RebaseRelativePosition(const cChunkCoords a_From, const cChunkCoords a_To, const Vector3f a_Position)
33  {
34  return
35  {
36  a_Position.x + (a_From.m_ChunkX - a_To.m_ChunkX) * cChunkDef::Width,
37  a_Position.y,
38  a_Position.z + (a_From.m_ChunkZ - a_To.m_ChunkZ) * cChunkDef::Width
39  };
40  }
41 
46  {
47  switch (Block)
48  {
49  case E_BLOCK_BEDROCK:
52  case E_BLOCK_END_PORTAL:
53  case E_BLOCK_END_PORTAL_FRAME: return 1080000.09f;
54  case E_BLOCK_ANVIL:
56  case E_BLOCK_OBSIDIAN: return 360.09f;
57  case E_BLOCK_ENDER_CHEST: return 180.09f;
58  case E_BLOCK_LAVA:
60  case E_BLOCK_WATER:
61  case E_BLOCK_STATIONARY_WATER: return 30.09f;
62  case E_BLOCK_DRAGON_EGG:
63  case E_BLOCK_END_STONE:
64  case E_BLOCK_END_BRICKS: return 2.79f;
65  case E_BLOCK_STONE:
69  case E_BLOCK_GOLD_BLOCK:
70  case E_BLOCK_IRON_BLOCK:
72  case E_BLOCK_BRICK:
76  case E_BLOCK_IRON_BARS:
77  case E_BLOCK_JUKEBOX:
85  case E_BLOCK_COBBLESTONE_WALL: return 1.89f;
86  case E_BLOCK_IRON_DOOR:
88  case E_BLOCK_MOB_SPAWNER: return 1.59f;
89  case E_BLOCK_HOPPER: return 1.53f;
90  case E_BLOCK_TERRACOTTA: return 1.35f;
91  case E_BLOCK_COBWEB: return 1.29f;
92  case E_BLOCK_DISPENSER:
93  case E_BLOCK_DROPPER:
94  case E_BLOCK_FURNACE:
95  case E_BLOCK_OBSERVER: return 1.14f;
96  case E_BLOCK_BEACON:
97  case E_BLOCK_COAL_ORE:
98  case E_BLOCK_COCOA_POD:
100  case E_BLOCK_EMERALD_ORE:
101  case E_BLOCK_GOLD_ORE:
102  case E_BLOCK_IRON_ORE:
103  case E_BLOCK_LAPIS_BLOCK:
104  case E_BLOCK_LAPIS_ORE:
106  case E_BLOCK_PLANKS:
108  case E_BLOCK_FENCE:
109  case E_BLOCK_FENCE_GATE:
110  case E_BLOCK_WOODEN_DOOR:
111  case E_BLOCK_WOODEN_SLAB:
113  case E_BLOCK_TRAPDOOR: return 0.99f;
114  case E_BLOCK_CHEST:
115  case E_BLOCK_WORKBENCH:
116  case E_BLOCK_TRAPPED_CHEST: return 0.84f;
117  case E_BLOCK_BONE_BLOCK:
118  case E_BLOCK_CAULDRON:
119  case E_BLOCK_LOG: return 0.69f; // nIcE
120  case E_BLOCK_CONCRETE: return 0.63f;
121  case E_BLOCK_BOOKCASE: return 0.54f;
123  case E_BLOCK_WALL_BANNER:
125  case E_BLOCK_MELON:
126  case E_BLOCK_HEAD:
128  case E_BLOCK_PUMPKIN:
129  case E_BLOCK_SIGN_POST:
130  case E_BLOCK_WALLSIGN: return 0.39f;
135  case E_BLOCK_SANDSTONE:
137  case E_BLOCK_WOOL: return 0.33f;
138  case E_BLOCK_SILVERFISH_EGG: return 0.315f;
142  case E_BLOCK_RAIL: return 0.3f;
143  case E_BLOCK_GRASS_PATH:
144  case E_BLOCK_CLAY:
145  case E_BLOCK_FARMLAND:
146  case E_BLOCK_GRASS:
147  case E_BLOCK_GRAVEL:
148  case E_BLOCK_SPONGE: return 0.27f;
152  case E_BLOCK_CAKE:
154  case E_BLOCK_DIRT:
155  case E_BLOCK_FROSTED_ICE:
156  case E_BLOCK_HAY_BALE:
157  case E_BLOCK_ICE: return 0.24f;
158  default: return 0.09f;
159  }
160  }
161 
163  static float CalculateEntityExposure(const cChunk & a_Chunk, const cEntity & a_Entity, const Vector3f a_Position, const int a_SquareRadius)
164  {
165  class LineOfSightCallbacks final : public cLineBlockTracer::cCallbacks
166  {
167  virtual bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
168  {
169  return a_BlockType != E_BLOCK_AIR;
170  }
171  } Callback;
172 
173  const Vector3d Position = a_Position;
174  unsigned Unobstructed = 0, Total = 0;
175  const auto Box = a_Entity.GetBoundingBox();
176  cLineBlockTracer Tracer(*a_Chunk.GetWorld(), Callback);
177 
178  for (double X = Box.GetMinX(); X < Box.GetMaxX(); X += BoundingBoxStepUnit)
179  {
180  for (double Y = Box.GetMinY(); Y < Box.GetMaxY(); Y += BoundingBoxStepUnit)
181  {
182  for (double Z = Box.GetMinZ(); Z < Box.GetMaxZ(); Z += BoundingBoxStepUnit)
183  {
184  const Vector3d Destination{X, Y, Z};
185  if ((Destination - Position).SqrLength() > a_SquareRadius)
186  {
187  // Don't bother with points outside our designated area-of-effect
188  // This is, surprisingly, a massive amount of work saved (~3m to detonate a sphere of 37k TNT before, ~1m after):
189  continue;
190  }
191 
192  if (Tracer.Trace(a_Position, Destination))
193  {
194  Unobstructed++;
195  }
196  Total++;
197  }
198  }
199  }
200 
201  return (Total == 0) ? 0 : (static_cast<float>(Unobstructed) / Total);
202  }
203 
205  static void DamageEntities(const cChunk & a_Chunk, const Vector3f a_Position, const int a_Power)
206  {
207  const auto Radius = a_Power * 2;
208  const auto SquareRadius = Radius * Radius;
209 
210  a_Chunk.GetWorld()->ForEachEntityInBox({ a_Position, Radius * 2.f }, [&a_Chunk, a_Position, a_Power, Radius, SquareRadius](cEntity & Entity)
211  {
212  // Percentage of rays unobstructed.
213  const auto Exposure = CalculateEntityExposure(a_Chunk, Entity, a_Position, SquareRadius);
214  const auto Direction = Entity.GetPosition() - a_Position;
215  const auto Impact = (1 - (static_cast<float>(Direction.Length()) / Radius)) * Exposure;
216 
217  // Don't apply damage to other TNT entities and falling blocks, they should be invincible:
218  if (!Entity.IsTNT() && !Entity.IsFallingBlock())
219  {
220  const auto Damage = (Impact * Impact + Impact) * 7 * a_Power + 1;
221  Entity.TakeDamage(dtExplosion, nullptr, FloorC(Damage), 0);
222  }
223 
224  // Impact reduced by armour, expensive call so only apply to Pawns:
225  if (Entity.IsPawn())
226  {
227  const auto ReducedImpact = Impact - Impact * Entity.GetEnchantmentBlastKnockbackReduction();
228  Entity.AddSpeed(Direction.NormalizeCopy() * KnockbackFactor * ReducedImpact);
229  }
230  else
231  {
232  Entity.AddSpeed(Direction.NormalizeCopy() * KnockbackFactor * Impact);
233  }
234 
235  // Continue iteration:
236  return false;
237  });
238  }
239 
242  static bool BlockAlwaysDrops(const BLOCKTYPE a_Block)
243  {
244  if (IsBlockShulkerBox(a_Block))
245  {
246  return true;
247  }
248 
249  switch (a_Block)
250  {
251  case E_BLOCK_DRAGON_EGG:
252  case E_BLOCK_BEACON:
253  case E_BLOCK_HEAD: return true;
254  }
255 
256  return false;
257  }
258 
260  static void SetBlock(cWorld & a_World, cChunk & a_Chunk, const Vector3i a_AbsolutePosition, const Vector3i a_RelativePosition, const BLOCKTYPE a_DestroyedBlock, const BLOCKTYPE a_NewBlock, const cEntity * const a_ExplodingEntity)
261  {
262  const auto DestroyedMeta = a_Chunk.GetMeta(a_RelativePosition);
263 
264  // SetBlock wakes up all simulators for the area, so that water and lava flows and sand falls into the blasted holes
265  // It also is responsible for calling cBlockHandler::OnNeighborChanged to pop off blocks that fail CanBeAt
266  // An explicit call to cBlockHandler::OnBroken handles the destruction of multiblock structures
267  // References at (FS #391, GH #4418):
268  a_Chunk.SetBlock(a_RelativePosition, a_NewBlock, 0);
269 
270  cChunkInterface Interface(a_World.GetChunkMap());
271  cBlockHandler::For(a_DestroyedBlock).OnBroken(Interface, a_World, a_AbsolutePosition, a_DestroyedBlock, DestroyedMeta, a_ExplodingEntity);
272  }
273 
277  static void DestroyBlock(cChunk & a_Chunk, const Vector3i a_Position, const int a_Power, const bool a_Fiery, const cEntity * const a_ExplodingEntity)
278  {
279  const auto DestroyedBlock = a_Chunk.GetBlock(a_Position);
280  if (DestroyedBlock == E_BLOCK_AIR)
281  {
282  // There's nothing left for us here, but a barren and empty land
283  // Let's go.
284  return;
285  }
286 
287  auto & World = *a_Chunk.GetWorld();
288  auto & Random = GetRandomProvider();
289  const auto Absolute = cChunkDef::RelativeToAbsolute(a_Position, a_Chunk.GetPos());
290 
291  if (DestroyedBlock == E_BLOCK_TNT) // If the block is TNT we should set it off
292  {
293  // Random fuse between 10 to 30 game ticks.
294  const int FuseTime = Random.RandInt(10, 30);
295 
296  // Activate the TNT, with initial velocity and no fuse sound:
297  World.SpawnPrimedTNT(Vector3d(0.5, 0, 0.5) + Absolute, FuseTime, 1, false);
298  }
299  else if ((a_ExplodingEntity != nullptr) && (a_ExplodingEntity->IsTNT() || BlockAlwaysDrops(DestroyedBlock) || Random.RandBool(1.f / a_Power))) // For TNT explosions, destroying a block that always drops, or if RandBool, drop pickups
300  {
301  const auto DestroyedMeta = a_Chunk.GetMeta(a_Position);
302  a_Chunk.GetWorld()->SpawnItemPickups(cBlockHandler::For(DestroyedBlock).ConvertToPickups(DestroyedMeta), Absolute);
303  }
304  else if (a_Fiery && Random.RandBool(1 / 3.0)) // 33% chance of starting fires if it can start fires
305  {
306  const auto Below = a_Position.addedY(-1);
307  if ((Below.y >= 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(Below)))
308  {
309  // Start a fire:
310  SetBlock(World, a_Chunk, Absolute, a_Position, DestroyedBlock, E_BLOCK_FIRE, a_ExplodingEntity);
311  return;
312  }
313  }
314  else if (const auto Shrapnel = World.GetTNTShrapnelLevel(); (Shrapnel > slNone) && Random.RandBool(0)) // Currently 0% chance of flinging stuff around
315  {
316  // If the block is shrapnel-able, make a falling block entity out of it:
317  if (
318  ((Shrapnel == slAll) && cBlockInfo::FullyOccupiesVoxel(DestroyedBlock)) ||
319  ((Shrapnel == slGravityAffectedOnly) && cSandSimulator::IsAllowedBlock(DestroyedBlock))
320  )
321  {
322  const auto DestroyedMeta = a_Chunk.GetMeta(a_Position);
323  auto FallingBlock = std::make_unique<cFallingBlock>(Vector3d(0.5, 0, 0.5) + Absolute, DestroyedBlock, DestroyedMeta);
324  // TODO: correct velocity FallingBlock->SetSpeedY(40);
325  FallingBlock->Initialize(std::move(FallingBlock), World);
326  }
327  }
328 
329  SetBlock(World, a_Chunk, Absolute, a_Position, DestroyedBlock, E_BLOCK_AIR, a_ExplodingEntity);
330  }
331 
333  static void DestructionTrace(cChunk * a_Chunk, Vector3f a_Origin, const Vector3f a_Direction, const int a_Power, const bool a_Fiery, float a_Intensity, const cEntity * const a_ExplodingEntity)
334  {
335  // The current position the ray is at.
336  auto Checkpoint = a_Origin;
337 
338  // The displacement that the ray in one iteration step should travel.
339  const auto Step = a_Direction.NormalizeCopy() * StepUnit;
340 
341  // Loop until intensity runs out:
342  while (a_Intensity > 0)
343  {
344  auto Position = Checkpoint.Floor();
345  if (!cChunkDef::IsValidHeight(Position))
346  {
347  break;
348  }
349 
350  const auto Neighbour = a_Chunk->GetRelNeighborChunkAdjustCoords(Position);
351  if ((Neighbour == nullptr) || !Neighbour->IsValid())
352  {
353  break;
354  }
355 
356  a_Intensity -= GetExplosionAbsorption(Neighbour->GetBlock(Position));
357  if (a_Intensity <= 0)
358  {
359  // The ray is exhausted:
360  break;
361  }
362 
363  DestroyBlock(*Neighbour, Position, a_Power, a_Fiery, a_ExplodingEntity);
364 
365  // Adjust coordinates to be relative to the neighbour chunk:
366  Checkpoint = RebaseRelativePosition(a_Chunk->GetPos(), Neighbour->GetPos(), Checkpoint);
367  a_Origin = RebaseRelativePosition(a_Chunk->GetPos(), Neighbour->GetPos(), a_Origin);
368  a_Chunk = Neighbour;
369 
370  // Increment the simulation, weaken the ray:
371  Checkpoint += Step;
372  a_Intensity -= StepAttenuation;
373  }
374  }
375 
377  static float RandomIntensity(MTRand & a_Random, const int a_Power)
378  {
379  return a_Power * (0.7f + a_Random.RandReal(0.6f));
380  }
381 
383  static void DamageBlocks(cChunk & a_Chunk, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity * const a_ExplodingEntity)
384  {
385  // Oh boy... Better hope you have a hot cache, 'cos this little manoeuvre's gonna cost us 1352 raytraces in one tick...
386  const int HalfSide = TraceCubeSideLength / 2;
387  auto & Random = GetRandomProvider();
388 
389  // The following loops implement the tracing algorithm described in http://minecraft.wiki/w/Explosion
390 
391  // Trace rays from the explosion centre to all points in a square of area TraceCubeSideLength * TraceCubeSideLength
392  // for the top and bottom sides:
393  for (float OffsetX = -HalfSide; OffsetX < HalfSide; OffsetX++)
394  {
395  for (float OffsetZ = -HalfSide; OffsetZ < HalfSide; OffsetZ++)
396  {
397  DestructionTrace(&a_Chunk, a_Position, Vector3f(OffsetX, +HalfSide, OffsetZ), a_Power, a_Fiery, RandomIntensity(Random, a_Power), a_ExplodingEntity);
398  DestructionTrace(&a_Chunk, a_Position, Vector3f(OffsetX, -HalfSide, OffsetZ), a_Power, a_Fiery, RandomIntensity(Random, a_Power), a_ExplodingEntity);
399  }
400  }
401 
402  // Left and right sides, avoid duplicates at top and bottom edges:
403  for (float OffsetX = -HalfSide; OffsetX < HalfSide; OffsetX++)
404  {
405  for (float OffsetY = -HalfSide + 1; OffsetY < HalfSide - 1; OffsetY++)
406  {
407  DestructionTrace(&a_Chunk, a_Position, Vector3f(OffsetX, OffsetY, +HalfSide), a_Power, a_Fiery, RandomIntensity(Random, a_Power), a_ExplodingEntity);
408  DestructionTrace(&a_Chunk, a_Position, Vector3f(OffsetX, OffsetY, -HalfSide), a_Power, a_Fiery, RandomIntensity(Random, a_Power), a_ExplodingEntity);
409  }
410  }
411 
412  // Front and back sides, avoid all edges:
413  for (float OffsetZ = -HalfSide + 1; OffsetZ < HalfSide - 1; OffsetZ++)
414  {
415  for (float OffsetY = -HalfSide + 1; OffsetY < HalfSide - 1; OffsetY++)
416  {
417  DestructionTrace(&a_Chunk, a_Position, Vector3f(+HalfSide, OffsetY, OffsetZ), a_Power, a_Fiery, RandomIntensity(Random, a_Power), a_ExplodingEntity);
418  DestructionTrace(&a_Chunk, a_Position, Vector3f(-HalfSide, OffsetY, OffsetZ), a_Power, a_Fiery, RandomIntensity(Random, a_Power), a_ExplodingEntity);
419  }
420  }
421  }
422 
424  static void LagTheClient(cChunk & a_Chunk, const Vector3f a_Position, const int a_Power)
425  {
426  for (const auto Client : a_Chunk.GetAllClients())
427  {
428  Client->SendExplosion(a_Position, static_cast<float>(a_Power));
429  }
430  }
431 
432  void Kaboom(cWorld & a_World, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity * const a_ExplodingEntity)
433  {
434  a_World.DoWithChunkAt(a_Position.Floor(), [a_Position, a_Power, a_Fiery, a_ExplodingEntity](cChunk & a_Chunk)
435  {
436  LagTheClient(a_Chunk, a_Position, a_Power);
437  DamageEntities(a_Chunk, a_Position, a_Power);
438  DamageBlocks(a_Chunk, AbsoluteToRelative(a_Position, a_Chunk.GetPos()), a_Power, a_Fiery, a_ExplodingEntity);
439 
440  return false;
441  });
442  }
443 }
bool IsBlockShulkerBox(BLOCKTYPE a_BlockType)
Definition: BlockInfo.cpp:137
@ E_BLOCK_WOODEN_BUTTON
Definition: BlockType.h:158
@ E_BLOCK_NETHER_BRICK_STAIRS
Definition: BlockType.h:129
@ E_BLOCK_SPONGE
Definition: BlockType.h:29
@ E_BLOCK_WOODEN_STAIRS
Definition: BlockType.h:287
@ E_BLOCK_HEAD
Definition: BlockType.h:159
@ E_BLOCK_STANDING_BANNER
Definition: BlockType.h:195
@ E_BLOCK_CLAY
Definition: BlockType.h:96
@ E_BLOCK_COCOA_POD
Definition: BlockType.h:142
@ E_BLOCK_BREWING_STAND
Definition: BlockType.h:132
@ E_BLOCK_JACK_O_LANTERN
Definition: BlockType.h:106
@ E_BLOCK_JUKEBOX
Definition: BlockType.h:99
@ E_BLOCK_BONE_BLOCK
Definition: BlockType.h:235
@ E_BLOCK_DRAGON_EGG
Definition: BlockType.h:137
@ E_BLOCK_COBBLESTONE_STAIRS
Definition: BlockType.h:81
@ E_BLOCK_DIAMOND_BLOCK
Definition: BlockType.h:67
@ E_BLOCK_WATER
Definition: BlockType.h:18
@ E_BLOCK_TRAPDOOR
Definition: BlockType.h:111
@ E_BLOCK_GRASS_PATH
Definition: BlockType.h:227
@ E_BLOCK_ACTIVATOR_RAIL
Definition: BlockType.h:174
@ E_BLOCK_STATIONARY_LAVA
Definition: BlockType.h:21
@ E_BLOCK_REDSTONE_ORE
Definition: BlockType.h:87
@ E_BLOCK_COAL_ORE
Definition: BlockType.h:26
@ E_BLOCK_FARMLAND
Definition: BlockType.h:72
@ E_BLOCK_DIAMOND_ORE
Definition: BlockType.h:66
@ E_BLOCK_BRICK_STAIRS
Definition: BlockType.h:123
@ E_BLOCK_CAULDRON
Definition: BlockType.h:133
@ E_BLOCK_BRICK
Definition: BlockType.h:55
@ E_BLOCK_STONE_BRICK_STAIRS
Definition: BlockType.h:124
@ E_BLOCK_AIR
Definition: BlockType.h:10
@ E_BLOCK_WOOL
Definition: BlockType.h:45
@ E_BLOCK_ENCHANTMENT_TABLE
Definition: BlockType.h:131
@ E_BLOCK_FURNACE
Definition: BlockType.h:73
@ E_BLOCK_SIGN_POST
Definition: BlockType.h:76
@ E_BLOCK_END_PORTAL_FRAME
Definition: BlockType.h:135
@ E_BLOCK_PRISMARINE_BLOCK
Definition: BlockType.h:187
@ E_BLOCK_GOLD_BLOCK
Definition: BlockType.h:51
@ E_BLOCK_TERRACOTTA
Definition: BlockType.h:178
@ E_BLOCK_BLOCK_OF_REDSTONE
Definition: BlockType.h:168
@ E_BLOCK_STONE_BRICKS
Definition: BlockType.h:113
@ E_BLOCK_MOSSY_COBBLESTONE
Definition: BlockType.h:58
@ E_BLOCK_OBSERVER
Definition: BlockType.h:237
@ E_BLOCK_BEACON
Definition: BlockType.h:153
@ E_BLOCK_FENCE_GATE
Definition: BlockType.h:286
@ E_BLOCK_FIRE
Definition: BlockType.h:61
@ E_BLOCK_TNT
Definition: BlockType.h:56
@ E_BLOCK_LAPIS_ORE
Definition: BlockType.h:31
@ E_BLOCK_IRON_BLOCK
Definition: BlockType.h:52
@ E_BLOCK_NETHER_WART_BLOCK
Definition: BlockType.h:233
@ E_BLOCK_CONCRETE
Definition: BlockType.h:270
@ E_BLOCK_CHEST
Definition: BlockType.h:64
@ E_BLOCK_COBWEB
Definition: BlockType.h:40
@ E_BLOCK_END_BRICKS
Definition: BlockType.h:225
@ E_BLOCK_CAKE
Definition: BlockType.h:107
@ E_BLOCK_BLOCK_OF_COAL
Definition: BlockType.h:192
@ E_BLOCK_LAPIS_BLOCK
Definition: BlockType.h:32
@ E_BLOCK_IRON_DOOR
Definition: BlockType.h:85
@ E_BLOCK_FENCE
Definition: BlockType.h:100
@ E_BLOCK_GRASS
Definition: BlockType.h:12
@ E_BLOCK_WORKBENCH
Definition: BlockType.h:69
@ E_BLOCK_EMERALD_ORE
Definition: BlockType.h:144
@ E_BLOCK_ICE
Definition: BlockType.h:93
@ E_BLOCK_BEDROCK
Definition: BlockType.h:17
@ E_BLOCK_MELON
Definition: BlockType.h:118
@ E_BLOCK_SILVERFISH_EGG
Definition: BlockType.h:112
@ E_BLOCK_POWERED_RAIL
Definition: BlockType.h:37
@ E_BLOCK_OBSIDIAN
Definition: BlockType.h:59
@ E_BLOCK_RED_SANDSTONE_STAIRS
Definition: BlockType.h:199
@ E_BLOCK_BOOKCASE
Definition: BlockType.h:57
@ E_BLOCK_RED_SANDSTONE
Definition: BlockType.h:198
@ E_BLOCK_IRON_ORE
Definition: BlockType.h:25
@ E_BLOCK_TRAPPED_CHEST
Definition: BlockType.h:161
@ E_BLOCK_PLANKS
Definition: BlockType.h:15
@ E_BLOCK_DETECTOR_RAIL
Definition: BlockType.h:38
@ E_BLOCK_WOODEN_DOOR
Definition: BlockType.h:285
@ E_BLOCK_GRAVEL
Definition: BlockType.h:23
@ E_BLOCK_IRON_BARS
Definition: BlockType.h:116
@ E_BLOCK_HAY_BALE
Definition: BlockType.h:189
@ E_BLOCK_CONCRETE_POWDER
Definition: BlockType.h:271
@ E_BLOCK_PUMPKIN
Definition: BlockType.h:101
@ E_BLOCK_ANVIL
Definition: BlockType.h:160
@ E_BLOCK_COMMAND_BLOCK
Definition: BlockType.h:152
@ E_BLOCK_SANDSTONE
Definition: BlockType.h:34
@ E_BLOCK_EMERALD_BLOCK
Definition: BlockType.h:148
@ E_BLOCK_GOLD_ORE
Definition: BlockType.h:24
@ E_BLOCK_STONE
Definition: BlockType.h:11
@ E_BLOCK_END_GATEWAY
Definition: BlockType.h:228
@ E_BLOCK_NETHER_QUARTZ_ORE
Definition: BlockType.h:170
@ E_BLOCK_WOODEN_SLAB
Definition: BlockType.h:141
@ E_BLOCK_DIRT
Definition: BlockType.h:13
@ E_BLOCK_SANDSTONE_STAIRS
Definition: BlockType.h:143
@ E_BLOCK_QUARTZ_BLOCK
Definition: BlockType.h:172
@ E_BLOCK_LOG
Definition: BlockType.h:27
@ E_BLOCK_HOPPER
Definition: BlockType.h:171
@ E_BLOCK_DROPPER
Definition: BlockType.h:176
@ E_BLOCK_ENDER_CHEST
Definition: BlockType.h:145
@ E_BLOCK_END_PORTAL
Definition: BlockType.h:134
@ E_BLOCK_RAIL
Definition: BlockType.h:79
@ E_BLOCK_DISPENSER
Definition: BlockType.h:33
@ E_BLOCK_IRON_TRAPDOOR
Definition: BlockType.h:186
@ E_BLOCK_STONE_BUTTON
Definition: BlockType.h:91
@ E_BLOCK_END_STONE
Definition: BlockType.h:136
@ E_BLOCK_STATIONARY_WATER
Definition: BlockType.h:19
@ E_BLOCK_COBBLESTONE_WALL
Definition: BlockType.h:154
@ E_BLOCK_MOB_SPAWNER
Definition: BlockType.h:62
@ E_BLOCK_NETHER_BRICK_FENCE
Definition: BlockType.h:128
@ E_BLOCK_QUARTZ_STAIRS
Definition: BlockType.h:173
@ E_BLOCK_WALLSIGN
Definition: BlockType.h:82
@ E_BLOCK_LAVA
Definition: BlockType.h:20
@ E_BLOCK_NETHER_BRICK
Definition: BlockType.h:127
@ E_BLOCK_FROSTED_ICE
Definition: BlockType.h:231
@ E_BLOCK_WALL_BANNER
Definition: BlockType.h:196
@ E_BLOCK_COBBLESTONE
Definition: BlockType.h:14
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
@ slNone
Definition: Defines.h:329
@ slGravityAffectedOnly
Definition: Defines.h:330
@ slAll
Definition: Defines.h:331
@ dtExplosion
Definition: Defines.h:264
eBlockFace
Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc.
Definition: Defines.h:38
MTRand & GetRandomProvider()
Returns the current thread's random number source.
Definition: FastRandom.cpp:12
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:347
Direction
Vector3< double > Vector3d
Definition: Vector3.h:485
Vector3< float > Vector3f
Definition: Vector3.h:486
Utilities to allow casting a cWorld to one of its interfaces without including World....
Definition: OpaqueWorld.h:13
static const auto StepAttenuation
static void DestructionTrace(cChunk *a_Chunk, Vector3f a_Origin, const Vector3f a_Direction, const int a_Power, const bool a_Fiery, float a_Intensity, const cEntity *const a_ExplodingEntity)
Traces the path taken by one Explosion Lazor (tm) with given direction and intensity,...
static void DamageEntities(const cChunk &a_Chunk, const Vector3f a_Position, const int a_Power)
Applies distance-based damage and knockback to all entities within the explosion's effect range.
static void SetBlock(cWorld &a_World, cChunk &a_Chunk, const Vector3i a_AbsolutePosition, const Vector3i a_RelativePosition, const BLOCKTYPE a_DestroyedBlock, const BLOCKTYPE a_NewBlock, const cEntity *const a_ExplodingEntity)
Sets the block at the given position, updating surroundings.
static void LagTheClient(cChunk &a_Chunk, const Vector3f a_Position, const int a_Power)
Sends an explosion packet to all clients in the given chunk.
static const auto StepUnit
static const auto KnockbackFactor
static const auto TraceCubeSideLength
static const auto BoundingBoxStepUnit
static Vector3f RebaseRelativePosition(const cChunkCoords a_From, const cChunkCoords a_To, const Vector3f a_Position)
Make a From Chunk-relative Position into a To Chunk-relative position.
static void DamageBlocks(cChunk &a_Chunk, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Sends out Explosion Lazors (tm) originating from the given position that destroy blocks.
void Kaboom(cWorld &a_World, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Creates an explosion of Power, centred at Position, with ability to set fires as provided.
static float GetExplosionAbsorption(const BLOCKTYPE Block)
Returns how much of an explosion Destruction Lazor's (tm) intensity the given block attenuates.
static bool BlockAlwaysDrops(const BLOCKTYPE a_Block)
Returns true if block should always drop when exploded.
static void DestroyBlock(cChunk &a_Chunk, const Vector3i a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Work out what should happen when an explosion destroys the given block.
static Vector3f AbsoluteToRelative(const Vector3f a_Position, const cChunkCoords a_ChunkPosition)
Converts an absolute floating-point Position into a Chunk-relative one.
static float RandomIntensity(MTRand &a_Random, const int a_Power)
Returns a random intensity for an Explosion Lazor (tm) as a function of the explosion's power.
static float CalculateEntityExposure(const cChunk &a_Chunk, const cEntity &a_Entity, const Vector3f a_Position, const int a_SquareRadius)
Calculates the approximate percentage of an Entity's bounding box that is exposed to an explosion cen...
static bool FullyOccupiesVoxel(BLOCKTYPE Block)
Does this block fully occupy its voxel - is it a 'full' block?
Definition: BlockInfo.cpp:606
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, const cEntity *a_Digger) const
Called after a block gets broken (replaced with air), by natural means.
Definition: BlockHandler.h:60
Definition: Chunk.h:36
NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:279
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
Definition: Chunk.h:146
cChunk * GetRelNeighborChunkAdjustCoords(Vector3i &a_RelPos) const
Returns the chunk into which the relatively-specified block belongs.
Definition: Chunk.cpp:1885
cChunkCoords GetPos() const
Definition: Chunk.h:133
void SetBlock(Vector3i a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: Chunk.cpp:1263
const auto & GetAllClients(void) const
Definition: Chunk.h:443
cWorld * GetWorld(void) const
Definition: Chunk.h:135
Wraps the chunk coords into a single structure.
Definition: ChunkDef.h:57
int m_ChunkZ
Definition: ChunkDef.h:60
int m_ChunkX
Definition: ChunkDef.h:59
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
Definition: ChunkDef.h:185
static Vector3i RelativeToAbsolute(Vector3i a_RelBlockPosition, cChunkCoords a_ChunkCoords)
Converts relative block coordinates into absolute coordinates with a known chunk location.
Definition: ChunkDef.h:174
static const int Width
Definition: ChunkDef.h:124
Definition: Entity.h:76
cBoundingBox GetBoundingBox() const
Definition: Entity.h:211
bool IsTNT(void) const
Definition: Entity.h:167
Class to wrap any random engine to provide a more convenient interface.
Definition: FastRandom.h:58
RealType RandReal(RealType a_Min, RealType a_Max)
Return a random RealType in the range [a_Min, a_Max).
Definition: FastRandom.h:123
bool Trace(Vector3d a_Start, Vector3d a_End)
Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits...
static bool IsAllowedBlock(BLOCKTYPE a_BlockType)
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Definition: Vector3.h:314
T x
Definition: Vector3.h:17
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector's coords.
Definition: Vector3.h:177
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
Vector3< T > NormalizeCopy(void) const
Definition: Vector3.h:58
Definition: World.h:53
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
Definition: World.cpp:1460
virtual bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) override
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
Definition: World.cpp:2445
void SpawnItemPickups(const cItems &a_Pickups, Vector3i a_BlockPos, double a_FlyAwaySpeed=1.0, bool a_IsPlayerCreated=false)
Spawns item pickups for each item in the list.
Definition: World.cpp:1806
cChunkMap * GetChunkMap(void)
Definition: World.h:852