soiz1's picture
Upload folder using huggingface_hub
d46f4a3 verified
package net.minecraft.world.entity;
import com.google.common.collect.Sets;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LightningRodBlock;
import net.minecraft.world.level.block.WeatheringCopper;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class LightningBolt extends Entity {
private static final int START_LIFE = 2;
private static final double DAMAGE_RADIUS = 3.0;
private static final double DETECTION_RADIUS = 15.0;
private int life;
public long seed;
private int flashes;
private boolean visualOnly;
@Nullable
private ServerPlayer cause;
private final Set<Entity> hitEntities = Sets.newHashSet();
private int blocksSetOnFire;
public LightningBolt(EntityType<? extends LightningBolt> p_20865_, Level p_20866_) {
super(p_20865_, p_20866_);
this.life = 2;
this.seed = this.random.nextLong();
this.flashes = this.random.nextInt(3) + 1;
}
public void setVisualOnly(boolean p_20875_) {
this.visualOnly = p_20875_;
}
@Override
public SoundSource getSoundSource() {
return SoundSource.WEATHER;
}
@Nullable
public ServerPlayer getCause() {
return this.cause;
}
public void setCause(@Nullable ServerPlayer p_20880_) {
this.cause = p_20880_;
}
private void powerLightningRod() {
BlockPos blockpos = this.getStrikePosition();
BlockState blockstate = this.level().getBlockState(blockpos);
if (blockstate.is(Blocks.LIGHTNING_ROD)) {
((LightningRodBlock)blockstate.getBlock()).onLightningStrike(blockstate, this.level(), blockpos);
}
}
@Override
public void tick() {
super.tick();
if (this.life == 2) {
if (this.level().isClientSide()) {
this.level()
.playLocalSound(
this.getX(),
this.getY(),
this.getZ(),
SoundEvents.LIGHTNING_BOLT_THUNDER,
SoundSource.WEATHER,
10000.0F,
0.8F + this.random.nextFloat() * 0.2F,
false
);
this.level()
.playLocalSound(
this.getX(),
this.getY(),
this.getZ(),
SoundEvents.LIGHTNING_BOLT_IMPACT,
SoundSource.WEATHER,
2.0F,
0.5F + this.random.nextFloat() * 0.2F,
false
);
} else {
Difficulty difficulty = this.level().getDifficulty();
if (difficulty == Difficulty.NORMAL || difficulty == Difficulty.HARD) {
this.spawnFire(4);
}
this.powerLightningRod();
clearCopperOnLightningStrike(this.level(), this.getStrikePosition());
this.gameEvent(GameEvent.LIGHTNING_STRIKE);
}
}
this.life--;
if (this.life < 0) {
if (this.flashes == 0) {
if (this.level() instanceof ServerLevel) {
List<Entity> list = this.level()
.getEntities(
this,
new AABB(
this.getX() - 15.0,
this.getY() - 15.0,
this.getZ() - 15.0,
this.getX() + 15.0,
this.getY() + 6.0 + 15.0,
this.getZ() + 15.0
),
p_147140_ -> p_147140_.isAlive() && !this.hitEntities.contains(p_147140_)
);
for (ServerPlayer serverplayer : ((ServerLevel)this.level()).getPlayers(p_326774_ -> p_326774_.distanceTo(this) < 256.0F)) {
CriteriaTriggers.LIGHTNING_STRIKE.trigger(serverplayer, this, list);
}
}
this.discard();
} else if (this.life < -this.random.nextInt(10)) {
this.flashes--;
this.life = 1;
this.seed = this.random.nextLong();
this.spawnFire(0);
}
}
if (this.life >= 0) {
if (!(this.level() instanceof ServerLevel)) {
this.level().setSkyFlashTime(2);
} else if (!this.visualOnly) {
List<Entity> list1 = this.level()
.getEntities(
this,
new AABB(
this.getX() - 3.0,
this.getY() - 3.0,
this.getZ() - 3.0,
this.getX() + 3.0,
this.getY() + 6.0 + 3.0,
this.getZ() + 3.0
),
Entity::isAlive
);
for (Entity entity : list1) {
entity.thunderHit((ServerLevel)this.level(), this);
}
this.hitEntities.addAll(list1);
if (this.cause != null) {
CriteriaTriggers.CHANNELED_LIGHTNING.trigger(this.cause, list1);
}
}
}
}
private BlockPos getStrikePosition() {
Vec3 vec3 = this.position();
return BlockPos.containing(vec3.x, vec3.y - 1.0E-6, vec3.z);
}
private void spawnFire(int p_20871_) {
if (!this.visualOnly && this.level() instanceof ServerLevel serverlevel && serverlevel.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) {
BlockPos blockpos1 = this.blockPosition();
BlockState blockstate = BaseFireBlock.getState(this.level(), blockpos1);
if (this.level().getBlockState(blockpos1).isAir() && blockstate.canSurvive(this.level(), blockpos1)) {
this.level().setBlockAndUpdate(blockpos1, blockstate);
this.blocksSetOnFire++;
}
for (int i = 0; i < p_20871_; i++) {
BlockPos blockpos = blockpos1.offset(this.random.nextInt(3) - 1, this.random.nextInt(3) - 1, this.random.nextInt(3) - 1);
blockstate = BaseFireBlock.getState(this.level(), blockpos);
if (this.level().getBlockState(blockpos).isAir() && blockstate.canSurvive(this.level(), blockpos)) {
this.level().setBlockAndUpdate(blockpos, blockstate);
this.blocksSetOnFire++;
}
}
}
}
private static void clearCopperOnLightningStrike(Level p_147151_, BlockPos p_147152_) {
BlockState blockstate = p_147151_.getBlockState(p_147152_);
BlockPos blockpos;
BlockState blockstate1;
if (blockstate.is(Blocks.LIGHTNING_ROD)) {
blockpos = p_147152_.relative(blockstate.getValue(LightningRodBlock.FACING).getOpposite());
blockstate1 = p_147151_.getBlockState(blockpos);
} else {
blockpos = p_147152_;
blockstate1 = blockstate;
}
if (blockstate1.getBlock() instanceof WeatheringCopper) {
p_147151_.setBlockAndUpdate(blockpos, WeatheringCopper.getFirst(p_147151_.getBlockState(blockpos)));
BlockPos.MutableBlockPos blockpos$mutableblockpos = p_147152_.mutable();
int i = p_147151_.random.nextInt(3) + 3;
for (int j = 0; j < i; j++) {
int k = p_147151_.random.nextInt(8) + 1;
randomWalkCleaningCopper(p_147151_, blockpos, blockpos$mutableblockpos, k);
}
}
}
private static void randomWalkCleaningCopper(Level p_147146_, BlockPos p_147147_, BlockPos.MutableBlockPos p_147148_, int p_147149_) {
p_147148_.set(p_147147_);
for (int i = 0; i < p_147149_; i++) {
Optional<BlockPos> optional = randomStepCleaningCopper(p_147146_, p_147148_);
if (optional.isEmpty()) {
break;
}
p_147148_.set(optional.get());
}
}
private static Optional<BlockPos> randomStepCleaningCopper(Level p_147154_, BlockPos p_147155_) {
for (BlockPos blockpos : BlockPos.randomInCube(p_147154_.random, 10, p_147155_, 1)) {
BlockState blockstate = p_147154_.getBlockState(blockpos);
if (blockstate.getBlock() instanceof WeatheringCopper) {
WeatheringCopper.getPrevious(blockstate).ifPresent(p_147144_ -> p_147154_.setBlockAndUpdate(blockpos, p_147144_));
p_147154_.levelEvent(3002, blockpos, -1);
return Optional.of(blockpos);
}
}
return Optional.empty();
}
@Override
public boolean shouldRenderAtSqrDistance(double p_20869_) {
double d0 = 64.0 * getViewScale();
return p_20869_ < d0 * d0;
}
@Override
protected void defineSynchedData(SynchedEntityData.Builder p_336100_) {
}
@Override
protected void readAdditionalSaveData(CompoundTag p_20873_) {
}
@Override
protected void addAdditionalSaveData(CompoundTag p_20877_) {
}
public int getBlocksSetOnFire() {
return this.blocksSetOnFire;
}
public Stream<Entity> getHitEntities() {
return this.hitEntities.stream().filter(Entity::isAlive);
}
@Override
public final boolean hurtServer(ServerLevel p_368015_, DamageSource p_364945_, float p_364228_) {
return false;
}
}