minecraft-source/src/net/minecraft/world/level/block/entity/BellBlockEntity.java

179 lines
6.5 KiB
Java

package net.minecraft.world.level.block.entity;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.util.Mth;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.minecraft.world.level.Level;
import net.minecraft.tags.EntityTypeTags;
import java.util.Iterator;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.core.Position;
import net.minecraft.world.phys.AABB;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.LivingEntity;
import java.util.List;
import net.minecraft.core.Direction;
public class BellBlockEntity extends BlockEntity implements TickableBlockEntity {
private long lastRingTimestamp;
public int ticks;
public boolean shaking;
public Direction clickDirection;
private List<LivingEntity> nearbyEntities;
private boolean resonating;
private int resonationTicks;
public BellBlockEntity() {
super(BlockEntityType.BELL);
}
@Override
public boolean triggerEvent(final int integer1, final int integer2) {
if (integer1 == 1) {
this.updateEntities();
this.resonationTicks = 0;
this.clickDirection = Direction.from3DDataValue(integer2);
this.ticks = 0;
return this.shaking = true;
}
return super.triggerEvent(integer1, integer2);
}
@Override
public void tick() {
if (this.shaking) {
++this.ticks;
}
if (this.ticks >= 50) {
this.shaking = false;
this.ticks = 0;
}
if (this.ticks >= 5 && this.resonationTicks == 0 && this.areRaidersNearby()) {
this.resonating = true;
this.playResonateSound();
}
if (this.resonating) {
if (this.resonationTicks < 40) {
++this.resonationTicks;
}
else {
this.makeRaidersGlow(this.level);
this.showBellParticles(this.level);
this.resonating = false;
}
}
}
private void playResonateSound() {
this.level.playSound(null, this.getBlockPos(), SoundEvents.BELL_RESONATE, SoundSource.BLOCKS, 1.0f, 1.0f);
}
public void onHit(final Direction fp) {
final BlockPos fk3 = this.getBlockPos();
this.clickDirection = fp;
if (this.shaking) {
this.ticks = 0;
}
else {
this.shaking = true;
}
this.level.blockEvent(fk3, this.getBlockState().getBlock(), 1, fp.get3DDataValue());
}
private void updateEntities() {
final BlockPos fk2 = this.getBlockPos();
if (this.level.getGameTime() > this.lastRingTimestamp + 60L || this.nearbyEntities == null) {
this.lastRingTimestamp = this.level.getGameTime();
final AABB cvc3 = new AABB(fk2).inflate(48.0);
this.nearbyEntities = this.level.<LivingEntity>getEntitiesOfClass(LivingEntity.class, cvc3);
}
if (!this.level.isClientSide) {
for (final LivingEntity akw4 : this.nearbyEntities) {
if (akw4.isAlive()) {
if (akw4.removed) {
continue;
}
if (!fk2.closerThan(akw4.position(), 32.0)) {
continue;
}
akw4.getBrain().<Long>setMemory(MemoryModuleType.HEARD_BELL_TIME, this.level.getGameTime());
}
}
}
}
private boolean areRaidersNearby() {
final BlockPos fk2 = this.getBlockPos();
for (final LivingEntity akw4 : this.nearbyEntities) {
if (akw4.isAlive()) {
if (akw4.removed) {
continue;
}
if (fk2.closerThan(akw4.position(), 32.0) && akw4.getType().is(EntityTypeTags.RAIDERS)) {
return true;
}
continue;
}
}
return false;
}
private void makeRaidersGlow(final Level bjt) {
if (bjt.isClientSide) {
return;
}
this.nearbyEntities.stream().filter(this::isRaiderWithinRange).forEach(this::glow);
}
private void showBellParticles(final Level bjt) {
if (!bjt.isClientSide) {
return;
}
final BlockPos fk3 = this.getBlockPos();
final AtomicInteger atomicInteger4 = new AtomicInteger(16700985);
final int integer5 = (int)this.nearbyEntities.stream().filter(akw -> fk3.closerThan(akw.position(), 48.0)).count();
final float float6;
final Vec3i vec3i;
final float float7;
final double double8;
final double double9;
final int n;
int integer6;
int integer7;
final AtomicInteger atomicInteger5;
double double10;
double double11;
double double12;
this.nearbyEntities.stream().filter(this::isRaiderWithinRange).forEach(akw -> {
float6 = 1.0f;
float7 = Mth.sqrt((akw.getX() - vec3i.getX()) * (akw.getX() - vec3i.getX()) + (akw.getZ() - vec3i.getZ()) * (akw.getZ() - vec3i.getZ()));
double8 = vec3i.getX() + 0.5f + 1.0f / float7 * (akw.getX() - vec3i.getX());
double9 = vec3i.getZ() + 0.5f + 1.0f / float7 * (akw.getZ() - vec3i.getZ());
for (integer6 = Mth.clamp((n - 21) / -2, 3, 15), integer7 = 0; integer7 < integer6; ++integer7) {
atomicInteger5.addAndGet(5);
double10 = (atomicInteger5.get() >> 16 & 0xFF) / 255.0;
double11 = (atomicInteger5.get() >> 8 & 0xFF) / 255.0;
double12 = (atomicInteger5.get() & 0xFF) / 255.0;
bjt.addParticle(ParticleTypes.ENTITY_EFFECT, double8, vec3i.getY() + 0.5f, double9, double10, double11, double12);
}
});
}
private boolean isRaiderWithinRange(final LivingEntity akw) {
return akw.isAlive() && !akw.removed && this.getBlockPos().closerThan(akw.position(), 48.0) && akw.getType().is(EntityTypeTags.RAIDERS);
}
private void glow(final LivingEntity akw) {
akw.addEffect(new MobEffectInstance(MobEffects.GLOWING, 60));
}
}