Fixed spellbook open/closing behaviour, and fixed spellbooks sinking in water

This commit is contained in:
Sollace 2023-08-11 00:43:14 +01:00
parent 034691a758
commit f7b1fc6d62
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB

View file

@ -1,10 +1,9 @@
package com.minelittlepony.unicopia.entity; package com.minelittlepony.unicopia.entity;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.container.SpellbookScreenHandler; import com.minelittlepony.unicopia.container.SpellbookScreenHandler;
import com.minelittlepony.unicopia.container.SpellbookState; import com.minelittlepony.unicopia.container.SpellbookState;
import com.minelittlepony.unicopia.entity.player.MeteorlogicalUtil;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgSpellbookStateChanged; import com.minelittlepony.unicopia.network.MsgSpellbookStateChanged;
@ -37,14 +36,13 @@ import net.minecraft.world.GameRules;
import net.minecraft.world.World; import net.minecraft.world.World;
public class SpellbookEntity extends MobEntity { public class SpellbookEntity extends MobEntity {
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); private static final TrackedData<Byte> LOCKED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BYTE);
private static final TrackedData<Boolean> ALTERED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN); private static final TrackedData<Boolean> ALTERED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final int TICKS_TO_SLEEP = 2000; private static final int TICKS_TO_SLEEP = 600;
private int activeTicks = TICKS_TO_SLEEP; private int activeTicks = TICKS_TO_SLEEP;
private boolean prevDaytime;
private final SpellbookState state = new SpellbookState(); private final SpellbookState state = new SpellbookState();
@ -68,8 +66,6 @@ public class SpellbookEntity extends MobEntity {
@Override @Override
protected void initDataTracker() { protected void initDataTracker() {
super.initDataTracker(); super.initDataTracker();
dataTracker.startTracking(AWAKE, true);
dataTracker.startTracking(BORED, false);
dataTracker.startTracking(LOCKED, (byte)1); dataTracker.startTracking(LOCKED, (byte)1);
dataTracker.startTracking(ALTERED, false); dataTracker.startTracking(ALTERED, false);
} }
@ -103,47 +99,45 @@ public class SpellbookEntity extends MobEntity {
dataTracker.set(ALTERED, altered); dataTracker.set(ALTERED, altered);
} }
protected void setLocked(TriState closed) { protected void setForcedState(TriState state) {
dataTracker.set(LOCKED, (byte)closed.ordinal()); dataTracker.set(LOCKED, (byte)state.ordinal());
} }
@Nullable public void clearForcedState() {
protected TriState isLocked() { setForcedState(TriState.DEFAULT);
activeTicks = 0;
}
private TriState getForcedState() {
if (activeTicks <= 0) {
setForcedState(TriState.DEFAULT);
}
return TriState.values()[Math.abs(dataTracker.get(LOCKED)) % 3]; return TriState.values()[Math.abs(dataTracker.get(LOCKED)) % 3];
} }
public boolean isOpen() { public boolean isOpen() {
return isLocked().orElse(isAwake()) && !isBored(); return getForcedState().orElse(!shouldBeSleeping());
} }
public boolean isAwake() { public void keepAwake() {
return dataTracker.get(AWAKE); activeTicks = 100;
}
public void setAwake(boolean awake) {
if (awake != isAwake()) {
dataTracker.set(AWAKE, awake);
}
}
public boolean isBored() {
return dataTracker.get(BORED);
}
public void setBored(boolean bored) {
activeTicks = TICKS_TO_SLEEP;
if (bored != isBored()) {
dataTracker.set(BORED, bored);
}
} }
@Override @Override
public void tick() { public void tick() {
boolean awake = isAwake(); boolean open = isOpen();
jumping = awake && isTouchingWater();
super.tick(); super.tick();
if (getWorld().isClient && isOpen()) { if (open && isTouchingWater()) {
addVelocity(0, 0.01, 0);
keepAwake();
}
if (activeTicks > 0) {
activeTicks--;
}
if (getWorld().isClient && open) {
for (int offX = -2; offX <= 1; ++offX) { for (int offX = -2; offX <= 1; ++offX) {
for (int offZ = -2; offZ <= 1; ++offZ) { for (int offZ = -2; offZ <= 1; ++offZ) {
if (offX > -1 && offX < 1 && offZ == -1) { if (offX > -1 && offX < 1 && offZ == -1) {
@ -164,36 +158,30 @@ public class SpellbookEntity extends MobEntity {
} }
} }
if (awake) { getWorld().getOtherEntities(this, getBoundingBox().expand(2), EquinePredicates.PLAYER_UNICORN.and(e -> e instanceof PlayerEntity)).stream().findFirst().ifPresent(player -> {
getWorld().getOtherEntities(this, getBoundingBox().expand(2), EquinePredicates.PLAYER_UNICORN.and(e -> e instanceof PlayerEntity)).stream().findFirst().ifPresent(player -> { keepAwake();
setBored(false); if (open) {
if (isOpen()) { Vec3d diff = player.getPos().subtract(getPos());
Vec3d diff = player.getPos().subtract(getPos()); double yaw = Math.atan2(diff.z, diff.x) * 180D / Math.PI - 90;
double yaw = Math.atan2(diff.z, diff.x) * 180D / Math.PI - 90;
setHeadYaw((float)yaw); setHeadYaw((float)yaw);
setBodyYaw((float)yaw); setBodyYaw((float)yaw);
} }
}); });
if (!getWorld().isClient) { System.out.println(activeTicks);
if (activeTicks > 0 && --activeTicks <= 0) {
setBored(true); boolean daytime = MeteorlogicalUtil.getSkyAngle(getWorld()) < 1;
} if (daytime != prevDaytime) {
prevDaytime = daytime;
if (daytime != getForcedState().orElse(daytime)) {
clearForcedState();
} }
} }
}
if (!getWorld().isClient && getWorld().random.nextInt(30) == 0) { private boolean shouldBeSleeping() {
float celest = getWorld().getSkyAngle(1) * 4; return MeteorlogicalUtil.getSkyAngle(getWorld()) > 1 && activeTicks <= 0;
boolean daytime = celest > 3 || celest < 1;
setAwake(daytime);
if (daytime != awake && daytime == isLocked().orElse(daytime)) {
setLocked(TriState.DEFAULT);
}
}
} }
@Override @Override
@ -215,15 +203,14 @@ public class SpellbookEntity extends MobEntity {
@Override @Override
public ActionResult interactAt(PlayerEntity player, Vec3d vec, Hand hand) { public ActionResult interactAt(PlayerEntity player, Vec3d vec, Hand hand) {
if (player.isSneaking()) { if (player.isSneaking()) {
setBored(false); setForcedState(TriState.of(!isOpen()));
setAwake(!isOpen()); keepAwake();
setLocked(TriState.of(isAwake()));
player.playSound(SoundEvents.ITEM_BOOK_PAGE_TURN, 2, 1); player.playSound(SoundEvents.ITEM_BOOK_PAGE_TURN, 2, 1);
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
if (isOpen()) { if (isOpen()) {
setBored(false); keepAwake();
player.openHandledScreen(new ExtendedScreenHandlerFactory() { player.openHandledScreen(new ExtendedScreenHandlerFactory() {
@Override @Override
public Text getDisplayName() { public Text getDisplayName() {
@ -250,26 +237,23 @@ public class SpellbookEntity extends MobEntity {
@Override @Override
public void readCustomDataFromNbt(NbtCompound compound) { public void readCustomDataFromNbt(NbtCompound compound) {
super.readCustomDataFromNbt(compound); super.readCustomDataFromNbt(compound);
setAwake(compound.getBoolean("awake")); prevDaytime = compound.getBoolean("prevDaytime");
setBored(compound.getBoolean("bored")); activeTicks = compound.getInt("activeTicks");
setAltered(compound.getBoolean("altered")); setAltered(compound.getBoolean("altered"));
setLocked(compound.contains("locked") ? TriState.of(compound.getBoolean("locked")) : TriState.DEFAULT); setForcedState(compound.contains("locked") ? TriState.of(compound.getBoolean("locked")) : TriState.DEFAULT);
state.fromNBT(compound.getCompound("spellbookState")); state.fromNBT(compound.getCompound("spellbookState"));
} }
@Override @Override
public void writeCustomDataToNbt(NbtCompound compound) { public void writeCustomDataToNbt(NbtCompound compound) {
super.writeCustomDataToNbt(compound); super.writeCustomDataToNbt(compound);
compound.putBoolean("awake", isAwake()); compound.putInt("activeTicks", activeTicks);
compound.putBoolean("bored", isBored()); compound.putBoolean("prevDaytime", prevDaytime);
compound.putBoolean("altered", isAltered()); compound.putBoolean("altered", isAltered());
TriState locked = isLocked();
if (locked != TriState.DEFAULT) {
compound.putBoolean("locked", locked.get());
}
compound.put("spellbookState", state.toNBT()); compound.put("spellbookState", state.toNBT());
getForcedState().map(t -> {
compound.putBoolean("locked", t);
return null;
});
} }
} }