aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/Explosion.cpp
diff options
context:
space:
mode:
authordaoge <3523206925@qq.com>2026-03-03 03:04:10 +0800
committerGitHub <noreply@github.com>2026-03-03 03:04:10 +0800
commitb3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch)
tree267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.World/Explosion.cpp
parent84c31a2331f7a0ec85b9d438992e244f60e5020f (diff)
feat: TU19 (Dec 2014) Features & Content (#155)
* try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.World/Explosion.cpp')
-rw-r--r--Minecraft.World/Explosion.cpp145
1 files changed, 86 insertions, 59 deletions
diff --git a/Minecraft.World/Explosion.cpp b/Minecraft.World/Explosion.cpp
index 604813b7..028ad673 100644
--- a/Minecraft.World/Explosion.cpp
+++ b/Minecraft.World/Explosion.cpp
@@ -1,5 +1,7 @@
#include "stdafx.h"
#include "net.minecraft.world.entity.h"
+#include "net.minecraft.world.entity.item.h"
+#include "net.minecraft.world.item.enchantment.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.phys.h"
@@ -69,9 +71,11 @@ void Explosion::explode()
int t = level->getTile(xt, yt, zt);
if (t > 0)
{
- remainingPower -= (Tile::tiles[t]->getExplosionResistance(source) + 0.3f) * stepSize;
+ Tile *tile = Tile::tiles[t];
+ float resistance = source != NULL ? source->getTileExplosionResistance(this, level, xt, yt, zt, tile) : tile->getExplosionResistance(source);
+ remainingPower -= (resistance + 0.3f) * stepSize;
}
- if (remainingPower > 0)
+ if (remainingPower > 0&& (source == NULL || source->shouldTileExplode(this, level, xt, yt, zt, t, remainingPower)))
{
toBlow.insert(TilePos(xt, yt, zt));
}
@@ -142,16 +146,17 @@ void Explosion::explode()
double sp = level->getSeenPercent(center, e->bb);
double pow = (1 - dist) * sp;
- if(canDamage) e->hurt(DamageSource::explosion, (int) ((pow * pow + pow) / 2 * 8 * r + 1));
+ if(canDamage) e->hurt(DamageSource::explosion(this), (int) ((pow * pow + pow) / 2 * 8 * r + 1));
- double push = pow;
- e->xd += xa * push;
- e->yd += ya * push;
- e->zd += za * push;
+ double kbPower = ProtectionEnchantment::getExplosionKnockbackAfterDampener(e, pow);
+ e->xd += xa *kbPower;
+ e->yd += ya *kbPower;
+ e->zd += za *kbPower;
- shared_ptr<Player> player = dynamic_pointer_cast<Player>(e);
- if (player != NULL)
+
+ if (e->instanceof(eTYPE_PLAYER))
{
+ shared_ptr<Player> player = dynamic_pointer_cast<Player>(e);
//app.DebugPrintf("Adding player knockback (%f,%f,%f)\n", xa * pow, ya * pow, za * pow);
hitPlayers.insert( playerVec3Map::value_type( player, Vec3::newPermanent(xa * pow, ya * pow, za * pow)));
}
@@ -164,68 +169,82 @@ void Explosion::explode()
void Explosion::finalizeExplosion(bool generateParticles, vector<TilePos> *toBlowDirect/*=NULL*/) // 4J - added toBlowDirect parameter
{
level->playSound(x, y, z, eSoundType_RANDOM_EXPLODE, 4, (1 + (level->random->nextFloat() - level->random->nextFloat()) * 0.2f) * 0.7f);
- level->addParticle(eParticleType_hugeexplosion, x, y, z, 0, 0, 0);
-
+ if (r < 2 || !destroyBlocks)
+ {
+ level->addParticle(eParticleType_largeexplode, x, y, z, 1.0f, 0, 0);
+ }
+ else
+ {
+ level->addParticle(eParticleType_hugeexplosion, x, y, z, 1.0f, 0, 0);
+ }
+
// 4J - use pointer to vector directly passed in if this is available - used to speed up calling this from an incoming packet
vector<TilePos> *toBlowArray = toBlowDirect ? toBlowDirect : new vector<TilePos>( toBlow.begin(), toBlow.end() );
- //toBlowArray.addAll(toBlow);
- // TODO 4J Stu - Reverse iterator
- PIXBeginNamedEvent(0,"Finalizing explosion size %d",toBlow.size());
- app.DebugPrintf("Finalizing explosion size %d\n",toBlow.size());
- static const int MAX_EXPLODE_PARTICLES = 50;
- // 4J - try and make at most MAX_EXPLODE_PARTICLES pairs of particles
- int fraction = (int)toBlowArray->size() / MAX_EXPLODE_PARTICLES;
- if( fraction == 0 ) fraction = 1;
- size_t j = toBlowArray->size() - 1;
- //for (size_t j = toBlowArray->size() - 1; j >= 0; j--)
- for(AUTO_VAR(it,toBlowArray->rbegin()); it != toBlowArray->rend(); ++it)
+ if (destroyBlocks)
{
- TilePos *tp = &(*it); //&toBlowArray->at(j);
- int xt = tp->x;
- int yt = tp->y;
- int zt = tp->z;
- // if (xt >= 0 && yt >= 0 && zt >= 0 && xt < width && yt < depth &&
- // zt < height) {
- int t = level->getTile(xt, yt, zt);
-
- if (generateParticles)
+ //toBlowArray.addAll(toBlow);
+ // TODO 4J Stu - Reverse iterator
+ PIXBeginNamedEvent(0,"Finalizing explosion size %d",toBlow.size());
+ app.DebugPrintf("Finalizing explosion size %d\n",toBlow.size());
+ static const int MAX_EXPLODE_PARTICLES = 50;
+ // 4J - try and make at most MAX_EXPLODE_PARTICLES pairs of particles
+ int fraction = (int)toBlowArray->size() / MAX_EXPLODE_PARTICLES;
+ if( fraction == 0 ) fraction = 1;
+ size_t j = toBlowArray->size() - 1;
+ //for (size_t j = toBlowArray->size() - 1; j >= 0; j--)
+ for(AUTO_VAR(it,toBlowArray->rbegin()); it != toBlowArray->rend(); ++it)
{
- if( ( j % fraction ) == 0 )
+ TilePos *tp = &(*it); //&toBlowArray->at(j);
+ int xt = tp->x;
+ int yt = tp->y;
+ int zt = tp->z;
+ // if (xt >= 0 && yt >= 0 && zt >= 0 && xt < width && yt < depth &&
+ // zt < height) {
+ int t = level->getTile(xt, yt, zt);
+
+ if (generateParticles)
{
- double xa = xt + level->random->nextFloat();
- double ya = yt + level->random->nextFloat();
- double za = zt + level->random->nextFloat();
+ if( ( j % fraction ) == 0 )
+ {
+ double xa = xt + level->random->nextFloat();
+ double ya = yt + level->random->nextFloat();
+ double za = zt + level->random->nextFloat();
- double xd = xa - x;
- double yd = ya - y;
- double zd = za - z;
+ double xd = xa - x;
+ double yd = ya - y;
+ double zd = za - z;
- double dd = sqrt(xd * xd + yd * yd + zd * zd);
+ double dd = sqrt(xd * xd + yd * yd + zd * zd);
- xd /= dd;
- yd /= dd;
- zd /= dd;
+ xd /= dd;
+ yd /= dd;
+ zd /= dd;
- double speed = 0.5 / (dd / r + 0.1);
- speed *= (level->random->nextFloat() * level->random->nextFloat() + 0.3f);
- xd *= speed;
- yd *= speed;
- zd *= speed;
+ double speed = 0.5 / (dd / r + 0.1);
+ speed *= (level->random->nextFloat() * level->random->nextFloat() + 0.3f);
+ xd *= speed;
+ yd *= speed;
+ zd *= speed;
- level->addParticle(eParticleType_explode, (xa + x * 1) / 2, (ya + y * 1) / 2, (za + z * 1) / 2, xd, yd, zd);
- level->addParticle(eParticleType_smoke, xa, ya, za, xd, yd, zd);
+ level->addParticle(eParticleType_explode, (xa + x * 1) / 2, (ya + y * 1) / 2, (za + z * 1) / 2, xd, yd, zd);
+ level->addParticle(eParticleType_smoke, xa, ya, za, xd, yd, zd);
+ }
}
- }
- if (t > 0)
- {
- Tile::tiles[t]->spawnResources(level, xt, yt, zt, level->getData(xt, yt, zt), 0.3f, 0);
- level->setTile(xt, yt, zt, 0);
- Tile::tiles[t]->wasExploded(level, xt, yt, zt);
- }
- // }
+ if (t > 0)
+ {
+ Tile *tile = Tile::tiles[t];
- --j;
+ if (tile->dropFromExplosion(this))
+ {
+ tile->spawnResources(level, xt, yt, zt, level->getData(xt, yt, zt), 1.0f / r, 0);
+ }
+ level->setTileAndData(xt, yt, zt, 0, 0, Tile::UPDATE_ALL);
+ tile->wasExploded(level, xt, yt, zt, this);
+ }
+
+ --j;
+ }
}
if (fire)
@@ -241,7 +260,7 @@ void Explosion::finalizeExplosion(bool generateParticles, vector<TilePos> *toBlo
int b = level->getTile(xt, yt - 1, zt);
if (t == 0 && Tile::solid[b] && random->nextInt(3) == 0)
{
- level->setTile(xt, yt, zt, Tile::fire_Id);
+ level->setTileAndUpdate(xt, yt, zt, Tile::fire_Id);
}
}
}
@@ -262,4 +281,12 @@ Vec3 *Explosion::getHitPlayerKnockback( shared_ptr<Player> player )
if(it == hitPlayers.end() ) return Vec3::newTemp(0.0,0.0,0.0);
return it->second;
+}
+
+shared_ptr<LivingEntity> Explosion::getSourceMob()
+{
+ if (source == NULL) return nullptr;
+ if (source->instanceof(eTYPE_PRIMEDTNT)) return dynamic_pointer_cast<PrimedTnt>(source)->getOwner();
+ if (source->instanceof(eTYPE_LIVINGENTITY)) return dynamic_pointer_cast<LivingEntity>(source);
+ return nullptr;
} \ No newline at end of file