diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index aad4a870..aabca319 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -22,18 +22,18 @@ import net.minecraft.util.Identifier; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; -public final class Race implements Affine { +public record Race (boolean canCast, FlightType flightType, boolean canUseEarth, boolean isNocturnal) implements Affine { public static final String DEFAULT_ID = "unicopia:unset"; public static final Registry REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race"), DEFAULT_ID); public static final RegistryKey> REGISTRY_KEY = REGISTRY.getKey(); private static final DynamicCommandExceptionType UNKNOWN_RACE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("race.unknown", id)); - public static Race register(String name, boolean magic, FlightType flight, boolean earth) { - return register(Unicopia.id(name), magic, flight, earth); + public static Race register(String name, boolean magic, FlightType flight, boolean earth, boolean nocturnal) { + return register(Unicopia.id(name), magic, flight, earth, false); } - public static Race register(Identifier id, boolean magic, FlightType flight, boolean earth) { - return Registry.register(REGISTRY, id, new Race(magic, flight, earth)); + public static Race register(Identifier id, boolean magic, FlightType flight, boolean earth, boolean nocturnal) { + return Registry.register(REGISTRY, id, new Race(magic, flight, earth, nocturnal)); } public static RegistryKeyArgumentType argument() { @@ -44,27 +44,17 @@ public final class Race implements Affine { * The default, unset race. * This is used if there are no other races. */ - public static final Race UNSET = register("unset", false, FlightType.NONE, false); - public static final Race HUMAN = register("human", false, FlightType.NONE, false); - public static final Race EARTH = register("earth", false, FlightType.NONE, true); - public static final Race UNICORN = register("unicorn", true, FlightType.NONE, false); - public static final Race PEGASUS = register("pegasus", false, FlightType.AVIAN, false); - public static final Race BAT = register("bat", false, FlightType.AVIAN, false); - public static final Race ALICORN = register("alicorn", true, FlightType.AVIAN, true); - public static final Race CHANGELING = register("changeling", false, FlightType.INSECTOID, false); + public static final Race UNSET = register("unset", false, FlightType.NONE, false, false); + public static final Race HUMAN = register("human", false, FlightType.NONE, false, false); + public static final Race EARTH = register("earth", false, FlightType.NONE, true, false); + public static final Race UNICORN = register("unicorn", true, FlightType.NONE, false, false); + public static final Race PEGASUS = register("pegasus", false, FlightType.AVIAN, false, false); + public static final Race BAT = register("bat", false, FlightType.AVIAN, false, true); + public static final Race ALICORN = register("alicorn", true, FlightType.AVIAN, true, false); + public static final Race CHANGELING = register("changeling", false, FlightType.INSECTOID, false, false); public static void bootstrap() {} - private final boolean magic; - private final FlightType flight; - private final boolean earth; - - Race(boolean magic, FlightType flight, boolean earth) { - this.magic = magic; - this.flight = flight; - this.earth = earth; - } - @Override public Affinity getAffinity() { return this == CHANGELING ? Affinity.BAD : Affinity.NEUTRAL; @@ -90,20 +80,8 @@ public final class Race implements Affine { return this == ALICORN; } - public FlightType getFlightType() { - return flight; - } - public boolean canFly() { - return !getFlightType().isGrounded(); - } - - public boolean canCast() { - return magic; - } - - public boolean canUseEarth() { - return earth; + return !flightType().isGrounded(); } public boolean canInteractWithClouds() { diff --git a/src/main/java/com/minelittlepony/unicopia/UGameRules.java b/src/main/java/com/minelittlepony/unicopia/UGameRules.java index 275b2f89..8b6cea3f 100644 --- a/src/main/java/com/minelittlepony/unicopia/UGameRules.java +++ b/src/main/java/com/minelittlepony/unicopia/UGameRules.java @@ -7,6 +7,7 @@ import net.minecraft.world.GameRules.IntRule; public interface UGameRules { GameRules.Key SWAP_TRIBE_ON_DEATH = GameRules.register("swapTribeOnDeath", GameRules.Category.SPAWNING, BooleanRule.create(false)); GameRules.Key ANNOUNCE_TRIBE_JOINS = GameRules.register("announceTribeJoins", GameRules.Category.SPAWNING, BooleanRule.create(false)); + GameRules.Key DO_NOCTURNAL_BAT_PONIES = GameRules.register("doNocturnalBatPonies", GameRules.Category.PLAYER, BooleanRule.create(true)); GameRules.Key WEATHER_EFFECTS_STRENGTH = GameRules.register("weatherEffectsStrength", GameRules.Category.MISC, IntRule.create(100)); static void bootstrap() { } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java index 5739db70..b5a76098 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityAppearance.java @@ -220,7 +220,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi @SuppressWarnings("unchecked") Pony iplayer = Pony.of(((Owned)entity).getMaster()); - return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType(); + return iplayer == null ? FlightType.NONE : iplayer.getSpecies().flightType(); } if (entity instanceof FlyingEntity diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 401470bb..9a642bf9 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -158,7 +158,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab .filter(effect -> !effect.isDead() && effect instanceof FlightType.Provider) .map(effect -> ((FlightType.Provider)effect).getFlightType()) .filter(FlightType::isPresent) - .orElse(pony.getSpecies().getFlightType()); + .orElse(pony.getSpecies().flightType()); } public void cancelFlight(boolean force) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index a3577633..939492bb 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -570,6 +570,10 @@ public class Pony extends Living implements Copyable, Update .map(p -> Text.translatable("block.unicopia.bed.not_safe")); } + public boolean isDaytime() { + return asWorld().getGameRules().getBoolean(UGameRules.DO_NOCTURNAL_BAT_PONIES) && getActualSpecies().isNocturnal() ? !asWorld().isDay() : asWorld().isDay(); + } + @Override public boolean isEnemy(Affine other) { return getArmour().contains(UItems.ALICORN_AMULET) || super.isEnemy(other); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java index e4a389b5..20581ea8 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java @@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.entity.duck.PlayerEntityDuck; @@ -24,6 +25,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.stat.Stats; import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; @Mixin(PlayerEntity.class) abstract class MixinPlayerEntity extends LivingEntity implements Equine.Container, PlayerEntityDuck { @@ -99,4 +101,12 @@ abstract class MixinPlayerEntity extends LivingEntity implements Equine.Containe private void onGetBlockBreakingSpeed(BlockState state, CallbackInfoReturnable info) { info.setReturnValue(info.getReturnValue() * get().getBlockBreakingSpeed()); } + + @Redirect(method = "tick", at = @At( + value = "INVOKE", + target = "net/minecraft/world/World.isDay()Z" + )) + private boolean redirectIsDay(World world) { + return get().isDaytime(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java index 0d84d448..4b7b3998 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java @@ -4,6 +4,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.entity.Equine; @@ -12,6 +13,7 @@ import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.screen.ScreenHandlerListener; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.world.World; @Mixin(ServerPlayerEntity.class) abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHandlerListener, Equine.Container, ServerPlayerEntityDuck { @@ -27,4 +29,11 @@ abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHan get().copyFrom(((Equine.Container)oldPlayer).get(), alive); } + @Redirect(method = "trySleep", at = @At( + value = "INVOKE", + target = "net/minecraft/world/World.isDay()Z" + )) + private boolean redirectIsDay(World world) { + return get().isDaytime(); + } }