176 lines
7.2 KiB
Java
176 lines
7.2 KiB
Java
|
package net.minecraft.world.level.block.entity;
|
||
|
|
||
|
import java.util.List;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.core.Direction;
|
||
|
import net.minecraft.core.particles.ColorParticleOption;
|
||
|
import net.minecraft.core.particles.ParticleTypes;
|
||
|
import net.minecraft.sounds.SoundEvents;
|
||
|
import net.minecraft.sounds.SoundSource;
|
||
|
import net.minecraft.tags.EntityTypeTags;
|
||
|
import net.minecraft.util.Mth;
|
||
|
import net.minecraft.world.effect.MobEffectInstance;
|
||
|
import net.minecraft.world.effect.MobEffects;
|
||
|
import net.minecraft.world.entity.LivingEntity;
|
||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
|
||
|
import net.minecraft.world.level.Level;
|
||
|
import net.minecraft.world.level.block.state.BlockState;
|
||
|
import net.minecraft.world.phys.AABB;
|
||
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||
|
|
||
|
public class BellBlockEntity extends BlockEntity {
|
||
|
private static final int DURATION = 50;
|
||
|
private static final int GLOW_DURATION = 60;
|
||
|
private static final int MIN_TICKS_BETWEEN_SEARCHES = 60;
|
||
|
private static final int MAX_RESONATION_TICKS = 40;
|
||
|
private static final int TICKS_BEFORE_RESONATION = 5;
|
||
|
private static final int SEARCH_RADIUS = 48;
|
||
|
private static final int HEAR_BELL_RADIUS = 32;
|
||
|
private static final int HIGHLIGHT_RAIDERS_RADIUS = 48;
|
||
|
private long lastRingTimestamp;
|
||
|
public int ticks;
|
||
|
public boolean shaking;
|
||
|
public Direction clickDirection;
|
||
|
private List<LivingEntity> nearbyEntities;
|
||
|
private boolean resonating;
|
||
|
private int resonationTicks;
|
||
|
|
||
|
public BellBlockEntity(BlockPos p_155173_, BlockState p_155174_) {
|
||
|
super(BlockEntityType.BELL, p_155173_, p_155174_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean triggerEvent(int p_58837_, int p_58838_) {
|
||
|
if (p_58837_ == 1) {
|
||
|
this.updateEntities();
|
||
|
this.resonationTicks = 0;
|
||
|
this.clickDirection = Direction.from3DDataValue(p_58838_);
|
||
|
this.ticks = 0;
|
||
|
this.shaking = true;
|
||
|
return true;
|
||
|
} else {
|
||
|
return super.triggerEvent(p_58837_, p_58838_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void tick(
|
||
|
Level p_155181_, BlockPos p_155182_, BlockState p_155183_, BellBlockEntity p_155184_, BellBlockEntity.ResonationEndAction p_155185_
|
||
|
) {
|
||
|
if (p_155184_.shaking) {
|
||
|
p_155184_.ticks++;
|
||
|
}
|
||
|
|
||
|
if (p_155184_.ticks >= 50) {
|
||
|
p_155184_.shaking = false;
|
||
|
p_155184_.ticks = 0;
|
||
|
}
|
||
|
|
||
|
if (p_155184_.ticks >= 5 && p_155184_.resonationTicks == 0 && areRaidersNearby(p_155182_, p_155184_.nearbyEntities)) {
|
||
|
p_155184_.resonating = true;
|
||
|
p_155181_.playSound(null, p_155182_, SoundEvents.BELL_RESONATE, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||
|
}
|
||
|
|
||
|
if (p_155184_.resonating) {
|
||
|
if (p_155184_.resonationTicks < 40) {
|
||
|
p_155184_.resonationTicks++;
|
||
|
} else {
|
||
|
p_155185_.run(p_155181_, p_155182_, p_155184_.nearbyEntities);
|
||
|
p_155184_.resonating = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void clientTick(Level p_155176_, BlockPos p_155177_, BlockState p_155178_, BellBlockEntity p_155179_) {
|
||
|
tick(p_155176_, p_155177_, p_155178_, p_155179_, BellBlockEntity::showBellParticles);
|
||
|
}
|
||
|
|
||
|
public static void serverTick(Level p_155203_, BlockPos p_155204_, BlockState p_155205_, BellBlockEntity p_155206_) {
|
||
|
tick(p_155203_, p_155204_, p_155205_, p_155206_, BellBlockEntity::makeRaidersGlow);
|
||
|
}
|
||
|
|
||
|
public void onHit(Direction p_58835_) {
|
||
|
BlockPos blockpos = this.getBlockPos();
|
||
|
this.clickDirection = p_58835_;
|
||
|
if (this.shaking) {
|
||
|
this.ticks = 0;
|
||
|
} else {
|
||
|
this.shaking = true;
|
||
|
}
|
||
|
|
||
|
this.level.blockEvent(blockpos, this.getBlockState().getBlock(), 1, p_58835_.get3DDataValue());
|
||
|
}
|
||
|
|
||
|
private void updateEntities() {
|
||
|
BlockPos blockpos = this.getBlockPos();
|
||
|
if (this.level.getGameTime() > this.lastRingTimestamp + 60L || this.nearbyEntities == null) {
|
||
|
this.lastRingTimestamp = this.level.getGameTime();
|
||
|
AABB aabb = new AABB(blockpos).inflate(48.0);
|
||
|
this.nearbyEntities = this.level.getEntitiesOfClass(LivingEntity.class, aabb);
|
||
|
}
|
||
|
|
||
|
if (!this.level.isClientSide) {
|
||
|
for (LivingEntity livingentity : this.nearbyEntities) {
|
||
|
if (livingentity.isAlive() && !livingentity.isRemoved() && blockpos.closerToCenterThan(livingentity.position(), 32.0)) {
|
||
|
livingentity.getBrain().setMemory(MemoryModuleType.HEARD_BELL_TIME, this.level.getGameTime());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static boolean areRaidersNearby(BlockPos p_155200_, List<LivingEntity> p_155201_) {
|
||
|
for (LivingEntity livingentity : p_155201_) {
|
||
|
if (livingentity.isAlive()
|
||
|
&& !livingentity.isRemoved()
|
||
|
&& p_155200_.closerToCenterThan(livingentity.position(), 32.0)
|
||
|
&& livingentity.getType().is(EntityTypeTags.RAIDERS)) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private static void makeRaidersGlow(Level p_155187_, BlockPos p_155188_, List<LivingEntity> p_155189_) {
|
||
|
p_155189_.stream().filter(p_155219_ -> isRaiderWithinRange(p_155188_, p_155219_)).forEach(BellBlockEntity::glow);
|
||
|
}
|
||
|
|
||
|
private static void showBellParticles(Level p_155208_, BlockPos p_155209_, List<LivingEntity> p_155210_) {
|
||
|
MutableInt mutableint = new MutableInt(16700985);
|
||
|
int i = (int)p_155210_.stream().filter(p_375333_ -> p_155209_.closerToCenterThan(p_375333_.position(), 48.0)).count();
|
||
|
p_155210_.stream()
|
||
|
.filter(p_155213_ -> isRaiderWithinRange(p_155209_, p_155213_))
|
||
|
.forEach(
|
||
|
p_327289_ -> {
|
||
|
float f = 1.0F;
|
||
|
double d0 = Math.sqrt(
|
||
|
(p_327289_.getX() - p_155209_.getX()) * (p_327289_.getX() - p_155209_.getX())
|
||
|
+ (p_327289_.getZ() - p_155209_.getZ()) * (p_327289_.getZ() - p_155209_.getZ())
|
||
|
);
|
||
|
double d1 = p_155209_.getX() + 0.5F + 1.0 / d0 * (p_327289_.getX() - p_155209_.getX());
|
||
|
double d2 = p_155209_.getZ() + 0.5F + 1.0 / d0 * (p_327289_.getZ() - p_155209_.getZ());
|
||
|
int j = Mth.clamp((i - 21) / -2, 3, 15);
|
||
|
|
||
|
for (int k = 0; k < j; k++) {
|
||
|
int l = mutableint.addAndGet(5);
|
||
|
p_155208_.addParticle(ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, l), d1, p_155209_.getY() + 0.5F, d2, 0.0, 0.0, 0.0);
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
private static boolean isRaiderWithinRange(BlockPos p_155197_, LivingEntity p_155198_) {
|
||
|
return p_155198_.isAlive()
|
||
|
&& !p_155198_.isRemoved()
|
||
|
&& p_155197_.closerToCenterThan(p_155198_.position(), 48.0)
|
||
|
&& p_155198_.getType().is(EntityTypeTags.RAIDERS);
|
||
|
}
|
||
|
|
||
|
private static void glow(LivingEntity p_58841_) {
|
||
|
p_58841_.addEffect(new MobEffectInstance(MobEffects.GLOWING, 60));
|
||
|
}
|
||
|
|
||
|
@FunctionalInterface
|
||
|
interface ResonationEndAction {
|
||
|
void run(Level p_155221_, BlockPos p_155222_, List<LivingEntity> p_155223_);
|
||
|
}
|
||
|
}
|