diff --git a/Minecraft.Client/Camera.cpp b/Minecraft.Client/Camera.cpp index 0216149f..5d7c8717 100644 --- a/Minecraft.Client/Camera.cpp +++ b/Minecraft.Client/Camera.cpp @@ -111,7 +111,9 @@ int Camera::getBlockAt(Level *level, shared_ptr player, float alph Vec3 *p = Camera::getCameraPos(player, alpha); TilePos tp = TilePos(p); int t = level->getTile(tp.x, tp.y, tp.z); - if (t != 0 && Tile::tiles[t]->material->isLiquid()) + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return 0; // tu31 tutorial world fix + if (t != 0 && tile->material->isLiquid()) { float hh = LiquidTile::getHeight(level->getData(tp.x, tp.y, tp.z)) - 1 / 9.0f; float h = tp.y + 1 - hh; diff --git a/Minecraft.Client/EntityRenderer.cpp b/Minecraft.Client/EntityRenderer.cpp index 22698db3..c292448e 100644 --- a/Minecraft.Client/EntityRenderer.cpp +++ b/Minecraft.Client/EntityRenderer.cpp @@ -213,9 +213,11 @@ void EntityRenderer::renderShadow(shared_ptr e, double x, double y, doub for (int zt = z0; zt <= z1; zt++) { int t = level->getTile(xt, yt - 1, zt); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) continue; // tu31 tutorial world fix if (t > 0 && level->getRawBrightness(xt, yt, zt) > 3) { - renderTileShadow(Tile::tiles[t], x, y + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, z, xt, yt , zt, pow, r, xo, yo + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, zo); + renderTileShadow(tile, x, y + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, z, xt, yt , zt, pow, r, xo, yo + e->getShadowHeightOffs() + fYLocalPlayerShadowOffset, zo); } } tt->end(); diff --git a/Minecraft.Client/MultiPlayerLevel.cpp b/Minecraft.Client/MultiPlayerLevel.cpp index 49fa51f7..b719b550 100644 --- a/Minecraft.Client/MultiPlayerLevel.cpp +++ b/Minecraft.Client/MultiPlayerLevel.cpp @@ -721,13 +721,15 @@ void MultiPlayerLevel::animateTickDoWork() int y = cy + random->nextInt(8); int z = cz + random->nextInt(8); int t = getTile(x, y, z); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return; // tu31 tutorial world fix if (random->nextInt(8) > y && t == 0 && dimension->hasBedrockFog()) // 4J - test for bedrock fog brought forward from 1.2.3 { addParticle(eParticleType_depthsuspend, x + random->nextFloat(), y + random->nextFloat(), z + random->nextFloat(), 0, 0, 0); } else if (t > 0) { - Tile::tiles[t]->animateTick(this, x, y, z, animateRandom); + tile->animateTick(this, x, y, z, animateRandom); } } } diff --git a/Minecraft.Client/TerrainParticle.cpp b/Minecraft.Client/TerrainParticle.cpp index 15a86465..b0cb0511 100644 --- a/Minecraft.Client/TerrainParticle.cpp +++ b/Minecraft.Client/TerrainParticle.cpp @@ -8,6 +8,7 @@ TerrainParticle::TerrainParticle(Level *level, double x, double y, double z, double xa, double ya, double za, Tile *tile, int face, int data, Textures *textures) : Particle(level, x, y, z, xa, ya, za) { this->tile = tile; + if (tile == nullptr) return; // tu31 tutorial world fix this->setTex(textures, tile->getTexture(0, data)); // 4J - change brought forward from 1.8.2 to fix purple particles on door damage this->gravity = tile->gravity; rCol = gCol = bCol = 0.6f; @@ -16,6 +17,7 @@ TerrainParticle::TerrainParticle(Level *level, double x, double y, double z, dou shared_ptr TerrainParticle::init(int x, int y, int z, int data) // 4J - added data parameter { + if (tile == nullptr) return nullptr; // tu31 tutorial world fix if (tile == Tile::grass) return dynamic_pointer_cast( shared_from_this() ); int col = tile->getColor(level, x, y, z, data); // 4J - added data parameter rCol *= ((col >> 16) & 0xff) / 255.0f; @@ -26,6 +28,7 @@ shared_ptr TerrainParticle::init(int x, int y, int z, int data) shared_ptr TerrainParticle::init(int data) { + if (tile == nullptr) return nullptr; // tu31 tutorial world fix if (tile == Tile::grass) return dynamic_pointer_cast( shared_from_this() ); int col = tile->getColor(data); rCol *= ((col >> 16) & 0xff) / 255.0f; diff --git a/Minecraft.World/Entity.cpp b/Minecraft.World/Entity.cpp index 1b42ba6e..a275448d 100644 --- a/Minecraft.World/Entity.cpp +++ b/Minecraft.World/Entity.cpp @@ -932,7 +932,9 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J - playSound(eSoundType_LIQUID_SWIM, speed, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f); } playStepSound(xt, yt, zt, t); - Tile::tiles[t]->stepOn(level, xt, yt, zt, self); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr && t != 0) return; // tu31 tutorial world fix + tile->stepOn(level, xt, yt, zt, self); } } @@ -981,9 +983,10 @@ void Entity::checkInsideTiles() for (int z = z0; z <= z1; z++) { int t = level->getTile(x, y, z); - if (t > 0) + Tile *tile = Tile::tiles[t]; + if (t > 0 && tile != nullptr) // tu31 tutorial world fix { - Tile::tiles[t]->entityInside(level, x, y, z, self); + tile->entityInside(level, x, y, z, self); } } } @@ -992,6 +995,8 @@ void Entity::checkInsideTiles() void Entity::playStepSound(int xt, int yt, int zt, int t) { + Tile *tile = Tile::tiles[t]; + if (tile == nullptr && t != 0) return; // tu31 tutorial world fix const Tile::SoundType *soundType = Tile::tiles[t]->soundType; MemSect(31); @@ -1122,7 +1127,9 @@ bool Entity::isUnderLiquid(Material *material) int yt = Mth::floor(yp); // 4J - this used to be a nested pair of floors for some reason int zt = Mth::floor(z); int t = level->getTile(xt, yt, zt); - if (t != 0 && Tile::tiles[t]->material == material) { + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return false; // tu31 tutorial world fix + if (t != 0 && tile->material == material) { float hh = LiquidTile::getHeight(level->getData(xt, yt, zt)) - 1 / 9.0f; float h = yt + 1 - hh; return yp < h; diff --git a/Minecraft.World/Level.cpp b/Minecraft.World/Level.cpp index 5f9355be..ca03bde3 100644 --- a/Minecraft.World/Level.cpp +++ b/Minecraft.World/Level.cpp @@ -1518,7 +1518,7 @@ HitResult *Level::clip(Vec3 *a, Vec3 *b, bool liquid, bool solidOnly) // No collision } - else if (t > 0 && tile->mayPick(data, liquid)) + else if (t > 0 && tile != nullptr && tile->mayPick(data, liquid)) { HitResult *r = tile->clip(this, xTile0, yTile0, zTile0, a, b); if (r != nullptr) return r; @@ -1620,7 +1620,7 @@ HitResult *Level::clip(Vec3 *a, Vec3 *b, bool liquid, bool solidOnly) // No collision } - else if (t > 0 && tile->mayPick(data, liquid)) + else if (t > 0 && tile != nullptr && tile->mayPick(data, liquid)) { HitResult *r = tile->clip(this, xTile0, yTile0, zTile0, a, b); if (r != nullptr) return r; @@ -3993,7 +3993,9 @@ int Level::getDirectSignal(int x, int y, int z, int dir) { int t = getTile(x, y, z); if (t == 0) return Redstone::SIGNAL_NONE; - return Tile::tiles[t]->getDirectSignal(this, x, y, z, dir); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return Redstone::SIGNAL_NONE; // tu31 tutorial world fix + return tile->getDirectSignal(this, x, y, z, dir); } int Level::getDirectSignalTo(int x, int y, int z) @@ -4026,8 +4028,9 @@ int Level::getSignal(int x, int y, int z, int dir) return getDirectSignalTo(x, y, z); } int t = getTile(x, y, z); - if (t == 0) return Redstone::SIGNAL_NONE; - return Tile::tiles[t]->getSignal(this, x, y, z, dir); + Tile *tile = Tile::tiles[t]; + if (t == 0 || tile == nullptr) return Redstone::SIGNAL_NONE; + return tile->getSignal(this, x, y, z, dir); } bool Level::hasNeighborSignal(int x, int y, int z) diff --git a/Minecraft.World/LevelChunk.cpp b/Minecraft.World/LevelChunk.cpp index e61f7b58..0cb11539 100644 --- a/Minecraft.World/LevelChunk.cpp +++ b/Minecraft.World/LevelChunk.cpp @@ -949,9 +949,12 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) } int xOffs = this->x * 16 + x; int zOffs = this->z * 16 + z; + + Tile *oldTile = Tile::tiles[old]; + if (oldTile == nullptr & old != 0) return false; // tu31 tutorial world fix if (old != 0 && !level->isClientSide) { - Tile::tiles[old]->onRemoving(level, xOffs, y, zOffs, oldData); + oldTile->onRemoving(level, xOffs, y, zOffs, oldData); } PIXBeginNamedEvent(0,"Chunk setting tile"); blocks->set(x,y % Level::COMPRESSED_CHUNK_SECTION_HEIGHT,z,tile); @@ -1329,7 +1332,9 @@ shared_ptr LevelChunk::getTileEntity(int x, int y, int z) if(level->m_bDisableAddNewTileEntities) return nullptr; int t = getTile(x, y, z); - if (t <= 0 || !Tile::tiles[t]->isEntityTile()) return nullptr; + Tile *tile = Tile::tiles[t]; + if (tile == nullptr) return nullptr; // tu31 tutorial world fix + if (t <= 0 || !tile->isEntityTile()) return nullptr; // 4J-PB changed from this in 1.7.3 //EntityTile *et = (EntityTile *) Tile::tiles[t]; @@ -1337,7 +1342,7 @@ shared_ptr LevelChunk::getTileEntity(int x, int y, int z) //if (tileEntity == nullptr) //{ - tileEntity = dynamic_cast(Tile::tiles[t])->newTileEntity(level); + tileEntity = dynamic_cast(tile)->newTileEntity(level); level->setTileEntity(this->x * 16 + x, y, this->z * 16 + z, tileEntity); //} diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 642ec3b1..76358b9a 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -179,7 +179,8 @@ void LivingEntity::checkFallDamage(double ya, bool onGround) } } - if (t > 0) + Tile *tile = Tile::tiles[t]; + if (t > 0 && tile != nullptr) // tu31 tutorial world fix { Tile::tiles[t]->fallOn(level, xt, yt, zt, shared_from_this(), fallDistance); } @@ -1560,10 +1561,12 @@ void LivingEntity::travel(float xa, float ya) if (onGround) { frictionTile = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z)); + Tile *tile = Tile::tiles[frictionTile]; friction = 0.6f * 0.91f; if (frictionTile > 0) { - friction = Tile::tiles[frictionTile]->friction * 0.91f; + if (tile == nullptr) tile = Tile::tiles[1]; + friction = tile->friction * 0.91f; } } @@ -1586,8 +1589,10 @@ void LivingEntity::travel(float xa, float ya) { friction = 0.6f * 0.91f; if (frictionTile > 0) - { - friction = Tile::tiles[frictionTile]->friction * 0.91f; + { + Tile *tile = Tile::tiles[frictionTile]; + if (tile == nullptr) tile = Tile::tiles[1]; + friction = tile->friction * 0.91f; } } if (onLadder()) diff --git a/Minecraft.World/PistonBaseTile.cpp b/Minecraft.World/PistonBaseTile.cpp index e0a0a30b..47e6dcec 100644 --- a/Minecraft.World/PistonBaseTile.cpp +++ b/Minecraft.World/PistonBaseTile.cpp @@ -502,6 +502,9 @@ int PistonBaseTile::getNewFacing(Level *level, int x, int y, int z, shared_ptrgetDestroySpeed(level, cx, cy, cz) == Tile::INDESTRUCTIBLE_DESTROY_TIME) + if (tile->getDestroySpeed(level, cx, cy, cz) == Tile::INDESTRUCTIBLE_DESTROY_TIME) { return false; } - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_BLOCK) + if (tile->getPistonPushReaction() == Material::PUSH_BLOCK) { return false; } - if (Tile::tiles[block]->getPistonPushReaction() == Material::PUSH_DESTROY) + if (tile->getPistonPushReaction() == Material::PUSH_DESTROY) { if(!allowDestroyable) { @@ -538,7 +541,7 @@ bool PistonBaseTile::isPushable(int block, Level *level, int cx, int cy, int cz, } } - if( Tile::tiles[block]->isEntityTile() ) // 4J - java uses instanceof EntityTile here + if( tile->isEntityTile() ) // 4J - java uses instanceof EntityTile here { // may not push tile entities return false; diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index 925217f5..59746272 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -1230,7 +1230,9 @@ bool Tile::mayPlace(Level *level, int x, int y, int z, int face) bool Tile::mayPlace(Level *level, int x, int y, int z) { int t = level->getTile(x, y, z); - return t == 0 || Tile::tiles[t]->material->isReplaceable(); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr && t != 0) return false; + return t == 0 || tile->material->isReplaceable(); } // 4J-PB - Adding a TestUse for tooltip display