Unicopia/src/main/java/com/minelittlepony/unicopia/entity/SpellbookEntity.java

231 lines
7.6 KiB
Java
Raw Normal View History

2021-11-09 17:29:55 +01:00
package com.minelittlepony.unicopia.entity;
2021-11-09 20:42:01 +01:00
import org.jetbrains.annotations.Nullable;
2021-11-09 17:29:55 +01:00
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.container.UScreenHandlers;
import com.minelittlepony.unicopia.item.UItems;
2021-11-09 20:42:01 +01:00
import net.fabricmc.fabric.api.util.TriState;
2021-11-09 17:29:55 +01:00
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.screen.SimpleNamedScreenHandlerFactory;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
public class SpellbookEntity extends MobEntity {
2021-11-09 20:42:01 +01:00
private static final TrackedData<Boolean> AWAKE = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final TrackedData<Boolean> BORED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final TrackedData<Byte> LOCKED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BYTE);
2021-11-09 17:29:55 +01:00
private static final TrackedData<Boolean> ALTERED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
2021-11-09 20:42:01 +01:00
private static final int TICKS_TO_SLEEP = 2000;
private int activeTicks = TICKS_TO_SLEEP;
2021-11-09 17:29:55 +01:00
public SpellbookEntity(EntityType<SpellbookEntity> type, World world) {
super(type, world);
setPersistent();
2021-11-09 20:42:01 +01:00
setAltered(world.random.nextInt(3) == 0);
2021-11-09 17:29:55 +01:00
}
@Override
protected void initDataTracker() {
super.initDataTracker();
2021-11-09 20:42:01 +01:00
dataTracker.startTracking(AWAKE, true);
dataTracker.startTracking(BORED, false);
dataTracker.startTracking(LOCKED, (byte)1);
2021-11-09 17:29:55 +01:00
dataTracker.startTracking(ALTERED, false);
}
@Override
public ItemStack getPickBlockStack() {
return new ItemStack(UItems.SPELLBOOK);
}
@Override
public boolean isPushable() {
return false;
}
@Override
public boolean doesRenderOnFire() {
return false;
}
2021-11-09 20:42:01 +01:00
public boolean isAltered() {
2021-11-09 17:29:55 +01:00
return dataTracker.get(ALTERED);
}
2021-11-09 20:42:01 +01:00
public void setAltered(boolean altered) {
dataTracker.set(ALTERED, altered);
}
protected void setLocked(TriState closed) {
dataTracker.set(LOCKED, (byte)closed.ordinal());
}
@Nullable
protected TriState isLocked() {
return TriState.values()[Math.abs(dataTracker.get(LOCKED)) % 3];
2021-11-09 17:29:55 +01:00
}
2021-11-09 20:42:01 +01:00
public boolean isOpen() {
return isLocked().orElse(isAwake()) && !isBored();
2021-11-09 17:29:55 +01:00
}
2021-11-09 20:42:01 +01:00
public boolean isAwake() {
return dataTracker.get(AWAKE);
}
public void setAwake(boolean awake) {
if (awake != isAwake()) {
dataTracker.set(AWAKE, awake);
}
2021-11-09 17:29:55 +01:00
}
2021-11-09 20:42:01 +01:00
public boolean isBored() {
return dataTracker.get(BORED);
2021-11-09 17:29:55 +01:00
}
2021-11-09 20:42:01 +01:00
public void setBored(boolean bored) {
activeTicks = TICKS_TO_SLEEP;
if (bored != isBored()) {
dataTracker.set(BORED, bored);
}
2021-11-09 17:29:55 +01:00
}
@Override
public void tick() {
2021-11-09 20:42:01 +01:00
boolean awake = isAwake();
jumping = awake && isTouchingWater();
2021-11-09 17:29:55 +01:00
super.tick();
2021-11-09 20:42:01 +01:00
if (world.isClient && isOpen()) {
2021-11-09 17:29:55 +01:00
for (int offX = -2; offX <= 1; ++offX) {
for (int offZ = -2; offZ <= 1; ++offZ) {
if (offX > -1 && offX < 1 && offZ == -1) {
offZ = 1;
}
if (random.nextInt(320) == 0) {
for (int offY = 0; offY <= 1; ++offY) {
world.addParticle(ParticleTypes.ENCHANT,
getX(), getY(), getZ(),
offX/2F + random.nextFloat(),
offY/2F - random.nextFloat() + 0.5f,
offZ/2F + random.nextFloat()
);
}
}
}
}
}
2021-11-09 20:42:01 +01:00
if (awake) {
world.getOtherEntities(this, getBoundingBox().expand(2), EquinePredicates.PLAYER_UNICORN.and(e -> e instanceof PlayerEntity)).stream().findFirst().ifPresent(player -> {
setBored(false);
if (isOpen()) {
Vec3d diff = player.getPos().subtract(getPos());
double yaw = Math.atan2(diff.z, diff.x) * 180D / Math.PI - 90;
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
setHeadYaw((float)yaw);
setBodyYaw((float)yaw);
}
2021-11-09 17:29:55 +01:00
});
2021-11-09 20:42:01 +01:00
if (!world.isClient) {
System.out.println(activeTicks);
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
if (activeTicks > 0 && --activeTicks <= 0) {
setBored(true);
}
}
}
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
if (!world.isClient && world.random.nextInt(30) == 0) {
float celest = world.getSkyAngle(1) * 4;
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
boolean daytime = celest > 3 || celest < 1;
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
setAwake(daytime);
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
if (daytime != awake && daytime == isLocked().orElse(daytime)) {
setLocked(TriState.DEFAULT);
2021-11-09 17:29:55 +01:00
}
}
}
@Override
public boolean damage(DamageSource source, float amount) {
if (!world.isClient) {
remove(Entity.RemovalReason.KILLED);
BlockSoundGroup sound = BlockSoundGroup.WOOD;
world.playSound(getX(), getY(), getZ(), sound.getBreakSound(), SoundCategory.BLOCKS, sound.getVolume(), sound.getPitch(), true);
if (world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) {
dropItem(UItems.SPELLBOOK, 1);
}
}
return false;
}
@Override
public ActionResult interactAt(PlayerEntity player, Vec3d vec, Hand hand) {
if (player.isSneaking()) {
2021-11-09 20:42:01 +01:00
setBored(false);
setAwake(!isOpen());
setLocked(TriState.of(isAwake()));
2021-11-09 17:29:55 +01:00
return ActionResult.SUCCESS;
}
2021-11-09 20:42:01 +01:00
if (isOpen() && EquinePredicates.PLAYER_UNICORN.test(player)) {
setBored(false);
2021-11-09 17:29:55 +01:00
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((syncId, inv, ply) -> UScreenHandlers.SPELL_BOOK.create(syncId, inv), getDisplayName()));
player.playSound(SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, 2, 1);
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
@Override
public void readCustomDataFromNbt(NbtCompound compound) {
super.readCustomDataFromNbt(compound);
2021-11-09 20:42:01 +01:00
setAwake(compound.getBoolean("awake"));
setBored(compound.getBoolean("bored"));
setAltered(compound.getBoolean("altered"));
setLocked(compound.contains("locked") ? TriState.of(compound.getBoolean("locked")) : TriState.DEFAULT);
2021-11-09 17:29:55 +01:00
}
@Override
public void writeCustomDataToNbt(NbtCompound compound) {
super.writeCustomDataToNbt(compound);
2021-11-09 20:42:01 +01:00
compound.putBoolean("awake", isAwake());
compound.putBoolean("bored", isBored());
compound.putBoolean("altered", isAltered());
2021-11-09 17:29:55 +01:00
2021-11-09 20:42:01 +01:00
TriState locked = isLocked();
if (locked != TriState.DEFAULT) {
compound.putBoolean("locked", locked.get());
2021-11-09 17:29:55 +01:00
}
}
}