Code/net/minecraft/world/level/block/BaseFireBlock.java

214 lines
9.4 KiB
Java

package net.minecraft.world.level.block;
import com.mojang.serialization.MapCodec;
import java.util.Optional;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.InsideBlockEffectApplier;
import net.minecraft.world.entity.InsideBlockEffectType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.portal.PortalShape;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public abstract class BaseFireBlock extends Block {
private static final int SECONDS_ON_FIRE = 8;
private static final int MIN_FIRE_TICKS_TO_ADD = 1;
private static final int MAX_FIRE_TICKS_TO_ADD = 3;
private final float fireDamage;
protected static final VoxelShape SHAPE = Block.column(16.0, 0.0, 1.0);
public BaseFireBlock(BlockBehaviour.Properties p_49241_, float p_49242_) {
super(p_49241_);
this.fireDamage = p_49242_;
}
@Override
protected abstract MapCodec<? extends BaseFireBlock> codec();
@Override
public BlockState getStateForPlacement(BlockPlaceContext p_49244_) {
return getState(p_49244_.getLevel(), p_49244_.getClickedPos());
}
public static BlockState getState(BlockGetter p_49246_, BlockPos p_49247_) {
BlockPos blockpos = p_49247_.below();
BlockState blockstate = p_49246_.getBlockState(blockpos);
return SoulFireBlock.canSurviveOnBlock(blockstate) ? Blocks.SOUL_FIRE.defaultBlockState() : ((FireBlock)Blocks.FIRE).getStateForPlacement(p_49246_, p_49247_);
}
@Override
protected VoxelShape getShape(BlockState p_49274_, BlockGetter p_49275_, BlockPos p_49276_, CollisionContext p_49277_) {
return SHAPE;
}
@Override
public void animateTick(BlockState p_220763_, Level p_220764_, BlockPos p_220765_, RandomSource p_220766_) {
if (p_220766_.nextInt(24) == 0) {
p_220764_.playLocalSound(
p_220765_.getX() + 0.5,
p_220765_.getY() + 0.5,
p_220765_.getZ() + 0.5,
SoundEvents.FIRE_AMBIENT,
SoundSource.BLOCKS,
1.0F + p_220766_.nextFloat(),
p_220766_.nextFloat() * 0.7F + 0.3F,
false
);
}
BlockPos blockpos = p_220765_.below();
BlockState blockstate = p_220764_.getBlockState(blockpos);
if (!this.canBurn(blockstate) && !blockstate.isFaceSturdy(p_220764_, blockpos, Direction.UP)) {
if (this.canBurn(p_220764_.getBlockState(p_220765_.west()))) {
for (int j = 0; j < 2; j++) {
double d3 = p_220765_.getX() + p_220766_.nextDouble() * 0.1F;
double d8 = p_220765_.getY() + p_220766_.nextDouble();
double d13 = p_220765_.getZ() + p_220766_.nextDouble();
p_220764_.addParticle(ParticleTypes.LARGE_SMOKE, d3, d8, d13, 0.0, 0.0, 0.0);
}
}
if (this.canBurn(p_220764_.getBlockState(p_220765_.east()))) {
for (int k = 0; k < 2; k++) {
double d4 = p_220765_.getX() + 1 - p_220766_.nextDouble() * 0.1F;
double d9 = p_220765_.getY() + p_220766_.nextDouble();
double d14 = p_220765_.getZ() + p_220766_.nextDouble();
p_220764_.addParticle(ParticleTypes.LARGE_SMOKE, d4, d9, d14, 0.0, 0.0, 0.0);
}
}
if (this.canBurn(p_220764_.getBlockState(p_220765_.north()))) {
for (int l = 0; l < 2; l++) {
double d5 = p_220765_.getX() + p_220766_.nextDouble();
double d10 = p_220765_.getY() + p_220766_.nextDouble();
double d15 = p_220765_.getZ() + p_220766_.nextDouble() * 0.1F;
p_220764_.addParticle(ParticleTypes.LARGE_SMOKE, d5, d10, d15, 0.0, 0.0, 0.0);
}
}
if (this.canBurn(p_220764_.getBlockState(p_220765_.south()))) {
for (int i1 = 0; i1 < 2; i1++) {
double d6 = p_220765_.getX() + p_220766_.nextDouble();
double d11 = p_220765_.getY() + p_220766_.nextDouble();
double d16 = p_220765_.getZ() + 1 - p_220766_.nextDouble() * 0.1F;
p_220764_.addParticle(ParticleTypes.LARGE_SMOKE, d6, d11, d16, 0.0, 0.0, 0.0);
}
}
if (this.canBurn(p_220764_.getBlockState(p_220765_.above()))) {
for (int j1 = 0; j1 < 2; j1++) {
double d7 = p_220765_.getX() + p_220766_.nextDouble();
double d12 = p_220765_.getY() + 1 - p_220766_.nextDouble() * 0.1F;
double d17 = p_220765_.getZ() + p_220766_.nextDouble();
p_220764_.addParticle(ParticleTypes.LARGE_SMOKE, d7, d12, d17, 0.0, 0.0, 0.0);
}
}
} else {
for (int i = 0; i < 3; i++) {
double d0 = p_220765_.getX() + p_220766_.nextDouble();
double d1 = p_220765_.getY() + p_220766_.nextDouble() * 0.5 + 0.5;
double d2 = p_220765_.getZ() + p_220766_.nextDouble();
p_220764_.addParticle(ParticleTypes.LARGE_SMOKE, d0, d1, d2, 0.0, 0.0, 0.0);
}
}
}
protected abstract boolean canBurn(BlockState p_49284_);
@Override
protected void entityInside(BlockState p_49260_, Level p_49261_, BlockPos p_49262_, Entity p_49263_, InsideBlockEffectApplier p_397865_) {
p_397865_.apply(InsideBlockEffectType.FIRE_IGNITE);
p_397865_.runAfter(InsideBlockEffectType.FIRE_IGNITE, p_394328_ -> p_394328_.hurt(p_394328_.level().damageSources().inFire(), this.fireDamage));
}
public static void fireIgnite(Entity p_396191_) {
if (!p_396191_.fireImmune()) {
if (p_396191_.getRemainingFireTicks() < 0) {
p_396191_.setRemainingFireTicks(p_396191_.getRemainingFireTicks() + 1);
} else if (p_396191_ instanceof ServerPlayer) {
int i = p_396191_.level().getRandom().nextInt(1, 3);
p_396191_.setRemainingFireTicks(p_396191_.getRemainingFireTicks() + i);
}
if (p_396191_.getRemainingFireTicks() >= 0) {
p_396191_.igniteForSeconds(8.0F);
}
}
}
@Override
protected void onPlace(BlockState p_49279_, Level p_49280_, BlockPos p_49281_, BlockState p_49282_, boolean p_49283_) {
if (!p_49282_.is(p_49279_.getBlock())) {
if (inPortalDimension(p_49280_)) {
Optional<PortalShape> optional = PortalShape.findEmptyPortalShape(p_49280_, p_49281_, Direction.Axis.X);
if (optional.isPresent()) {
optional.get().createPortalBlocks(p_49280_);
return;
}
}
if (!p_49279_.canSurvive(p_49280_, p_49281_)) {
p_49280_.removeBlock(p_49281_, false);
}
}
}
private static boolean inPortalDimension(Level p_49249_) {
return p_49249_.dimension() == Level.OVERWORLD || p_49249_.dimension() == Level.NETHER;
}
@Override
protected void spawnDestroyParticles(Level p_152139_, Player p_152140_, BlockPos p_152141_, BlockState p_152142_) {
}
@Override
public BlockState playerWillDestroy(Level p_49251_, BlockPos p_49252_, BlockState p_49253_, Player p_49254_) {
if (!p_49251_.isClientSide()) {
p_49251_.levelEvent(null, 1009, p_49252_, 0);
}
return super.playerWillDestroy(p_49251_, p_49252_, p_49253_, p_49254_);
}
public static boolean canBePlacedAt(Level p_49256_, BlockPos p_49257_, Direction p_49258_) {
BlockState blockstate = p_49256_.getBlockState(p_49257_);
return !blockstate.isAir() ? false : getState(p_49256_, p_49257_).canSurvive(p_49256_, p_49257_) || isPortal(p_49256_, p_49257_, p_49258_);
}
private static boolean isPortal(Level p_49270_, BlockPos p_49271_, Direction p_49272_) {
if (!inPortalDimension(p_49270_)) {
return false;
} else {
BlockPos.MutableBlockPos blockpos$mutableblockpos = p_49271_.mutable();
boolean flag = false;
for (Direction direction : Direction.values()) {
if (p_49270_.getBlockState(blockpos$mutableblockpos.set(p_49271_).move(direction)).is(Blocks.OBSIDIAN)) {
flag = true;
break;
}
}
if (!flag) {
return false;
} else {
Direction.Axis direction$axis = p_49272_.getAxis().isHorizontal()
? p_49272_.getCounterClockWise().getAxis()
: Direction.Plane.HORIZONTAL.getRandomAxis(p_49270_.random);
return PortalShape.findEmptyPortalShape(p_49270_, p_49271_, direction$axis).isPresent();
}
}
}
}