diff --git a/Common/src/main/java/at/petrak/hexcasting/annotations/SoftImplement.java b/Common/src/main/java/at/petrak/hexcasting/annotations/SoftImplement.java index c90949187f..caf4cfdcf2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/annotations/SoftImplement.java +++ b/Common/src/main/java/at/petrak/hexcasting/annotations/SoftImplement.java @@ -9,22 +9,18 @@ // yoinky sploinky /** - * A purely-documentative annotation. - * This annotation is used by developers in xplat code. The annotated method is intended - * to "soft implement" a certain method in a loader specific interface that cannot be - * named in xplat code and thus cannot be checked with @Override. - * In this context, "soft implement" means to implement the method by matching the signature - * with the intended interface method. - * Examples of interfaces that we would use this for is IForgeItem or FabricItem. - *

- * The intent is that we audit such sites every major Minecraft version or so, to ensure - * that they still properly override the intended target. + * A purely-documentative annotation. This annotation is used by developers in xplat code. The + * annotated method is intended to "soft implement" a certain method in a loader specific interface + * that cannot be named in xplat code and thus cannot be checked with @Override. In this context, + * "soft implement" means to implement the method by matching the signature with the intended + * interface method. Examples of interfaces that we would use this for is IForgeItem or FabricItem. + * + *

The intent is that we audit such sites every major Minecraft version or so, to ensure that + * they still properly override the intended target. */ @Retention(RetentionPolicy.SOURCE) @Target(ElementType.METHOD) public @interface SoftImplement { - /** - * What interface we're soft implementing - */ + /** What interface we're soft implementing */ String value(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java index 8ddde5669b..73b63bdc2f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java @@ -6,7 +6,9 @@ import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.player.Sentinel; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import com.google.common.base.Suppliers; + import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; @@ -16,7 +18,6 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ArmorItem; @@ -24,6 +25,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.phys.Vec3; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; @@ -36,23 +38,27 @@ public interface HexAPI { String MOD_ID = "hexcasting"; Logger LOGGER = LogManager.getLogger(MOD_ID); - Supplier INSTANCE = Suppliers.memoize(() -> { - try { - return (HexAPI) Class.forName("at.petrak.hexcasting.common.impl.HexAPIImpl") - .getDeclaredConstructor().newInstance(); - } catch (ReflectiveOperationException e) { - LogManager.getLogger().warn("Unable to find HexAPIImpl, using a dummy"); - return new HexAPI() { - }; - } - }); + Supplier INSTANCE = + Suppliers.memoize( + () -> { + try { + return (HexAPI) + Class.forName("at.petrak.hexcasting.common.impl.HexAPIImpl") + .getDeclaredConstructor() + .newInstance(); + } catch (ReflectiveOperationException e) { + LogManager.getLogger().warn("Unable to find HexAPIImpl, using a dummy"); + return new HexAPI() {}; + } + }); /** * Return the localization key for the given action. - *

- * Note we're allowed to have action resource keys on the client, just no actual actions. - *

- * Special handlers should be calling {@link SpecialHandler#getName()} + * + *

Note we're allowed to have action resource keys on the client, just no actual + * actions. + * + *

Special handlers should be calling {@link SpecialHandler#getName()} */ default String getActionI18nKey(ResourceKey action) { return "hexcasting.action.%s".formatted(action.location().toString()); @@ -63,7 +69,8 @@ default String getSpecialHandlerI18nKey(ResourceKey> a } /** - * Currently introspection/retrospection/consideration are hardcoded, but at least their names won't be + * Currently introspection/retrospection/consideration are hardcoded, but at least their names + * won't be */ default String getRawHookI18nKey(ResourceLocation name) { return "hexcasting.rawhook.%s".formatted(name); @@ -71,29 +78,31 @@ default String getRawHookI18nKey(ResourceLocation name) { default Component getActionI18n(ResourceKey key, boolean isGreat) { return Component.translatable(getActionI18nKey(key)) - .withStyle(isGreat ? ChatFormatting.GOLD : ChatFormatting.LIGHT_PURPLE); + .withStyle(isGreat ? ChatFormatting.GOLD : ChatFormatting.LIGHT_PURPLE); } default Component getSpecialHandlerI18n(ResourceKey> key) { return Component.translatable(getSpecialHandlerI18nKey(key)) - .withStyle(ChatFormatting.LIGHT_PURPLE); + .withStyle(ChatFormatting.LIGHT_PURPLE); } default Component getRawHookI18n(ResourceLocation name) { - return Component.translatable(getRawHookI18nKey(name)).withStyle(ChatFormatting.LIGHT_PURPLE); + return Component.translatable(getRawHookI18nKey(name)) + .withStyle(ChatFormatting.LIGHT_PURPLE); } /** - * Register an entity with the given ID to have its velocity as perceived by OpEntityVelocity be different - * than it's "normal" velocity + * Register an entity with the given ID to have its velocity as perceived by OpEntityVelocity be + * different than it's "normal" velocity */ // Should be OK to use the type directly as the key as they're singleton identity objects - default void registerSpecialVelocityGetter(EntityType key, EntityVelocityGetter getter) { - } + default void registerSpecialVelocityGetter( + EntityType key, EntityVelocityGetter getter) {} /** - * If the entity has had a special getter registered with {@link HexAPI#registerSpecialVelocityGetter} then - * return that, otherwise return its normal delta movement + * If the entity has had a special getter registered with {@link + * HexAPI#registerSpecialVelocityGetter} then return that, otherwise return its normal delta + * movement */ default Vec3 getEntityVelocitySpecial(Entity entity) { return entity.getDeltaMovement(); @@ -106,36 +115,34 @@ interface EntityVelocityGetter { /** * Register an entity type to have a custom behavior when getting brainswept. - *

- * This knocks out the normal behavior; if you want that behavior you should call + * + *

This knocks out the normal behavior; if you want that behavior you should call */ - default void registerCustomBrainsweepingBehavior(EntityType key, Consumer hook) { - } + default void registerCustomBrainsweepingBehavior( + EntityType key, Consumer hook) {} /** * The default behavior when an entity gets brainswept. - *

- * Something registered with {@link HexAPI#registerCustomBrainsweepingBehavior} doesn't call this automatically; - * you can use this to add things on top of the default behavior + * + *

Something registered with {@link HexAPI#registerCustomBrainsweepingBehavior} doesn't call + * this automatically; you can use this to add things on top of the default behavior */ default Consumer defaultBrainsweepingBehavior() { - return mob -> { - }; + return mob -> {}; } /** - * If something special's been returned with {@link HexAPI#registerCustomBrainsweepingBehavior}, return that, - * otherwise return the default behavior + * If something special's been returned with {@link HexAPI#registerCustomBrainsweepingBehavior}, + * return that, otherwise return the default behavior */ default Consumer getBrainsweepBehavior(EntityType mobType) { - return mob -> { - }; + return mob -> {}; } /** * Brainsweep (flay the mind of) the given mob. - *

- * This ignores the unbrainsweepable tag. + * + *

This ignores the unbrainsweepable tag. */ default void brainsweep(Mob mob) { var type = (EntityType) mob.getType(); @@ -165,61 +172,59 @@ default FrozenPigment getColorizer(Player player) { return FrozenPigment.DEFAULT.get(); } - ArmorMaterial DUMMY_ARMOR_MATERIAL = new ArmorMaterial() { - @Override - public int getDurabilityForType(ArmorItem.Type type) { - return 0; - } - - @Override - public int getDefenseForType(ArmorItem.Type type) { - return 0; - } - - @Override - public int getEnchantmentValue() { - return 0; - } - - @NotNull - @Override - public SoundEvent getEquipSound() { - return SoundEvents.ARMOR_EQUIP_LEATHER; - } - - @NotNull - @Override - public Ingredient getRepairIngredient() { - return Ingredient.EMPTY; - } - - @Override - public String getName() { - return "missingno"; - } - - @Override - public float getToughness() { - return 0; - } - - @Override - public float getKnockbackResistance() { - return 0; - } - }; + ArmorMaterial DUMMY_ARMOR_MATERIAL = + new ArmorMaterial() { + @Override + public int getDurabilityForType(ArmorItem.Type type) { + return 0; + } + + @Override + public int getDefenseForType(ArmorItem.Type type) { + return 0; + } + + @Override + public int getEnchantmentValue() { + return 0; + } + + @NotNull + @Override + public SoundEvent getEquipSound() { + return SoundEvents.ARMOR_EQUIP_LEATHER; + } + + @NotNull + @Override + public Ingredient getRepairIngredient() { + return Ingredient.EMPTY; + } + + @Override + public String getName() { + return "missingno"; + } + + @Override + public float getToughness() { + return 0; + } + + @Override + public float getKnockbackResistance() { + return 0; + } + }; default ArmorMaterial robesMaterial() { return DUMMY_ARMOR_MATERIAL; } - /** - * Location in the userdata of the ravenmind - */ + /** Location in the userdata of the ravenmind */ String RAVENMIND_USERDATA = modLoc("ravenmind").toString(); - /** - * Location in the userdata of the number of ops executed - */ + + /** Location in the userdata of the number of ops executed */ String OP_COUNT_USERDATA = modLoc("op_count").toString(); String MARKED_MOVED_USERDATA = modLoc("impulsed").toString(); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADHexHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADHexHolder.java index 15defd673b..65a16ea2f6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADHexHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADHexHolder.java @@ -2,7 +2,9 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.pigment.FrozenPigment; + import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.Nullable; import java.util.List; @@ -20,5 +22,6 @@ public interface ADHexHolder { void clearHex(); - @Nullable FrozenPigment getPigment(); + @Nullable + FrozenPigment getPigment(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java index 7b8fcc1c95..042c1fcab8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADIotaHolder.java @@ -2,8 +2,10 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.casting.iota.IotaType; + import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.Nullable; public interface ADIotaHolder { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADMediaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADMediaHolder.java index 547f6afc31..cfce695bd6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADMediaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADMediaHolder.java @@ -30,38 +30,32 @@ public interface ADMediaHolder { @ApiStatus.OverrideOnly void setMedia(long media); - /** - * Whether this media holder can have media inserted into it. - */ + /** Whether this media holder can have media inserted into it. */ boolean canRecharge(); - /** - * Whether this media holder can be extracted from. - */ + /** Whether this media holder can be extracted from. */ boolean canProvide(); /** - * The priority for this media holder to be selected when casting a hex. Higher priorities are taken first. - *

- * By default, - * * Charged Amethyst has priority 1000 - * * Amethyst Shards have priority 2000 - * * Amethyst Dust has priority 3000 - * * Items which hold media have priority 4000 + * The priority for this media holder to be selected when casting a hex. Higher priorities are + * taken first. + * + *

By default, * Charged Amethyst has priority 1000 * Amethyst Shards have priority 2000 * + * Amethyst Dust has priority 3000 * Items which hold media have priority 4000 */ int getConsumptionPriority(); - /** - * Whether the media inside this media holder may be used to construct a battery. - */ + /** Whether the media inside this media holder may be used to construct a battery. */ boolean canConstructBattery(); /** - * Withdraws media from the holder. Returns the amount of media extracted, which may be less or more than the cost. - *

- * Even if {@link ADMediaHolder#canProvide} is false, you can still withdraw media this way. - *

- * Withdrawing a negative amount will act as though you attempted to withdraw as much media as the holder contains. + * Withdraws media from the holder. Returns the amount of media extracted, which may be less or + * more than the cost. + * + *

Even if {@link ADMediaHolder#canProvide} is false, you can still withdraw media this way. + * + *

Withdrawing a negative amount will act as though you attempted to withdraw as much media + * as the holder contains. */ default long withdrawMedia(long cost, boolean simulate) { var mediaHere = getMedia(); @@ -76,12 +70,13 @@ default long withdrawMedia(long cost, boolean simulate) { } /** - * Inserts media into the holder. Returns the amount of media inserted, which may be less than the requested amount. - *

- * Even if {@link ADMediaHolder#canRecharge} is false, you can still insert media this way. - *

- * Inserting a negative amount will act as though you attempted to insert exactly as much media as the holder was - * missing. + * Inserts media into the holder. Returns the amount of media inserted, which may be less than + * the requested amount. + * + *

Even if {@link ADMediaHolder#canRecharge} is false, you can still insert media this way. + * + *

Inserting a negative amount will act as though you attempted to insert exactly as much + * media as the holder was missing. */ default long insertMedia(long amount, boolean simulate) { var mediaHere = getMedia(); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADPigment.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADPigment.java index 86984439c9..f5dbfb7ab0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADPigment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADPigment.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.addldata; import at.petrak.hexcasting.api.pigment.ColorProvider; + import net.minecraft.util.FastColor; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; @@ -11,11 +12,13 @@ public interface ADPigment { ColorProvider provideColor(UUID owner); static int morphBetweenColors(int[] colors, Vec3 gradientDir, float time, Vec3 position) { - float fIdx = Mth.positiveModulo(time + (float) gradientDir.dot(position), 1f) * colors.length; + float fIdx = + Mth.positiveModulo(time + (float) gradientDir.dot(position), 1f) * colors.length; int baseIdx = Mth.floor(fIdx); float tRaw = fIdx - baseIdx; - float t = tRaw < 0.5 ? 4 * tRaw * tRaw * tRaw : (float) (1 - Math.pow(-2 * tRaw + 2, 3) / 2); + float t = + tRaw < 0.5 ? 4 * tRaw * tRaw * tRaw : (float) (1 - Math.pow(-2 * tRaw + 2, 3) / 2); int start = colors[baseIdx % colors.length]; int end = colors[(baseIdx + 1) % colors.length]; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADVariantItem.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADVariantItem.java index 6b1a59f76d..49b290e41f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADVariantItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ADVariantItem.java @@ -2,8 +2,8 @@ public interface ADVariantItem { int numVariants(); - int getVariant(); + int getVariant(); void setVariant(int variant); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java index 5af67a99ab..d100bb8b3a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ItemDelegatingEntityIotaHolder.java @@ -3,11 +3,13 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.common.entities.EntityWallScroll; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; + import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -18,7 +20,8 @@ public abstract class ItemDelegatingEntityIotaHolder implements ADIotaHolder { private final Consumer save; - public ItemDelegatingEntityIotaHolder(Supplier stackSupplier, Consumer save) { + public ItemDelegatingEntityIotaHolder( + Supplier stackSupplier, Consumer save) { this.stackSupplier = stackSupplier; this.save = save; } @@ -60,12 +63,14 @@ public boolean writeIota(@Nullable Iota datum, boolean simulate) { public static class ToItemEntity extends ItemDelegatingEntityIotaHolder { public ToItemEntity(ItemEntity entity) { - super(entity::getItem, stack -> { - // https://github.com/VazkiiMods/Botania/blob/e6d095ff5010074b45408d6cce8ee1e328af3383/Xplat/src/main/java/vazkii/botania/common/helper/EntityHelper.java#L16 - entity.setItem(ItemStack.EMPTY); - entity.setItem(stack); - entity.setUnlimitedLifetime(); - }); + super( + entity::getItem, + stack -> { + // https://github.com/VazkiiMods/Botania/blob/e6d095ff5010074b45408d6cce8ee1e328af3383/Xplat/src/main/java/vazkii/botania/common/helper/EntityHelper.java#L16 + entity.setItem(ItemStack.EMPTY); + entity.setItem(stack); + entity.setUnlimitedLifetime(); + }); } } @@ -77,8 +82,7 @@ public ToItemFrame(ItemFrame entity) { public static class ToWallScroll extends ItemDelegatingEntityIotaHolder { public ToWallScroll(EntityWallScroll entity) { - super(() -> entity.scroll.copy(), stack -> { - }); + super(() -> entity.scroll.copy(), stack -> {}); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/package-info.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/package-info.java index a11787c85a..0e6736a833 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/addldata/package-info.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/package-info.java @@ -1,10 +1,11 @@ /** * An "Additional Data," or AD, is what I am calling the abstraction over capabilities on Forge and * cardinal components on Fabric. - *

- * An {@code ADFooBar} in this package will be implemented by a {@code CCFooBar} on Fabric. - * On Forge, there are a set of private records that implement them. - *

- * The point is, this provides an interface for interacting with however whatever platform sticks extra info on stuff. + * + *

An {@code ADFooBar} in this package will be implemented by a {@code CCFooBar} on Fabric. On + * Forge, there are a set of private records that implement them. + * + *

The point is, this provides an interface for interacting with however whatever platform sticks + * extra info on stuff. */ package at.petrak.hexcasting.api.addldata; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java index fe85fec5b3..19acd6106d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/FailToCastGreatSpellTrigger.java @@ -1,12 +1,15 @@ package at.petrak.hexcasting.api.advancements; import com.google.gson.JsonObject; + import net.minecraft.advancements.critereon.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -public class FailToCastGreatSpellTrigger extends SimpleCriterionTrigger { - private static final ResourceLocation ID = new ResourceLocation("hexcasting", "fail_to_cast_great_spell"); +public class FailToCastGreatSpellTrigger + extends SimpleCriterionTrigger { + private static final ResourceLocation ID = + new ResourceLocation("hexcasting", "fail_to_cast_great_spell"); @Override public ResourceLocation getId() { @@ -14,7 +17,8 @@ public ResourceLocation getId() { } @Override - protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, DeserializationContext context) { + protected Instance createInstance( + JsonObject json, ContextAwarePredicate predicate, DeserializationContext context) { return new Instance(predicate); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java index 16af02ab39..40f67c99a7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/HexAdvancementTriggers.java @@ -5,7 +5,8 @@ public class HexAdvancementTriggers { public static final OvercastTrigger OVERCAST_TRIGGER = new OvercastTrigger(); public static final SpendMediaTrigger SPEND_MEDIA_TRIGGER = new SpendMediaTrigger(); - public static final FailToCastGreatSpellTrigger FAIL_GREAT_SPELL_TRIGGER = new FailToCastGreatSpellTrigger(); + public static final FailToCastGreatSpellTrigger FAIL_GREAT_SPELL_TRIGGER = + new FailToCastGreatSpellTrigger(); public static void registerTriggers() { CriteriaTriggersAccessor.hex$register(OVERCAST_TRIGGER); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java index 0be502c86e..070ebb6aa7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/MinMaxLongs.java @@ -4,21 +4,22 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.BuiltInExceptionProvider; import com.mojang.brigadier.exceptions.CommandSyntaxException; + import net.minecraft.advancements.critereon.MinMaxBounds; import net.minecraft.util.GsonHelper; -import javax.annotation.Nullable; import java.util.Objects; import java.util.function.Function; +import javax.annotation.Nullable; + public class MinMaxLongs extends MinMaxBounds { public static final MinMaxLongs ANY = new MinMaxLongs(null, null); - @Nullable - private final Long minSq; - @Nullable - private final Long maxSq; + @Nullable private final Long minSq; + @Nullable private final Long maxSq; - private static MinMaxLongs create(StringReader reader, @Nullable Long min, @Nullable Long max) throws CommandSyntaxException { + private static MinMaxLongs create(StringReader reader, @Nullable Long min, @Nullable Long max) + throws CommandSyntaxException { if (min != null && max != null && min > max) { throw ERROR_SWAPPED.createWithContext(reader); } else { @@ -77,9 +78,15 @@ public static MinMaxLongs fromReader(StringReader reader) throws CommandSyntaxEx return fromReader(reader, (l) -> l); } - public static MinMaxLongs fromReader(StringReader reader, Function map) throws CommandSyntaxException { + public static MinMaxLongs fromReader(StringReader reader, Function map) + throws CommandSyntaxException { BuiltInExceptionProvider builtInExceptions = CommandSyntaxException.BUILT_IN_EXCEPTIONS; Objects.requireNonNull(builtInExceptions); - return fromReader(reader, MinMaxLongs::create, Long::parseLong, builtInExceptions::readerInvalidInt, map); + return fromReader( + reader, + MinMaxLongs::create, + Long::parseLong, + builtInExceptions::readerInvalidInt, + map); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java index b1661e869e..dfb9d3345a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/OvercastTrigger.java @@ -1,7 +1,9 @@ package at.petrak.hexcasting.api.advancements; import at.petrak.hexcasting.api.mod.HexConfig; + import com.google.gson.JsonObject; + import net.minecraft.advancements.critereon.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; @@ -16,7 +18,7 @@ public class OvercastTrigger extends SimpleCriterionTrigger { - var mediaToHealth = HexConfig.common().mediaToHealthRate(); - var healthUsed = mediaGenerated / mediaToHealth; - return inst.test(mediaGenerated, healthUsed / player.getMaxHealth(), player.getHealth()); - }); + super.trigger( + player, + inst -> { + var mediaToHealth = HexConfig.common().mediaToHealthRate(); + var healthUsed = mediaGenerated / mediaToHealth; + return inst.test( + mediaGenerated, healthUsed / player.getMaxHealth(), player.getHealth()); + }); } public static class Instance extends AbstractCriterionTriggerInstance { @@ -47,8 +53,11 @@ public static class Instance extends AbstractCriterionTriggerInstance { // DID YOU KNOW THERES ONE TO CHECK THE WORLD TIME, BUT NOT THE HEALTH!? protected final MinMaxBounds.Doubles healthLeft; - public Instance(ContextAwarePredicate predicate, MinMaxBounds.Ints mediaGenerated, - MinMaxBounds.Doubles healthUsed, MinMaxBounds.Doubles healthLeft) { + public Instance( + ContextAwarePredicate predicate, + MinMaxBounds.Ints mediaGenerated, + MinMaxBounds.Doubles healthUsed, + MinMaxBounds.Doubles healthLeft) { super(OvercastTrigger.ID, predicate); this.mediaGenerated = mediaGenerated; this.healthUsed = healthUsed; @@ -78,9 +87,10 @@ public JsonObject serializeToJson(SerializationContext ctx) { private boolean test(int mediaGeneratedIn, double healthUsedIn, float healthLeftIn) { return this.mediaGenerated.matches(mediaGeneratedIn) - && this.healthUsed.matches(healthUsedIn) - // DID YOU KNOW ALL THE ENEITYT PREDICATES ARE HARD-CODED AND YOU CANT MAKE NEW ONES - && this.healthLeft.matches(healthLeftIn); + && this.healthUsed.matches(healthUsedIn) + // DID YOU KNOW ALL THE ENEITYT PREDICATES ARE HARD-CODED AND YOU CANT MAKE NEW + // ONES + && this.healthLeft.matches(healthLeftIn); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java b/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java index d610807f59..282872cf45 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/advancements/SpendMediaTrigger.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.advancements; import com.google.gson.JsonObject; + import net.minecraft.advancements.critereon.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; @@ -17,11 +18,12 @@ public ResourceLocation getId() { } @Override - protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate, - DeserializationContext context) { - return new Instance(predicate, - MinMaxLongs.fromJson(json.get(TAG_MEDIA_SPENT)), - MinMaxLongs.fromJson(json.get(TAG_MEDIA_WASTED))); + protected Instance createInstance( + JsonObject json, ContextAwarePredicate predicate, DeserializationContext context) { + return new Instance( + predicate, + MinMaxLongs.fromJson(json.get(TAG_MEDIA_SPENT)), + MinMaxLongs.fromJson(json.get(TAG_MEDIA_WASTED))); } public void trigger(ServerPlayer player, long mediaSpent, long mediaWasted) { @@ -32,8 +34,8 @@ public static class Instance extends AbstractCriterionTriggerInstance { protected final MinMaxLongs mediaSpent; protected final MinMaxLongs mediaWasted; - public Instance(ContextAwarePredicate predicate, MinMaxLongs mediaSpent, - MinMaxLongs mediaWasted) { + public Instance( + ContextAwarePredicate predicate, MinMaxLongs mediaSpent, MinMaxLongs mediaWasted) { super(SpendMediaTrigger.ID, predicate); this.mediaSpent = mediaSpent; this.mediaWasted = mediaWasted; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java b/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java index e531ddb12d..99f06eebdf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/block/HexBlockEntity.java @@ -10,7 +10,8 @@ import net.minecraft.world.level.block.state.BlockState; public abstract class HexBlockEntity extends BlockEntity { - public HexBlockEntity(BlockEntityType pType, BlockPos pWorldPosition, BlockState pBlockState) { + public HexBlockEntity( + BlockEntityType pType, BlockPos pWorldPosition, BlockState pBlockState) { super(pType, pWorldPosition, pBlockState); } @@ -43,7 +44,7 @@ public Packet getUpdatePacket() { public void sync() { this.setChanged(); - this.level.sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 3); + this.level.sendBlockUpdated( + this.getBlockPos(), this.getBlockState(), this.getBlockState(), 3); } - } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java b/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java index d5197fce68..5b935a73eb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockAbstractImpetus.java @@ -3,6 +3,7 @@ import at.petrak.hexcasting.api.casting.circles.BlockEntityAbstractImpetus; import at.petrak.hexcasting.api.casting.eval.env.CircleCastEnv; import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; + import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; @@ -27,18 +28,28 @@ public abstract class BlockAbstractImpetus extends BlockCircleComponent implemen public BlockAbstractImpetus(Properties p_49795_) { super(p_49795_); this.registerDefaultState( - this.stateDefinition.any().setValue(ENERGIZED, false).setValue(FACING, Direction.NORTH)); + this.stateDefinition + .any() + .setValue(ENERGIZED, false) + .setValue(FACING, Direction.NORTH)); } @Override - public ControlFlow acceptControlFlow(CastingImage imageIn, CircleCastEnv env, Direction enterDir, BlockPos pos, - BlockState bs, ServerLevel world) { + public ControlFlow acceptControlFlow( + CastingImage imageIn, + CircleCastEnv env, + Direction enterDir, + BlockPos pos, + BlockState bs, + ServerLevel world) { return new ControlFlow.Stop(); } @Override - public boolean canEnterFromDirection(Direction enterDir, BlockPos pos, BlockState bs, ServerLevel world) { - // FACING is the direction media EXITS from, so we can't have media entering in that direction + public boolean canEnterFromDirection( + Direction enterDir, BlockPos pos, BlockState bs, ServerLevel world) { + // FACING is the direction media EXITS from, so we can't have media entering in that + // direction // so, flip it return enterDir != bs.getValue(FACING).getOpposite(); } @@ -60,15 +71,21 @@ public float particleHeight(BlockPos pos, BlockState bs, Level world) { @Override public void tick(BlockState pState, ServerLevel pLevel, BlockPos pPos, RandomSource pRandom) { - if (pLevel.getBlockEntity(pPos) instanceof BlockEntityAbstractImpetus tile && pState.getValue(ENERGIZED)) { + if (pLevel.getBlockEntity(pPos) instanceof BlockEntityAbstractImpetus tile + && pState.getValue(ENERGIZED)) { tile.tickExecution(); } } @Override - public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) { + public void onRemove( + BlockState pState, + Level pLevel, + BlockPos pPos, + BlockState pNewState, + boolean pIsMoving) { if (!pNewState.is(pState.getBlock()) - && pLevel.getBlockEntity(pPos) instanceof BlockEntityAbstractImpetus impetus) { + && pLevel.getBlockEntity(pPos) instanceof BlockEntityAbstractImpetus impetus) { impetus.endExecution(); // TODO: Determine if this was important // TODO: Fix this, it should make all the glowy circle components stop glowing. } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockCircleComponent.java b/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockCircleComponent.java index f2c1458c7b..e8f59112e7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockCircleComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/block/circle/BlockCircleComponent.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.block.circle; import at.petrak.hexcasting.api.casting.circles.ICircleComponent; + import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; @@ -41,15 +42,16 @@ public BlockState endEnergized(BlockPos pos, BlockState bs, Level world) { } /** - * Which direction points "up" or "out" for this block? - * This is used for {@link ICircleComponent#canEnterFromDirection(Direction, BlockPos, BlockState, ServerLevel)} - * as well as particles. + * Which direction points "up" or "out" for this block? This is used for {@link + * ICircleComponent#canEnterFromDirection(Direction, BlockPos, BlockState, ServerLevel)} as well + * as particles. */ public Direction normalDir(BlockPos pos, BlockState bs, Level world) { return normalDir(pos, bs, world, 16); } - abstract public Direction normalDir(BlockPos pos, BlockState bs, Level world, int recursionLeft); + public abstract Direction normalDir( + BlockPos pos, BlockState bs, Level world, int recursionLeft); public static Direction normalDirOfOther(BlockPos other, Level world, int recursionLeft) { if (recursionLeft <= 0) { @@ -65,10 +67,10 @@ public static Direction normalDirOfOther(BlockPos other, Level world, int recurs } /** - * How many blocks in the {@link BlockCircleComponent#normalDir(BlockPos, BlockState, Level)} from the center - * particles should be spawned in + * How many blocks in the {@link BlockCircleComponent#normalDir(BlockPos, BlockState, Level)} + * from the center particles should be spawned in */ - abstract public float particleHeight(BlockPos pos, BlockState bs, Level world); + public abstract float particleHeight(BlockPos pos, BlockState bs, Level world); @Override protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionRegistryEntry.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionRegistryEntry.java index dbc5dc060b..d7bb7876b6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionRegistryEntry.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionRegistryEntry.java @@ -6,10 +6,9 @@ /** * A bit of wrapper information around an action to go in the registry. * - * @param prototype The pattern associated with this action. The start dir acts as the "canonical" start direction - * for display in the book. For per-world patterns, the angle signature is the *shape* of the pattern - * but probably not the pattern itself. - * @param action The action itself + * @param prototype The pattern associated with this action. The start dir acts as the "canonical" + * start direction for display in the book. For per-world patterns, the angle signature is the + * *shape* of the pattern but probably not the pattern itself. + * @param action The action itself */ -public record ActionRegistryEntry(HexPattern prototype, Action action) { -} +public record ActionRegistryEntry(HexPattern prototype, Action action) {} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt index c6dda37c9a..79f8af0147 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/ActionUtils.kt @@ -8,6 +8,10 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.utils.asTranslatedComponent import com.mojang.datafixers.util.Either +import java.util.function.DoubleUnaryOperator +import kotlin.math.abs +import kotlin.math.roundToInt +import kotlin.math.roundToLong import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.Entity @@ -17,10 +21,6 @@ import net.minecraft.world.entity.decoration.ArmorStand import net.minecraft.world.entity.item.ItemEntity import net.minecraft.world.phys.Vec3 import org.joml.Vector3f -import java.util.function.DoubleUnaryOperator -import kotlin.math.abs -import kotlin.math.roundToInt -import kotlin.math.roundToLong fun List.getDouble(idx: Int, argc: Int = 0): Double { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } @@ -83,8 +83,7 @@ fun List.getItemEntity(idx: Int, argc: Int = 0): ItemEntity { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity - if (e is ItemEntity) - return e + if (e is ItemEntity) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.item") } @@ -93,8 +92,7 @@ fun List.getPlayer(idx: Int, argc: Int = 0): ServerPlayer { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity - if (e is ServerPlayer) - return e + if (e is ServerPlayer) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.player") } @@ -103,8 +101,7 @@ fun List.getMob(idx: Int, argc: Int = 0): Mob { val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity - if (e is Mob) - return e + if (e is Mob) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.mob") } @@ -113,8 +110,7 @@ fun List.getLivingEntityButNotArmorStand(idx: Int, argc: Int = 0): LivingE val x = this.getOrElse(idx) { throw MishapNotEnoughArgs(idx + 1, this.size) } if (x is EntityIota) { val e = x.entity - if (e is LivingEntity && e !is ArmorStand) - return e + if (e is LivingEntity && e !is ArmorStand) return e } throw MishapInvalidIota.ofType(x, if (argc == 0) idx else argc - (idx + 1), "entity.living") } @@ -138,7 +134,8 @@ fun List.getPositiveDoubleUnder(idx: Int, max: Double, argc: Int = 0): Dou return double } } - throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.positive.less", max) + throw MishapInvalidIota.of( + x, if (argc == 0) idx else argc - (idx + 1), "double.positive.less", max) } fun List.getPositiveDoubleUnderInclusive(idx: Int, max: Double, argc: Int = 0): Double { @@ -149,7 +146,8 @@ fun List.getPositiveDoubleUnderInclusive(idx: Int, max: Double, argc: Int return double } } - throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.positive.less.equal", max) + throw MishapInvalidIota.of( + x, if (argc == 0) idx else argc - (idx + 1), "double.positive.less.equal", max) } fun List.getDoubleBetween(idx: Int, min: Double, max: Double, argc: Int = 0): Double { @@ -160,7 +158,8 @@ fun List.getDoubleBetween(idx: Int, min: Double, max: Double, argc: Int = return double } } - throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "double.between", min, max) + throw MishapInvalidIota.of( + x, if (argc == 0) idx else argc - (idx + 1), "double.between", min, max) } fun List.getInt(idx: Int, argc: Int = 0): Int { @@ -184,7 +183,8 @@ fun List.getLong(idx: Int, argc: Int = 0): Long { return rounded } } - throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int") // shh we're lying + throw MishapInvalidIota.of( + x, if (argc == 0) idx else argc - (idx + 1), "int") // shh we're lying } fun List.getPositiveInt(idx: Int, argc: Int = 0): Int { @@ -220,7 +220,8 @@ fun List.getPositiveIntUnder(idx: Int, max: Int, argc: Int = 0): Int { return rounded } } - throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less", max) + throw MishapInvalidIota.of( + x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less", max) } fun List.getPositiveIntUnderInclusive(idx: Int, max: Int, argc: Int = 0): Int { @@ -232,7 +233,8 @@ fun List.getPositiveIntUnderInclusive(idx: Int, max: Int, argc: Int = 0): return rounded } } - throw MishapInvalidIota.of(x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less.equal", max) + throw MishapInvalidIota.of( + x, if (argc == 0) idx else argc - (idx + 1), "int.positive.less.equal", max) } fun List.getIntBetween(idx: Int, min: Int, max: Int, argc: Int = 0): Int { @@ -261,11 +263,8 @@ fun List.getNumOrVec(idx: Int, argc: Int = 0): Either { return when (datum) { is DoubleIota -> Either.left(datum.double) is Vec3Iota -> Either.right(datum.vec3) - else -> throw MishapInvalidIota.of( - datum, - if (argc == 0) idx else argc - (idx + 1), - "numvec" - ) + else -> + throw MishapInvalidIota.of(datum, if (argc == 0) idx else argc - (idx + 1), "numvec") } } @@ -280,21 +279,19 @@ fun List.getLongOrList(idx: Int, argc: Int = 0): Either { } else if (datum is ListIota) { return Either.right(datum.list) } - throw MishapInvalidIota.of( - datum, - if (argc == 0) idx else argc - (idx + 1), - "numlist" - ) + throw MishapInvalidIota.of(datum, if (argc == 0) idx else argc - (idx + 1), "numlist") } fun evaluatable(datum: Iota, reverseIdx: Int): Either = when (datum) { is ListIota -> Either.right(datum.list) - else -> if (datum.executable()) Either.left(datum) else throw MishapInvalidIota( - datum, - reverseIdx, - "hexcasting.mishap.invalid_value.evaluatable".asTranslatedComponent - ) + else -> + if (datum.executable()) Either.left(datum) + else + throw MishapInvalidIota( + datum, + reverseIdx, + "hexcasting.mishap.invalid_value.evaluatable".asTranslatedComponent) } fun Iota?.orNull() = this ?: NullIota() @@ -305,19 +302,31 @@ fun Iota?.orNull() = this ?: NullIota() fun aplKinnie(operatee: Either, fn: DoubleUnaryOperator): Iota = operatee.map( { num -> DoubleIota(fn.applyAsDouble(num)) }, - { vec -> Vec3Iota(Vec3(fn.applyAsDouble(vec.x), fn.applyAsDouble(vec.y), fn.applyAsDouble(vec.z))) } - ) - -inline val Boolean.asActionResult get() = listOf(BooleanIota(this)) -inline val Double.asActionResult get() = listOf(DoubleIota(this)) -inline val Number.asActionResult get() = listOf(DoubleIota(this.toDouble())) - -inline val SpellList.asActionResult get() = listOf(ListIota(this)) -inline val List.asActionResult get() = listOf(ListIota(this)) - -inline val BlockPos.asActionResult get() = listOf(Vec3Iota(Vec3.atCenterOf(this))) -inline val Vector3f.asActionResult get() = listOf(Vec3Iota(Vec3(this))) -inline val Vec3.asActionResult get() = listOf(Vec3Iota(this)) - -inline val Entity?.asActionResult get() = listOf(if (this == null) NullIota() else EntityIota(this)) -inline val HexPattern.asActionResult get() = listOf(PatternIota(this)) + { vec -> + Vec3Iota( + Vec3(fn.applyAsDouble(vec.x), fn.applyAsDouble(vec.y), fn.applyAsDouble(vec.z))) + }) + +inline val Boolean.asActionResult + get() = listOf(BooleanIota(this)) +inline val Double.asActionResult + get() = listOf(DoubleIota(this)) +inline val Number.asActionResult + get() = listOf(DoubleIota(this.toDouble())) + +inline val SpellList.asActionResult + get() = listOf(ListIota(this)) +inline val List.asActionResult + get() = listOf(ListIota(this)) + +inline val BlockPos.asActionResult + get() = listOf(Vec3Iota(Vec3.atCenterOf(this))) +inline val Vector3f.asActionResult + get() = listOf(Vec3Iota(Vec3(this))) +inline val Vec3.asActionResult + get() = listOf(Vec3Iota(this)) + +inline val Entity?.asActionResult + get() = listOf(if (this == null) NullIota() else EntityIota(this)) +inline val HexPattern.asActionResult + get() = listOf(PatternIota(this)) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt index 88129e6bf8..2b7d796146 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/ParticleSpray.kt @@ -10,7 +10,13 @@ import net.minecraft.world.phys.Vec3 * @param fuzziness the radius of the sphere the particle might happen in (pos) * @param spread the max angle in radians the particle can move in, in relation to vel */ -data class ParticleSpray(val pos: Vec3, val vel: Vec3, val fuzziness: Double, val spread: Double, val count: Int = 20) { +data class ParticleSpray( + val pos: Vec3, + val vel: Vec3, + val fuzziness: Double, + val spread: Double, + val count: Int = 20 +) { companion object { @JvmStatic fun burst(pos: Vec3, size: Double, count: Int = 20): ParticleSpray { @@ -24,6 +30,7 @@ data class ParticleSpray(val pos: Vec3, val vel: Vec3, val fuzziness: Double, va } fun sprayParticles(world: ServerLevel, color: FrozenPigment) { - IXplatAbstractions.INSTANCE.sendPacketNear(this.pos, 128.0, world, MsgCastParticleS2C(this, color)) + IXplatAbstractions.INSTANCE.sendPacketNear( + this.pos, 128.0, world, MsgCastParticleS2C(this, color)) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/PatternShapeMatch.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/PatternShapeMatch.java index b72d349895..ba00c90993 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/PatternShapeMatch.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/PatternShapeMatch.java @@ -1,21 +1,15 @@ package at.petrak.hexcasting.api.casting; import at.petrak.hexcasting.api.casting.castables.SpecialHandler; + import net.minecraft.resources.ResourceKey; -/** - * Possible things we find when trying to match a pattern's shape. - */ +/** Possible things we find when trying to match a pattern's shape. */ public abstract sealed class PatternShapeMatch { - /** - * I've never met that pattern in my life - */ - public static final class Nothing extends PatternShapeMatch { - } + /** I've never met that pattern in my life */ + public static final class Nothing extends PatternShapeMatch {} - /** - * The shape exactly matches a pattern that isn't altered per world - */ + /** The shape exactly matches a pattern that isn't altered per world */ public static final class Normal extends PatternShapeMatch { public final ResourceKey key; @@ -26,11 +20,11 @@ public Normal(ResourceKey key) { /** * The pattern is the right shape to be one of the per-world patterns. - *

- * On the server, {@link PerWorld#certain} means whether this is an exact match, or if it's just the - * right shape. (In other words it should only actually be casted if it is true.) - *

- * On the client, it is always false. + * + *

On the server, {@link PerWorld#certain} means whether this is an exact match, or if it's + * just the right shape. (In other words it should only actually be casted if it is true.) + * + *

On the client, it is always false. */ public static final class PerWorld extends PatternShapeMatch { public final ResourceKey key; @@ -42,9 +36,7 @@ public PerWorld(ResourceKey key, boolean certain) { } } - /** - * The shape matches a special handler - */ + /** The shape matches a special handler */ public static final class Special extends PatternShapeMatch { public final ResourceKey> key; public final SpecialHandler handler; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt index 2e76c18c76..f38d83e362 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/SpellList.kt @@ -20,8 +20,10 @@ sealed class SpellList : Iterable { class LList(val idx: Int, val list: List) : SpellList() { override val nonEmpty: Boolean get() = idx < list.size + override val car: Iota get() = list[idx] + override val cdr: SpellList get() = LList(idx + 1, list) @@ -69,9 +71,7 @@ sealed class SpellList : Iterable { override fun iterator() = SpellListIterator(this) - /** - * Note this is O(n), probably. - */ + /** Note this is O(n), probably. */ fun size(): Int { var size = 0 var ptr = this @@ -84,6 +84,7 @@ sealed class SpellList : Iterable { class SpellListIterator(var list: SpellList) : Iterator { override fun hasNext() = list.nonEmpty + override operator fun next(): Iota { val car = list.car list = list.cdr diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java index 10f9f9cd6e..4f2ce9a975 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/Arithmetic.java @@ -5,68 +5,67 @@ import at.petrak.hexcasting.api.casting.math.HexPattern; /** - * This is the interface to implement if you want to override the behaviour of an Operator pattern like ADD, SUB, etc. for some type/s of - * iotas for which that Operator pattern is not yet defined. + * This is the interface to implement if you want to override the behaviour of an Operator pattern + * like ADD, SUB, etc. for some type/s of iotas for which that Operator pattern is not yet defined. */ public interface Arithmetic { - String arithName(); + String arithName(); - /** - * @return All the HexPatterns for which this Arithmetic has defined Operators. - */ - Iterable opTypes(); + /** + * @return All the HexPatterns for which this Arithmetic has defined Operators. + */ + Iterable opTypes(); - /** - * @param pattern The HexPattern that would be drawn by the caster. - * @return The Operator that this Arithmetic has defined for that pattern. - */ - Operator getOperator(HexPattern pattern); + /** + * @param pattern The HexPattern that would be drawn by the caster. + * @return The Operator that this Arithmetic has defined for that pattern. + */ + Operator getOperator(HexPattern pattern); - // Below are some common Operator patterns that you can make use of in your Arithmetic: + // Below are some common Operator patterns that you can make use of in your Arithmetic: - HexPattern ADD = HexPattern.fromAngles("waaw", HexDir.NORTH_EAST); - HexPattern SUB = HexPattern.fromAngles("wddw", HexDir.NORTH_WEST); - HexPattern MUL = HexPattern.fromAngles("waqaw", HexDir.SOUTH_EAST); - HexPattern DIV = HexPattern.fromAngles("wdedw", HexDir.NORTH_EAST); - HexPattern ABS = HexPattern.fromAngles("wqaqw", HexDir.NORTH_EAST); - HexPattern POW = HexPattern.fromAngles("wedew", HexDir.NORTH_WEST); - HexPattern FLOOR = HexPattern.fromAngles("ewq", HexDir.EAST); - HexPattern CEIL = HexPattern.fromAngles("qwe", HexDir.EAST); - HexPattern SIN = HexPattern.fromAngles("qqqqqaa", HexDir.SOUTH_EAST); - HexPattern COS = HexPattern.fromAngles("qqqqqad", HexDir.SOUTH_EAST); - HexPattern TAN = HexPattern.fromAngles("wqqqqqadq", HexDir.SOUTH_WEST); - HexPattern ARCSIN = HexPattern.fromAngles("ddeeeee", HexDir.SOUTH_EAST); - HexPattern ARCCOS = HexPattern.fromAngles("adeeeee", HexDir.NORTH_EAST); - HexPattern ARCTAN = HexPattern.fromAngles("eadeeeeew", HexDir.NORTH_EAST); - HexPattern ARCTAN2 = HexPattern.fromAngles("deadeeeeewd", HexDir.WEST); - HexPattern LOG = HexPattern.fromAngles("eqaqe", HexDir.NORTH_WEST); - HexPattern MOD = HexPattern.fromAngles("addwaad", HexDir.NORTH_EAST); + HexPattern ADD = HexPattern.fromAngles("waaw", HexDir.NORTH_EAST); + HexPattern SUB = HexPattern.fromAngles("wddw", HexDir.NORTH_WEST); + HexPattern MUL = HexPattern.fromAngles("waqaw", HexDir.SOUTH_EAST); + HexPattern DIV = HexPattern.fromAngles("wdedw", HexDir.NORTH_EAST); + HexPattern ABS = HexPattern.fromAngles("wqaqw", HexDir.NORTH_EAST); + HexPattern POW = HexPattern.fromAngles("wedew", HexDir.NORTH_WEST); + HexPattern FLOOR = HexPattern.fromAngles("ewq", HexDir.EAST); + HexPattern CEIL = HexPattern.fromAngles("qwe", HexDir.EAST); + HexPattern SIN = HexPattern.fromAngles("qqqqqaa", HexDir.SOUTH_EAST); + HexPattern COS = HexPattern.fromAngles("qqqqqad", HexDir.SOUTH_EAST); + HexPattern TAN = HexPattern.fromAngles("wqqqqqadq", HexDir.SOUTH_WEST); + HexPattern ARCSIN = HexPattern.fromAngles("ddeeeee", HexDir.SOUTH_EAST); + HexPattern ARCCOS = HexPattern.fromAngles("adeeeee", HexDir.NORTH_EAST); + HexPattern ARCTAN = HexPattern.fromAngles("eadeeeeew", HexDir.NORTH_EAST); + HexPattern ARCTAN2 = HexPattern.fromAngles("deadeeeeewd", HexDir.WEST); + HexPattern LOG = HexPattern.fromAngles("eqaqe", HexDir.NORTH_WEST); + HexPattern MOD = HexPattern.fromAngles("addwaad", HexDir.NORTH_EAST); + // Vecs + HexPattern PACK = HexPattern.fromAngles("eqqqqq", HexDir.EAST); + HexPattern UNPACK = HexPattern.fromAngles("qeeeee", HexDir.EAST); - // Vecs - HexPattern PACK = HexPattern.fromAngles("eqqqqq", HexDir.EAST); - HexPattern UNPACK = HexPattern.fromAngles("qeeeee", HexDir.EAST); + // Lists + HexPattern INDEX = HexPattern.fromAngles("deeed", HexDir.NORTH_WEST); + HexPattern SLICE = HexPattern.fromAngles("qaeaqwded", HexDir.NORTH_WEST); + HexPattern APPEND = HexPattern.fromAngles("edqde", HexDir.SOUTH_WEST); + HexPattern UNAPPEND = HexPattern.fromAngles("qaeaq", HexDir.NORTH_WEST); + HexPattern REV = HexPattern.fromAngles("qqqaede", HexDir.EAST); + HexPattern INDEX_OF = HexPattern.fromAngles("dedqde", HexDir.EAST); + HexPattern REMOVE = HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST); + HexPattern REPLACE = HexPattern.fromAngles("wqaeaqw", HexDir.NORTH_WEST); + HexPattern CONS = HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST); + HexPattern UNCONS = HexPattern.fromAngles("aaqwqaa", HexDir.SOUTH_WEST); - // Lists - HexPattern INDEX = HexPattern.fromAngles("deeed", HexDir.NORTH_WEST); - HexPattern SLICE = HexPattern.fromAngles("qaeaqwded", HexDir.NORTH_WEST); - HexPattern APPEND = HexPattern.fromAngles("edqde", HexDir.SOUTH_WEST); - HexPattern UNAPPEND = HexPattern.fromAngles("qaeaq", HexDir.NORTH_WEST); - HexPattern REV = HexPattern.fromAngles("qqqaede", HexDir.EAST); - HexPattern INDEX_OF = HexPattern.fromAngles("dedqde", HexDir.EAST); - HexPattern REMOVE = HexPattern.fromAngles("edqdewaqa", HexDir.SOUTH_WEST); - HexPattern REPLACE = HexPattern.fromAngles("wqaeaqw", HexDir.NORTH_WEST); - HexPattern CONS = HexPattern.fromAngles("ddewedd", HexDir.SOUTH_EAST); - HexPattern UNCONS = HexPattern.fromAngles("aaqwqaa", HexDir.SOUTH_WEST); - - // Boolean Logic, Comparisons, & Sets - HexPattern AND = HexPattern.fromAngles("wdw", HexDir.NORTH_EAST); - HexPattern OR = HexPattern.fromAngles("waw", HexDir.SOUTH_EAST); - HexPattern XOR = HexPattern.fromAngles("dwa", HexDir.NORTH_WEST); - HexPattern GREATER = HexPattern.fromAngles("e", HexDir.SOUTH_EAST); - HexPattern LESS = HexPattern.fromAngles("q", HexDir.SOUTH_WEST); - HexPattern GREATER_EQ = HexPattern.fromAngles("ee", HexDir.SOUTH_EAST); - HexPattern LESS_EQ = HexPattern.fromAngles("qq", HexDir.SOUTH_WEST); - HexPattern NOT = HexPattern.fromAngles("dw", HexDir.NORTH_WEST); - HexPattern UNIQUE = HexPattern.fromAngles("aweaqa", HexDir.NORTH_EAST); + // Boolean Logic, Comparisons, & Sets + HexPattern AND = HexPattern.fromAngles("wdw", HexDir.NORTH_EAST); + HexPattern OR = HexPattern.fromAngles("waw", HexDir.SOUTH_EAST); + HexPattern XOR = HexPattern.fromAngles("dwa", HexDir.NORTH_WEST); + HexPattern GREATER = HexPattern.fromAngles("e", HexDir.SOUTH_EAST); + HexPattern LESS = HexPattern.fromAngles("q", HexDir.SOUTH_WEST); + HexPattern GREATER_EQ = HexPattern.fromAngles("ee", HexDir.SOUTH_EAST); + HexPattern LESS_EQ = HexPattern.fromAngles("qq", HexDir.SOUTH_WEST); + HexPattern NOT = HexPattern.fromAngles("dw", HexDir.NORTH_WEST); + HexPattern UNIQUE = HexPattern.fromAngles("aweaqa", HexDir.NORTH_EAST); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/IterPair.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/IterPair.java index 64ff91fb25..9be0c68922 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/IterPair.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/IterPair.java @@ -3,22 +3,26 @@ import java.util.Iterator; public record IterPair(T left, T right) implements Iterable { - @Override - public Iterator iterator() { - return new Iterator() { - int ix; - @Override - public boolean hasNext() { - return ix < 2; - } - @Override - public T next() { - switch (ix++) { - case 0: return left; - case 1: return right; - } - return null; - } - }; - } + @Override + public Iterator iterator() { + return new Iterator() { + int ix; + + @Override + public boolean hasNext() { + return ix < 2; + } + + @Override + public T next() { + switch (ix++) { + case 0: + return left; + case 1: + return right; + } + return null; + } + }; + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/TripleIterable.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/TripleIterable.java index e066a106c1..f841966eff 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/TripleIterable.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/TripleIterable.java @@ -5,14 +5,18 @@ import java.util.Iterator; -public class TripleIterable implements Iterable { +public class TripleIterable implements Iterable { private final Iterable iterableA; private final Iterable iterableB; private final Iterable iterableC; private final TriFunction map; - public TripleIterable(Iterable iterableA, Iterable iterableB, Iterable iterableC, TriFunction map) { + public TripleIterable( + Iterable iterableA, + Iterable iterableB, + Iterable iterableC, + TriFunction map) { this.iterableA = iterableA; this.iterableB = iterableB; this.iterableC = iterableC; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java index 2f7e1fe7dc..f7dff3551f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/ArithmeticEngine.java @@ -14,13 +14,14 @@ import java.util.*; /** - * This is the class responsible for managing the various Arithmetics that are in use, deciding based on the current - * stack which Operator should be called, etc. + * This is the class responsible for managing the various Arithmetics that are in use, deciding + * based on the current stack which Operator should be called, etc. */ public class ArithmeticEngine { /** - * Data structure for mapping the pattern that gets drawn on the stack to the list of Operators that - * are overloading that pattern. + * Data structure for mapping the pattern that gets drawn on the stack to the list of Operators + * that are overloading that pattern. + * * @param pattern The pattern that the caster will need to draw to cast one of these operators. * @param arity The number of arguments that all of these operators must consume from the stack. * @param operators The list of all operators that overload this pattern. @@ -28,8 +29,16 @@ public class ArithmeticEngine { private record OpCandidates(HexPattern pattern, int arity, List operators) { public void addOp(Operator next) { if (next.arity != arity) { - throw new IllegalArgumentException("Operators exist of differing arity! The pattern " + pattern - + " already had arity " + arity + " when the operator with arity " + next.arity + ", " + next + " was added."); + throw new IllegalArgumentException( + "Operators exist of differing arity! The pattern " + + pattern + + " already had arity " + + arity + + " when the operator with arity " + + next.arity + + ", " + + next + + " was added."); } operators.add(next); } @@ -39,8 +48,9 @@ public void addOp(Operator next) { private final Map operators = new HashMap<>(); /** - * A cache mapping specific sets of Pattern, IotaType, IotaType, ..., IotaType to Operators so that the Operators don't need to be - * queried for what types they accept every time they are used. + * A cache mapping specific sets of Pattern, IotaType, IotaType, ..., IotaType to Operators so + * that the Operators don't need to be queried for what types they accept every time they are + * used. */ private final Map cache = new HashMap<>(); @@ -48,14 +58,16 @@ public ArithmeticEngine(List arithmetics) { this.arithmetics = arithmetics.toArray(new Arithmetic[0]); for (var arith : arithmetics) { for (var op : arith.opTypes()) { - operators.compute(op, ($, info) -> { - var operator = arith.getOperator(op); - if (info == null) { - info = new OpCandidates(op, operator.arity, new ArrayList<>()); - } - info.addOp(operator); - return info; - }); + operators.compute( + op, + ($, info) -> { + var operator = arith.getOperator(op); + if (info == null) { + info = new OpCandidates(op, operator.arity, new ArrayList<>()); + } + info.addOp(operator); + return info; + }); } } } @@ -65,7 +77,9 @@ public Iterable operatorSyms() { } /** - * Runs one of the contained Operators assigned to the given pattern, modifying the passed stack of iotas. + * Runs one of the contained Operators assigned to the given pattern, modifying the passed stack + * of iotas. + * * @param pattern The pattern that was drawn, used to determine which operators are candidates. * @param env The casting environment. * @param image The casting image. @@ -73,7 +87,12 @@ public Iterable operatorSyms() { * @return The iotas to be added to the stack. * @throws Mishap mishaps if invalid input to the operators is given by the caster. */ - public OperationResult run(HexPattern pattern, CastingEnvironment env, CastingImage image, SpellContinuation continuation) throws Mishap { + public OperationResult run( + HexPattern pattern, + CastingEnvironment env, + CastingImage image, + SpellContinuation continuation) + throws Mishap { var stackList = image.getStack(); var stack = new Stack(); stack.addAll(stackList); @@ -81,7 +100,8 @@ public OperationResult run(HexPattern pattern, CastingEnvironment env, CastingIm var candidates = operators.get(pattern); if (candidates == null) - throw new InvalidOperatorException("the pattern " + pattern + " is not an operator."); // + throw new InvalidOperatorException( + "the pattern " + pattern + " is not an operator."); // HashCons hash = new HashCons.Pattern(pattern); var args = new ArrayList(candidates.arity()); for (var i = 0; i < candidates.arity(); i++) { @@ -98,13 +118,21 @@ public OperationResult run(HexPattern pattern, CastingEnvironment env, CastingIm } private Operator resolveCandidates(List args, HashCons hash, OpCandidates candidates) { - return cache.computeIfAbsent(hash, $ -> { - for (var op : candidates.operators()) { - if (op.accepts.test(args)) { - return op; - } - } - throw new NoOperatorCandidatesException(candidates.pattern(), args, "No implementation candidates for op " + candidates.pattern() + " on args: " + args); - }); + return cache.computeIfAbsent( + hash, + $ -> { + for (var op : candidates.operators()) { + if (op.accepts.test(args)) { + return op; + } + } + throw new NoOperatorCandidatesException( + candidates.pattern(), + args, + "No implementation candidates for op " + + candidates.pattern() + + " on args: " + + args); + }); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/HashCons.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/HashCons.java index c7566e783b..20ce9f0140 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/HashCons.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/HashCons.java @@ -1,12 +1,11 @@ package at.petrak.hexcasting.api.casting.arithmetic.engine; - import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.casting.math.HexPattern; // Helper type for hashing lists of types. public sealed interface HashCons { - public record Pattern(HexPattern operator) implements HashCons {} + public record Pattern(HexPattern operator) implements HashCons {} - public record Pair(IotaType head, HashCons tail) implements HashCons {} + public record Pair(IotaType head, HashCons tail) implements HashCons {} } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/InvalidOperatorException.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/InvalidOperatorException.java index 1d826da67e..6adc8e6a18 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/InvalidOperatorException.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/engine/InvalidOperatorException.java @@ -1,8 +1,7 @@ package at.petrak.hexcasting.api.casting.arithmetic.engine; public class InvalidOperatorException extends RuntimeException { - public InvalidOperatorException() { - } + public InvalidOperatorException() {} public InvalidOperatorException(String s) { super(s); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt index 8804e0d628..7e3f7d60ee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/Operator.kt @@ -8,31 +8,28 @@ import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.mishaps.Mishap -import at.petrak.hexcasting.common.lib.hex.HexEvalSounds -import java.util.function.Consumer abstract class Operator /** - * @param arity The number of arguments from the stack that this Operator requires; all Operators with the same pattern must have arity. - * @param accepts A function that should return true if the passed list of Iotas satisfies this Operator's type constraints, and false otherwise. + * @param arity The number of arguments from the stack that this Operator requires; all Operators + * with the same pattern must have arity. + * @param accepts A function that should return true if the passed list of Iotas satisfies this + * Operator's type constraints, and false otherwise. */ - ( - @JvmField - val arity: Int, - @JvmField - val accepts: IotaMultiPredicate -) { +(@JvmField val arity: Int, @JvmField val accepts: IotaMultiPredicate) { - /** - * Functionally update the image. Return the image and any side effects. - */ + /** Functionally update the image. Return the image and any side effects. */ @Throws(Mishap::class) - abstract fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult - + abstract fun operate( + env: CastingEnvironment, + image: CastingImage, + continuation: SpellContinuation + ): OperationResult companion object { /** - * A helper method to take an iota that you know is of iotaType and returning it as an iota of that type. + * A helper method to take an iota that you know is of iotaType and returning it as an iota + * of that type. */ @JvmStatic fun downcast(iota: Iota, iotaType: IotaType): T { @@ -40,4 +37,4 @@ abstract class Operator return iota as T } } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt index 1d43c890ce..72013fb44d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBasic.kt @@ -13,7 +13,11 @@ import java.util.function.Consumer abstract class OperatorBasic(arity: Int, accepts: IotaMultiPredicate) : Operator(arity, accepts) { @Throws(Mishap::class) - override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { + override fun operate( + env: CastingEnvironment, + image: CastingImage, + continuation: SpellContinuation + ): OperationResult { val stack = image.stack.toMutableList() val args = stack.takeLast(arity) repeat(arity) { stack.removeLast() } @@ -26,14 +30,16 @@ abstract class OperatorBasic(arity: Int, accepts: IotaMultiPredicate) : Operator } /** - * / ** - * The method called when this Operator is actually acting on the stack, for real. - * @param iotas An iterable of iotas with [Operator.arity] elements that satisfied [Operator.accepts]. + * / ** The method called when this Operator is actually acting on the stack, for real. + * + * @param iotas An iterable of iotas with [Operator.arity] elements that satisfied + * [Operator.accepts]. * @param env The casting environment, to make use of if this operator needs it. - * @return the iotas that this operator will return to the stack (with the first element of the returned iterable being placed deepest into the stack, and the last element on top of the stack). + * @return the iotas that this operator will return to the stack (with the first element of the + * returned iterable being placed deepest into the stack, and the last element on top of the + * stack). * @throws Mishap if the Operator mishaps for any reason it will be passed up the chain. */ @Throws(Mishap::class) abstract fun apply(iotas: Iterable, env: CastingEnvironment): Iterable - -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java index 02914dc4d1..4678fe0d8e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorBinary.java @@ -1,28 +1,27 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator; - import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.iota.Iota; + import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.BinaryOperator; -/** - * A helper class for defining {@link Operator}s of two iotas. - */ +/** A helper class for defining {@link Operator}s of two iotas. */ public class OperatorBinary extends OperatorBasic { - public BinaryOperator inner; + public BinaryOperator inner; - public OperatorBinary(IotaMultiPredicate accepts, BinaryOperator inner) { - super(2, accepts); - this.inner = inner; - } + public OperatorBinary(IotaMultiPredicate accepts, BinaryOperator inner) { + super(2, accepts); + this.inner = inner; + } - @Override - public @NotNull Iterable apply(Iterable iotas, @NotNull CastingEnvironment env) { - var it = iotas.iterator(); - return List.of(inner.apply(it.next(), it.next())); - } + @Override + public @NotNull Iterable apply( + Iterable iotas, @NotNull CastingEnvironment env) { + var it = iotas.iterator(); + return List.of(inner.apply(it.next(), it.next())); + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java index 9797b83b1d..4cd205d915 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/operator/OperatorUnary.java @@ -1,27 +1,26 @@ package at.petrak.hexcasting.api.casting.arithmetic.operator; - import at.petrak.hexcasting.api.casting.arithmetic.predicates.IotaMultiPredicate; import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.iota.Iota; + import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.UnaryOperator; -/** - * A helper class for defining {@link Operator}s of one iota. - */ +/** A helper class for defining {@link Operator}s of one iota. */ public class OperatorUnary extends OperatorBasic { - public UnaryOperator inner; + public UnaryOperator inner; - public OperatorUnary(IotaMultiPredicate accepts, UnaryOperator inner) { - super(1, accepts); - this.inner = inner; - } + public OperatorUnary(IotaMultiPredicate accepts, UnaryOperator inner) { + super(1, accepts); + this.inner = inner; + } - @Override - public @NotNull Iterable apply(Iterable iotas, @NotNull CastingEnvironment env) { - return List.of(inner.apply(iotas.iterator().next())); - } + @Override + public @NotNull Iterable apply( + Iterable iotas, @NotNull CastingEnvironment env) { + return List.of(inner.apply(iotas.iterator().next())); + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java index 63a64b5a02..62d33307bc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaMultiPredicate.java @@ -3,89 +3,113 @@ import at.petrak.hexcasting.api.casting.iota.Iota; /** - * Used to determine whether a given set of iotas on the stack are acceptable types for - * the operator that is storing this IotaMultiPredicate. + * Used to determine whether a given set of iotas on the stack are acceptable types for the operator + * that is storing this IotaMultiPredicate. */ @FunctionalInterface public interface IotaMultiPredicate { - boolean test(Iterable iotas); + boolean test(Iterable iotas); - /** - * The resulting IotaMultiPredicate only returns true if all iotas passed into test match the type dictated by child. - */ - static IotaMultiPredicate all(IotaPredicate child) { - return new All(child); - } - /** - * The resulting IotaMultiPredicate returns true if two iotas are passed, the first matching first, and the second matching second. - */ - static IotaMultiPredicate pair(IotaPredicate first, IotaPredicate second) { - return new Pair(first, second); - } - /** - * The resulting IotaMultiPredicate returns true if three iotas are passed, the first matching first, the second matching second, and the third matching third. - */ - static IotaMultiPredicate triple(IotaPredicate first, IotaPredicate second, IotaPredicate third) { - return new Triple(first, second, third); - } - /** - * The resulting IotaMultiPredicate returns true if at least one iota passed matches needs, and the rest match fallback. - */ - static IotaMultiPredicate any(IotaPredicate needs, IotaPredicate fallback) { - return new Any(needs, fallback); - } + /** + * The resulting IotaMultiPredicate only returns true if all iotas passed into test match the + * type dictated by child. + */ + static IotaMultiPredicate all(IotaPredicate child) { + return new All(child); + } - /** - * The resulting IotaMultiPredicate returns true if either the first returns true or the second returns true. - */ - static IotaMultiPredicate either(IotaMultiPredicate first, IotaMultiPredicate second) { - return new Either(first, second); - } + /** + * The resulting IotaMultiPredicate returns true if two iotas are passed, the first matching + * first, and the second matching second. + */ + static IotaMultiPredicate pair(IotaPredicate first, IotaPredicate second) { + return new Pair(first, second); + } - record Pair(IotaPredicate first, IotaPredicate second) implements IotaMultiPredicate { - @Override - public boolean test(Iterable iotas) { - var it = iotas.iterator(); - return it.hasNext() && first.test(it.next()) && it.hasNext() && second.test(it.next()) && !it.hasNext(); - } - } - record Triple(IotaPredicate first, IotaPredicate second, IotaPredicate third) implements IotaMultiPredicate { - @Override - public boolean test(Iterable iotas) { - var it = iotas.iterator(); - return it.hasNext() && first.test(it.next()) && it.hasNext() && second.test(it.next()) && it.hasNext() && third.test(it.next()) && !it.hasNext(); - } - } - record Any(IotaPredicate needs, IotaPredicate fallback) implements IotaMultiPredicate { - @Override - public boolean test(Iterable iotas) { - var ok = false; - for (var iota : iotas) { - if (needs.test(iota)) { - ok = true; - } else if (!fallback.test(iota)) { - return false; - } - } - return ok; - } - } - record All(IotaPredicate inner) implements IotaMultiPredicate { - @Override - public boolean test(Iterable iotas) { - for (var iota : iotas) { - if (!inner.test(iota)) { - return false; - } - } - return true; - } - } + /** + * The resulting IotaMultiPredicate returns true if three iotas are passed, the first matching + * first, the second matching second, and the third matching third. + */ + static IotaMultiPredicate triple( + IotaPredicate first, IotaPredicate second, IotaPredicate third) { + return new Triple(first, second, third); + } - record Either(IotaMultiPredicate first, IotaMultiPredicate second) implements IotaMultiPredicate { - @Override - public boolean test(Iterable iotas) { - return first.test(iotas) || second.test(iotas); - } - } + /** + * The resulting IotaMultiPredicate returns true if at least one iota passed matches needs, and + * the rest match fallback. + */ + static IotaMultiPredicate any(IotaPredicate needs, IotaPredicate fallback) { + return new Any(needs, fallback); + } + + /** + * The resulting IotaMultiPredicate returns true if either the first returns true or the second + * returns true. + */ + static IotaMultiPredicate either(IotaMultiPredicate first, IotaMultiPredicate second) { + return new Either(first, second); + } + + record Pair(IotaPredicate first, IotaPredicate second) implements IotaMultiPredicate { + @Override + public boolean test(Iterable iotas) { + var it = iotas.iterator(); + return it.hasNext() + && first.test(it.next()) + && it.hasNext() + && second.test(it.next()) + && !it.hasNext(); + } + } + + record Triple(IotaPredicate first, IotaPredicate second, IotaPredicate third) + implements IotaMultiPredicate { + @Override + public boolean test(Iterable iotas) { + var it = iotas.iterator(); + return it.hasNext() + && first.test(it.next()) + && it.hasNext() + && second.test(it.next()) + && it.hasNext() + && third.test(it.next()) + && !it.hasNext(); + } + } + + record Any(IotaPredicate needs, IotaPredicate fallback) implements IotaMultiPredicate { + @Override + public boolean test(Iterable iotas) { + var ok = false; + for (var iota : iotas) { + if (needs.test(iota)) { + ok = true; + } else if (!fallback.test(iota)) { + return false; + } + } + return ok; + } + } + + record All(IotaPredicate inner) implements IotaMultiPredicate { + @Override + public boolean test(Iterable iotas) { + for (var iota : iotas) { + if (!inner.test(iota)) { + return false; + } + } + return true; + } + } + + record Either(IotaMultiPredicate first, IotaMultiPredicate second) + implements IotaMultiPredicate { + @Override + public boolean test(Iterable iotas) { + return first.test(iotas) || second.test(iotas); + } + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java index 41d0648145..e82ee4d00a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/arithmetic/predicates/IotaPredicate.java @@ -6,63 +6,60 @@ import java.util.List; /** - * Used to determine whether a given iota is an acceptable type for the operator that is storing this. It must be strictly a function - * of the passed Iota's IotaType, or the caching done by ArithmeticEngine will be invalid. + * Used to determine whether a given iota is an acceptable type for the operator that is storing + * this. It must be strictly a function of the passed Iota's IotaType, or the caching done by + * ArithmeticEngine will be invalid. */ @FunctionalInterface public interface IotaPredicate { - boolean test(Iota iota); + boolean test(Iota iota); - /** - * The resulting IotaPredicate returns true if the given iota matches either the left or right predicates. - */ - static IotaPredicate or(IotaPredicate left, IotaPredicate right) { - return new Or(left, right); - } + /** + * The resulting IotaPredicate returns true if the given iota matches either the left or right + * predicates. + */ + static IotaPredicate or(IotaPredicate left, IotaPredicate right) { + return new Or(left, right); + } - static IotaPredicate any(IotaPredicate... any) { - return new Any(any); - } + static IotaPredicate any(IotaPredicate... any) { + return new Any(any); + } - static IotaPredicate any(List any) { - return new Any(any.toArray(IotaPredicate[]::new)); - } + static IotaPredicate any(List any) { + return new Any(any.toArray(IotaPredicate[]::new)); + } - /** - * The resulting IotaPredicate returns true if the given iota's type is type. - */ - static IotaPredicate ofType(IotaType type) { - return new OfType(type); - } + /** The resulting IotaPredicate returns true if the given iota's type is type. */ + static IotaPredicate ofType(IotaType type) { + return new OfType(type); + } - record Or(IotaPredicate left, IotaPredicate right) implements IotaPredicate { - @Override - public boolean test(Iota iota) { - return left.test(iota) || right.test(iota); - } - } + record Or(IotaPredicate left, IotaPredicate right) implements IotaPredicate { + @Override + public boolean test(Iota iota) { + return left.test(iota) || right.test(iota); + } + } - record Any(IotaPredicate[] any) implements IotaPredicate { + record Any(IotaPredicate[] any) implements IotaPredicate { - @Override - public boolean test(Iota iota) { - for (var i : any) { - if (i.test(iota)) - return true; - } - return false; - } - } + @Override + public boolean test(Iota iota) { + for (var i : any) { + if (i.test(iota)) return true; + } + return false; + } + } - record OfType(IotaType type) implements IotaPredicate { - @Override - public boolean test(Iota iota) { - return iota.getType().equals(this.type); - } - } + record OfType(IotaType type) implements IotaPredicate { + @Override + public boolean test(Iota iota) { + return iota.getType().equals(this.type); + } + } - /** - * This IotaPredicate returns true for all iotas. - */ - IotaPredicate TRUE = iota -> true; + /** This IotaPredicate returns true for all iotas. */ + IotaPredicate TRUE = iota -> true; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt index e60ff2dfe3..1449218dbf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/Action.kt @@ -5,19 +5,19 @@ import at.petrak.hexcasting.api.casting.eval.OperationResult import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation import at.petrak.hexcasting.api.casting.iota.Iota -import net.minecraft.world.phys.Vec3 import java.text.DecimalFormat +import net.minecraft.world.phys.Vec3 /** - * Manipulates the stack in some way, usually by popping some number of values off the stack - * and pushing one new value. - * For a more "traditional" pop arguments, push return experience, see [ConstMediaAction]. + * Manipulates the stack in some way, usually by popping some number of values off the stack and + * pushing one new value. For a more "traditional" pop arguments, push return experience, see + * [ConstMediaAction]. * - * Instances of this can exist on the client, but they should NEVER be used there. They only - * exist on the client because Minecraft's registry system demands they do; any information - * the client needs about them is stored elsewhere. (For example, their canonical stroke order - * is stored in [ActionRegistryEntry], and their localization key is gotten from the resource key - * via [at.petrak.hexcasting.api.HexAPI.getActionI18nKey].) + * Instances of this can exist on the client, but they should NEVER be used there. They only exist + * on the client because Minecraft's registry system demands they do; any information the client + * needs about them is stored elsewhere. (For example, their canonical stroke order is stored in + * [ActionRegistryEntry], and their localization key is gotten from the resource key via + * [at.petrak.hexcasting.api.HexAPI.getActionI18nKey].) * * Each action is a singleton */ @@ -25,13 +25,14 @@ interface Action { /** * Functionally update the image. Return the image and any side effects. * - * This is a very low-level function -- the implementor is responsible for a lot. For example, - * remember to increment the op count, sil vous plait. + * This is a very low-level function -- the implementor is responsible for a lot. For + * example, remember to increment the op count, sil vous plait. * - * A particle effect at the cast site and various messages and advancements are done automagically. + * A particle effect at the cast site and various messages and advancements are done + * automagically. * - * The userdata tag is copied for you, so you don't need to worry about mutation messing up things - * behind the scenes. + * The userdata tag is copied for you, so you don't need to worry about mutation messing up + * things behind the scenes. */ fun operate( env: CastingEnvironment, @@ -43,22 +44,23 @@ interface Action { // I see why vazkii did this: you can't raycast out to infinity! const val RAYCAST_DISTANCE: Double = 32.0 - // TODO: currently, this means you can't raycast in a very long spell circle, or out of your local ambit into + // TODO: currently, this means you can't raycast in a very long spell circle, or out of your + // local ambit into // your sentinel's. @JvmStatic fun raycastEnd(origin: Vec3, look: Vec3): Vec3 = origin.add(look.normalize().scale(RAYCAST_DISTANCE)) @JvmStatic - fun makeConstantOp(x: Iota): Action = object : ConstMediaAction { - override val argc: Int - get() = 0 + fun makeConstantOp(x: Iota): Action = + object : ConstMediaAction { + override val argc: Int + get() = 0 - override fun execute(args: List, env: CastingEnvironment): List = - listOf(x) - } + override fun execute(args: List, env: CastingEnvironment): List = + listOf(x) + } public val DOUBLE_FORMATTER = DecimalFormat("####.####") } } - diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt index 276ee73122..b94bbc79f5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/ConstMediaAction.kt @@ -10,9 +10,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughArgs import at.petrak.hexcasting.api.casting.mishaps.MishapNotEnoughMedia import at.petrak.hexcasting.common.lib.hex.HexEvalSounds -/** - * A SimpleOperator that always costs the same amount of media. - */ +/** A SimpleOperator that always costs the same amount of media. */ interface ConstMediaAction : Action { val argc: Int val mediaCost: Long @@ -25,19 +23,22 @@ interface ConstMediaAction : Action { return CostMediaActionResult(stack) } - override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { + override fun operate( + env: CastingEnvironment, + image: CastingImage, + continuation: SpellContinuation + ): OperationResult { val stack = image.stack.toMutableList() - if (env.extractMedia(this.mediaCost, true) > 0) - throw MishapNotEnoughMedia(this.mediaCost) - if (this.argc > stack.size) - throw MishapNotEnoughArgs(this.argc, stack.size) + if (env.extractMedia(this.mediaCost, true) > 0) throw MishapNotEnoughMedia(this.mediaCost) + if (this.argc > stack.size) throw MishapNotEnoughArgs(this.argc, stack.size) val args = stack.takeLast(this.argc) repeat(this.argc) { stack.removeLast() } val result = this.executeWithOpCount(args, env) stack.addAll(result.resultStack) - val sideEffects = mutableListOf(OperatorSideEffect.ConsumeMedia(this.mediaCost)) + val sideEffects = + mutableListOf(OperatorSideEffect.ConsumeMedia(this.mediaCost)) val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount) return OperationResult(image2, sideEffects, continuation, HexEvalSounds.NORMAL_EXECUTE) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt index 1e9a39f80f..11a0b9d5e1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/OperationAction.kt @@ -10,15 +10,20 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidOperatorArgs import at.petrak.hexcasting.common.lib.hex.HexArithmetics /** - * Represents an Operator with the give pattern as its identifier, a special type of Action that calls a different function depending on the type of its arguments. - * This exists so that addons can easily define their own overloads to patterns like addition, subtraction, etc. + * Represents an Operator with the give pattern as its identifier, a special type of Action that + * calls a different function depending on the type of its arguments. This exists so that addons can + * easily define their own overloads to patterns like addition, subtraction, etc. */ data class OperationAction(val pattern: HexPattern) : Action { - override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { + override fun operate( + env: CastingEnvironment, + image: CastingImage, + continuation: SpellContinuation + ): OperationResult { return try { HexArithmetics.getEngine().run(pattern, env, image, continuation) } catch (e: NoOperatorCandidatesException) { throw MishapInvalidOperatorArgs(e.args) } } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpecialHandler.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpecialHandler.java index 14a64879e9..4181abb1ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpecialHandler.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpecialHandler.java @@ -2,40 +2,41 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment; import at.petrak.hexcasting.api.casting.math.HexPattern; + import net.minecraft.network.chat.Component; + import org.jetbrains.annotations.Nullable; /** * Special handling of a pattern. Before checking any of the normal angle-signature based patterns, - * a given pattern is run by all of these special handlers patterns. If none of them return non-null, - * then its signature is checked. - *

- * In the base mod, this is used for number patterns and Bookkeeper's Gambit. - *

- * There's a separation between the special handlers and their factories so we never have to use - * {@link Action} instances on the client. We can have SpecialHandlers on the client though because they're just - * wrappers. + * a given pattern is run by all of these special handlers patterns. If none of them return + * non-null, then its signature is checked. + * + *

In the base mod, this is used for number patterns and Bookkeeper's Gambit. + * + *

There's a separation between the special handlers and their factories so we never have to use + * {@link Action} instances on the client. We can have SpecialHandlers on the client though because + * they're just wrappers. */ public interface SpecialHandler { /** * Convert this to an action, for modification of the stack and state. - *

- * This is called on the SERVER-SIDE ONLY. + * + *

This is called on the SERVER-SIDE ONLY. */ Action act(); - /** - * Get the name of this handler. - */ + /** Get the name of this handler. */ Component getName(); /** * Given a pattern, possibly make up the special handler from it. - *

- * This is what goes in the registry! Think of it like BlockEntityType vs BlockEntity. + * + *

This is what goes in the registry! Think of it like BlockEntityType vs BlockEntity. */ @FunctionalInterface public interface Factory { - @Nullable T tryMatch(HexPattern pattern, CastingEnvironment env); + @Nullable + T tryMatch(HexPattern pattern, CastingEnvironment env); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt index fcf17d08d0..34911d721b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/castables/SpellAction.kt @@ -20,22 +20,24 @@ interface SpellAction : Action { fun awardsCastingStat(ctx: CastingEnvironment): Boolean = true - fun execute( - args: List, - env: CastingEnvironment - ): Result + fun execute(args: List, env: CastingEnvironment): Result fun executeWithUserdata( - args: List, env: CastingEnvironment, userData: CompoundTag + args: List, + env: CastingEnvironment, + userData: CompoundTag ): Result { return this.execute(args, env) } - override fun operate(env: CastingEnvironment, image: CastingImage, continuation: SpellContinuation): OperationResult { + override fun operate( + env: CastingEnvironment, + image: CastingImage, + continuation: SpellContinuation + ): OperationResult { val stack = image.stack.toMutableList() - if (this.argc > stack.size) - throw MishapNotEnoughArgs(this.argc, stack.size) + if (this.argc > stack.size) throw MishapNotEnoughArgs(this.argc, stack.size) val args = stack.takeLast(this.argc) for (_i in 0 until this.argc) stack.removeLast() @@ -45,27 +47,29 @@ interface SpellAction : Action { val sideEffects = mutableListOf() - if (env.extractMedia(result.cost, true) > 0) - throw MishapNotEnoughMedia(result.cost) - if (result.cost > 0) - sideEffects.add(OperatorSideEffect.ConsumeMedia(result.cost)) + if (env.extractMedia(result.cost, true) > 0) throw MishapNotEnoughMedia(result.cost) + if (result.cost > 0) sideEffects.add(OperatorSideEffect.ConsumeMedia(result.cost)) sideEffects.add( OperatorSideEffect.AttemptSpell( - result.effect, - this.hasCastingSound(env), - this.awardsCastingStat(env) - ) - ) + result.effect, this.hasCastingSound(env), this.awardsCastingStat(env))) - for (spray in result.particles) - sideEffects.add(OperatorSideEffect.Particles(spray)) + for (spray in result.particles) sideEffects.add(OperatorSideEffect.Particles(spray)) - val image2 = image.copy(stack = stack, opsConsumed = image.opsConsumed + result.opCount, userData = userDataMut) + val image2 = + image.copy( + stack = stack, + opsConsumed = image.opsConsumed + result.opCount, + userData = userDataMut) val sound = if (this.hasCastingSound(env)) HexEvalSounds.SPELL else HexEvalSounds.MUTE return OperationResult(image2, sideEffects, continuation, sound) } - data class Result(val effect: RenderedSpell, val cost: Long, val particles: List, val opCount: Long = 1) + data class Result( + val effect: RenderedSpell, + val cost: Long, + val particles: List, + val opCount: Long = 1 + ) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java index ac8bf92d0d..a8e023512c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/BlockEntityAbstractImpetus.java @@ -7,7 +7,9 @@ import at.petrak.hexcasting.api.utils.MediaHelper; import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker; import at.petrak.hexcasting.common.lib.HexItems; + import com.mojang.datafixers.util.Pair; + import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -28,6 +30,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.phys.AABB; + import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; @@ -36,39 +39,35 @@ /** * Default impl for an impetus, not tecnically necessary but I'm exposing it for ease of use - *

- * This does assume a great deal so you might have to re-implement a lot of this yourself if you + * + *

This does assume a great deal so you might have to re-implement a lot of this yourself if you * wanna do something wild and new */ -public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implements WorldlyContainer { +public abstract class BlockEntityAbstractImpetus extends HexBlockEntity + implements WorldlyContainer { private static final DecimalFormat DUST_AMOUNT = new DecimalFormat("###,###.##"); private static final long MAX_CAPACITY = 9_000_000_000_000_000_000L; - public static final String - TAG_EXECUTION_STATE = "executor", - TAG_MEDIA = "media", - TAG_ERROR_MSG = "errorMsg", - TAG_ERROR_DISPLAY = "errorDisplay", - TAG_PIGMENT = "pigment"; + public static final String TAG_EXECUTION_STATE = "executor", + TAG_MEDIA = "media", + TAG_ERROR_MSG = "errorMsg", + TAG_ERROR_DISPLAY = "errorDisplay", + TAG_PIGMENT = "pigment"; // We might try to load the executor in loadModData when the level doesn't exist yet, // so save the tag and load it lazy @Nullable CompoundTag lazyExecutionState; - @Nullable - protected CircleExecutionState executionState; + @Nullable protected CircleExecutionState executionState; protected long media = 0; // these are null together - @Nullable - protected Component displayMsg = null; - @Nullable - protected ItemStack displayItem = null; - @Nullable - protected FrozenPigment pigment = null; - + @Nullable protected Component displayMsg = null; + @Nullable protected ItemStack displayItem = null; + @Nullable protected FrozenPigment pigment = null; - public BlockEntityAbstractImpetus(BlockEntityType pType, BlockPos pWorldPosition, BlockState pBlockState) { + public BlockEntityAbstractImpetus( + BlockEntityType pType, BlockPos pWorldPosition, BlockState pBlockState) { super(pType, pWorldPosition, pBlockState); } @@ -104,16 +103,16 @@ public void postPrint(Component printDisplay) { // Pull this out because we may need to call it both on startup and halfway thru public void postNoExits(BlockPos pos) { this.postDisplay( - Component.translatable("hexcasting.tooltip.circle.no_exit", - Component.literal(pos.toShortString()).withStyle(ChatFormatting.RED)), - new ItemStack(Items.OAK_SIGN)); + Component.translatable( + "hexcasting.tooltip.circle.no_exit", + Component.literal(pos.toShortString()).withStyle(ChatFormatting.RED)), + new ItemStack(Items.OAK_SIGN)); } - //region execution + // region execution public void tickExecution() { - if (this.level == null) - return; + if (this.level == null) return; this.setChanged(); @@ -128,38 +127,35 @@ public void tickExecution() { this.endExecution(); this.executionState = null; } else - this.level.scheduleTick(this.getBlockPos(), this.getBlockState().getBlock(), state.getTickSpeed()); + this.level.scheduleTick( + this.getBlockPos(), this.getBlockState().getBlock(), state.getTickSpeed()); } public void endExecution() { - if (this.executionState == null) - return; + if (this.executionState == null) return; this.executionState.endExecution(this); } - /** - * ONLY CALL THIS WHEN YOU KNOW THE WORLD EXISTS AND ON THE SERVER, lazy-loads it - */ + /** ONLY CALL THIS WHEN YOU KNOW THE WORLD EXISTS AND ON THE SERVER, lazy-loads it */ public @Nullable CircleExecutionState getExecutionState() { if (this.level == null) { - throw new IllegalStateException("didn't you read the doc comment, don't call this if the level is null"); + throw new IllegalStateException( + "didn't you read the doc comment, don't call this if the level is null"); } - if (this.executionState != null) - return this.executionState; + if (this.executionState != null) return this.executionState; if (this.lazyExecutionState != null) - this.executionState = CircleExecutionState.load(this.lazyExecutionState, (ServerLevel) this.level); + this.executionState = + CircleExecutionState.load(this.lazyExecutionState, (ServerLevel) this.level); return this.executionState; } public void startExecution(@Nullable ServerPlayer player) { - if (this.level == null) - return; // TODO: error here? - if (this.level.isClientSide) - return; // TODO: error here? + if (this.level == null) return; // TODO: error here? + if (this.level.isClientSide) return; // TODO: error here? if (this.executionState != null) { return; @@ -168,13 +164,18 @@ public void startExecution(@Nullable ServerPlayer player) { if (result.isErr()) { var errPos = result.unwrapErr(); if (errPos == null) { - ICircleComponent.sfx(this.getBlockPos(), this.getBlockState(), this.level, null, false); + ICircleComponent.sfx( + this.getBlockPos(), this.getBlockState(), this.level, null, false); this.postNoExits(this.getBlockPos()); } else { - ICircleComponent.sfx(errPos, this.level.getBlockState(errPos), this.level, null, false); - this.postDisplay(Component.translatable("hexcasting.tooltip.circle.no_closure", - Component.literal(errPos.toShortString()).withStyle(ChatFormatting.RED)), - new ItemStack(Items.LEAD)); + ICircleComponent.sfx( + errPos, this.level.getBlockState(errPos), this.level, null, false); + this.postDisplay( + Component.translatable( + "hexcasting.tooltip.circle.no_closure", + Component.literal(errPos.toShortString()) + .withStyle(ChatFormatting.RED)), + new ItemStack(Items.LEAD)); } return; @@ -183,10 +184,13 @@ public void startExecution(@Nullable ServerPlayer player) { this.clearDisplay(); var serverLevel = (ServerLevel) this.level; - serverLevel.scheduleTick(this.getBlockPos(), this.getBlockState().getBlock(), - this.executionState.getTickSpeed()); - serverLevel.setBlockAndUpdate(this.getBlockPos(), - this.getBlockState().setValue(BlockCircleComponent.ENERGIZED, true)); + serverLevel.scheduleTick( + this.getBlockPos(), + this.getBlockState().getBlock(), + this.executionState.getTickSpeed()); + serverLevel.setBlockAndUpdate( + this.getBlockPos(), + this.getBlockState().setValue(BlockCircleComponent.ENERGIZED, true)); } @Contract(pure = true) @@ -222,9 +226,9 @@ protected static AABB getBounds(List poses) { return new AABB(minX, minY, minZ, maxX + 1, maxY + 1, maxZ + 1); } - //endregion + // endregion - //region media handling + // region media handling public long getMedia() { return this.media; @@ -267,12 +271,10 @@ public long remainingMediaCapacity() { return Math.max(0, MAX_CAPACITY - this.media); } - //endregion - + // endregion public FrozenPigment getPigment() { - if (pigment != null) - return pigment; + if (pigment != null) return pigment; if (executionState != null && executionState.casterPigment != null) return executionState.casterPigment; return FrozenPigment.DEFAULT.get(); @@ -297,8 +299,7 @@ protected void saveModData(CompoundTag tag) { this.displayItem.save(itemTag); tag.put(TAG_ERROR_DISPLAY, itemTag); } - if (this.pigment != null) - tag.put(TAG_PIGMENT, this.pigment.serializeToNBT()); + if (this.pigment != null) tag.put(TAG_PIGMENT, this.pigment.serializeToNBT()); } @Override @@ -314,7 +315,8 @@ protected void loadModData(CompoundTag tag) { this.media = tag.getLong(TAG_MEDIA); } - if (tag.contains(TAG_ERROR_MSG, Tag.TAG_STRING) && tag.contains(TAG_ERROR_DISPLAY, Tag.TAG_COMPOUND)) { + if (tag.contains(TAG_ERROR_MSG, Tag.TAG_STRING) + && tag.contains(TAG_ERROR_DISPLAY, Tag.TAG_COMPOUND)) { var msg = Component.Serializer.fromJson(tag.getString(TAG_ERROR_MSG)); var display = ItemStack.of(tag.getCompound(TAG_ERROR_DISPLAY)); this.displayMsg = msg; @@ -327,15 +329,24 @@ protected void loadModData(CompoundTag tag) { this.pigment = FrozenPigment.fromNBT(tag.getCompound(TAG_PIGMENT)); } - public void applyScryingLensOverlay(List> lines, - BlockState state, BlockPos pos, Player observer, Level world, Direction hitFace) { + public void applyScryingLensOverlay( + List> lines, + BlockState state, + BlockPos pos, + Player observer, + Level world, + Direction hitFace) { if (world.getBlockEntity(pos) instanceof BlockEntityAbstractImpetus beai) { if (beai.getMedia() < 0) { - lines.add(new Pair<>(new ItemStack(HexItems.AMETHYST_DUST), ItemCreativeUnlocker.infiniteMedia(world))); + lines.add( + new Pair<>( + new ItemStack(HexItems.AMETHYST_DUST), + ItemCreativeUnlocker.infiniteMedia(world))); } else { var dustCount = (float) beai.getMedia() / (float) MediaConstants.DUST_UNIT; - var dustCmp = Component.translatable("hexcasting.tooltip.media", - DUST_AMOUNT.format(dustCount)); + var dustCmp = + Component.translatable( + "hexcasting.tooltip.media", DUST_AMOUNT.format(dustCount)); lines.add(new Pair<>(new ItemStack(HexItems.AMETHYST_DUST), dustCmp)); } @@ -345,7 +356,7 @@ public void applyScryingLensOverlay(List> lines, } } - //region music + // region music protected int semitoneFromScale(int note) { var blockBelow = this.level.getBlockState(this.getBlockPos().below()); @@ -357,9 +368,12 @@ protected int semitoneFromScale(int note) { } else if (blockBelow.is(Blocks.PISTON) || blockBelow.is(Blocks.STICKY_PISTON)) { scale = MIXOLYDIAN_SCALE; } else if (blockBelow.is(Blocks.BLUE_WOOL) - || blockBelow.is(Blocks.BLUE_CONCRETE) || blockBelow.is(Blocks.BLUE_CONCRETE_POWDER) - || blockBelow.is(Blocks.BLUE_TERRACOTTA) || blockBelow.is(Blocks.BLUE_GLAZED_TERRACOTTA) - || blockBelow.is(Blocks.BLUE_STAINED_GLASS) || blockBelow.is(Blocks.BLUE_STAINED_GLASS_PANE)) { + || blockBelow.is(Blocks.BLUE_CONCRETE) + || blockBelow.is(Blocks.BLUE_CONCRETE_POWDER) + || blockBelow.is(Blocks.BLUE_TERRACOTTA) + || blockBelow.is(Blocks.BLUE_GLAZED_TERRACOTTA) + || blockBelow.is(Blocks.BLUE_STAINED_GLASS) + || blockBelow.is(Blocks.BLUE_STAINED_GLASS_PANE)) { scale = BLUES_SCALE; } else if (blockBelow.is(Blocks.BONE_BLOCK)) { scale = BAD_TIME; @@ -380,9 +394,9 @@ protected int semitoneFromScale(int note) { private static final int[] BAD_TIME = {0, 0, 12, 7, 6, 5, 3, 0, 3, 5}; private static final int[] SUSSY_BAKA = {5, 8, 10, 11, 10, 8, 5, 3, 7, 5}; - //endregion + // endregion - //region item handler contract stuff + // region item handler contract stuff private static final int[] SLOTS = {0}; @Override @@ -454,5 +468,5 @@ public boolean canPlaceItem(int index, ItemStack stack) { return mediamount > 0; } - //endregion + // endregion } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java index f95fa84f01..2b607b5e52 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/CircleExecutionState.java @@ -6,7 +6,9 @@ import at.petrak.hexcasting.api.misc.Result; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.HexUtils; + import com.mojang.datafixers.util.Pair; + import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -20,24 +22,22 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.phys.AABB; + import org.jetbrains.annotations.Nullable; import java.util.*; -/** - * See {@link BlockEntityAbstractImpetus}, this is what's stored in it - */ +/** See {@link BlockEntityAbstractImpetus}, this is what's stored in it */ public class CircleExecutionState { - public static final String - TAG_IMPETUS_POS = "impetus_pos", - TAG_IMPETUS_DIR = "impetus_dir", - TAG_KNOWN_POSITIONS = "known_positions", - TAG_REACHED_POSITIONS = "reached_positions", - TAG_CURRENT_POS = "current_pos", - TAG_ENTERED_FROM = "entered_from", - TAG_IMAGE = "image", - TAG_CASTER = "caster", - TAG_PIGMENT = "pigment"; + public static final String TAG_IMPETUS_POS = "impetus_pos", + TAG_IMPETUS_DIR = "impetus_dir", + TAG_KNOWN_POSITIONS = "known_positions", + TAG_REACHED_POSITIONS = "reached_positions", + TAG_CURRENT_POS = "current_pos", + TAG_ENTERED_FROM = "entered_from", + TAG_IMAGE = "image", + TAG_CASTER = "caster", + TAG_PIGMENT = "pigment"; public final BlockPos impetusPos; public final Direction impetusDir; @@ -52,10 +52,16 @@ public class CircleExecutionState { public final AABB bounds; - - protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set knownPositions, - List reachedPositions, BlockPos currentPos, Direction enteredFrom, - CastingImage currentImage, @Nullable UUID caster, @Nullable FrozenPigment casterPigment) { + protected CircleExecutionState( + BlockPos impetusPos, + Direction impetusDir, + Set knownPositions, + List reachedPositions, + BlockPos currentPos, + Direction enteredFrom, + CastingImage currentImage, + @Nullable UUID caster, + @Nullable FrozenPigment casterPigment) { this.impetusPos = impetusPos; this.impetusDir = impetusDir; this.knownPositions = knownPositions; @@ -82,17 +88,19 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set createNew(BlockEntityAbstractImpetus impetus, - @Nullable ServerPlayer caster) { + public static Result createNew( + BlockEntityAbstractImpetus impetus, @Nullable ServerPlayer caster) { var level = (ServerLevel) impetus.getLevel(); - if (level == null) - return new Result.Err<>(null); + if (level == null) return new Result.Err<>(null); // Flood fill! Just like VCC all over again. // this contains tentative positions and directions entered from var todo = new Stack>(); - todo.add(Pair.of(impetus.getStartDirection(), impetus.getBlockPos().relative(impetus.getStartDirection()))); + todo.add( + Pair.of( + impetus.getStartDirection(), + impetus.getBlockPos().relative(impetus.getStartDirection()))); var seenGoodPosSet = new HashSet(); var seenGoodPositions = new ArrayList(); @@ -122,7 +130,8 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set(null); } else if (!seenGoodPosSet.contains(impetus.getBlockPos())) { - // we can't enter from the side the directrix exits from, so this means we couldn't loop back. + // we can't enter from the side the directrix exits from, so this means we couldn't loop + // back. // the last item we tried to examine will always be a terminal slate (b/c if it wasn't, // then the *next* slate would be last qed) return new Result.Err<>(seenGoodPositions.get(seenGoodPositions.size() - 1)); @@ -142,8 +151,16 @@ protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set( - new CircleExecutionState(impetus.getBlockPos(), impetus.getStartDirection(), knownPositions, - reachedPositions, start, impetus.getStartDirection(), new CastingImage(), casterUUID, colorizer)); + new CircleExecutionState( + impetus.getBlockPos(), + impetus.getStartDirection(), + knownPositions, + reachedPositions, + start, + impetus.getStartDirection(), + new CastingImage(), + casterUUID, + colorizer)); } public CompoundTag save() { @@ -168,11 +185,9 @@ public CompoundTag save() { out.putByte(TAG_ENTERED_FROM, (byte) this.enteredFrom.ordinal()); out.put(TAG_IMAGE, this.currentImage.serializeToNbt()); - if (this.caster != null) - out.putUUID(TAG_CASTER, this.caster); + if (this.caster != null) out.putUUID(TAG_CASTER, this.caster); - if (this.casterPigment != null) - out.put(TAG_PIGMENT, this.casterPigment.serializeToNBT()); + if (this.casterPigment != null) out.put(TAG_PIGMENT, this.casterPigment.serializeToNBT()); return out; } @@ -197,35 +212,45 @@ public static CircleExecutionState load(CompoundTag nbt, ServerLevel world) { var image = CastingImage.loadFromNbt(nbt.getCompound(TAG_IMAGE), world); UUID caster = null; - if (nbt.hasUUID(TAG_CASTER)) - caster = nbt.getUUID(TAG_CASTER); + if (nbt.hasUUID(TAG_CASTER)) caster = nbt.getUUID(TAG_CASTER); FrozenPigment pigment = null; if (nbt.contains(TAG_PIGMENT, Tag.TAG_COMPOUND)) pigment = FrozenPigment.fromNBT(nbt.getCompound(TAG_PIGMENT)); - return new CircleExecutionState(startPos, startDir, knownPositions, reachedPositions, currentPos, - enteredFrom, image, caster, pigment); + return new CircleExecutionState( + startPos, + startDir, + knownPositions, + reachedPositions, + currentPos, + enteredFrom, + image, + caster, + pigment); } /** * Update this, also mutates the impetus. - *

- * Returns whether to continue. + * + *

Returns whether to continue. */ public boolean tick(BlockEntityAbstractImpetus impetus) { var world = (ServerLevel) impetus.getLevel(); - if (world == null) - return true; // if the world is null, try again next tick. + if (world == null) return true; // if the world is null, try again next tick. var env = new CircleCastEnv(world, this); var executorBlockState = world.getBlockState(this.currentPos); if (!(executorBlockState.getBlock() instanceof ICircleComponent executor)) { // TODO: notification of the error? - ICircleComponent.sfx(this.currentPos, executorBlockState, world, - Objects.requireNonNull(env.getImpetus()), false); + ICircleComponent.sfx( + this.currentPos, + executorBlockState, + world, + Objects.requireNonNull(env.getImpetus()), + false); return false; } @@ -234,11 +259,18 @@ public boolean tick(BlockEntityAbstractImpetus impetus) { // Do the execution! boolean halt = false; - var ctrl = executor.acceptControlFlow(this.currentImage, env, this.enteredFrom, this.currentPos, - executorBlockState, world); + var ctrl = + executor.acceptControlFlow( + this.currentImage, + env, + this.enteredFrom, + this.currentPos, + executorBlockState, + world); if (env.getImpetus() == null) - return false; //the impetus got removed during the cast and no longer exists in the world. stop casting + return false; // the impetus got removed during the cast and no longer exists in the + // world. stop casting if (ctrl instanceof ICircleComponent.ControlFlow.Stop) { // acceptControlFlow should have already posted the error @@ -249,15 +281,22 @@ public boolean tick(BlockEntityAbstractImpetus impetus) { for (var exit : cont.exits) { var there = world.getBlockState(exit.getFirst()); if (there.getBlock() instanceof ICircleComponent cc - && cc.canEnterFromDirection(exit.getSecond(), exit.getFirst(), there, world)) { + && cc.canEnterFromDirection( + exit.getSecond(), exit.getFirst(), there, world)) { if (found != null) { // oh no! impetus.postDisplay( - Component.translatable("hexcasting.tooltip.circle.many_exits", - Component.literal(this.currentPos.toShortString()).withStyle(ChatFormatting.RED)), - new ItemStack(Items.COMPASS)); - ICircleComponent.sfx(this.currentPos, executorBlockState, world, - Objects.requireNonNull(env.getImpetus()), false); + Component.translatable( + "hexcasting.tooltip.circle.many_exits", + Component.literal(this.currentPos.toShortString()) + .withStyle(ChatFormatting.RED)), + new ItemStack(Items.COMPASS)); + ICircleComponent.sfx( + this.currentPos, + executorBlockState, + world, + Objects.requireNonNull(env.getImpetus()), + false); halt = true; break; } else { @@ -268,17 +307,27 @@ public boolean tick(BlockEntityAbstractImpetus impetus) { if (found == null) { // will never enter here if there were too many because found will have been set - ICircleComponent.sfx(this.currentPos, executorBlockState, world, - Objects.requireNonNull(env.getImpetus()), false); + ICircleComponent.sfx( + this.currentPos, + executorBlockState, + world, + Objects.requireNonNull(env.getImpetus()), + false); impetus.postNoExits(this.currentPos); halt = true; } else { // A single valid exit position has been found. - ICircleComponent.sfx(this.currentPos, executorBlockState, world, - Objects.requireNonNull(env.getImpetus()), true); + ICircleComponent.sfx( + this.currentPos, + executorBlockState, + world, + Objects.requireNonNull(env.getImpetus()), + true); currentPos = found.getFirst(); enteredFrom = found.getSecond(); - currentImage = cont.update.withOverriddenUsedOps(0); // reset ops used after each slate finishes executing + currentImage = + cont.update.withOverriddenUsedOps( + 0); // reset ops used after each slate finishes executing } } @@ -286,7 +335,8 @@ public boolean tick(BlockEntityAbstractImpetus impetus) { } /** - * How many ticks should pass between activations, given the number of blocks encountered so far. + * How many ticks should pass between activations, given the number of blocks encountered so + * far. */ protected int getTickSpeed() { return Math.max(2, 10 - (this.reachedPositions.size() - 1) / 3); @@ -295,8 +345,7 @@ protected int getTickSpeed() { public void endExecution(BlockEntityAbstractImpetus impetus) { var world = (ServerLevel) impetus.getLevel(); - if (world == null) - return; // TODO: error here? + if (world == null) return; // TODO: error here? for (var pos : this.reachedPositions) { var there = world.getBlockState(pos); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/ICircleComponent.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/ICircleComponent.java index 66e06b4d0d..b1e1dadc43 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/ICircleComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/circles/ICircleComponent.java @@ -10,7 +10,9 @@ import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.lib.HexSounds; + import com.mojang.datafixers.util.Pair; + import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -23,6 +25,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.Contract; import java.util.EnumSet; @@ -31,44 +34,51 @@ /** * Implement this on a block to make circles interact with it. - *

- * This is its own interface so you can have your blocks subclass something else, and to avoid enormous - * files. The mod doesn't check for the interface on anything but blocks. + * + *

This is its own interface so you can have your blocks subclass something else, and to avoid + * enormous files. The mod doesn't check for the interface on anything but blocks. */ public interface ICircleComponent { /** * The heart of the interface! Functionally modify the casting environment. - *

- * With the new update you can have the side effects happen inline. In fact, you have to have the side effects - * happen inline. - *

- * Also, return a list of directions that the control flow can exit this block in. - * The circle environment will mishap if not exactly 1 of the returned directions can be accepted from. + * + *

With the new update you can have the side effects happen inline. In fact, you have to have + * the side effects happen inline. + * + *

Also, return a list of directions that the control flow can exit this block in. The circle + * environment will mishap if not exactly 1 of the returned directions can be accepted from. */ - ControlFlow acceptControlFlow(CastingImage imageIn, CircleCastEnv env, Direction enterDir, BlockPos pos, - BlockState bs, ServerLevel world); + ControlFlow acceptControlFlow( + CastingImage imageIn, + CircleCastEnv env, + Direction enterDir, + BlockPos pos, + BlockState bs, + ServerLevel world); /** - * Can this component get transferred to from a block coming in from that direction, with the given normal? + * Can this component get transferred to from a block coming in from that direction, with the + * given normal? */ @Contract(pure = true) - boolean canEnterFromDirection(Direction enterDir, BlockPos pos, BlockState bs, ServerLevel world); + boolean canEnterFromDirection( + Direction enterDir, BlockPos pos, BlockState bs, ServerLevel world); /** - * This determines the directions the control flow can exit from. It's called at the beginning of execution - * to see if the circle actually forms a loop. - *

- * For most blocks, this should be the same as returned from {@link ICircleComponent#acceptControlFlow} - * Things like directrices might return otherwise. Whatever is returned when controlling flow must be a subset of - * this set. + * This determines the directions the control flow can exit from. It's called at the + * beginning of execution to see if the circle actually forms a loop. + * + *

For most blocks, this should be the same as returned from {@link + * ICircleComponent#acceptControlFlow} Things like directrices might return otherwise. Whatever + * is returned when controlling flow must be a subset of this set. */ @Contract(pure = true) EnumSet possibleExitDirections(BlockPos pos, BlockState bs, Level world); /** - * Given the current position and a direction, return a pair of the new position after a step - * in that direction, along with the direction (this is a helper function for creating - * {@link ICircleComponent.ControlFlow}s. + * Given the current position and a direction, return a pair of the new position after a step in + * that direction, along with the direction (this is a helper function for creating {@link + * ICircleComponent.ControlFlow}s. */ @Contract(pure = true) default Pair exitPositionFromDirection(BlockPos pos, Direction dir) { @@ -76,37 +86,43 @@ default Pair exitPositionFromDirection(BlockPos pos, Direct } /** - * Start the {@link ICircleComponent} at the given position glowing. Returns the new state - * of the given block. - * // TODO: determine if this should just be in - * {@link ICircleComponent#acceptControlFlow(CastingImage, CircleCastEnv, Direction, BlockPos, BlockState, ServerLevel)}. + * Start the {@link ICircleComponent} at the given position glowing. Returns the new state of + * the given block. // TODO: determine if this should just be in {@link + * ICircleComponent#acceptControlFlow(CastingImage, CircleCastEnv, Direction, BlockPos, + * BlockState, ServerLevel)}. */ BlockState startEnergized(BlockPos pos, BlockState bs, Level world); - /** - * Returns whether the {@link ICircleComponent} at the given position is energized. - */ + /** Returns whether the {@link ICircleComponent} at the given position is energized. */ boolean isEnergized(BlockPos pos, BlockState bs, Level world); /** - * End the {@link ICircleComponent} at the given position glowing. Returns the new state of - * the given block. + * End the {@link ICircleComponent} at the given position glowing. Returns the new state of the + * given block. */ BlockState endEnergized(BlockPos pos, BlockState bs, Level world); - static void sfx(BlockPos pos, BlockState bs, Level world, BlockEntityAbstractImpetus impetus, boolean success) { + static void sfx( + BlockPos pos, + BlockState bs, + Level world, + BlockEntityAbstractImpetus impetus, + boolean success) { Vec3 vpos; Vec3 vecOutDir; FrozenPigment colorizer; UUID activator = Util.NIL_UUID; - if (impetus != null && impetus.getExecutionState() != null && impetus.getExecutionState().caster != null) + if (impetus != null + && impetus.getExecutionState() != null + && impetus.getExecutionState().caster != null) activator = impetus.getExecutionState().caster; if (impetus == null || impetus.getExecutionState() == null) - colorizer = new FrozenPigment(new ItemStack(HexItems.DYE_PIGMENTS.get(DyeColor.RED)), activator); - else - colorizer = impetus.getPigment(); + colorizer = + new FrozenPigment( + new ItemStack(HexItems.DYE_PIGMENTS.get(DyeColor.RED)), activator); + else colorizer = impetus.getPigment(); if (bs.getBlock() instanceof BlockCircleComponent bcc) { var outDir = bcc.normalDir(pos, bs, world); @@ -120,11 +136,20 @@ static void sfx(BlockPos pos, BlockState bs, Level world, BlockEntityAbstractImp } if (world instanceof ServerLevel serverLevel) { - var spray = new ParticleSpray(vpos, vecOutDir.scale(success ? 1.0 : 1.5), success ? 0.1 : 0.5, - Mth.PI / (success ? 4 : 2), success ? 30 : 100); - spray.sprayParticles(serverLevel, - success ? colorizer : new FrozenPigment(new ItemStack(HexItems.DYE_PIGMENTS.get(DyeColor.RED)), - activator)); + var spray = + new ParticleSpray( + vpos, + vecOutDir.scale(success ? 1.0 : 1.5), + success ? 0.1 : 0.5, + Mth.PI / (success ? 4 : 2), + success ? 30 : 100); + spray.sprayParticles( + serverLevel, + success + ? colorizer + : new FrozenPigment( + new ItemStack(HexItems.DYE_PIGMENTS.get(DyeColor.RED)), + activator)); } var pitch = 1f; @@ -142,12 +167,17 @@ static void sfx(BlockPos pos, BlockState bs, Level world, BlockEntityAbstractImp world.playSound(null, vpos.x, vpos.y, vpos.z, sound, SoundSource.BLOCKS, 1f, pitch); } - /** - * Helper function to "throw a mishap" - */ - default void fakeThrowMishap(BlockPos pos, BlockState bs, CastingImage image, CircleCastEnv env, Mishap mishap) { - Mishap.Context errorCtx = new Mishap.Context(null, - bs.getBlock().getName().append(" (").append(Component.literal(pos.toShortString())).append(")")); + /** Helper function to "throw a mishap" */ + default void fakeThrowMishap( + BlockPos pos, BlockState bs, CastingImage image, CircleCastEnv env, Mishap mishap) { + Mishap.Context errorCtx = + new Mishap.Context( + null, + bs.getBlock() + .getName() + .append(" (") + .append(Component.literal(pos.toShortString())) + .append(")")); var sideEffect = new OperatorSideEffect.DoMishap(mishap, errorCtx); var vm = new CastingVM(image, env); sideEffect.performEffect(vm); @@ -164,7 +194,6 @@ public Continue(CastingImage update, List> exits) { } } - public static final class Stop extends ControlFlow { - } + public static final class Stop extends ControlFlow {} } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt index c0b4d4442d..33847c69d3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastResult.kt @@ -9,15 +9,15 @@ import at.petrak.hexcasting.api.casting.iota.Iota /** * The result of doing something to a cast harness. * - * Contains the iota that was executed to produce this CastResult, - * the next thing to execute after this is finished, the modified state of the stack, - * and side effects, as well as display information for the client. + * Contains the iota that was executed to produce this CastResult, the next thing to execute after + * this is finished, the modified state of the stack, and side effects, as well as display + * information for the client. */ data class CastResult( - val cast: Iota, - val continuation: SpellContinuation, - val newData: CastingImage?, - val sideEffects: List, - val resolutionType: ResolvedPatternType, - val sound: EvalSound, + val cast: Iota, + val continuation: SpellContinuation, + val newData: CastingImage?, + val sideEffects: List, + val resolutionType: ResolvedPatternType, + val sound: EvalSound, ) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java index 6eaaf765ec..48325c9d82 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java @@ -1,5 +1,8 @@ package at.petrak.hexcasting.api.casting.eval; +import static at.petrak.hexcasting.api.HexAPI.modLoc; +import static at.petrak.hexcasting.api.casting.eval.CastingEnvironmentComponent.*; + import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.casting.PatternShapeMatch; import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; @@ -10,6 +13,7 @@ import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.api.utils.HexUtils; + import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -23,6 +27,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,50 +39,50 @@ import java.util.function.Consumer; import java.util.function.Predicate; -import static at.petrak.hexcasting.api.HexAPI.modLoc; -import static at.petrak.hexcasting.api.casting.eval.CastingEnvironmentComponent.*; - /** * Environment within which hexes are cast. - *

- * Stuff like "the player with a staff," "the player with a trinket," "spell circles," + * + *

Stuff like "the player with a staff," "the player with a trinket," "spell circles," */ public abstract class CastingEnvironment { /** * Stores all listeners that should be notified whenever a CastingEnvironment is initialised. */ - private static final List> createEventListeners = new ArrayList<>(); + private static final List> createEventListeners = + new ArrayList<>(); - /** - * Add a listener that will be called whenever a new CastingEnvironment is created. - */ - public static void addCreateEventListener(BiConsumer listener) { + /** Add a listener that will be called whenever a new CastingEnvironment is created. */ + public static void addCreateEventListener( + BiConsumer listener) { createEventListeners.add(listener); } /** * Add a listener that will be called whenever a new CastingEnvironment is created (legacy). + * * @deprecated replaced by {@link #addCreateEventListener(BiConsumer)} */ @Deprecated(since = "0.11.0-pre-660") public static void addCreateEventListener(Consumer listener) { - createEventListeners.add((env, data) -> {listener.accept(env);}); + createEventListeners.add( + (env, data) -> { + listener.accept(env); + }); } private boolean createEventTriggered = false; public final void triggerCreateEvent(CompoundTag userData) { if (!createEventTriggered) { - for (var listener : createEventListeners) - listener.accept(this, userData); + for (var listener : createEventListeners) listener.accept(this, userData); createEventTriggered = true; } } - protected final ServerLevel world; - protected Map, @NotNull CastingEnvironmentComponent> componentMap = new HashMap<>(); + protected Map, @NotNull CastingEnvironmentComponent> + componentMap = new HashMap<>(); private final List postExecutions = new ArrayList<>(); private final List postCasts = new ArrayList<>(); @@ -101,78 +106,73 @@ public int maxOpCount() { /** * Get the caster. Might be null! - *

- * Implementations should NOT rely on this in general, use the methods on this class instead. + * + *

Implementations should NOT rely on this in general, use the methods on this class instead. * This is mostly for spells (flight, etc) + * * @deprecated as of build 0.11.1-7-pre-619 you are recommended to use {@link #getCastingEntity} */ - @Deprecated(since="0.11.1-7-pre-619") + @Deprecated(since = "0.11.1-7-pre-619") @Nullable public ServerPlayer getCaster() { return getCastingEntity() instanceof ServerPlayer sp ? sp : null; - }; + } + ; /** * Gets the caster. Can be null if {@link #getCaster()} is also null + * * @return the entity casting */ @Nullable public abstract LivingEntity getCastingEntity(); - /** - * Get an interface used to do mishaps - */ + /** Get an interface used to do mishaps */ public abstract MishapEnvironment getMishapEnvironment(); public void addExtension(@NotNull T extension) { componentMap.put(extension.getKey(), extension); - if (extension instanceof PostExecution postExecution) - postExecutions.add(postExecution); - if (extension instanceof PostCast postCast) - postCasts.add(postCast); + if (extension instanceof PostExecution postExecution) postExecutions.add(postExecution); + if (extension instanceof PostCast postCast) postCasts.add(postCast); if (extension instanceof ExtractMedia extractMedia) if (extension instanceof ExtractMedia.Pre pre) { preMediaExtract.add(pre); } else if (extension instanceof ExtractMedia.Post post) { postMediaExtract.add(post); } - if (extension instanceof IsVecInRange isVecInRange) - isVecInRanges.add(isVecInRange); + if (extension instanceof IsVecInRange isVecInRange) isVecInRanges.add(isVecInRange); if (extension instanceof HasEditPermissionsAt hasEditPermissionsAt) hasEditPermissionsAts.add(hasEditPermissionsAt); } public void removeExtension(@NotNull CastingEnvironmentComponent.Key key) { var extension = componentMap.remove(key); - if (extension == null) - return; + if (extension == null) return; - if (extension instanceof PostExecution postExecution) - postExecutions.remove(postExecution); - if (extension instanceof PostCast postCast) - postCasts.remove(postCast); + if (extension instanceof PostExecution postExecution) postExecutions.remove(postExecution); + if (extension instanceof PostCast postCast) postCasts.remove(postCast); if (extension instanceof ExtractMedia extractMedia) if (extension instanceof ExtractMedia.Pre pre) { preMediaExtract.remove(pre); } else if (extension instanceof ExtractMedia.Post post) { postMediaExtract.remove(post); } - if (extension instanceof IsVecInRange isVecInRange) - isVecInRanges.remove(isVecInRange); + if (extension instanceof IsVecInRange isVecInRange) isVecInRanges.remove(isVecInRange); if (extension instanceof HasEditPermissionsAt hasEditPermissionsAt) hasEditPermissionsAts.remove(hasEditPermissionsAt); } @Nullable @SuppressWarnings("unchecked") - public T getExtension(@NotNull CastingEnvironmentComponent.Key key) { + public T getExtension( + @NotNull CastingEnvironmentComponent.Key key) { return (T) componentMap.get(key); } /** * If something about this ARE itself is invalid, mishap. - *

- * This is used for stuff like requiring enlightenment and pattern denylists + * + *

This is used for stuff like requiring enlightenment and pattern denylists */ public void precheckAction(PatternShapeMatch match) throws Mishap { // TODO: this doesn't let you select special handlers. @@ -199,31 +199,26 @@ protected ResourceLocation actionKey(PatternShapeMatch match) { return key; } - /** - * Do whatever you like after a pattern is executed. - */ + /** Do whatever you like after a pattern is executed. */ public void postExecution(CastResult result) { for (var postExecutionComponent : postExecutions) postExecutionComponent.onPostExecution(result); } /** - * Do things after the whole cast is finished (i.e. every pattern to be executed has been executed). + * Do things after the whole cast is finished (i.e. every pattern to be executed has been + * executed). */ public void postCast(CastingImage image) { - for (var postCastComponent : postCasts) - postCastComponent.onPostCast(image); + for (var postCastComponent : postCasts) postCastComponent.onPostCast(image); } public abstract Vec3 mishapSprayPos(); - /** - * Return whether this env can cast great spells. - */ + /** Return whether this env can cast great spells. */ public boolean isEnlightened() { var adv = this.world.getServer().getAdvancements().getAdvancement(modLoc("enlightenment")); - if (adv == null) - return false; + if (adv == null) return false; var caster = this.getCastingEntity(); if (caster instanceof ServerPlayer player) @@ -234,9 +229,9 @@ public boolean isEnlightened() { /** * Attempt to extract the given amount of media. Returns the amount of media left in the cost. - *

- * If there was enough media found, it will return less or equal to zero; if there wasn't, it will be - * positive. + * + *

If there was enough media found, it will return less or equal to zero; if there wasn't, it + * will be positive. */ public long extractMedia(long cost, boolean simulate) { for (var extractMediaComponent : preMediaExtract) @@ -249,16 +244,16 @@ public long extractMedia(long cost, boolean simulate) { /** * Attempt to extract the given amount of media. Returns the amount of media left in the cost. - *

- * If there was enough media found, it will return less or equal to zero; if there wasn't, it will be - * positive. + * + *

If there was enough media found, it will return less or equal to zero; if there wasn't, it + * will be positive. */ protected abstract long extractMediaEnvironment(long cost, boolean simulate); /** * Get if the vec is close enough, to the player or sentinel ... - *

- * Doesn't take into account being out of the world. + * + *

Doesn't take into account being out of the world. */ public boolean isVecInRange(Vec3 vec) { boolean isInRange = isVecInRangeEnvironment(vec); @@ -269,29 +264,32 @@ public boolean isVecInRange(Vec3 vec) { /** * Get if the vec is close enough, to the player or sentinel ... - *

- * Doesn't take into account being out of the world. + * + *

Doesn't take into account being out of the world. */ protected abstract boolean isVecInRangeEnvironment(Vec3 vec); /** - * Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, etc.) + * Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, + * etc.) */ public boolean hasEditPermissionsAt(BlockPos pos) { boolean hasEditPermissionsAt = hasEditPermissionsAtEnvironment(pos); for (var hasEditPermissionsAtComponent : hasEditPermissionsAts) - hasEditPermissionsAt = hasEditPermissionsAtComponent.onHasEditPermissionsAt(pos, hasEditPermissionsAt); + hasEditPermissionsAt = + hasEditPermissionsAtComponent.onHasEditPermissionsAt(pos, hasEditPermissionsAt); return hasEditPermissionsAt; } /** - * Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, etc.) + * Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, + * etc.) */ protected abstract boolean hasEditPermissionsAtEnvironment(BlockPos pos); public final boolean isVecInWorld(Vec3 vec) { return this.world.isInWorldBounds(BlockPos.containing(vec)) - && this.world.getWorldBorder().isWithinBounds(vec.x, vec.z, 0.5); + && this.world.getWorldBorder().isWithinBounds(vec.x, vec.z, 0.5); } public final boolean isVecInAmbit(Vec3 vec) { @@ -299,12 +297,11 @@ public final boolean isVecInAmbit(Vec3 vec) { } public final boolean isEntityInRange(Entity e) { - return (e instanceof Player && HexConfig.server().trueNameHasAmbit()) || (this.isVecInWorld(e.position()) && this.isVecInRange(e.position())); + return (e instanceof Player && HexConfig.server().trueNameHasAmbit()) + || (this.isVecInWorld(e.position()) && this.isVecInRange(e.position())); } - /** - * Convenience function to throw if the vec is out of the caster's range or the world - */ + /** Convenience function to throw if the vec is out of the caster's range or the world */ public final void assertVecInRange(Vec3 vec) throws MishapBadLocation { this.assertVecInWorld(vec); if (!this.isVecInRange(vec)) { @@ -326,9 +323,7 @@ public final boolean canEditBlockAt(BlockPos vec) { return this.isVecInRange(Vec3.atCenterOf(vec)) && this.hasEditPermissionsAt(vec); } - /** - * Convenience function to throw if the entity is out of the caster's range or the world - */ + /** Convenience function to throw if the entity is out of the caster's range or the world */ public final void assertEntityInRange(Entity e) throws MishapEntityTooFarAway { if (e instanceof ServerPlayer && HexConfig.server().trueNameHasAmbit()) { return; @@ -341,9 +336,7 @@ public final void assertEntityInRange(Entity e) throws MishapEntityTooFarAway { } } - /** - * Convenience function to throw if the vec is out of the world (for GTP) - */ + /** Convenience function to throw if the vec is out of the world (for GTP) */ public final void assertVecInWorld(Vec3 vec) throws MishapBadLocation { if (!this.isVecInWorld(vec)) { throw new MishapBadLocation(vec, "out_of_world"); @@ -356,12 +349,11 @@ public InteractionHand getOtherHand() { return HexUtils.otherHand(this.getCastingHand()); } - /** - * Get all the item stacks this env can use. - */ + /** Get all the item stacks this env can use. */ protected abstract List getUsableStacks(StackDiscoveryMode mode); - protected List getUsableStacksForPlayer(StackDiscoveryMode mode, @Nullable InteractionHand castingHand, ServerPlayer caster) { + protected List getUsableStacksForPlayer( + StackDiscoveryMode mode, @Nullable InteractionHand castingHand, ServerPlayer caster) { return switch (mode) { case QUERY -> { var out = new ArrayList(); @@ -383,12 +375,13 @@ protected List getUsableStacksForPlayer(StackDiscoveryMode mode, @Nul } } - // If we're casting from the main hand, try to pick from the slot one to the right of the selected slot + // If we're casting from the main hand, try to pick from the slot one to the right + // of the selected slot // Otherwise, scan the hotbar left to right - var anchorSlot = castingHand != InteractionHand.OFF_HAND - ? (caster.getInventory().selected + 1) % 9 - : 0; - + var anchorSlot = + castingHand != InteractionHand.OFF_HAND + ? (caster.getInventory().selected + 1) % 9 + : 0; for (int delta = 0; delta < 9; delta++) { var slot = (anchorSlot + delta) % 9; @@ -424,28 +417,27 @@ protected List getUsableStacksForPlayer(StackDiscoveryMode mode, @Nul } /** - * Get the primary/secondary item stacks this env can use (i.e. main hand and offhand for the player). + * Get the primary/secondary item stacks this env can use (i.e. main hand and offhand for the + * player). */ protected abstract List getPrimaryStacks(); - protected List getPrimaryStacksForPlayer(InteractionHand castingHand, ServerPlayer caster) { + protected List getPrimaryStacksForPlayer( + InteractionHand castingHand, ServerPlayer caster) { var primaryItem = caster.getItemInHand(castingHand); - if (primaryItem.isEmpty()) - primaryItem = ItemStack.EMPTY.copy(); + if (primaryItem.isEmpty()) primaryItem = ItemStack.EMPTY.copy(); var secondaryItem = caster.getItemInHand(HexUtils.otherHand(castingHand)); - if (secondaryItem.isEmpty()) - secondaryItem = ItemStack.EMPTY.copy(); + if (secondaryItem.isEmpty()) secondaryItem = ItemStack.EMPTY.copy(); - return List.of(new HeldItemInfo(secondaryItem, HexUtils.otherHand(castingHand)), new HeldItemInfo(primaryItem, - castingHand)); + return List.of( + new HeldItemInfo(secondaryItem, HexUtils.otherHand(castingHand)), + new HeldItemInfo(primaryItem, castingHand)); } - /** - * Return the slot from which to take blocks and items. - */ + /** Return the slot from which to take blocks and items. */ @Nullable public ItemStack queryForMatchingStack(Predicate stackOk) { var stacks = this.getUsableStacks(StackDiscoveryMode.QUERY); @@ -468,9 +460,7 @@ public ItemStack component1() { } } - /** - * Return the slot from which to take blocks and items. - */ + /** Return the slot from which to take blocks and items. */ // TODO winfy: resolve the null here public @Nullable HeldItemInfo getHeldItemToOperateOn(Predicate stackOk) { var stacks = this.getPrimaryStacks(); @@ -483,17 +473,15 @@ public ItemStack component1() { return null; } - /** - * Whether to provide infinite items. - */ + /** Whether to provide infinite items. */ protected boolean isCreativeMode() { return false; } /** * Attempt to withdraw some number of items from stacks available. - *

- * Return whether it was successful. + * + *

Return whether it was successful. */ public boolean withdrawItem(Predicate stackOk, int count, boolean actuallyRemove) { if (this.isCreativeMode()) { @@ -509,8 +497,7 @@ public boolean withdrawItem(Predicate stackOk, int count, boolean act presentCount += stack.getCount(); matches.add(stack); - if (presentCount >= count) - break; + if (presentCount >= count) break; } } if (presentCount < count) { @@ -536,15 +523,20 @@ public boolean withdrawItem(Predicate stackOk, int count, boolean act } /** - * Attempt to replace the first stack found which matches the predicate with the stack to replace with. + * Attempt to replace the first stack found which matches the predicate with the stack to + * replace with. + * * @return whether it was successful. */ - public abstract boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand); + public abstract boolean replaceItem( + Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand); - - public boolean replaceItemForPlayer(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand, ServerPlayer caster) { - if (caster == null) - return false; + public boolean replaceItemForPlayer( + Predicate stackOk, + ItemStack replaceWith, + @Nullable InteractionHand hand, + ServerPlayer caster) { + if (caster == null) return false; if (hand != null && stackOk.test(caster.getItemInHand(hand))) { caster.setItemInHand(hand, replaceWith); @@ -573,17 +565,11 @@ public boolean replaceItemForPlayer(Predicate stackOk, ItemStack repl return false; } - /** - * The order/mode stacks should be discovered in - */ + /** The order/mode stacks should be discovered in */ protected enum StackDiscoveryMode { - /** - * When finding items to pick (hotbar) - */ + /** When finding items to pick (hotbar) */ QUERY, - /** - * When extracting things - */ + /** When extracting things */ EXTRACTION, } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java index 73f7775a44..0e66dd87cc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironmentComponent.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api.casting.eval; import at.petrak.hexcasting.api.casting.eval.vm.CastingImage; + import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; @@ -10,50 +11,46 @@ public interface CastingEnvironmentComponent { interface Key {} interface PostExecution extends CastingEnvironmentComponent { - /** - * Do whatever you like after a pattern is executed. - */ + /** Do whatever you like after a pattern is executed. */ void onPostExecution(CastResult result); } interface PostCast extends CastingEnvironmentComponent { /** - * Do things after the whole cast is finished (i.e. every pattern to be executed has been executed). + * Do things after the whole cast is finished (i.e. every pattern to be executed has been + * executed). */ void onPostCast(CastingImage image); } interface ExtractMedia extends CastingEnvironmentComponent { /** - * Receives the cost that is being extracted, should return the - * remaining cost after deducting whatever cost source this component - * is responsible for (should be >= 0) + * Receives the cost that is being extracted, should return the remaining cost after + * deducting whatever cost source this component is responsible for (should be >= 0) */ long onExtractMedia(long cost, boolean simulate); /** - * ExtractMedia component that extracts media BEFORE the call to {@link CastingEnvironment#extractMediaEnvironment(long, boolean)} + * ExtractMedia component that extracts media BEFORE the call to {@link + * CastingEnvironment#extractMediaEnvironment(long, boolean)} */ interface Pre extends ExtractMedia {} /** - * ExtractMedia component that extracts media AFTER the call to {@link CastingEnvironment#extractMediaEnvironment(long, boolean)} - * if the input is <= 0 you should also probably return 0 (since media cost was already paid off) + * ExtractMedia component that extracts media AFTER the call to {@link + * CastingEnvironment#extractMediaEnvironment(long, boolean)} if the input is <= 0 you + * should also probably return 0 (since media cost was already paid off) */ interface Post extends ExtractMedia {} } interface IsVecInRange extends CastingEnvironmentComponent { - /** - * Receives the vec, and the current return value, and returns the new return value. - */ + /** Receives the vec, and the current return value, and returns the new return value. */ boolean onIsVecInRange(Vec3 vec, boolean current); } interface HasEditPermissionsAt extends CastingEnvironmentComponent { - /** - * Receives the vec, and the current return value, and returns the new return value. - */ + /** Receives the vec, and the current return value, and returns the new return value. */ boolean onHasEditPermissionsAt(BlockPos pos, boolean current); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt index 3fcf1bf766..f875ccb384 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ExecutionClientView.kt @@ -2,9 +2,7 @@ package at.petrak.hexcasting.api.casting.eval import net.minecraft.nbt.CompoundTag -/** - * Information sent back to the client - */ +/** Information sent back to the client */ data class ExecutionClientView( val isStackClear: Boolean, val resolutionType: ResolvedPatternType, @@ -14,4 +12,3 @@ data class ExecutionClientView( val stackDescs: List, val ravenmind: CompoundTag?, ) - diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java index 5469914454..5008f2d0fa 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java @@ -5,17 +5,17 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.Nullable; /** * Kinda like {@link CastingEnvironment} but for executing mishaps. - *

- * To avoid horrible O(mn) scope problems we offer a set of stock bad effects. - * The player is exposed nullably if you like though. + * + *

To avoid horrible O(mn) scope problems we offer a set of stock bad effects. The player is + * exposed nullably if you like though. */ public abstract class MishapEnvironment { - @Nullable - protected final ServerPlayer caster; + @Nullable protected final ServerPlayer caster; protected final ServerLevel world; protected MishapEnvironment(ServerLevel world, @Nullable ServerPlayer caster) { @@ -36,14 +36,16 @@ protected MishapEnvironment(ServerLevel world, @Nullable ServerPlayer caster) { public abstract void blind(int ticks); protected void yeetItem(ItemStack stack, Vec3 srcPos, Vec3 delta) { - var entity = new ItemEntity( - this.world, - srcPos.x, srcPos.y, srcPos.z, - stack, - delta.x + (Math.random() - 0.5) * 0.1, - delta.y + (Math.random() - 0.5) * 0.1, - delta.z + (Math.random() - 0.5) * 0.1 - ); + var entity = + new ItemEntity( + this.world, + srcPos.x, + srcPos.y, + srcPos.z, + stack, + delta.x + (Math.random() - 0.5) * 0.1, + delta.y + (Math.random() - 0.5) * 0.1, + delta.z + (Math.random() - 0.5) * 0.1); entity.setPickUpDelay(40); this.world.addWithUUID(entity); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/OperationResult.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/OperationResult.kt index 3a0f066fbc..bd60020295 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/OperationResult.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/OperationResult.kt @@ -5,9 +5,7 @@ import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect import at.petrak.hexcasting.api.casting.eval.vm.CastingImage import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation -/** - * What happens when an operator is through? - */ +/** What happens when an operator is through? */ data class OperationResult( val newImage: CastingImage, val sideEffects: List, diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt index 6108850727..077825701c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/ResolvedPattern.kt @@ -3,11 +3,14 @@ package at.petrak.hexcasting.api.casting.eval import at.petrak.hexcasting.api.casting.math.HexCoord import at.petrak.hexcasting.api.casting.math.HexPattern import at.petrak.hexcasting.api.utils.NBTBuilder -import net.minecraft.nbt.CompoundTag import java.util.* +import net.minecraft.nbt.CompoundTag - -data class ResolvedPattern(val pattern: HexPattern, val origin: HexCoord, var type: ResolvedPatternType) { +data class ResolvedPattern( + val pattern: HexPattern, + val origin: HexCoord, + var type: ResolvedPatternType +) { fun serializeToNBT() = NBTBuilder { "Pattern" %= pattern.serializeToNBT() "OriginQ" %= origin.q diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/SpellCircleContext.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/SpellCircleContext.kt index 269d6465c4..d97d452d8a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/SpellCircleContext.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/SpellCircleContext.kt @@ -5,10 +5,12 @@ import net.minecraft.core.BlockPos import net.minecraft.nbt.CompoundTag import net.minecraft.world.phys.AABB -/** - * Optional field on a [CastingEnvironment] for the spell circle - */ -data class SpellCircleContext(val impetusPos: BlockPos, val aabb: AABB, val activatorAlwaysInRange: Boolean) { +/** Optional field on a [CastingEnvironment] for the spell circle */ +data class SpellCircleContext( + val impetusPos: BlockPos, + val aabb: AABB, + val activatorAlwaysInRange: Boolean +) { fun serializeToNBT() = NBTBuilder { TAG_IMPETUS_X %= impetusPos.x TAG_IMPETUS_Y %= impetusPos.y @@ -50,7 +52,8 @@ data class SpellCircleContext(val impetusPos: BlockPos, val aabb: AABB, val acti val playerAIR = tag.getBoolean(TAG_PLAYER_ALWAYS_IN_RANGE) - return SpellCircleContext(BlockPos(impX, impY, impZ), AABB(minX, minY, minZ, maxX, maxY, maxZ), playerAIR) + return SpellCircleContext( + BlockPos(impX, impY, impZ), AABB(minX, minY, minZ, maxX, maxY, maxZ), playerAIR) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java index d1d542780d..c24cd54309 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleCastEnv.java @@ -1,5 +1,7 @@ package at.petrak.hexcasting.api.casting.eval.env; +import static at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv.SENTINEL_RADIUS; + import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.ParticleSpray; import at.petrak.hexcasting.api.casting.PatternShapeMatch; @@ -13,6 +15,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell; import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.pigment.FrozenPigment; + import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -23,14 +26,13 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; -import static at.petrak.hexcasting.api.casting.eval.env.PlayerBasedCastEnv.SENTINEL_RADIUS; - public class CircleCastEnv extends CastingEnvironment { protected final CircleExecutionState execState; @@ -96,7 +98,8 @@ public void postExecution(CastResult result) { if (imp != null) { for (var sideEffect : result.getSideEffects()) { if (sideEffect instanceof OperatorSideEffect.DoMishap doMishap) { - var msg = doMishap.getMishap().errorMessageWithName(this, doMishap.getErrorCtx()); + var msg = + doMishap.getMishap().errorMessageWithName(this, doMishap.getErrorCtx()); if (msg != null) { imp.postMishap(msg); } @@ -113,12 +116,10 @@ public Vec3 mishapSprayPos() { @Override public long extractMediaEnvironment(long cost, boolean simulate) { var entity = this.getImpetus(); - if (entity == null) - return cost; + if (entity == null) return cost; var mediaAvailable = entity.getMedia(); - if (mediaAvailable < 0) - return 0; + if (mediaAvailable < 0) return 0; long mediaToTake = Math.min(cost, mediaAvailable); cost -= mediaToTake; @@ -133,16 +134,17 @@ public long extractMediaEnvironment(long cost, boolean simulate) { public boolean isVecInRangeEnvironment(Vec3 vec) { var caster = this.execState.getCaster(this.world); if (caster != null) { - if (vec.distanceToSqr(caster.position()) <= caster.getBbHeight() * caster.getBbHeight()) { + if (vec.distanceToSqr(caster.position()) + <= caster.getBbHeight() * caster.getBbHeight()) { return true; } var sentinel = HexAPI.instance().getSentinel(caster); if (sentinel != null - && sentinel.extendsRange() - && caster.level().dimension() == sentinel.dimension() - && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS + 0.00000000001 - ) { + && sentinel.extendsRange() + && caster.level().dimension() == sentinel.dimension() + && vec.distanceToSqr(sentinel.position()) + <= SENTINEL_RADIUS * SENTINEL_RADIUS + 0.00000000001) { return true; } } @@ -153,7 +155,7 @@ public boolean isVecInRangeEnvironment(Vec3 vec) { @Override public boolean isEnlightened() { // have unbound circles be enlightened. - if(getCastingEntity() == null) return true; + if (getCastingEntity() == null) return true; return super.isEnlightened(); } @@ -170,8 +172,7 @@ public InteractionHand getCastingHand() { @Override // TODO: Could do something like get items in inventories adjacent to the circle? protected List getUsableStacks(StackDiscoveryMode mode) { - if (this.getCaster() != null) - return getUsableStacksForPlayer(mode, null, this.getCaster()); + if (this.getCaster() != null) return getUsableStacksForPlayer(mode, null, this.getCaster()); return new ArrayList<>(); } @@ -185,7 +186,8 @@ protected List getPrimaryStacks() { @Override // TODO: Adjacent inv! - public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { + public boolean replaceItem( + Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { if (this.getCaster() != null) return replaceItemForPlayer(stackOk, replaceWith, hand, this.getCaster()); return false; @@ -194,16 +196,14 @@ public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Override public FrozenPigment getPigment() { var impetus = this.getImpetus(); - if (impetus == null) - return FrozenPigment.DEFAULT.get(); + if (impetus == null) return FrozenPigment.DEFAULT.get(); return impetus.getPigment(); } @Override public @Nullable FrozenPigment setPigment(@Nullable FrozenPigment pigment) { var impetus = this.getImpetus(); - if (impetus == null) - return null; + if (impetus == null) return null; return impetus.setPigment(pigment); } @@ -215,8 +215,7 @@ public void produceParticles(ParticleSpray particles, FrozenPigment pigment) { @Override public void printMessage(Component message) { var impetus = getImpetus(); - if (impetus == null) - return; + if (impetus == null) return; impetus.postPrint(message); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleMishapEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleMishapEnv.java index 407f0eb307..52db6d5f26 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleMishapEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/CircleMishapEnv.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.casting.circles.CircleExecutionState; import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; + import net.minecraft.server.level.ServerLevel; import net.minecraft.world.phys.Vec3; @@ -14,32 +15,20 @@ protected CircleMishapEnv(ServerLevel world, CircleExecutionState execState) { } @Override - public void yeetHeldItemsTowards(Vec3 targetPos) { - - } + public void yeetHeldItemsTowards(Vec3 targetPos) {} @Override - public void dropHeldItems() { - - } + public void dropHeldItems() {} @Override - public void drown() { - - } + public void drown() {} @Override - public void damage(float healthProportion) { - - } + public void damage(float healthProportion) {} @Override - public void removeXp(int amount) { - - } + public void removeXp(int amount) {} @Override - public void blind(int ticks) { - - } + public void blind(int ticks) {} } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java index 43d0c67d28..bdd4f749f0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PackagedItemCastEnv.java @@ -7,6 +7,7 @@ import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; import at.petrak.hexcasting.common.msgs.MsgNewSpiralPatternsS2C; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -25,9 +26,9 @@ public void postExecution(CastResult result) { super.postExecution(result); if (result.component1() instanceof PatternIota patternIota) { - var packet = new MsgNewSpiralPatternsS2C( - this.caster.getUUID(), List.of(patternIota.getPattern()), 140 - ); + var packet = + new MsgNewSpiralPatternsS2C( + this.caster.getUUID(), List.of(patternIota.getPattern()), 140); IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); } @@ -38,13 +39,11 @@ public void postExecution(CastResult result) { @Override public long extractMediaEnvironment(long costLeft, boolean simulate) { - if (this.caster.isCreative()) - return 0; + if (this.caster.isCreative()) return 0; var casterStack = this.caster.getItemInHand(this.castingHand); var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack); - if (casterHexHolder == null) - return costLeft; + if (casterHexHolder == null) return costLeft; var canCastFromInv = casterHexHolder.canDrawMediaFromInventory(); var casterMediaHolder = IXplatAbstractions.INSTANCE.findMediaHolder(casterStack); @@ -71,11 +70,9 @@ public InteractionHand getCastingHand() { public FrozenPigment getPigment() { var casterStack = this.caster.getItemInHand(this.castingHand); var casterHexHolder = IXplatAbstractions.INSTANCE.findHexHolder(casterStack); - if (casterHexHolder == null) - return IXplatAbstractions.INSTANCE.getPigment(this.caster); + if (casterHexHolder == null) return IXplatAbstractions.INSTANCE.getPigment(this.caster); var hexHolderPigment = casterHexHolder.getPigment(); - if (hexHolderPigment != null) - return hexHolderPigment; + if (hexHolderPigment != null) return hexHolderPigment; return IXplatAbstractions.INSTANCE.getPigment(this.caster); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java index 10ff3b052b..6b69163d8f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedCastEnv.java @@ -1,5 +1,7 @@ package at.petrak.hexcasting.api.casting.eval.env; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.addldata.ADMediaHolder; import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers; @@ -12,28 +14,25 @@ import at.petrak.hexcasting.api.mod.HexConfig; import at.petrak.hexcasting.api.mod.HexStatistics; import at.petrak.hexcasting.api.pigment.FrozenPigment; -import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.MediaHelper; import at.petrak.hexcasting.common.lib.HexDamageTypes; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - public abstract class PlayerBasedCastEnv extends CastingEnvironment { public static final double AMBIT_RADIUS = 32.0; public static final double SENTINEL_RADIUS = 16.0; @@ -79,7 +78,8 @@ protected List getPrimaryStacks() { } @Override - public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { + public boolean replaceItem( + Predicate stackOk, ItemStack replaceWith, @Nullable InteractionHand hand) { return replaceItemForPlayer(stackOk, replaceWith, hand, this.caster); } @@ -87,26 +87,27 @@ public boolean replaceItem(Predicate stackOk, ItemStack replaceWith, public boolean isVecInRangeEnvironment(Vec3 vec) { var sentinel = HexAPI.instance().getSentinel(this.caster); if (sentinel != null - && sentinel.extendsRange() - && this.caster.level().dimension() == sentinel.dimension() + && sentinel.extendsRange() + && this.caster.level().dimension() == sentinel.dimension() // adding 0.00000000001 to avoid machine precision errors at specific angles - && vec.distanceToSqr(sentinel.position()) <= SENTINEL_RADIUS * SENTINEL_RADIUS + 0.00000000001 - ) { + && vec.distanceToSqr(sentinel.position()) + <= SENTINEL_RADIUS * SENTINEL_RADIUS + 0.00000000001) { return true; } - return vec.distanceToSqr(this.caster.position()) <= AMBIT_RADIUS * AMBIT_RADIUS + 0.00000000001; + return vec.distanceToSqr(this.caster.position()) + <= AMBIT_RADIUS * AMBIT_RADIUS + 0.00000000001; } @Override public boolean hasEditPermissionsAtEnvironment(BlockPos pos) { - return this.caster.gameMode.getGameModeForPlayer() != GameType.ADVENTURE && this.world.mayInteract(this.caster, pos); + return this.caster.gameMode.getGameModeForPlayer() != GameType.ADVENTURE + && this.world.mayInteract(this.caster, pos); } - /** - * Search the player's inventory for media ADs and use them. - */ - protected long extractMediaFromInventory(long costLeft, boolean allowOvercast, boolean simulate) { + /** Search the player's inventory for media ADs and use them. */ + protected long extractMediaFromInventory( + long costLeft, boolean allowOvercast, boolean simulate) { List sources = MediaHelper.scanPlayerForMediaStuff(this.caster); var startCost = costLeft; @@ -123,14 +124,19 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast, b double mediaToHealth = HexConfig.common().mediaToHealthRate(); double healthToRemove = Math.max(costLeft / mediaToHealth, 0.5); if (simulate) { - long simulatedRemovedMedia = Mth.ceil(Math.min(this.caster.getHealth(), healthToRemove) * mediaToHealth); + long simulatedRemovedMedia = + Mth.ceil(Math.min(this.caster.getHealth(), healthToRemove) * mediaToHealth); costLeft -= simulatedRemovedMedia; } else { var mediaAbleToCastFromHP = this.caster.getHealth() * mediaToHealth; - Mishap.trulyHurt(this.caster, this.caster.damageSources().source(HexDamageTypes.OVERCAST), (float) healthToRemove); + Mishap.trulyHurt( + this.caster, + this.caster.damageSources().source(HexDamageTypes.OVERCAST), + (float) healthToRemove); - var actuallyTaken = Mth.ceil(mediaAbleToCastFromHP - (this.caster.getHealth() * mediaToHealth)); + var actuallyTaken = + Mth.ceil(mediaAbleToCastFromHP - (this.caster.getHealth() * mediaToHealth)); HexAdvancementTriggers.OVERCAST_TRIGGER.trigger(this.caster, actuallyTaken); this.caster.awardStat(HexStatistics.MEDIA_OVERCAST, actuallyTaken); @@ -142,17 +148,15 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast, b if (!simulate) { this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft)); HexAdvancementTriggers.SPEND_MEDIA_TRIGGER.trigger( - this.caster, - startCost - costLeft, - costLeft < 0 ? -costLeft : 0 - ); + this.caster, startCost - costLeft, costLeft < 0 ? -costLeft : 0); } return costLeft; } protected boolean canOvercast() { - var adv = this.world.getServer().getAdvancements().getAdvancement(modLoc("y_u_no_cast_angy")); + var adv = + this.world.getServer().getAdvancements().getAdvancement(modLoc("y_u_no_cast_angy")); var advs = this.caster.getAdvancements(); return advs.getOrStartProgress(adv).isDone(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java index 370ba5002a..81025a9534 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/PlayerBasedMishapEnv.java @@ -3,6 +3,7 @@ import at.petrak.hexcasting.api.casting.eval.MishapEnvironment; import at.petrak.hexcasting.api.casting.mishaps.Mishap; import at.petrak.hexcasting.common.lib.HexDamageTypes; + import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffectInstance; @@ -35,7 +36,10 @@ public void dropHeldItems() { @Override public void damage(float healthProportion) { - Mishap.trulyHurt(this.caster, this.caster.damageSources().source(HexDamageTypes.OVERCAST), this.caster.getHealth() * healthProportion); + Mishap.trulyHurt( + this.caster, + this.caster.damageSources().source(HexDamageTypes.OVERCAST), + this.caster.getHealth() * healthProportion); } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java index 29e80d3817..091cf58f6f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/StaffCastEnv.java @@ -13,7 +13,7 @@ import at.petrak.hexcasting.api.pigment.FrozenPigment; import at.petrak.hexcasting.common.msgs.*; import at.petrak.hexcasting.xplat.IXplatAbstractions; -import net.minecraft.network.chat.Component; + import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -29,7 +29,6 @@ public class StaffCastEnv extends PlayerBasedCastEnv { private final Set castPatterns = new HashSet<>(); private int soundsPlayed = 0; - public StaffCastEnv(ServerPlayer caster, InteractionHand castingHand) { super(caster, castingHand); @@ -48,8 +47,8 @@ public void postExecution(CastResult result) { var sound = result.getSound().sound(); if (soundsPlayed < 100 && sound != null) { // TODO: Make configurable var soundPos = this.caster.position(); - this.world.playSound(null, soundPos.x, soundPos.y, soundPos.z, - sound, SoundSource.PLAYERS, 1f, 1f); + this.world.playSound( + null, soundPos.x, soundPos.y, soundPos.z, sound, SoundSource.PLAYERS, 1f, 1f); soundsPlayed++; } } @@ -58,9 +57,9 @@ public void postExecution(CastResult result) { public void postCast(CastingImage image) { super.postCast(image); - var packet = new MsgNewSpiralPatternsS2C( - this.caster.getUUID(), castPatterns.stream().toList(), Integer.MAX_VALUE - ); + var packet = + new MsgNewSpiralPatternsS2C( + this.caster.getUUID(), castPatterns.stream().toList(), Integer.MAX_VALUE); IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet); IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet); @@ -70,8 +69,7 @@ public void postCast(CastingImage image) { @Override public long extractMediaEnvironment(long cost, boolean simulate) { - if (this.caster.isCreative()) - return 0; + if (this.caster.isCreative()) return 0; var canOvercast = this.canOvercast(); return this.extractMediaFromInventory(cost, canOvercast, simulate); @@ -98,8 +96,10 @@ public static void handleNewPatternOnServer(ServerPlayer sender, MsgNewSpellPatt allPoints.addAll(pat.getPattern().positions(pat.getOrigin())); } var currentResolvedPattern = resolvedPatterns.get(resolvedPatterns.size() - 1); - var currentSpellPoints = currentResolvedPattern.getPattern() - .positions(currentResolvedPattern.getOrigin()); + var currentSpellPoints = + currentResolvedPattern + .getPattern() + .positions(currentResolvedPattern.getOrigin()); if (currentSpellPoints.stream().anyMatch(allPoints::contains)) { cheatedPatternOverlap = true; } @@ -113,29 +113,36 @@ public static void handleNewPatternOnServer(ServerPlayer sender, MsgNewSpellPatt var vm = IXplatAbstractions.INSTANCE.getStaffcastVM(sender, msg.handUsed()); - // TODO: do we reset the number of evals run via the staff? because each new pat is a new tick. + // TODO: do we reset the number of evals run via the staff? because each new pat is a new + // tick. - ExecutionClientView clientInfo = vm.queueExecuteAndWrapIota(new PatternIota(msg.pattern()), sender.serverLevel()); + ExecutionClientView clientInfo = + vm.queueExecuteAndWrapIota(new PatternIota(msg.pattern()), sender.serverLevel()); if (clientInfo.isStackClear()) { IXplatAbstractions.INSTANCE.setStaffcastImage(sender, null); IXplatAbstractions.INSTANCE.setPatterns(sender, List.of()); } else { - IXplatAbstractions.INSTANCE.setStaffcastImage(sender, vm.getImage().withOverriddenUsedOps(0)); + IXplatAbstractions.INSTANCE.setStaffcastImage( + sender, vm.getImage().withOverriddenUsedOps(0)); if (!resolvedPatterns.isEmpty()) { - resolvedPatterns.get(resolvedPatterns.size() - 1).setType(clientInfo.getResolutionType()); + resolvedPatterns + .get(resolvedPatterns.size() - 1) + .setType(clientInfo.getResolutionType()); } IXplatAbstractions.INSTANCE.setPatterns(sender, resolvedPatterns); } - IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, - new MsgNewSpellPatternS2C(clientInfo, resolvedPatterns.size() - 1)); + IXplatAbstractions.INSTANCE.sendPacketToPlayer( + sender, new MsgNewSpellPatternS2C(clientInfo, resolvedPatterns.size() - 1)); IMessage packet; if (clientInfo.isStackClear()) { packet = new MsgClearSpiralPatternsS2C(sender.getUUID()); } else { - packet = new MsgNewSpiralPatternsS2C(sender.getUUID(), List.of(msg.pattern()), Integer.MAX_VALUE); + packet = + new MsgNewSpiralPatternsS2C( + sender.getUUID(), List.of(msg.pattern()), Integer.MAX_VALUE); } IXplatAbstractions.INSTANCE.sendPacketToPlayer(sender, packet); IXplatAbstractions.INSTANCE.sendPacketTracking(sender, packet); @@ -144,7 +151,8 @@ public static void handleNewPatternOnServer(ServerPlayer sender, MsgNewSpellPatt // Somehow we lost spraying particles on each new pattern, so do it here // this also nicely prevents particle spam on trinkets new ParticleSpray(sender.position(), new Vec3(0.0, 1.5, 0.0), 0.4, Math.PI / 3, 30) - .sprayParticles(sender.serverLevel(), IXplatAbstractions.INSTANCE.getPigment(sender)); + .sprayParticles( + sender.serverLevel(), IXplatAbstractions.INSTANCE.getPigment(sender)); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/package-info.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/package-info.java index 036bb48b23..7818f29677 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/package-info.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/env/package-info.java @@ -2,4 +2,4 @@ * Default impls for some casting and mishap envs for your convenience and also so i can impl * BlockEntityAbstractImpetus in api guilt-free */ -package at.petrak.hexcasting.api.casting.eval.env; \ No newline at end of file +package at.petrak.hexcasting.api.casting.eval.env; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/EvalSound.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/EvalSound.java index f81a34eb3f..b66d2c6086 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/EvalSound.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/EvalSound.java @@ -1,15 +1,15 @@ package at.petrak.hexcasting.api.casting.eval.sideeffects; import net.minecraft.sounds.SoundEvent; + import org.jetbrains.annotations.Nullable; /** * The kind of sound that plays after a cast. * - * @param sound the actual sound file - * @param priority the priority of this sound. the sound with the highest priority in a given cast will be - * played. - * shortcutMetacasting takes precedence over this. + * @param sound the actual sound file + * @param priority the priority of this sound. the sound with the highest priority in a given cast + * will be played. shortcutMetacasting takes precedence over this. */ public record EvalSound(@Nullable SoundEvent sound, int priority) { public EvalSound greaterOf(EvalSound that) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt index 72226fe291..927e67dc17 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/sideeffects/OperatorSideEffect.kt @@ -13,26 +13,24 @@ import net.minecraft.server.level.ServerPlayer import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack -/** - * Things that happen after a spell is cast. - */ +/** Things that happen after a spell is cast. */ sealed class OperatorSideEffect { /** Return whether to cancel all further [OperatorSideEffect] */ abstract fun performEffect(harness: CastingVM) data class RequiredEnlightenment(val awardStat: Boolean) : OperatorSideEffect() { override fun performEffect(harness: CastingVM) { - harness.env.castingEntity?.sendSystemMessage("hexcasting.message.cant_great_spell".asTranslatedComponent) + harness.env.castingEntity?.sendSystemMessage( + "hexcasting.message.cant_great_spell".asTranslatedComponent) } } - /** Try to cast a spell */ + /** Try to cast a spell */ data class AttemptSpell( val spell: RenderedSpell, val hasCastingSound: Boolean = true, val awardStat: Boolean = true - ) : - OperatorSideEffect() { + ) : OperatorSideEffect() { override fun performEffect(harness: CastingVM) { this.spell.cast(harness.env, harness.image)?.let { harness.image = it } if (awardStat) @@ -49,7 +47,7 @@ sealed class OperatorSideEffect { data class Particles(val spray: ParticleSpray) : OperatorSideEffect() { override fun performEffect(harness: CastingVM) { harness.env.produceParticles(this.spray, harness.env.pigment) -// this.spray.sprayParticles(harness.env.world, harness.env.colorizer) + // this.spray.sprayParticles(harness.env.world, harness.env.colorizer) } } @@ -60,13 +58,13 @@ sealed class OperatorSideEffect { spray.sprayParticles(harness.env.world, color) spray.sprayParticles( harness.env.world, - FrozenPigment( - ItemStack(HexItems.DYE_PIGMENTS[DyeColor.RED]!!), - Util.NIL_UUID - ) - ) + FrozenPigment(ItemStack(HexItems.DYE_PIGMENTS[DyeColor.RED]!!), Util.NIL_UUID)) - harness.image = harness.image.copy(stack = mishap.executeReturnStack(harness.env, errorCtx, harness.image.stack.toMutableList())) + harness.image = + harness.image.copy( + stack = + mishap.executeReturnStack( + harness.env, errorCtx, harness.image.stack.toMutableList())) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt index 3ffd771bcd..f0f93268e2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt @@ -13,17 +13,14 @@ import net.minecraft.nbt.Tag import net.minecraft.server.level.ServerLevel import net.minecraft.world.entity.Entity -/** - * The state of a casting VM, containing the stack and all - */ -data class CastingImage private constructor( +/** The state of a casting VM, containing the stack and all */ +data class CastingImage +private constructor( val stack: List, - val parenCount: Int, val parenthesized: List, val escapeNext: Boolean, val opsConsumed: Long, - val userData: CompoundTag ) { constructor() : this(listOf(), 0, listOf(), false, 0, CompoundTag()) @@ -35,9 +32,7 @@ data class CastingImage private constructor( } } - /** - * Returns an empty list if it's too complicated. - */ + /** Returns an empty list if it's too complicated. */ private fun Iterable.serializeToNBT(): CompoundTag { val tag = CompoundTag() @@ -52,24 +47,16 @@ data class CastingImage private constructor( return tag } - /** - * Return a copy of this with the given number of ops additionally exhausted - */ + /** Return a copy of this with the given number of ops additionally exhausted */ fun withUsedOps(count: Long) = this.copy(opsConsumed = this.opsConsumed + count) - /** - * Return a copy of this with 1 op used - */ + /** Return a copy of this with 1 op used */ fun withUsedOp() = this.withUsedOps(1) - /** - * Returns a copy of this with the [opsConsumed] replaced with [count]. - */ + /** Returns a copy of this with the [opsConsumed] replaced with [count]. */ fun withOverriddenUsedOps(count: Long) = this.copy(opsConsumed = count) - /** - * Returns a copy of this with escape/paren-related fields cleared. - */ + /** Returns a copy of this with escape/paren-related fields cleared. */ fun withResetEscape() = this.copy(parenCount = 0, parenthesized = listOf(), escapeNext = false) fun serializeToNbt() = NBTBuilder { @@ -101,19 +88,24 @@ data class CastingImage private constructor( stack.add(datum) } - val userData = if (tag.contains(TAG_USERDATA)) { - tag.getCompound(TAG_USERDATA) - } else { - CompoundTag() - } + val userData = + if (tag.contains(TAG_USERDATA)) { + tag.getCompound(TAG_USERDATA) + } else { + CompoundTag() + } val parenthesized = mutableListOf() val parenTag = tag.getCompound(TAG_PARENTHESIZED) val parenIotasTag = parenTag.getList(TAG_IOTAS, Tag.TAG_COMPOUND) val parenEscapedTag = parenTag.getByteArray(TAG_ESCAPED) - for ((subtag, isEscapedByte) in parenIotasTag.zipWithDefault(parenEscapedTag) { _ -> 0 }) { - parenthesized.add(ParenthesizedIota(IotaType.deserialize(subtag.downcast(CompoundTag.TYPE), world), isEscapedByte != 0.toByte())) + for ((subtag, isEscapedByte) in + parenIotasTag.zipWithDefault(parenEscapedTag) { _ -> 0 }) { + parenthesized.add( + ParenthesizedIota( + IotaType.deserialize(subtag.downcast(CompoundTag.TYPE), world), + isEscapedByte != 0.toByte())) } val parenCount = tag.getInt(TAG_PAREN_COUNT) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt index 587500355b..ee64b92b1c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt @@ -19,28 +19,28 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel /** - * The virtual machine! This is the glue that determines the next iteration of a [CastingImage], using a - * [CastingEnvironment] to affect the world. + * The virtual machine! This is the glue that determines the next iteration of a [CastingImage], + * using a [CastingEnvironment] to affect the world. */ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { init { env.triggerCreateEvent(image.userData) } - /** - * Execute a single iota. - */ - fun queueExecuteAndWrapIota(iota: Iota, world: ServerLevel): ExecutionClientView = queueExecuteAndWrapIotas(listOf(iota), world) + /** Execute a single iota. */ + fun queueExecuteAndWrapIota(iota: Iota, world: ServerLevel): ExecutionClientView = + queueExecuteAndWrapIotas(listOf(iota), world) /** - * The main entrypoint to the VM. Given a list of iotas, execute them in sequence, and return whatever the client - * needs to see. + * The main entrypoint to the VM. Given a list of iotas, execute them in sequence, and return + * whatever the client needs to see. * * Mutates this */ fun queueExecuteAndWrapIotas(iotas: List, world: ServerLevel): ExecutionClientView { // Initialize the continuation stack to a single top-level eval for all iotas. - var continuation = SpellContinuation.Done.pushFrame(FrameEvaluate(SpellList.LList(0, iotas), false)) + var continuation = + SpellContinuation.Done.pushFrame(FrameEvaluate(SpellList.LList(0, iotas), false)) // Begin aggregating info val info = TempControllerInfo(earlyExit = false) var lastResolutionType = ResolvedPatternType.UNRESOLVED @@ -48,21 +48,27 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { // Take the top of the continuation stack... val next = continuation.frame // ...and execute it. - // TODO there used to be error checking code here; I'm pretty sure any and all mishaps should already + // TODO there used to be error checking code here; I'm pretty sure any and all mishaps + // should already // get caught and folded into CastResult by evaluate. - val image2 = next.evaluate(continuation.next, world, this).let { result -> - // if stack is unable to be serialized, have the result be an error - if (result.newData != null && IotaType.isTooLargeToSerialize(result.newData.stack)) { - result.copy( - newData = null, - sideEffects = listOf(OperatorSideEffect.DoMishap(MishapStackSize(), Mishap.Context(null, null))), - resolutionType = ResolvedPatternType.ERRORED, - sound = HexEvalSounds.MISHAP, - ) - } else { - result + val image2 = + next.evaluate(continuation.next, world, this).let { result -> + // if stack is unable to be serialized, have the result be an error + if (result.newData != null && + IotaType.isTooLargeToSerialize(result.newData.stack)) { + result.copy( + newData = null, + sideEffects = + listOf( + OperatorSideEffect.DoMishap( + MishapStackSize(), Mishap.Context(null, null))), + resolutionType = ResolvedPatternType.ERRORED, + sound = HexEvalSounds.MISHAP, + ) + } else { + result + } } - } // Then write all pertinent data back to the harness for the next iteration. if (image2.newData != null) { @@ -76,27 +82,30 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { performSideEffects(image2.sideEffects) } catch (e: Exception) { e.printStackTrace() - performSideEffects(listOf(OperatorSideEffect.DoMishap(MishapInternalException(e), Mishap.Context(null, null)))) + performSideEffects( + listOf( + OperatorSideEffect.DoMishap( + MishapInternalException(e), Mishap.Context(null, null)))) } info.earlyExit = info.earlyExit || !lastResolutionType.success } if (continuation is SpellContinuation.NotDone) { lastResolutionType = - if (lastResolutionType.success) ResolvedPatternType.EVALUATED else ResolvedPatternType.ERRORED + if (lastResolutionType.success) ResolvedPatternType.EVALUATED + else ResolvedPatternType.ERRORED } val (stackDescs, ravenmind) = generateDescs() - val isStackClear = image.stack.isEmpty() && image.parenCount == 0 && !image.escapeNext && ravenmind == null + val isStackClear = + image.stack.isEmpty() && image.parenCount == 0 && !image.escapeNext && ravenmind == null this.env.postCast(image) return ExecutionClientView(isStackClear, lastResolutionType, stackDescs, ravenmind) } - /** - * this DOES NOT THROW THINGS - */ + /** this DOES NOT THROW THINGS */ @Throws() fun executeInner(iota: Iota, world: ServerLevel, continuation: SpellContinuation): CastResult { try { @@ -104,7 +113,13 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { // ALSO TODO need to add reader macro-style things try { this.handleParentheses(iota)?.let { (data, resolutionType) -> - return@executeInner CastResult(iota, continuation, data, listOf(), resolutionType, HexEvalSounds.NORMAL_EXECUTE) + return@executeInner CastResult( + iota, + continuation, + data, + listOf(), + resolutionType, + HexEvalSounds.NORMAL_EXECUTE) } } catch (e: MishapTooManyCloseParens) { // This is ridiculous and needs to be fixed @@ -117,13 +132,9 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { e, Mishap.Context( (iota as? PatternIota)?.pattern ?: HexPattern(HexDir.WEST), - HexAPI.instance().getRawHookI18n(HexAPI.modLoc("close_paren")) - ) - ) - ), + HexAPI.instance().getRawHookI18n(HexAPI.modLoc("close_paren"))))), ResolvedPatternType.ERRORED, - HexEvalSounds.MISHAP - ) + HexEvalSounds.MISHAP) } return iota.execute(this, world, continuation) @@ -138,20 +149,13 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { OperatorSideEffect.DoMishap( MishapInternalException(exception), Mishap.Context( - (iota as? PatternIota)?.pattern ?: HexPattern(HexDir.WEST), - null - ) - ) - ), + (iota as? PatternIota)?.pattern ?: HexPattern(HexDir.WEST), null))), ResolvedPatternType.ERRORED, - HexEvalSounds.MISHAP - ) + HexEvalSounds.MISHAP) } } - /** - * Execute the side effects of a pattern, updating our aggregated info. - */ + /** Execute the side effects of a pattern, updating our aggregated info. */ fun performSideEffects(sideEffects: List) { for (haskellProgrammersShakingandCryingRN in sideEffects) { haskellProgrammersShakingandCryingRN.performEffect(this) @@ -160,15 +164,16 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { fun generateDescs(): Pair, CompoundTag?> { val stackDescs = this.image.stack.map { IotaType.serialize(it) } - val ravenmind = if (this.image.userData.contains(HexAPI.RAVENMIND_USERDATA)) { - this.image.userData.getCompound(HexAPI.RAVENMIND_USERDATA) - } else null + val ravenmind = + if (this.image.userData.contains(HexAPI.RAVENMIND_USERDATA)) { + this.image.userData.getCompound(HexAPI.RAVENMIND_USERDATA) + } else null return Pair(stackDescs, ravenmind) } /** - * Return a non-null value if we handled this in some sort of parenthesey way, - * either escaping it onto the stack or changing the parenthese-handling state. + * Return a non-null value if we handled this in some sort of parenthesey way, either escaping + * it onto the stack or changing the parenthese-handling state. */ @Throws(MishapTooManyCloseParens::class) private fun handleParentheses(iota: Iota): Pair? { @@ -176,108 +181,111 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) { var displayDepth = this.image.parenCount - val out = if (displayDepth > 0) { - if (this.image.escapeNext) { - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, true)) + val out = + if (displayDepth > 0) { + if (this.image.escapeNext) { + val newParens = this.image.parenthesized.toMutableList() + newParens.add(ParenthesizedIota(iota, true)) + this.image.copy(escapeNext = false, parenthesized = newParens) to + ResolvedPatternType.ESCAPED + } else { + + when (sig) { + SpecialPatterns.CONSIDERATION.angles -> { + this.image.copy( + escapeNext = true, + ) to ResolvedPatternType.EVALUATED + } + + SpecialPatterns.EVANITION.angles -> { + val newParens = this.image.parenthesized.toMutableList() + val last = newParens.removeLastOrNull() + val newParenCount = + this.image.parenCount + + if (last == null || last.escaped || last.iota !is PatternIota) 0 + else + when (last.iota.pattern) { + SpecialPatterns.INTROSPECTION -> -1 + SpecialPatterns.RETROSPECTION -> 1 + else -> 0 + } + this.image.copy( + parenthesized = newParens, parenCount = newParenCount) to + if (last == null) ResolvedPatternType.ERRORED + else ResolvedPatternType.UNDONE + } + + SpecialPatterns.INTROSPECTION.angles -> { + // we have escaped the parens onto the stack; we just also record our + // count. + val newParens = this.image.parenthesized.toMutableList() + newParens.add(ParenthesizedIota(iota, false)) + this.image.copy( + parenthesized = newParens, + parenCount = this.image.parenCount + 1) to + if (this.image.parenCount == 0) ResolvedPatternType.EVALUATED + else ResolvedPatternType.ESCAPED + } + + SpecialPatterns.RETROSPECTION.angles -> { + val newParenCount = this.image.parenCount - 1 + displayDepth-- + if (newParenCount == 0) { + val newStack = this.image.stack.toMutableList() + newStack.add( + ListIota(this.image.parenthesized.toList().map { it.iota })) + this.image.copy( + stack = newStack, + parenCount = newParenCount, + parenthesized = listOf()) to ResolvedPatternType.EVALUATED + } else if (newParenCount < 0) { + throw MishapTooManyCloseParens() + } else { + // we have this situation: "(()" + // we need to add the close paren + val newParens = this.image.parenthesized.toMutableList() + newParens.add(ParenthesizedIota(iota, false)) + this.image.copy( + parenCount = newParenCount, parenthesized = newParens) to + ResolvedPatternType.ESCAPED + } + } + + else -> { + val newParens = this.image.parenthesized.toMutableList() + newParens.add(ParenthesizedIota(iota, false)) + this.image.copy(parenthesized = newParens) to + ResolvedPatternType.ESCAPED + } + } + } + } else if (this.image.escapeNext) { + val newStack = this.image.stack.toMutableList() + newStack.add(iota) this.image.copy( + stack = newStack, escapeNext = false, - parenthesized = newParens ) to ResolvedPatternType.ESCAPED } else { - when (sig) { SpecialPatterns.CONSIDERATION.angles -> { - this.image.copy( - escapeNext = true, - ) to ResolvedPatternType.EVALUATED - } - - SpecialPatterns.EVANITION.angles -> { - val newParens = this.image.parenthesized.toMutableList() - val last = newParens.removeLastOrNull() - val newParenCount = this.image.parenCount + if (last == null || last.escaped || last.iota !is PatternIota) 0 else when (last.iota.pattern) { - SpecialPatterns.INTROSPECTION -> -1 - SpecialPatterns.RETROSPECTION -> 1 - else -> 0 - } - this.image.copy(parenthesized = newParens, parenCount = newParenCount) to if (last == null) ResolvedPatternType.ERRORED else ResolvedPatternType.UNDONE + this.image.copy(escapeNext = true) to ResolvedPatternType.EVALUATED } SpecialPatterns.INTROSPECTION.angles -> { - // we have escaped the parens onto the stack; we just also record our count. - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, false)) - this.image.copy( - parenthesized = newParens, - parenCount = this.image.parenCount + 1 - ) to if (this.image.parenCount == 0) ResolvedPatternType.EVALUATED else ResolvedPatternType.ESCAPED + this.image.copy(parenCount = this.image.parenCount + 1) to + ResolvedPatternType.EVALUATED } SpecialPatterns.RETROSPECTION.angles -> { - val newParenCount = this.image.parenCount - 1 - displayDepth-- - if (newParenCount == 0) { - val newStack = this.image.stack.toMutableList() - newStack.add(ListIota(this.image.parenthesized.toList().map { it.iota })) - this.image.copy( - stack = newStack, - parenCount = newParenCount, - parenthesized = listOf() - ) to ResolvedPatternType.EVALUATED - } else if (newParenCount < 0) { - throw MishapTooManyCloseParens() - } else { - // we have this situation: "(()" - // we need to add the close paren - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, false)) - this.image.copy( - parenCount = newParenCount, - parenthesized = newParens - ) to ResolvedPatternType.ESCAPED - } + throw MishapTooManyCloseParens() } else -> { - val newParens = this.image.parenthesized.toMutableList() - newParens.add(ParenthesizedIota(iota, false)) - this.image.copy( - parenthesized = newParens - ) to ResolvedPatternType.ESCAPED + null } } } - } else if (this.image.escapeNext) { - val newStack = this.image.stack.toMutableList() - newStack.add(iota) - this.image.copy( - stack = newStack, - escapeNext = false, - ) to ResolvedPatternType.ESCAPED - } else { - when (sig) { - SpecialPatterns.CONSIDERATION.angles -> { - this.image.copy( - escapeNext = true - ) to ResolvedPatternType.EVALUATED - } - - SpecialPatterns.INTROSPECTION.angles -> { - this.image.copy( - parenCount = this.image.parenCount + 1 - ) to ResolvedPatternType.EVALUATED - } - - SpecialPatterns.RETROSPECTION.angles -> { - throw MishapTooManyCloseParens() - } - - else -> { - null - } - } - } // TODO: replace this once we can read things from the client /* diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt index 8000ec09aa..d7b23e2364 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt @@ -12,38 +12,44 @@ import net.minecraft.server.level.ServerLevel /** * A single frame of evaluation during the execution of a spell. * - * Specifically, an evaluation will keep a stack of these frames. - * An evaluation with no meta-eval will consist of a single [Evaluate(rest of the pats)] at all times. - * When an Eval is invoked, we push Evaluate(pats) to the top of the stack. + * Specifically, an evaluation will keep a stack of these frames. An evaluation with no meta-eval + * will consist of a single [Evaluate(rest of the pats)] at all times. When an Eval is invoked, we + * push Evaluate(pats) to the top of the stack. * * Evaluation is performed by repeatedly popping the top-most (i.e. innermost) frame from the stack, - * then evaluating that frame (and possibly allowing it to push other frames (e.g. if it's a Hermes)). + * then evaluating that frame (and possibly allowing it to push other frames (e.g. if it's a + * Hermes)). * * Once the stack of frames is empty, there are no more computations to run, so we're done. - * */ interface ContinuationFrame { /** - * Step the evaluation forward once. - * For Evaluate, this consumes one pattern; for ForEach this queues the next iteration of the outer loop. + * Step the evaluation forward once. For Evaluate, this consumes one pattern; for ForEach this + * queues the next iteration of the outer loop. + * * @return the result of this pattern step */ - fun evaluate(continuation: SpellContinuation, level: ServerLevel, harness: CastingVM): CastResult + fun evaluate( + continuation: SpellContinuation, + level: ServerLevel, + harness: CastingVM + ): CastResult /** - * The OpHalt instruction wants us to "jump to" the END of the nearest meta-eval. - * In other words, we should consume Evaluate frames until we hit a FinishEval or Thoth frame. - * @return whether the break should stop here, alongside the new stack state (e.g. for finalizing a Thoth) + * The OpHalt instruction wants us to "jump to" the END of the nearest meta-eval. In other + * words, we should consume Evaluate frames until we hit a FinishEval or Thoth frame. + * + * @return whether the break should stop here, alongside the new stack state (e.g. for + * finalizing a Thoth) */ fun breakDownwards(stack: List): Pair> - /** - * Serializes this frame. Used for things like delays, where we pause execution. - */ + /** Serializes this frame. Used for things like delays, where we pause execution. */ fun serializeToNBT(): CompoundTag /** - * Return the number of iotas contained inside this frame, used for determining whether it is valid to serialise. + * Return the number of iotas contained inside this frame, used for determining whether it is + * valid to serialise. */ fun size(): Int @@ -55,27 +61,30 @@ interface ContinuationFrame { companion object { /** - * Takes a tag containing the ContinuationFrame.Type resourcelocation and the serialized continuation frame, and returns - * the deserialized continuation frame. + * Takes a tag containing the ContinuationFrame.Type resourcelocation and the serialized + * continuation frame, and returns the deserialized continuation frame. */ @JvmStatic fun fromNBT(tag: CompoundTag, world: ServerLevel): ContinuationFrame { - val type = getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false) + val type = + getTypeFromTag(tag) ?: return FrameEvaluate(SpellList.LList(0, listOf()), false) - return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { type.deserializeFromNBT(it, world) } - ?: FrameEvaluate(SpellList.LList(0, listOf()), false) + return (tag.get(HexContinuationTypes.KEY_DATA) as? CompoundTag)?.let { + type.deserializeFromNBT(it, world) + } ?: FrameEvaluate(SpellList.LList(0, listOf()), false) } - /** - * Takes a continuation frame and serializes it along with its type. - */ + /** Takes a continuation frame and serializes it along with its type. */ @JvmStatic fun toNBT(frame: ContinuationFrame): CompoundTag { val type = frame.type - val typeId = HexContinuationTypes.REGISTRY.getKey(type) - ?: throw IllegalStateException( - "Tried to serialize an unregistered continuation type. Continuation: " + frame - + " ; Type" + type.javaClass.typeName) + val typeId = + HexContinuationTypes.REGISTRY.getKey(type) + ?: throw IllegalStateException( + "Tried to serialize an unregistered continuation type. Continuation: " + + frame + + " ; Type" + + type.javaClass.typeName) val data = frame.serializeToNBT() @@ -86,8 +95,8 @@ interface ContinuationFrame { } /** - * This method attempts to find the type from the `type` key. - * See [ContinuationFrame.serializeToNBT] for the storage format. + * This method attempts to find the type from the `type` key. See + * [ContinuationFrame.serializeToNBT] for the storage format. * * @return `null` if it cannot get the type. */ diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt index 141148dfdc..a440349b0a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt @@ -16,6 +16,7 @@ import net.minecraft.server.level.ServerLevel /** * A list of patterns to be evaluated in sequence. + * * @property list the *remaining* list of patterns to be evaluated * @property isMetacasting only for sound effects, if this is being cast from a hermes / iris */ @@ -31,10 +32,11 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont ): CastResult { // If there are patterns left... return if (list.nonEmpty) { - val newCont = if (list.cdr.nonEmpty) { // yay TCO - // ...enqueue the evaluation of the rest of the patterns... - continuation.pushFrame(FrameEvaluate(list.cdr, this.isMetacasting)) - } else continuation + val newCont = + if (list.cdr.nonEmpty) { // yay TCO + // ...enqueue the evaluation of the rest of the patterns... + continuation.pushFrame(FrameEvaluate(list.cdr, this.isMetacasting)) + } else continuation // ...before evaluating the first one in the list. val update = harness.executeInner(list.car, level, newCont) if (this.isMetacasting && update.sound != HexEvalSounds.MISHAP) { @@ -44,7 +46,13 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont } } else { // If there are no patterns (e.g. empty Hermes), just return OK. - CastResult(ListIota(list), continuation, null, listOf(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES) + CastResult( + ListIota(list), + continuation, + null, + listOf(), + ResolvedPatternType.EVALUATED, + HexEvalSounds.HERMES) } } @@ -59,16 +67,18 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont companion object { @JvmField - val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { - override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameEvaluate { - return FrameEvaluate( - HexIotaTypes.LIST.deserialize( - tag.getList("patterns", Tag.TAG_COMPOUND), - world - )!!.list, - tag.getBoolean("isMetacasting")) + val TYPE: ContinuationFrame.Type = + object : ContinuationFrame.Type { + override fun deserializeFromNBT( + tag: CompoundTag, + world: ServerLevel + ): FrameEvaluate { + return FrameEvaluate( + HexIotaTypes.LIST.deserialize( + tag.getList("patterns", Tag.TAG_COMPOUND), world)!! + .list, + tag.getBoolean("isMetacasting")) + } } - - } } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt index 72bbb8c80c..f181ab87e3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt @@ -4,14 +4,13 @@ import at.petrak.hexcasting.api.casting.eval.CastResult import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.NullIota -import at.petrak.hexcasting.api.utils.NBTBuilder import at.petrak.hexcasting.common.lib.hex.HexEvalSounds import net.minecraft.nbt.CompoundTag import net.minecraft.server.level.ServerLevel /** - * A stack marker representing the end of a Hermes evaluation, - * so that we know when to stop removing frames during a Halt. + * A stack marker representing the end of a Hermes evaluation, so that we know when to stop removing + * frames during a Halt. */ object FrameFinishEval : ContinuationFrame { // Don't do anything else to the stack, just finish the halt statement. @@ -38,9 +37,10 @@ object FrameFinishEval : ContinuationFrame { override fun size() = 0 @JvmField - val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { - override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval - } + val TYPE: ContinuationFrame.Type = + object : ContinuationFrame.Type { + override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel) = FrameFinishEval + } override val type = TYPE } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt index 0221c1f36d..c24270358f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt @@ -16,9 +16,10 @@ import net.minecraft.nbt.Tag import net.minecraft.server.level.ServerLevel /** - * A frame representing all the state for a Thoth evaluation. - * Pushed by an OpForEach. - * @property first whether the input stack state is the first one (since we don't want to save the base-stack before any changes are made) + * A frame representing all the state for a Thoth evaluation. Pushed by an OpForEach. + * + * @property first whether the input stack state is the first one (since we don't want to save the + * base-stack before any changes are made) * @property data list of *remaining* datums to ForEach over * @property code code to run per datum * @property baseStack the stack state at Thoth entry @@ -31,7 +32,10 @@ data class FrameForEach( val acc: MutableList ) : ContinuationFrame { - /** When halting, we add the stack state at halt to the stack accumulator, then return the original pre-Thoth stack, plus the accumulator. */ + /** + * When halting, we add the stack state at halt to the stack accumulator, then return the + * original pre-Thoth stack, plus the accumulator. + */ override fun breakDownwards(stack: List): Pair> { val newStack = baseStack?.toMutableList() ?: mutableListOf() acc.addAll(stack) @@ -46,28 +50,31 @@ data class FrameForEach( harness: CastingVM ): CastResult { // If this isn't the very first Thoth step (i.e. no Thoth computations run yet)... - val stack = if (baseStack == null) { - // init stack to the harness stack... - harness.image.stack.toList() - } else { - // else save the stack to the accumulator and reuse the saved base stack. - acc.addAll(harness.image.stack) - baseStack - } + val stack = + if (baseStack == null) { + // init stack to the harness stack... + harness.image.stack.toList() + } else { + // else save the stack to the accumulator and reuse the saved base stack. + acc.addAll(harness.image.stack) + baseStack + } // If we still have data to process... - val (stackTop, newImage, newCont) = if (data.nonEmpty) { - // push the next datum to the top of the stack, - val cont2 = continuation - // put the next Thoth object back on the stack for the next Thoth cycle, - .pushFrame(FrameForEach(data.cdr, code, stack, acc)) - // and prep the Thoth'd code block for evaluation. - .pushFrame(FrameEvaluate(code, true)) - Triple(data.car, harness.image.withUsedOp(), cont2) - } else { - // Else, dump our final list onto the stack. - Triple(ListIota(acc), harness.image, continuation) - } + val (stackTop, newImage, newCont) = + if (data.nonEmpty) { + // push the next datum to the top of the stack, + val cont2 = + continuation + // put the next Thoth object back on the stack for the next Thoth cycle, + .pushFrame(FrameForEach(data.cdr, code, stack, acc)) + // and prep the Thoth'd code block for evaluation. + .pushFrame(FrameEvaluate(code, true)) + Triple(data.car, harness.image.withUsedOp(), cont2) + } else { + // Else, dump our final list onto the stack. + Triple(ListIota(acc), harness.image, continuation) + } val tStack = stack.toMutableList() tStack.add(stackTop) return CastResult( @@ -84,8 +91,7 @@ data class FrameForEach( override fun serializeToNBT() = NBTBuilder { "data" %= data.serializeToNBT() "code" %= code.serializeToNBT() - if (baseStack != null) - "base" %= baseStack.serializeToNBT() + if (baseStack != null) "base" %= baseStack.serializeToNBT() "accumulator" %= acc.serializeToNBT() } @@ -95,22 +101,30 @@ data class FrameForEach( companion object { @JvmField - val TYPE: ContinuationFrame.Type = object : ContinuationFrame.Type { - override fun deserializeFromNBT(tag: CompoundTag, world: ServerLevel): FrameForEach { - return FrameForEach( - HexIotaTypes.LIST.deserialize(tag.getList("data", Tag.TAG_COMPOUND), world)!!.list, - HexIotaTypes.LIST.deserialize(tag.getList("code", Tag.TAG_COMPOUND), world)!!.list, - if (tag.hasList("base", Tag.TAG_COMPOUND)) - HexIotaTypes.LIST.deserialize(tag.getList("base", Tag.TAG_COMPOUND), world)!!.list.toList() - else - null, - HexIotaTypes.LIST.deserialize( - tag.getList("accumulator", Tag.TAG_COMPOUND), - world - )!!.list.toMutableList() - ) + val TYPE: ContinuationFrame.Type = + object : ContinuationFrame.Type { + override fun deserializeFromNBT( + tag: CompoundTag, + world: ServerLevel + ): FrameForEach { + return FrameForEach( + HexIotaTypes.LIST.deserialize( + tag.getList("data", Tag.TAG_COMPOUND), world)!! + .list, + HexIotaTypes.LIST.deserialize( + tag.getList("code", Tag.TAG_COMPOUND), world)!! + .list, + if (tag.hasList("base", Tag.TAG_COMPOUND)) + HexIotaTypes.LIST.deserialize( + tag.getList("base", Tag.TAG_COMPOUND), world)!! + .list + .toList() + else null, + HexIotaTypes.LIST.deserialize( + tag.getList("accumulator", Tag.TAG_COMPOUND), world)!! + .list + .toMutableList()) + } } - - } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt index 49f3d149d0..e62340dadc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FunctionalData.kt @@ -2,9 +2,7 @@ package at.petrak.hexcasting.api.casting.eval.vm import at.petrak.hexcasting.api.casting.iota.Iota -/** - * A change to the data in a CastHarness after a pattern is drawn. - */ +/** A change to the data in a CastHarness after a pattern is drawn. */ data class FunctionalData( val stack: List, val parenCount: Int, @@ -12,4 +10,3 @@ data class FunctionalData( val escapeNext: Boolean, val ravenmind: Iota? ) - diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt index ec706c2858..96eb0b51b1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt @@ -6,19 +6,17 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag import net.minecraft.server.level.ServerLevel -/** - * A continuation during the execution of a spell. - */ +/** A continuation during the execution of a spell. */ sealed interface SpellContinuation { object Done : SpellContinuation - data class NotDone(val frame: ContinuationFrame, val next: SpellContinuation) : SpellContinuation + data class NotDone(val frame: ContinuationFrame, val next: SpellContinuation) : + SpellContinuation fun pushFrame(frame: ContinuationFrame): SpellContinuation = NotDone(frame, this) - fun serializeToNBT() = NBTBuilder { - TAG_FRAME %= list(getNBTFrames()) - } + fun serializeToNBT() = NBTBuilder { TAG_FRAME %= list(getNBTFrames()) } + fun getNBTFrames(): List { var self = this val frames = mutableListOf() @@ -28,6 +26,7 @@ sealed interface SpellContinuation { } return frames } + companion object { const val TAG_FRAME = "frame" diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java index 91cf0b339d..7f1d61cc0b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/BooleanIota.java @@ -2,11 +2,13 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,8 +29,8 @@ public boolean isTruthy() { @Override public boolean toleratesOther(Iota that) { return typesMatch(this, that) - && that instanceof BooleanIota b - && this.getBool() == b.getBool(); + && that instanceof BooleanIota b + && this.getBool() == b.getBool(); } @Override @@ -37,24 +39,26 @@ public boolean toleratesOther(Iota that) { return ByteTag.valueOf(this.getBool()); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public BooleanIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return BooleanIota.deserialize(tag); - } + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public BooleanIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + return BooleanIota.deserialize(tag); + } - @Override - public Component display(Tag tag) { - return BooleanIota.display(BooleanIota.deserialize(tag).getBool()); - } + @Override + public Component display(Tag tag) { + return BooleanIota.display(BooleanIota.deserialize(tag).getBool()); + } - @Override - public int color() { - // We can't set red or green ... so do yellow, I guess - return 0xff_ffff55; - } - }; + @Override + public int color() { + // We can't set red or green ... so do yellow, I guess + return 0xff_ffff55; + } + }; public static BooleanIota deserialize(Tag tag) throws IllegalArgumentException { var dtag = HexUtils.downcast(tag, ByteTag.TYPE); @@ -62,7 +66,8 @@ public static BooleanIota deserialize(Tag tag) throws IllegalArgumentException { } public static Component display(boolean b) { - return Component.translatable(b ? "hexcasting.tooltip.boolean_true" : "hexcasting.tooltip.boolean_false") - .withStyle(b ? ChatFormatting.DARK_GREEN : ChatFormatting.DARK_RED); + return Component.translatable( + b ? "hexcasting.tooltip.boolean_true" : "hexcasting.tooltip.boolean_false") + .withStyle(b ? ChatFormatting.DARK_GREEN : ChatFormatting.DARK_RED); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java index 13764c4675..8008468a4b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java @@ -7,20 +7,21 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import java.util.List; -/** - * An iota storing a continuation (in essence an execution state). - */ +/** An iota storing a continuation (in essence an execution state). */ public class ContinuationIota extends Iota { - public static final Component DISPLAY = Component.translatable("hexcasting.tooltip.jump_iota").withStyle(ChatFormatting.RED); + public static final Component DISPLAY = + Component.translatable("hexcasting.tooltip.jump_iota").withStyle(ChatFormatting.RED); public ContinuationIota(SpellContinuation cont) { super(HexIotaTypes.CONTINUATION, cont); @@ -37,18 +38,26 @@ public boolean isTruthy() { @Override public boolean toleratesOther(Iota that) { - return typesMatch(this, that) && that instanceof ContinuationIota cont && cont.getContinuation().equals(getContinuation()); + return typesMatch(this, that) + && that instanceof ContinuationIota cont + && cont.getContinuation().equals(getContinuation()); } @Override - public @NotNull - Tag serialize() { + public @NotNull Tag serialize() { return getContinuation().serializeToNBT(); } @Override - public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { - return new CastResult(this, this.getContinuation(), vm.getImage(), List.of(), ResolvedPatternType.EVALUATED, HexEvalSounds.HERMES); + public @NotNull CastResult execute( + CastingVM vm, ServerLevel world, SpellContinuation continuation) { + return new CastResult( + this, + this.getContinuation(), + vm.getImage(), + List.of(), + ResolvedPatternType.EVALUATED, + HexEvalSounds.HERMES); } @Override @@ -69,21 +78,23 @@ public int size() { return Math.min(size, 1); } - public static IotaType TYPE = new IotaType<>() { - @Override - public @NotNull ContinuationIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - var compoundTag = HexUtils.downcast(tag, CompoundTag.TYPE); - return new ContinuationIota(SpellContinuation.fromNBT(compoundTag, world)); - } + public static IotaType TYPE = + new IotaType<>() { + @Override + public @NotNull ContinuationIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + var compoundTag = HexUtils.downcast(tag, CompoundTag.TYPE); + return new ContinuationIota(SpellContinuation.fromNBT(compoundTag, world)); + } - @Override - public Component display(Tag tag) { - return DISPLAY; - } + @Override + public Component display(Tag tag) { + return DISPLAY; + } - @Override - public int color() { - return 0xff_cc0000; - } - }; + @Override + public int color() { + return 0xff_cc0000; + } + }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java index e9ff20f57c..7e3e788d8d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/DoubleIota.java @@ -2,11 +2,13 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,8 +31,8 @@ public boolean isTruthy() { @Override public boolean toleratesOther(Iota that) { return typesMatch(this, that) - && that instanceof DoubleIota dd - && tolerates(this.getDouble(), dd.getDouble()); + && that instanceof DoubleIota dd + && tolerates(this.getDouble(), dd.getDouble()); } public static boolean tolerates(double a, double b) { @@ -42,23 +44,25 @@ public static boolean tolerates(double a, double b) { return DoubleTag.valueOf(this.getDouble()); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public DoubleIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return DoubleIota.deserialize(tag); - } + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public DoubleIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + return DoubleIota.deserialize(tag); + } - @Override - public Component display(Tag tag) { - return DoubleIota.display(DoubleIota.deserialize(tag).getDouble()); - } + @Override + public Component display(Tag tag) { + return DoubleIota.display(DoubleIota.deserialize(tag).getDouble()); + } - @Override - public int color() { - return 0xff_55ff55; - } - }; + @Override + public int color() { + return 0xff_55ff55; + } + }; public static DoubleIota deserialize(Tag tag) throws IllegalArgumentException { var dtag = HexUtils.downcast(tag, DoubleTag.TYPE); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java index 2a8023cf01..e7e4c16df0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/EntityIota.java @@ -2,9 +2,11 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import com.samsthenerd.inline.api.InlineAPI; import com.samsthenerd.inline.api.data.EntityInlineData; import com.samsthenerd.inline.api.data.PlayerHeadData; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; @@ -14,6 +16,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,8 +32,8 @@ public Entity getEntity() { @Override public boolean toleratesOther(Iota that) { return typesMatch(this, that) - && that instanceof EntityIota dent - && this.getEntity() == dent.getEntity(); + && that instanceof EntityIota dent + && this.getEntity() == dent.getEntity(); } @Override @@ -39,8 +42,7 @@ public boolean isTruthy() { } @Override - public @NotNull - Tag serialize() { + public @NotNull Tag serialize() { var out = new CompoundTag(); out.putUUID("uuid", this.getEntity().getUUID()); out.putString("name", Component.Serializer.toJson(getEntityNameWithInline(true))); @@ -52,15 +54,21 @@ public Component display() { return getEntityNameWithInline(false).copy().withStyle(ChatFormatting.AQUA); } - private Component getEntityNameWithInline(boolean fearSerializer){ + private Component getEntityNameWithInline(boolean fearSerializer) { MutableComponent baseName = this.getEntity().getName().copy(); Component inlineEnt = null; - if(this.getEntity() instanceof Player player){ + if (this.getEntity() instanceof Player player) { inlineEnt = new PlayerHeadData(player.getGameProfile()).asText(!fearSerializer); - inlineEnt = inlineEnt.plainCopy().withStyle(InlineAPI.INSTANCE.withSizeModifier(inlineEnt.getStyle(), 1.5)); - } else{ - if(fearSerializer){ // we don't want to have to serialize an entity just to display it - inlineEnt = EntityInlineData.fromType(this.getEntity().getType()).asText(!fearSerializer); + inlineEnt = + inlineEnt + .plainCopy() + .withStyle( + InlineAPI.INSTANCE.withSizeModifier(inlineEnt.getStyle(), 1.5)); + } else { + if (fearSerializer) { // we don't want to have to serialize an entity just to display it + inlineEnt = + EntityInlineData.fromType(this.getEntity().getType()) + .asText(!fearSerializer); } else { inlineEnt = EntityInlineData.fromEntity(this.getEntity()).asText(!fearSerializer); } @@ -68,39 +76,42 @@ private Component getEntityNameWithInline(boolean fearSerializer){ return baseName.append(Component.literal(": ")).append(inlineEnt); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public EntityIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - var ctag = HexUtils.downcast(tag, CompoundTag.TYPE); - Tag uuidTag = ctag.get("uuid"); - if (uuidTag == null) { - return null; - } - var uuid = NbtUtils.loadUUID(uuidTag); - var entity = world.getEntity(uuid); - if (entity == null) { - return null; - } - return new EntityIota(entity); - } + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public EntityIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + var ctag = HexUtils.downcast(tag, CompoundTag.TYPE); + Tag uuidTag = ctag.get("uuid"); + if (uuidTag == null) { + return null; + } + var uuid = NbtUtils.loadUUID(uuidTag); + var entity = world.getEntity(uuid); + if (entity == null) { + return null; + } + return new EntityIota(entity); + } - @Override - public Component display(Tag tag) { - if (!(tag instanceof CompoundTag ctag)) { - return Component.translatable("hexcasting.spelldata.entity.whoknows"); - } - if (!ctag.contains("name", Tag.TAG_STRING)) { - return Component.translatable("hexcasting.spelldata.entity.whoknows"); - } - var nameJson = ctag.getString("name"); -// return Component.literal(nameJson); - return Component.Serializer.fromJsonLenient(nameJson).withStyle(ChatFormatting.AQUA); - } + @Override + public Component display(Tag tag) { + if (!(tag instanceof CompoundTag ctag)) { + return Component.translatable("hexcasting.spelldata.entity.whoknows"); + } + if (!ctag.contains("name", Tag.TAG_STRING)) { + return Component.translatable("hexcasting.spelldata.entity.whoknows"); + } + var nameJson = ctag.getString("name"); + // return Component.literal(nameJson); + return Component.Serializer.fromJsonLenient(nameJson) + .withStyle(ChatFormatting.AQUA); + } - @Override - public int color() { - return 0xff_55ffff; - } - }; + @Override + public int color() { + return 0xff_55ffff; + } + }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java index 0824985852..c917f4a3b1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/GarbageIota.java @@ -1,24 +1,28 @@ package at.petrak.hexcasting.api.casting.iota; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Random; /** - * this is LITERALLY a copy of NullIota but I can't see how to do it any better, i hate java generics + * this is LITERALLY a copy of NullIota but I can't see how to do it any better, i hate java + * generics */ public class GarbageIota extends Iota { private static final Object NULL_SUBSTITUTE = new Object(); - public static final Component DISPLAY = Component.literal("arimfexendrapuse") - .withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.OBFUSCATED); + public static final Component DISPLAY = + Component.literal("arimfexendrapuse") + .withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.OBFUSCATED); private static final Random RANDOM = new Random(); @@ -43,21 +47,23 @@ public boolean toleratesOther(Iota that) { return new CompoundTag(); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public GarbageIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return new GarbageIota(); - } - - @Override - public Component display(Tag tag) { - return DISPLAY; - } - - @Override - public int color() { - return 0xff_505050; - } - }; + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public GarbageIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + return new GarbageIota(); + } + + @Override + public Component display(Tag tag) { + return DISPLAY; + } + + @Override + public int color() { + return 0xff_505050; + } + }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java index 7f024abc94..1adb985f98 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java @@ -11,19 +11,19 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapUnescapedValue; import at.petrak.hexcasting.common.lib.hex.HexEvalSounds; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; public abstract class Iota { - @NotNull - protected final Object payload; - @NotNull - protected final IotaType type; + @NotNull protected final Object payload; + @NotNull protected final IotaType type; protected Iota(@NotNull IotaType type, @NotNull Object payload) { this.type = type; @@ -34,63 +34,62 @@ protected Iota(@NotNull IotaType type, @NotNull Object payload) { return this.type; } - abstract public boolean isTruthy(); + public abstract boolean isTruthy(); - /** - * Compare this to another object, within a tolerance. - */ - abstract protected boolean toleratesOther(Iota that); + /** Compare this to another object, within a tolerance. */ + protected abstract boolean toleratesOther(Iota that); /** * Serialize this under the {@code data} tag. - *

- * You probably don't want to call this directly; use {@link IotaType#serialize}. + * + *

You probably don't want to call this directly; use {@link IotaType#serialize}. */ - abstract public @NotNull Tag serialize(); + public abstract @NotNull Tag serialize(); /** - * This method is called when this iota is executed (i.e. Hermes is run on a list containing it, unescaped). - * By default it will return a {@link CastResult} indicating an error has occurred. + * This method is called when this iota is executed (i.e. Hermes is run on a list containing it, + * unescaped). By default it will return a {@link CastResult} indicating an error has occurred. */ - public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { + public @NotNull CastResult execute( + CastingVM vm, ServerLevel world, SpellContinuation continuation) { return new CastResult( - this, - continuation, - null, // Should never matter - List.of( - new OperatorSideEffect.DoMishap( - new MishapUnescapedValue(this), - new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null) - ) - ), - ResolvedPatternType.INVALID, - HexEvalSounds.MISHAP); + this, + continuation, + null, // Should never matter + List.of( + new OperatorSideEffect.DoMishap( + new MishapUnescapedValue(this), + new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null))), + ResolvedPatternType.INVALID, + HexEvalSounds.MISHAP); } /** - * Returns whether this iota is possible to execute (i.e. whether {@link Iota#execute} has been overridden. + * Returns whether this iota is possible to execute (i.e. whether {@link Iota#execute} has been + * overridden. */ public boolean executable() { return false; } /** - * This method is called to determine whether the iota is above the max serialisation depth/serialisation count - * limits. It should return every "iota" that is a subelement of this iota. - * For example, if you implemented a Map<Iota, Iota>, then it should be an iterable over the keys *and* - * values of the map. If you implemented a typed List<Double> iota for some reason, you should instead override - * {@link Iota#size}. + * This method is called to determine whether the iota is above the max serialisation + * depth/serialisation count limits. It should return every "iota" that is a subelement of this + * iota. For example, if you implemented a Map<Iota, Iota>, then it should be an iterable + * over the keys *and* values of the map. If you implemented a typed List<Double> iota for + * some reason, you should instead override {@link Iota#size}. */ public @Nullable Iterable subIotas() { return null; } /** - * This method is called to determine whether the iota is above the max serialisation depth/serialisation count limits. - * This is an alternative to deriving subIotas for if your Iota is a datastructure of variable size over something that - * doesn't make sense to convert to an Iota iterable, such as {@link ContinuationIota}, or a typed List<Double>. - * It should return "1" per "iota sized" unit of memory that it would occupy. Easy option, return the element count of - * your data structure. + * This method is called to determine whether the iota is above the max serialisation + * depth/serialisation count limits. This is an alternative to deriving subIotas for if your + * Iota is a datastructure of variable size over something that doesn't make sense to convert to + * an Iota iterable, such as {@link ContinuationIota}, or a typed List<Double>. It should + * return "1" per "iota sized" unit of memory that it would occupy. Easy option, return the + * element count of your data structure. */ public int size() { return 1; @@ -100,18 +99,14 @@ public Component display() { return this.type.display(this.serialize()); } - /** - * Helper method to see if two iotas have the same type. - */ + /** Helper method to see if two iotas have the same type. */ public static boolean typesMatch(Iota a, Iota b) { var resA = HexIotaTypes.REGISTRY.getKey(a.getType()); var resB = HexIotaTypes.REGISTRY.getKey(b.getType()); return resA != null && resA.equals(resB); } - /** - * Helper method to see if either iota tolerates the other. - */ + /** Helper method to see if either iota tolerates the other. */ public static boolean tolerates(Iota a, Iota b) { return a.toleratesOther(b) || b.toleratesOther(a); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java index 4bcf9b4b1f..e226370654 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/IotaType.java @@ -3,7 +3,9 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import com.mojang.datafixers.util.Pair; + import net.minecraft.ChatFormatting; import net.minecraft.client.gui.Font; import net.minecraft.nbt.CompoundTag; @@ -14,45 +16,42 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.util.FormattedCharSequence; -import javax.annotation.Nullable; import java.util.ArrayDeque; import java.util.Collections; import java.util.List; import java.util.Objects; +import javax.annotation.Nullable; + // Take notes from ForgeRegistryEntry public abstract class IotaType { /** * Spell datums are stored as such: {@code { "type": "modid:type", "datum": a_tag }}. - *

- * The {@code type} key is given when registering the spell datum type; this method + * + *

The {@code type} key is given when registering the spell datum type; this method * deserializes the tag associated with {@code "datum"}. - *

- * Returning {@code null} makes the resulting datum be {@link NullIota}. - * Throwing an exception raises a mishap. + * + *

Returning {@code null} makes the resulting datum be {@link NullIota}. Throwing an + * exception raises a mishap. */ @Nullable public abstract T deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException; /** - * Get a display of this datum from the {@code data} tag, without the world. - * This is for use on the client. + * Get a display of this datum from the {@code data} tag, without the world. This is for + * use on the client. */ public abstract Component display(Tag tag); - /** - * Get the color associated with this datum type. - */ + /** Get the color associated with this datum type. */ public abstract int color(); - /** - * Get a display component that's the name of this iota type. - */ + /** Get a display component that's the name of this iota type. */ public Component typeName() { var key = HexIotaTypes.REGISTRY.getKey(this); return Component.translatable("hexcasting.iota." + key) - .withStyle(style -> style.withColor(TextColor.fromRgb(color()))); + .withStyle(style -> style.withColor(TextColor.fromRgb(color()))); } public static CompoundTag serialize(Iota iota) { @@ -60,8 +59,10 @@ public static CompoundTag serialize(Iota iota) { var typeId = HexIotaTypes.REGISTRY.getKey(type); if (typeId == null) { throw new IllegalStateException( - "Tried to serialize an unregistered iota type. Iota: " + iota - + " ; Type" + type.getClass().getTypeName()); + "Tried to serialize an unregistered iota type. Iota: " + + iota + + " ; Type" + + type.getClass().getTypeName()); } // We check if it's too big on serialization; if it is we just return a garbage. @@ -111,8 +112,8 @@ private static boolean isTooLargeToSerialize(Iterable examinee, int starti } /** - * This method attempts to find the type from the {@code type} key. - * See {@link IotaType#serialize(Iota)} for the storage format. + * This method attempts to find the type from the {@code type} key. See {@link + * IotaType#serialize(Iota)} for the storage format. * * @return {@code null} if it cannot get the type. */ @@ -130,10 +131,8 @@ public static IotaType getTypeFromTag(CompoundTag tag) { } /** - * Attempt to deserialize an iota from a tag. - *
- * Iotas are saved as such: - * + * Attempt to deserialize an iota from a tag.
+ * Iotas are saved as such: * { * "type": "hexcasting:atype", * "data": {...} @@ -151,7 +150,8 @@ public static Iota deserialize(CompoundTag tag, ServerLevel world) { } Iota deserialized; try { - deserialized = Objects.requireNonNullElse(type.deserialize(data, world), new NullIota()); + deserialized = + Objects.requireNonNullElse(type.deserialize(data, world), new NullIota()); } catch (IllegalArgumentException exn) { HexAPI.LOGGER.warn("Caught an exception deserializing an iota", exn); deserialized = new GarbageIota(); @@ -161,7 +161,7 @@ public static Iota deserialize(CompoundTag tag, ServerLevel world) { private static Component brokenIota() { return Component.translatable("hexcasting.spelldata.unknown") - .withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC); + .withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC); } public static Component getDisplay(CompoundTag tag) { @@ -176,7 +176,8 @@ public static Component getDisplay(CompoundTag tag) { return type.display(data); } - public static FormattedCharSequence getDisplayWithMaxWidth(CompoundTag tag, int maxWidth, Font font) { + public static FormattedCharSequence getDisplayWithMaxWidth( + CompoundTag tag, int maxWidth, Font font) { var type = getTypeFromTag(tag); if (type == null) { return brokenIota().getVisualOrderText(); @@ -187,14 +188,13 @@ public static FormattedCharSequence getDisplayWithMaxWidth(CompoundTag tag, int } var display = type.display(data); var splitted = font.split(display, maxWidth - font.width("...")); - if (splitted.isEmpty()) - return FormattedCharSequence.EMPTY; - else if (splitted.size() == 1) - return splitted.get(0); + if (splitted.isEmpty()) return FormattedCharSequence.EMPTY; + else if (splitted.size() == 1) return splitted.get(0); else { var first = splitted.get(0); - return FormattedCharSequence.fromPair(first, - Component.literal("...").withStyle(ChatFormatting.GRAY).getVisualOrderText()); + return FormattedCharSequence.fromPair( + first, + Component.literal("...").withStyle(ChatFormatting.GRAY).getVisualOrderText()); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java index 251c4e161d..8249dfc184 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ListIota.java @@ -3,21 +3,21 @@ import at.petrak.hexcasting.api.casting.SpellList; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -/** - * This is a wrapper for {@link SpellList}. - */ +/** This is a wrapper for {@link SpellList}. */ public class ListIota extends Iota { public ListIota(@NotNull SpellList list) { super(HexIotaTypes.LIST, list); @@ -78,48 +78,57 @@ public boolean toleratesOther(Iota that) { return this.getList(); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public ListIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - var listTag = HexUtils.downcast(tag, ListTag.TYPE); - var out = new ArrayList(listTag.size()); - - for (var sub : listTag) { - var csub = HexUtils.downcast(sub, CompoundTag.TYPE); - var subiota = IotaType.deserialize(csub, world); - if (subiota == null) { - return null; + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public ListIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + var listTag = HexUtils.downcast(tag, ListTag.TYPE); + var out = new ArrayList(listTag.size()); + + for (var sub : listTag) { + var csub = HexUtils.downcast(sub, CompoundTag.TYPE); + var subiota = IotaType.deserialize(csub, world); + if (subiota == null) { + return null; + } + out.add(subiota); + } + + return new ListIota(out); } - out.add(subiota); - } - - return new ListIota(out); - } - @Override - public Component display(Tag tag) { - var out = Component.empty(); - var list = HexUtils.downcast(tag, ListTag.TYPE); - for (int i = 0; i < list.size(); i++) { - Tag sub = list.get(i); - var csub = HexUtils.downcast(sub, CompoundTag.TYPE); - - out.append(IotaType.getDisplay(csub)); - - // only add a comma between 2 non-patterns (commas don't look good with Inline patterns) - // TODO: maybe add a config? maybe add a method on IotaType to allow it to opt out of commas - if (i < list.size() - 1 && (IotaType.getTypeFromTag(csub) != PatternIota.TYPE - || IotaType.getTypeFromTag(HexUtils.downcast(list.get(i+1), CompoundTag.TYPE)) != PatternIota.TYPE)) { - out.append(", "); + @Override + public Component display(Tag tag) { + var out = Component.empty(); + var list = HexUtils.downcast(tag, ListTag.TYPE); + for (int i = 0; i < list.size(); i++) { + Tag sub = list.get(i); + var csub = HexUtils.downcast(sub, CompoundTag.TYPE); + + out.append(IotaType.getDisplay(csub)); + + // only add a comma between 2 non-patterns (commas don't look good with + // Inline patterns) + // TODO: maybe add a config? maybe add a method on IotaType to allow it to + // opt out of commas + if (i < list.size() - 1 + && (IotaType.getTypeFromTag(csub) != PatternIota.TYPE + || IotaType.getTypeFromTag( + HexUtils.downcast( + list.get(i + 1), CompoundTag.TYPE)) + != PatternIota.TYPE)) { + out.append(", "); + } + } + return Component.translatable("hexcasting.tooltip.list_contents", out) + .withStyle(ChatFormatting.DARK_PURPLE); } - } - return Component.translatable("hexcasting.tooltip.list_contents", out).withStyle(ChatFormatting.DARK_PURPLE); - } - @Override - public int color() { - return 0xff_aa00aa; - } - }; + @Override + public int color() { + return 0xff_aa00aa; + } + }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java index 525e6b22a9..247ced8817 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/NullIota.java @@ -1,22 +1,22 @@ package at.petrak.hexcasting.api.casting.iota; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -/** - * An iota with no data associated with it. - */ +/** An iota with no data associated with it. */ public class NullIota extends Iota { private static final Object NULL_SUBSTITUTE = new Object(); public static final Component DISPLAY = - Component.translatable("hexcasting.tooltip.null_iota").withStyle(ChatFormatting.GRAY); + Component.translatable("hexcasting.tooltip.null_iota").withStyle(ChatFormatting.GRAY); public NullIota() { // We have to pass *something* here, but there's nothing that actually needs to go there, @@ -39,21 +39,23 @@ public boolean toleratesOther(Iota that) { return new CompoundTag(); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public NullIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return new NullIota(); - } - - @Override - public Component display(Tag tag) { - return DISPLAY; - } - - @Override - public int color() { - return 0xff_aaaaaa; - } - }; + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public NullIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + return new NullIota(); + } + + @Override + public Component display(Tag tag) { + return DISPLAY; + } + + @Override + public int color() { + return 0xff_aaaaaa; + } + }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java index b86e8541ce..4b423c5039 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/PatternIota.java @@ -1,5 +1,7 @@ package at.petrak.hexcasting.api.casting.iota; +import static at.petrak.hexcasting.api.utils.HexUtils.isOfTag; + import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.api.casting.PatternShapeMatch; @@ -21,6 +23,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; import at.petrak.hexcasting.interop.inline.InlinePatternData; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; @@ -28,6 +31,7 @@ import net.minecraft.network.chat.Style; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.ServerLevel; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,8 +39,6 @@ import java.util.Objects; import java.util.function.Supplier; -import static at.petrak.hexcasting.api.utils.HexUtils.isOfTag; - public class PatternIota extends Iota { public PatternIota(@NotNull HexPattern pattern) { super(HexIotaTypes.PATTERN, pattern); @@ -58,8 +60,8 @@ public boolean isTruthy() { @Override public boolean toleratesOther(Iota that) { return typesMatch(this, that) - && that instanceof PatternIota piota - && this.getPattern().getAngles().equals(piota.getPattern().getAngles()); + && that instanceof PatternIota piota + && this.getPattern().getAngles().equals(piota.getPattern().getAngles()); } @Override @@ -68,14 +70,17 @@ public boolean toleratesOther(Iota that) { } @Override - public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) { + public @NotNull CastResult execute( + CastingVM vm, ServerLevel world, SpellContinuation continuation) { Supplier<@Nullable Component> castedName = () -> null; try { - var lookup = PatternRegistryManifest.matchPattern(this.getPattern(), vm.getEnv(), false); + var lookup = + PatternRegistryManifest.matchPattern(this.getPattern(), vm.getEnv(), false); vm.getEnv().precheckAction(lookup); Action action; - if (lookup instanceof PatternShapeMatch.Normal || lookup instanceof PatternShapeMatch.PerWorld) { + if (lookup instanceof PatternShapeMatch.Normal + || lookup instanceof PatternShapeMatch.PerWorld) { ResourceKey key; if (lookup instanceof PatternShapeMatch.Normal normal) { key = normal.key; @@ -84,11 +89,17 @@ public boolean toleratesOther(Iota that) { key = perWorld.key; } - var reqsEnlightenment = isOfTag(IXplatAbstractions.INSTANCE.getActionRegistry(), key, - HexTags.Actions.REQUIRES_ENLIGHTENMENT); + var reqsEnlightenment = + isOfTag( + IXplatAbstractions.INSTANCE.getActionRegistry(), + key, + HexTags.Actions.REQUIRES_ENLIGHTENMENT); castedName = () -> HexAPI.instance().getActionI18n(key, reqsEnlightenment); - action = Objects.requireNonNull(IXplatAbstractions.INSTANCE.getActionRegistry().get(key)).action(); + action = + Objects.requireNonNull( + IXplatAbstractions.INSTANCE.getActionRegistry().get(key)) + .action(); if (reqsEnlightenment && !vm.getEnv().isEnlightened()) { // this gets caught down below @@ -102,11 +113,7 @@ public boolean toleratesOther(Iota that) { } else throw new IllegalStateException(); // do the actual calculation!! - var result = action.operate( - vm.getEnv(), - vm.getImage(), - continuation - ); + var result = action.operate(vm.getEnv(), vm.getImage(), continuation); if (result.getNewImage().getOpsConsumed() > vm.getEnv().maxOpCount()) { throw new MishapEvalTooMuch(); @@ -117,21 +124,24 @@ public boolean toleratesOther(Iota that) { var sideEffects = result.getSideEffects(); return new CastResult( - this, - cont2, - result.getNewImage(), - sideEffects, - ResolvedPatternType.EVALUATED, - result.getSound()); + this, + cont2, + result.getNewImage(), + sideEffects, + ResolvedPatternType.EVALUATED, + result.getSound()); } catch (Mishap mishap) { return new CastResult( - this, - continuation, - null, - List.of(new OperatorSideEffect.DoMishap(mishap, new Mishap.Context(this.getPattern(), castedName.get()))), - mishap.resolutionType(vm.getEnv()), - HexEvalSounds.MISHAP); + this, + continuation, + null, + List.of( + new OperatorSideEffect.DoMishap( + mishap, + new Mishap.Context(this.getPattern(), castedName.get()))), + mishap.resolutionType(vm.getEnv()), + HexEvalSounds.MISHAP); } } @@ -140,22 +150,24 @@ public boolean executable() { return true; } - public static IotaType TYPE = new IotaType<>() { - @Override - public PatternIota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return PatternIota.deserialize(tag); - } + public static IotaType TYPE = + new IotaType<>() { + @Override + public PatternIota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + return PatternIota.deserialize(tag); + } - @Override - public Component display(Tag tag) { - return PatternIota.display(PatternIota.deserialize(tag).getPattern()); - } + @Override + public Component display(Tag tag) { + return PatternIota.display(PatternIota.deserialize(tag).getPattern()); + } - @Override - public int color() { - return 0xff_ffaa00; - } - }; + @Override + public int color() { + return 0xff_ffaa00; + } + }; public static PatternIota deserialize(Tag tag) throws IllegalArgumentException { var patTag = HexUtils.downcast(tag, CompoundTag.TYPE); @@ -165,11 +177,12 @@ public static PatternIota deserialize(Tag tag) throws IllegalArgumentException { public static Component display(HexPattern pat) { Component text = (new InlinePatternData(pat)).asText(true); - return text.copy().withStyle(text.getStyle().applyTo(Style.EMPTY.withColor(ChatFormatting.WHITE))); + return text.copy() + .withStyle(text.getStyle().applyTo(Style.EMPTY.withColor(ChatFormatting.WHITE))); } // keep around just in case it's needed. - public static Component displayNonInline(HexPattern pat){ + public static Component displayNonInline(HexPattern pat) { var bob = new StringBuilder(); bob.append(pat.getStartDir()); @@ -178,7 +191,8 @@ public static Component displayNonInline(HexPattern pat){ bob.append(" "); bob.append(sig); } - return Component.translatable("hexcasting.tooltip.pattern_iota", + return Component.translatable( + "hexcasting.tooltip.pattern_iota", Component.literal(bob.toString()).withStyle(ChatFormatting.WHITE)) .withStyle(ChatFormatting.GOLD); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java index 9d9d7fbf67..14be8111f6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Vec3Iota.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.LongArrayTag; @@ -9,6 +10,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.phys.Vec3; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,11 +21,7 @@ public Vec3Iota(@NotNull Vec3 datum) { public Vec3 getVec3() { var v = (Vec3) this.payload; - return new Vec3( - HexUtils.fixNAN(v.x), - HexUtils.fixNAN(v.y), - HexUtils.fixNAN(v.z) - ); + return new Vec3(HexUtils.fixNAN(v.x), HexUtils.fixNAN(v.y), HexUtils.fixNAN(v.z)); } @Override @@ -35,8 +33,9 @@ public boolean isTruthy() { @Override public boolean toleratesOther(Iota that) { return typesMatch(this, that) - && that instanceof Vec3Iota viota - && this.getVec3().distanceToSqr(viota.getVec3()) < DoubleIota.TOLERANCE * DoubleIota.TOLERANCE; + && that instanceof Vec3Iota viota + && this.getVec3().distanceToSqr(viota.getVec3()) + < DoubleIota.TOLERANCE * DoubleIota.TOLERANCE; } @Override @@ -44,37 +43,38 @@ public boolean toleratesOther(Iota that) { return HexUtils.serializeToNBT(this.getVec3()); } - public static IotaType TYPE = new IotaType<>() { - @Nullable - @Override - public Vec3Iota deserialize(Tag tag, ServerLevel world) throws IllegalArgumentException { - return Vec3Iota.deserialize(tag); - } + public static IotaType TYPE = + new IotaType<>() { + @Nullable + @Override + public Vec3Iota deserialize(Tag tag, ServerLevel world) + throws IllegalArgumentException { + return Vec3Iota.deserialize(tag); + } - @Override - public Component display(Tag tag) { - return Vec3Iota.display(Vec3Iota.deserialize(tag).getVec3()); - } + @Override + public Component display(Tag tag) { + return Vec3Iota.display(Vec3Iota.deserialize(tag).getVec3()); + } - @Override - public int color() { - return 0xff_ff3030; - } - }; + @Override + public int color() { + return 0xff_ff3030; + } + }; public static Vec3Iota deserialize(Tag tag) throws IllegalArgumentException { Vec3 vec; if (tag.getType() == LongArrayTag.TYPE) { var lat = HexUtils.downcast(tag, LongArrayTag.TYPE); vec = HexUtils.vecFromNBT(lat.getAsLongArray()); - } else - vec = HexUtils.vecFromNBT(HexUtils.downcast(tag, CompoundTag.TYPE)); + } else vec = HexUtils.vecFromNBT(HexUtils.downcast(tag, CompoundTag.TYPE)); return new Vec3Iota(vec); } public static Component display(double x, double y, double z) { return Component.literal(String.format("(%.2f, %.2f, %.2f)", x, y, z)) - .withStyle(ChatFormatting.RED); + .withStyle(ChatFormatting.RED); } public static Component display(Vec3 v) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt index d79ff002b8..561f9264ac 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/EulerPathFinder.kt @@ -5,12 +5,14 @@ import java.util.* import kotlin.random.Random object EulerPathFinder { - /** - * Find an alternative way to draw the given pattern, based on a random seed. - */ + /** Find an alternative way to draw the given pattern, based on a random seed. */ @JvmStatic @JvmOverloads - fun findAltDrawing(original: HexPattern, seed: Long, rule: (HexPattern) -> Boolean = { true }): HexPattern { + fun findAltDrawing( + original: HexPattern, + seed: Long, + rule: (HexPattern) -> Boolean = { true } + ): HexPattern { // http://www.graph-magics.com/articles/euler.php val rand = Random(seed) @@ -36,13 +38,14 @@ object EulerPathFinder { private fun walkPath(original: HexPattern, rand: Random): HexPattern { val graph = toGraph(original) val oddNodes = graph.filter { (_, dirs) -> dirs.size % 2 == 1 } - var current: HexCoord = when (oddNodes.size) { - // An euler-walkable graph must have 0 odd nodes and start anywhere... - 0 -> graph.keys.random(rand) - // or two, and start at one of them - 2 -> oddNodes.keys.random(rand) - else -> throw IllegalStateException() - } + var current: HexCoord = + when (oddNodes.size) { + // An euler-walkable graph must have 0 odd nodes and start anywhere... + 0 -> graph.keys.random(rand) + // or two, and start at one of them + 2 -> oddNodes.keys.random(rand) + else -> throw IllegalStateException() + } val stack = Stack() val out = mutableListOf() @@ -75,13 +78,17 @@ object EulerPathFinder { for (a in pat.angles) { // i hate kotlin graph.getOrPut(cursor) { EnumSet.noneOf(HexDir::class.java) }.add(compass) - graph.getOrPut(cursor + compass) { EnumSet.noneOf(HexDir::class.java) }.add(compass * HexAngle.BACK) + graph + .getOrPut(cursor + compass) { EnumSet.noneOf(HexDir::class.java) } + .add(compass * HexAngle.BACK) cursor += compass compass *= a } graph.getOrPut(cursor) { EnumSet.noneOf(HexDir::class.java) }.add(compass) - graph.getOrPut(cursor + compass) { EnumSet.noneOf(HexDir::class.java) }.add(compass * HexAngle.BACK) + graph + .getOrPut(cursor + compass) { EnumSet.noneOf(HexDir::class.java) } + .add(compass * HexAngle.BACK) return graph } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt index bca8b0b94b..762d1eef28 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexAngle.kt @@ -1,8 +1,14 @@ package at.petrak.hexcasting.api.casting.math enum class HexAngle { - FORWARD, RIGHT, RIGHT_BACK, BACK, LEFT_BACK, LEFT; + FORWARD, + RIGHT, + RIGHT_BACK, + BACK, + LEFT_BACK, + LEFT; fun rotatedBy(a: HexAngle) = values()[(this.ordinal + a.ordinal) % values().size] + operator fun times(a: HexAngle) = this.rotatedBy(a) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexCoord.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexCoord.kt index 7102bdcce0..a2f7b9cb2c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexCoord.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexCoord.kt @@ -4,9 +4,7 @@ import kotlin.math.abs import kotlin.math.max import kotlin.math.min -/** - * Uses axial coordinates as per https://www.redblobgames.com/grids/hexagons/ - */ +/** Uses axial coordinates as per https://www.redblobgames.com/grids/hexagons/ */ data class HexCoord(val q: Int, val r: Int) { fun s(): Int = -this.q - this.r @@ -17,7 +15,9 @@ data class HexCoord(val q: Int, val r: Int) { fun delta(x: HexCoord): HexCoord = HexCoord(this.q - x.q, this.r - x.r) operator fun plus(x: HexCoord) = this.shiftedBy(x) + operator fun plus(d: HexDir) = this.shiftedBy(d) + operator fun minus(x: HexCoord) = this.delta(x) fun distanceTo(x: HexCoord) = @@ -56,7 +56,6 @@ data class HexCoord(val q: Int, val r: Int) { } companion object { - @JvmStatic - val Origin = HexCoord(0, 0) + @JvmStatic val Origin = HexCoord(0, 0) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt index 03f4ca5a56..c3c7803bf3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexDir.kt @@ -4,10 +4,14 @@ import at.petrak.hexcasting.api.utils.getSafe import com.mojang.serialization.Codec enum class HexDir { - NORTH_EAST, EAST, SOUTH_EAST, SOUTH_WEST, WEST, NORTH_WEST; + NORTH_EAST, + EAST, + SOUTH_EAST, + SOUTH_WEST, + WEST, + NORTH_WEST; - fun rotatedBy(a: HexAngle): HexDir = - values()[(this.ordinal + a.ordinal).mod(values().size)] + fun rotatedBy(a: HexAngle): HexDir = values()[(this.ordinal + a.ordinal).mod(values().size)] operator fun times(a: HexAngle) = this.rotatedBy(a) @@ -27,10 +31,7 @@ enum class HexDir { } companion object { - val CODEC: Codec = Codec.STRING.xmap( - HexDir::fromString, - HexDir::name - ) + val CODEC: Codec = Codec.STRING.xmap(HexDir::fromString, HexDir::name) @JvmStatic fun fromString(key: String): HexDir { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt index 001cfdeab4..0a81ae15b5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/math/HexPattern.kt @@ -10,13 +10,9 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.Tag import net.minecraft.world.phys.Vec2 -/** - * Sequence of angles to define a pattern traced. - */ +/** Sequence of angles to define a pattern traced. */ data class HexPattern(val startDir: HexDir, val angles: MutableList = arrayListOf()) { - /** - * @return True if it successfully appended, false if not. - */ + /** @return True if it successfully appended, false if not. */ fun tryAppendDir(newDir: HexDir): Boolean { // Two restrictions: // - No adding a pos/dir pair we previously added @@ -70,9 +66,7 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = return out } - fun finalDir(): HexDir = - this.angles.fold(this.startDir) { acc, angle -> acc * angle } - + fun finalDir(): HexDir = this.angles.fold(this.startDir) { acc, angle -> acc * angle } fun serializeToNBT() = NBTBuilder { TAG_START_DIR %= byte(startDir.ordinal) @@ -91,15 +85,14 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = HexAngle.BACK -> "s" HexAngle.LEFT_BACK -> "a" HexAngle.LEFT -> "q" - } - ) + }) } } } /** - * Return the "center of mass" of the pattern. - * Drawing the pattern with the returned vector as the origin will center the pattern around it. + * Return the "center of mass" of the pattern. Drawing the pattern with the returned vector as + * the origin will center the pattern around it. */ @JvmOverloads fun getCenter(hexRadius: Float, origin: HexCoord = HexCoord.Origin): Vec2 { @@ -108,10 +101,7 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = return findCenter(points) } - - /** - * Convert a hex pattern into a sequence of straight linePoints spanning its points. - */ + /** Convert a hex pattern into a sequence of straight linePoints spanning its points. */ fun toLines(hexSize: Float, origin: Vec2): List = this.positions().map { coordToPx(it, hexSize, origin) } @@ -130,16 +120,19 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = const val TAG_ANGLES = "angles" @JvmField - val CODEC: Codec = RecordCodecBuilder.create({instance -> instance.group( - Codec.STRING.fieldOf(TAG_START_DIR).forGetter(HexPattern::anglesSignature), - HexDir.CODEC.fieldOf(TAG_ANGLES).forGetter(HexPattern::startDir) - ).apply(instance, HexPattern::fromAngles) - }) + val CODEC: Codec = + RecordCodecBuilder.create({ instance -> + instance + .group( + Codec.STRING.fieldOf(TAG_START_DIR).forGetter(HexPattern::anglesSignature), + HexDir.CODEC.fieldOf(TAG_ANGLES).forGetter(HexPattern::startDir)) + .apply(instance, HexPattern::fromAngles) + }) @JvmStatic fun isPattern(tag: CompoundTag): Boolean { - return tag.contains(TAG_START_DIR, Tag.TAG_ANY_NUMERIC.toInt()) - && tag.contains(TAG_ANGLES, Tag.TAG_BYTE_ARRAY.toInt()) + return tag.contains(TAG_START_DIR, Tag.TAG_ANY_NUMERIC.toInt()) && + tag.contains(TAG_ANGLES, Tag.TAG_BYTE_ARRAY.toInt()) } @JvmStatic @@ -155,24 +148,27 @@ data class HexPattern(val startDir: HexDir, val angles: MutableList = var compass = startDir for ((idx, c) in signature.withIndex()) { - val angle = when (c) { - 'w' -> HexAngle.FORWARD - 'e' -> HexAngle.RIGHT - 'd' -> HexAngle.RIGHT_BACK - // for completeness ... - 's' -> HexAngle.BACK - 'a' -> HexAngle.LEFT_BACK - 'q' -> HexAngle.LEFT - else -> throw IllegalArgumentException("Cannot match $c at idx $idx to a direction") - } + val angle = + when (c) { + 'w' -> HexAngle.FORWARD + 'e' -> HexAngle.RIGHT + 'd' -> HexAngle.RIGHT_BACK + // for completeness ... + 's' -> HexAngle.BACK + 'a' -> HexAngle.LEFT_BACK + 'q' -> HexAngle.LEFT + else -> + throw IllegalArgumentException( + "Cannot match $c at idx $idx to a direction") + } compass *= angle val success = out.tryAppendDir(compass) if (!success) { - throw IllegalStateException("Adding the angle $c at index $idx made the pattern invalid by looping back on itself") + throw IllegalStateException( + "Adding the angle $c at index $idx made the pattern invalid by looping back on itself") } } return out } - } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt index b9462fdda9..2490ee2446 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt @@ -25,12 +25,11 @@ abstract class Mishap : Throwable() { open fun particleSpray(ctx: CastingEnvironment): ParticleSpray { return ParticleSpray( - ctx.mishapSprayPos().add(0.0, 0.2, 0.0), - Vec3(0.0, 2.0, 0.0), - 0.2, Math.PI / 4, 40) + ctx.mishapSprayPos().add(0.0, 0.2, 0.0), Vec3(0.0, 2.0, 0.0), 0.2, Math.PI / 4, 40) } - open fun resolutionType(ctx: CastingEnvironment): ResolvedPatternType = ResolvedPatternType.ERRORED + open fun resolutionType(ctx: CastingEnvironment): ResolvedPatternType = + ResolvedPatternType.ERRORED /** * Execute the actual effect, not any sfx. @@ -41,17 +40,21 @@ abstract class Mishap : Throwable() { protected abstract fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component? - fun executeReturnStack(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList): List { + fun executeReturnStack( + ctx: CastingEnvironment, + errorCtx: Context, + stack: MutableList + ): List { execute(ctx, errorCtx, stack) return stack } - /** - * Every error message should be prefixed with the name of the action... - */ + /** Every error message should be prefixed with the name of the action... */ fun errorMessageWithName(ctx: CastingEnvironment, errorCtx: Context): Component? { return if (errorCtx.name != null) { - "hexcasting.mishap".asTranslatedComponent(errorCtx.name, this.errorMessage(ctx, errorCtx) ?: return null) + "hexcasting.mishap" + .asTranslatedComponent( + errorCtx.name, this.errorMessage(ctx, errorCtx) ?: return null) } else { this.errorMessage(ctx, errorCtx) } @@ -60,10 +63,7 @@ abstract class Mishap : Throwable() { // Useful helper functions protected fun dyeColor(color: DyeColor): FrozenPigment = - FrozenPigment( - ItemStack(HexItems.DYE_PIGMENTS[color]!!), - Util.NIL_UUID - ) + FrozenPigment(ItemStack(HexItems.DYE_PIGMENTS[color]!!), Util.NIL_UUID) protected fun error(stub: String, vararg args: Any): Component = "hexcasting.mishap.$stub".asTranslatedComponent(*args) @@ -85,16 +85,12 @@ abstract class Mishap : Throwable() { val targetHealth = entity.health - amount if (entity.invulnerableTime > 10) { val lastHurt = entity.lastHurt - if (lastHurt < amount) - entity.invulnerableTime = 0 - else - entity.lastHurt -= amount + if (lastHurt < amount) entity.invulnerableTime = 0 else entity.lastHurt -= amount } if (!entity.hurt(source, amount) && !entity.isInvulnerableTo(source) && !entity.level().isClientSide && - !entity.isDeadOrDying - ) { + !entity.isDeadOrDying) { // Ok, if you REALLY don't want to play nice... entity.health = targetHealth diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt index fcfe86b2d7..4c4f78c8b7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapAlreadyBrainswept.kt @@ -16,10 +16,8 @@ class MishapAlreadyBrainswept(val mob: Mob) : Mishap() { mob.hurt(mob.damageSources().source(HexDamageTypes.OVERCAST, ctx.castingEntity), mob.health) } - override fun particleSpray(ctx: CastingEnvironment) = - ParticleSpray.burst(mob.eyePosition, 1.0) + override fun particleSpray(ctx: CastingEnvironment) = ParticleSpray.burst(mob.eyePosition, 1.0) override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("already_brainswept") - } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt index b97a1b72f6..bc6da31024 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBlock.kt @@ -8,7 +8,6 @@ import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor -import net.minecraft.world.level.Explosion import net.minecraft.world.level.Level import net.minecraft.world.phys.Vec3 @@ -17,7 +16,8 @@ class MishapBadBlock(val pos: BlockPos, val expected: Component) : Mishap() { dyeColor(DyeColor.LIME) override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) { - ctx.world.explode(null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Level.ExplosionInteraction.NONE) + ctx.world.explode( + null, pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, 0.25f, Level.ExplosionInteraction.NONE) } override fun particleSpray(ctx: CastingEnvironment) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt index 99199f9561..53f76393d3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadCaster.kt @@ -5,13 +5,11 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment import net.minecraft.world.item.DyeColor -class MishapBadCaster: Mishap() { +class MishapBadCaster : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.RED) - override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - } + override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) {} - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("bad_caster") -} \ No newline at end of file + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("bad_caster") +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt index 336a4fa18e..786ab4ac94 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt @@ -25,8 +25,7 @@ class MishapBadEntity(val entity: Entity, val wanted: Component) : Mishap() { @JvmStatic fun of(entity: Entity, stub: String): Mishap { val component = "hexcasting.mishap.bad_item.$stub".asTranslatedComponent - if (entity is ItemEntity) - return MishapBadItem(entity, component) + if (entity is ItemEntity) return MishapBadItem(entity, component) return MishapBadEntity(entity, component) } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt index d41cc88f32..839a87d407 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadItem.kt @@ -13,13 +13,13 @@ class MishapBadItem(val item: ItemEntity, val wanted: Component) : Mishap() { dyeColor(DyeColor.BROWN) override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - item.deltaMovement = item.deltaMovement.add((Math.random() - 0.5) * 0.05, 0.75, (Math.random() - 0.5) * 0.05) + item.deltaMovement = + item.deltaMovement.add((Math.random() - 0.5) * 0.05, 0.75, (Math.random() - 0.5) * 0.05) } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item.item.isEmpty) - error("no_item", wanted) - else - error("bad_item", wanted, item.item.count, item.item.displayName) + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = + if (item.item.isEmpty) error("no_item", wanted) + else error("bad_item", wanted, item.item.count, item.item.displayName) companion object { @JvmStatic diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt index d35104dab4..0918d44575 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt @@ -5,7 +5,6 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component -import net.minecraft.world.InteractionHand import net.minecraft.world.item.DyeColor import net.minecraft.world.item.ItemStack @@ -17,15 +16,15 @@ class MishapBadOffhandItem(val item: ItemStack?, val wanted: Component) : Mishap env.mishapEnvironment.dropHeldItems() } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item?.isEmpty == false) - error("bad_item.offhand", wanted, item.count, item.displayName) - else - error("no_item.offhand", wanted) + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = + if (item?.isEmpty == false) error("bad_item.offhand", wanted, item.count, item.displayName) + else error("no_item.offhand", wanted) companion object { @JvmStatic fun of(item: ItemStack?, stub: String, vararg args: Any): MishapBadOffhandItem { - return MishapBadOffhandItem(item, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args)) + return MishapBadOffhandItem( + item, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args)) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt index d3118e5590..904692d11f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDisallowedSpell.kt @@ -16,6 +16,5 @@ class MishapDisallowedSpell(val type: String = "disallowed") : Mishap() { // NO-OP } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error(type) + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error(type) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt index 98050ee244..0b0972516b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt @@ -11,7 +11,11 @@ import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor import net.minecraft.world.phys.Vec3 -class MishapDivideByZero(val operand1: Component, val operand2: Component, val suffix: String = "divide") : Mishap() { +class MishapDivideByZero( + val operand1: Component, + val operand2: Component, + val suffix: String = "divide" +) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.RED) @@ -30,8 +34,10 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s @JvmStatic fun of(operand1: Double, operand2: Double, suffix: String = "divide"): MishapDivideByZero { if (suffix == "exponent") - return MishapDivideByZero(translate(DoubleIota(operand1)), powerOf(DoubleIota(operand2)), suffix) - return MishapDivideByZero(translate(DoubleIota(operand1)), translate(DoubleIota(operand2)), suffix) + return MishapDivideByZero( + translate(DoubleIota(operand1)), powerOf(DoubleIota(operand2)), suffix) + return MishapDivideByZero( + translate(DoubleIota(operand1)), translate(DoubleIota(operand2)), suffix) } @JvmStatic @@ -45,9 +51,8 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s fun tan(angle: Double): MishapDivideByZero { val translatedAngle = translate(DoubleIota(angle)) return MishapDivideByZero( - "$PREFIX.sin".asTranslatedComponent(translatedAngle), - "$PREFIX.cos".asTranslatedComponent(translatedAngle) - ) + "$PREFIX.sin".asTranslatedComponent(translatedAngle), + "$PREFIX.cos".asTranslatedComponent(translatedAngle)) } @JvmStatic @@ -55,8 +60,7 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s val translatedAngle = translate(angle) return MishapDivideByZero( "$PREFIX.sin".asTranslatedComponent(translatedAngle), - "$PREFIX.cos".asTranslatedComponent(translatedAngle) - ) + "$PREFIX.cos".asTranslatedComponent(translatedAngle)) } @JvmStatic @@ -71,20 +75,21 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s val zeroVector get() = "$PREFIX.zero.vec".asTranslatedComponent - @JvmStatic - fun powerOf(power: Component) = "$PREFIX.power".asTranslatedComponent(power) + @JvmStatic fun powerOf(power: Component) = "$PREFIX.power".asTranslatedComponent(power) @JvmStatic - fun powerOf(datum: Iota): Component = when { - datum is DoubleIota && datum.double == 0.0 -> zerothPower - else -> datum.display() - } + fun powerOf(datum: Iota): Component = + when { + datum is DoubleIota && datum.double == 0.0 -> zerothPower + else -> datum.display() + } @JvmStatic - fun translate(datum: Iota): Component = when { - datum is DoubleIota && datum.double == 0.0 -> zero - datum is Vec3Iota && datum.vec3 == Vec3.ZERO -> zeroVector - else -> datum.display() - } + fun translate(datum: Iota): Component = + when { + datum is DoubleIota && datum.double == 0.0 -> zero + datum is Vec3Iota && datum.vec3 == Vec3.ZERO -> zeroVector + else -> datum.display() + } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt index 24ecda81e8..acd486ab14 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooMuch.kt @@ -13,6 +13,5 @@ class MishapEvalTooMuch : Mishap() { env.mishapEnvironment.drown() } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("eval_too_deep") + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("eval_too_deep") } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt index 17e71d6044..425488c168 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidIota.kt @@ -8,26 +8,18 @@ import at.petrak.hexcasting.api.utils.asTranslatedComponent import net.minecraft.network.chat.Component import net.minecraft.world.item.DyeColor -/** - * The value failed some kind of predicate. - */ -class MishapInvalidIota( - val perpetrator: Iota, - val reverseIdx: Int, - val expected: Component -) : Mishap() { +/** The value failed some kind of predicate. */ +class MishapInvalidIota(val perpetrator: Iota, val reverseIdx: Int, val expected: Component) : + Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { - stack[stack.size - 1 - reverseIdx] = GarbageIota(); + stack[stack.size - 1 - reverseIdx] = GarbageIota() } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error( - "invalid_value", expected, reverseIdx, - perpetrator.display() - ) + error("invalid_value", expected, reverseIdx, perpetrator.display()) companion object { @JvmStatic @@ -36,9 +28,15 @@ class MishapInvalidIota( } @JvmStatic - fun of(perpetrator: Iota, reverseIdx: Int, name: String, vararg translations: Any): MishapInvalidIota { + fun of( + perpetrator: Iota, + reverseIdx: Int, + name: String, + vararg translations: Any + ): MishapInvalidIota { val key = "hexcasting.mishap.invalid_value.$name" - return MishapInvalidIota(perpetrator, reverseIdx, key.asTranslatedComponent(*translations)) + return MishapInvalidIota( + perpetrator, reverseIdx, key.asTranslatedComponent(*translations)) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt index a16c083f4c..85cc938fd0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidOperatorArgs.kt @@ -9,9 +9,7 @@ import net.minecraft.network.chat.Component import net.minecraft.network.chat.ComponentUtils import net.minecraft.world.item.DyeColor -/** - * The value failed some kind of predicate. - */ +/** The value failed some kind of predicate. */ class MishapInvalidOperatorArgs(val perpetrators: List) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) @@ -24,19 +22,14 @@ class MishapInvalidOperatorArgs(val perpetrators: List) : Mishap() { override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component { return if (perpetrators.size == 1) { - error( - "invalid_operator_args.one", - 0, - perpetrators[0].display() - ) + error("invalid_operator_args.one", 0, perpetrators[0].display()) } else { error( "invalid_operator_args.many", perpetrators.size, 0, perpetrators.lastIndex, - ComponentUtils.formatList(perpetrators.map { it.display() }, ", ".asTextComponent) - ) + ComponentUtils.formatList(perpetrators.map { it.display() }, ", ".asTextComponent)) } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt index 20fbd31fb5..93cda6d5e2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidPattern.kt @@ -17,6 +17,5 @@ class MishapInvalidPattern : Mishap() { stack.add(GarbageIota()) } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("invalid_pattern") + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("invalid_pattern") } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt index 92384b0792..3e315abc96 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInvalidSpellDatumType.kt @@ -5,9 +5,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment import net.minecraft.world.item.DyeColor -/** - * this is bad - */ +/** this is bad */ class MishapInvalidSpellDatumType(val perpetrator: Any) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLACK) @@ -17,5 +15,8 @@ class MishapInvalidSpellDatumType(val perpetrator: Any) : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("invalid_spell_datum_type", this.perpetrator.toString(), this.perpetrator.javaClass.typeName) + error( + "invalid_spell_datum_type", + this.perpetrator.toString(), + this.perpetrator.javaClass.typeName) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt index 2d0e721838..c39095d6e8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationInWrongDimension.kt @@ -18,7 +18,7 @@ class MishapLocationInWrongDimension(val properDimension: ResourceLocation) : Mi override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = error( - "wrong_dimension", properDimension.toString(), - ctx.world.dimension().location().toString() - ) + "wrong_dimension", + properDimension.toString(), + ctx.world.dimension().location().toString()) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt index 646f42c927..029c7fb01f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughArgs.kt @@ -15,8 +15,5 @@ class MishapNotEnoughArgs(val expected: Int, val got: Int) : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - if (got == 0) - error("no_args", expected) - else - error("not_enough_args", expected, got) + if (got == 0) error("no_args", expected) else error("not_enough_args", expected, got) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt index 07d686b56e..df1a9eff9d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNotEnoughMedia.kt @@ -17,5 +17,6 @@ class MishapNotEnoughMedia(private val cost: Long) : Mishap() { env.extractMedia(cost, false) } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = "hexcasting.message.cant_overcast".asTranslatedComponent -} \ No newline at end of file + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = + "hexcasting.message.cant_overcast".asTranslatedComponent +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt index e6ea0326ed..3fd0144333 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt @@ -3,14 +3,11 @@ package at.petrak.hexcasting.api.casting.mishaps import at.petrak.hexcasting.api.casting.eval.CastingEnvironment import at.petrak.hexcasting.api.casting.iota.EntityIota import at.petrak.hexcasting.api.casting.iota.Iota -import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.pigment.FrozenPigment import net.minecraft.world.entity.player.Player import net.minecraft.world.item.DyeColor -/** - * Also throwable for your *own* name, for cases like Chronicler's Gambit - */ +/** Also throwable for your *own* name, for cases like Chronicler's Gambit */ class MishapOthersName(val confidant: Player) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.BLACK) @@ -21,10 +18,8 @@ class MishapOthersName(val confidant: Player) : Mishap() { } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - if (this.confidant == ctx.castingEntity) - error("others_name.self") - else - error("others_name", confidant.name) + if (this.confidant == ctx.castingEntity) error("others_name.self") + else error("others_name", confidant.name) companion object { /** @@ -39,11 +34,12 @@ class MishapOthersName(val confidant: Player) : Mishap() { while (poolToSearch.isNotEmpty()) { val datumToCheck = poolToSearch.removeFirst() - if (datumToCheck is EntityIota && datumToCheck.entity is Player && datumToCheck.entity != caster) + if (datumToCheck is EntityIota && + datumToCheck.entity is Player && + datumToCheck.entity != caster) return datumToCheck.entity as Player val datumSubIotas = datumToCheck.subIotas() - if (datumSubIotas != null) - poolToSearch.addAll(datumSubIotas) + if (datumSubIotas != null) poolToSearch.addAll(datumSubIotas) } return null diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt index 571e39bcd9..02f438b668 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapStackSize.kt @@ -5,7 +5,6 @@ import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType import at.petrak.hexcasting.api.casting.iota.GarbageIota import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment -import at.petrak.hexcasting.common.lib.HexDamageTypes import net.minecraft.world.item.DyeColor class MishapStackSize() : Mishap() { @@ -19,6 +18,5 @@ class MishapStackSize() : Mishap() { stack.add(GarbageIota()) } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("stack_size") + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("stack_size") } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt index dfa159bda7..face3ec8bc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapTooManyCloseParens.kt @@ -12,8 +12,7 @@ class MishapTooManyCloseParens : Mishap() { override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { // TODO this is a kinda shitty mishap - if (errorCtx.pattern != null) - stack.add(PatternIota(errorCtx.pattern)) + if (errorCtx.pattern != null) stack.add(PatternIota(errorCtx.pattern)) } override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt index e0dde2150b..abd5037317 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnenlightened.kt @@ -19,11 +19,13 @@ class MishapUnenlightened : Mishap() { override fun execute(env: CastingEnvironment, errorCtx: Context, stack: MutableList) { env.mishapEnvironment.dropHeldItems() - env.castingEntity?.sendSystemMessage("hexcasting.message.cant_great_spell".asTranslatedComponent) + env.castingEntity?.sendSystemMessage( + "hexcasting.message.cant_great_spell".asTranslatedComponent) // add some non-zero level of juice I guess val pos = env.mishapSprayPos() - env.world.playSound(null, pos.x, pos.y, pos.z, SoundEvents.GLASS_BREAK, SoundSource.PLAYERS, 0.5f, 0.7f) + env.world.playSound( + null, pos.x, pos.y, pos.z, SoundEvents.GLASS_BREAK, SoundSource.PLAYERS, 0.5f, 0.7f) val castingPlayer = env.castingEntity as? ServerPlayer if (castingPlayer != null) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt index 6a30a8221e..f566318bd4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapUnescapedValue.kt @@ -5,12 +5,8 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.pigment.FrozenPigment import net.minecraft.world.item.DyeColor -/** - * The value was a naked iota without being Considered or Retrospected. - */ -class MishapUnescapedValue( - val perpetrator: Iota -) : Mishap() { +/** The value was a naked iota without being Considered or Retrospected. */ +class MishapUnescapedValue(val perpetrator: Iota) : Mishap() { override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenPigment = dyeColor(DyeColor.GRAY) diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt index ae27403f23..d339dce20d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixEmptyStack.kt @@ -21,4 +21,4 @@ class MishapBoolDirectrixEmptyStack( override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = error("circle.bool_directrix.empty_stack", pos.toShortString()) -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt index 7c3d7b1fb5..38a308b9b4 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapBoolDirectrixNotBool.kt @@ -22,4 +22,4 @@ class MishapBoolDirectrixNotBool( override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component = error("circle.bool_directrix_no_bool", pos.toShortString(), perpetrator.display()) -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt index 9eeae0f2b5..ad87bec3a0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/circle/MishapNoSpellCircle.kt @@ -15,7 +15,11 @@ class MishapNoSpellCircle : Mishap() { dyeColor(DyeColor.LIGHT_BLUE) // FIXME: make me work with any entity and not just players - private inline fun dropAll(player: Player, stacks: MutableList, filter: (ItemStack) -> Boolean = { true }) { + private inline fun dropAll( + player: Player, + stacks: MutableList, + filter: (ItemStack) -> Boolean = { true } + ) { for (index in stacks.indices) { val item = stacks[index] if (!item.isEmpty && filter(item)) { @@ -31,12 +35,9 @@ class MishapNoSpellCircle : Mishap() { // FIXME: handle null caster case dropAll(caster, caster.inventory.items) dropAll(caster, caster.inventory.offhand) - dropAll(caster, caster.inventory.armor) { - !EnchantmentHelper.hasBindingCurse(it) - } + dropAll(caster, caster.inventory.armor) { !EnchantmentHelper.hasBindingCurse(it) } } } - override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = - error("no_spell_circle") + override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = error("no_spell_circle") } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt index 249adc092b..987391e0e2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientCastingStack.kt @@ -3,7 +3,6 @@ package at.petrak.hexcasting.api.client import at.petrak.hexcasting.api.casting.math.HexPattern import kotlin.math.min - class ClientCastingStack { private var patterns = ArrayList() private var toRemove = mutableSetOf() @@ -12,7 +11,9 @@ class ClientCastingStack { fun addPattern(pattern: HexPattern?, lifetime: Int) { if (pattern == null) return - if (patterns.stream().anyMatch { patternRenderHolder -> patternRenderHolder.pattern.hashCode() == pattern.hashCode() }) { + if (patterns.stream().anyMatch { patternRenderHolder -> + patternRenderHolder.pattern.hashCode() == pattern.hashCode() + }) { return } if (patterns.size > 100) { @@ -58,4 +59,4 @@ class ClientCastingStack { patterns.removeAll(toRemove) toRemove.clear() } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt index 374e89c932..261be98f6e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/ClientRenderHelper.kt @@ -1,4 +1,5 @@ @file:JvmName("ClientRenderHelper") + package at.petrak.hexcasting.api.client import at.petrak.hexcasting.client.ClientTickCounter @@ -11,14 +12,13 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.PoseStack import com.mojang.math.Axis -import net.minecraft.client.renderer.GameRenderer -import net.minecraft.world.entity.player.Player -import net.minecraft.world.phys.Vec2 import kotlin.math.abs import kotlin.math.cos import kotlin.math.floor import kotlin.math.sin - +import net.minecraft.client.renderer.GameRenderer +import net.minecraft.world.entity.player.Player +import net.minecraft.world.phys.Vec2 fun renderCastingStack(ps: PoseStack, player: Player, pticks: Float) { val stack = IClientXplatAbstractions.INSTANCE.getClientCastingStack(player) @@ -30,9 +30,20 @@ fun renderCastingStack(ps: PoseStack, player: Player, pticks: Float) { val lifetimeOffset = if (lifetime <= 5f) (5f - lifetime) / 5f else 0f ps.pushPose() - ps.mulPose(Axis.YP.rotationDegrees(((player.level().gameTime + pticks) * (sin(k * 12.543565f) * 3.4f) * (k / 12.43f) % 360 + (1 + k) * 45f))) - ps.translate(0.0, 1 + sin(k.toDouble()) * 0.75, 0.75 + cos((k / 8.0)) * 0.25 + cos((player.level().gameTime + pticks) / (7 + k / 4)) * 0.065) - ps.scale(1 / 24f * (1 - lifetimeOffset), 1 / 24f * (1 - lifetimeOffset), 1 / 24f * (1 - lifetimeOffset)) + ps.mulPose( + Axis.YP.rotationDegrees( + ((player.level().gameTime + pticks) * (sin(k * 12.543565f) * 3.4f) * (k / 12.43f) % + 360 + (1 + k) * 45f))) + ps.translate( + 0.0, + 1 + sin(k.toDouble()) * 0.75, + 0.75 + + cos((k / 8.0)) * 0.25 + + cos((player.level().gameTime + pticks) / (7 + k / 4)) * 0.065) + ps.scale( + 1 / 24f * (1 - lifetimeOffset), + 1 / 24f * (1 - lifetimeOffset), + 1 / 24f * (1 - lifetimeOffset)) ps.translate(0.0, floor((k / 8.0)), 0.0) ps.translate(0.0, sin((player.level().gameTime + pticks) / (7.0 + k / 8.0)), 0.0) @@ -64,12 +75,23 @@ fun renderCastingStack(ps: PoseStack, player: Player, pticks: Float) { val variance = 0.65f val speed = 0.1f val stupidHash = player.hashCode().toDouble() - val zappy: List = makeZappy(lines2, findDupIndices(pattern.positions()), - 5, variance, speed, 0.2f, 0f, - 1f, stupidHash) - val outer: Int = IXplatAbstractions.INSTANCE.getPigment(player).colorProvider.getColor( - ClientTickCounter.getTotal() / 2f, - patternRenderHolder.getColourPos(player.random)) + val zappy: List = + makeZappy( + lines2, + findDupIndices(pattern.positions()), + 5, + variance, + speed, + 0.2f, + 0f, + 1f, + stupidHash) + val outer: Int = + IXplatAbstractions.INSTANCE.getPigment(player) + .colorProvider + .getColor( + ClientTickCounter.getTotal() / 2f, + patternRenderHolder.getColourPos(player.random)) val rgbOnly = outer and 0x00FFFFFF var newAlpha = outer ushr 24 if (lifetime <= 60) { @@ -83,4 +105,4 @@ fun renderCastingStack(ps: PoseStack, player: Player, pticks: Float) { RenderSystem.setShader { oldShader } RenderSystem.enableCull() } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt b/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt index 3092f3727a..8c9b25a2cf 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/HexPatternRenderHolder.kt @@ -8,12 +8,16 @@ data class HexPatternRenderHolder(val pattern: HexPattern, var lifetime: Int) { private var colourPos: Vec3? = null fun getColourPos(random: RandomSource): Vec3 { - return colourPos ?: let { - Vec3(random.nextDouble(), random.nextDouble(), random.nextDouble()).normalize().scale(3.0).also { colourPos = it } - } + return colourPos + ?: let { + Vec3(random.nextDouble(), random.nextDouble(), random.nextDouble()) + .normalize() + .scale(3.0) + .also { colourPos = it } + } } fun tick() { lifetime -= 1 } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java b/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java index da72b78b42..8906596997 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/client/ScryingLensOverlayRegistry.java @@ -2,9 +2,9 @@ import com.google.common.collect.Lists; import com.mojang.datafixers.util.Pair; + import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -13,6 +13,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; + import org.jetbrains.annotations.NotNull; import java.util.List; @@ -22,13 +23,15 @@ /** * Use this to make things display when the player looks at things with a Scrying Lens. - *

- * Client-side only. + * + *

Client-side only. */ public final class ScryingLensOverlayRegistry { - private static final ConcurrentMap ID_LOOKUP = new ConcurrentHashMap<>(); + private static final ConcurrentMap ID_LOOKUP = + new ConcurrentHashMap<>(); // vectors are thread-safe! - private static final List> PREDICATE_LOOKUP = new Vector<>(); + private static final List> PREDICATE_LOOKUP = + new Vector<>(); /** * Add the block to display things when the player is holding a lens and looking at it. @@ -53,20 +56,17 @@ public static void addDisplayer(ResourceLocation blockID, OverlayBuilder display /** * Display things when the player is holding a lens and looking at some block via a predicate. - *

- * These have a lower priority than the standard ID-based displays, so if an ID and predicate both match, - * this won't be displayed. + * + *

These have a lower priority than the standard ID-based displays, so if an ID and predicate + * both match, this won't be displayed. */ public static void addPredicateDisplayer(OverlayPredicate predicate, OverlayBuilder displayer) { PREDICATE_LOOKUP.add(new Pair<>(predicate, displayer)); } - /** - * Internal use only. - */ - public static @NotNull List> getLines(BlockState state, BlockPos pos, - Player observer, Level world, - Direction hitFace) { + /** Internal use only. */ + public static @NotNull List> getLines( + BlockState state, BlockPos pos, Player observer, Level world, Direction hitFace) { List> lines = Lists.newArrayList(); var idLookedup = ID_LOOKUP.get(BuiltInRegistries.BLOCK.getKey(state.getBlock())); if (idLookedup != null) { @@ -84,24 +84,24 @@ public static void addPredicateDisplayer(OverlayPredicate predicate, OverlayBuil /** * Return the lines displayed by the cursor: an item and some text. - *

- * The ItemStack can be empty; if it is, the text isn't shifted over for it. + * + *

The ItemStack can be empty; if it is, the text isn't shifted over for it. */ @FunctionalInterface public interface OverlayBuilder { - void addLines(List> lines, - BlockState state, BlockPos pos, Player observer, - Level world, - Direction hitFace); + void addLines( + List> lines, + BlockState state, + BlockPos pos, + Player observer, + Level world, + Direction hitFace); } - /** - * Predicate for matching on a block state. - */ + /** Predicate for matching on a block state. */ @FunctionalInterface public interface OverlayPredicate { - boolean test(BlockState state, BlockPos pos, Player observer, - Level world, - Direction hitFace); + boolean test( + BlockState state, BlockPos pos, Player observer, Level world, Direction hitFace); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java index a27ef900f1..780ee6860a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java @@ -2,8 +2,10 @@ import at.petrak.hexcasting.api.casting.iota.Iota; import at.petrak.hexcasting.api.pigment.FrozenPigment; + import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; + import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -11,9 +13,9 @@ /** * Items which can cast a packaged Hex can implement this interface. - *

- * On both the Forge and Fabric sides, the registry will be scanned for all items which implement this interface, - * and the appropriate cap/CC will be attached. + * + *

On both the Forge and Fabric sides, the registry will be scanned for all items which implement + * this interface, and the appropriate cap/CC will be attached. */ @ApiStatus.OverrideOnly public interface HexHolderItem extends MediaHolderItem { @@ -29,5 +31,6 @@ public interface HexHolderItem extends MediaHolderItem { void clearHex(ItemStack stack); - @Nullable FrozenPigment getPigment(ItemStack stack); + @Nullable + FrozenPigment getPigment(ItemStack stack); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java index c312383129..ad772f78f7 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/IotaHolderItem.java @@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.utils.NBTHelper; import at.petrak.hexcasting.client.ClientTickCounter; import at.petrak.hexcasting.common.lib.hex.HexIotaTypes; + import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; @@ -15,22 +16,24 @@ import net.minecraft.util.Mth; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; + import org.jetbrains.annotations.Nullable; import java.util.List; /** * Items that store an iota to their tag can implement this interface. - *

- * On both the Forge and Fabric sides, the registry will be scanned for all items which implement this interface, - * and the appropriate cap/CC will be attached. + * + *

On both the Forge and Fabric sides, the registry will be scanned for all items which implement + * this interface, and the appropriate cap/CC will be attached. */ public interface IotaHolderItem { /** - * If this key is set on the item, we ignore the rest of the item and render this as if it were of the - * {@link at.petrak.hexcasting.api.casting.iota.IotaType IotaType} given by the resource location. - *

- * This is not useful to the player at all. + * If this key is set on the item, we ignore the rest of the item and render this as if it were + * of the {@link at.petrak.hexcasting.api.casting.iota.IotaType IotaType} given by the resource + * location. + * + *

This is not useful to the player at all. */ String TAG_OVERRIDE_VISUALLY = "VisualOverride"; @@ -41,7 +44,8 @@ public interface IotaHolderItem { default Iota readIota(ItemStack stack, ServerLevel world) { if (!(stack.getItem() instanceof IotaHolderItem dh)) { // this should be checked via mishap beforehand - throw new IllegalArgumentException("stack's item must be an IotaHolderItem but was " + stack.getItem()); + throw new IllegalArgumentException( + "stack's item must be an IotaHolderItem but was " + stack.getItem()); } var tag = dh.readIotaTag(stack); @@ -52,9 +56,7 @@ default Iota readIota(ItemStack stack, ServerLevel world) { } } - /** - * What is this considered to contain when nothing can be read? - */ + /** What is this considered to contain when nothing can be read? */ @Nullable default Iota emptyIota(ItemStack stack) { return null; @@ -74,7 +76,8 @@ default int getColor(ItemStack stack) { } } - return 0xFF000000 | Mth.hsvToRgb(ClientTickCounter.getTotal() * 2 % 360 / 360F, 0.75F, 1F); + return 0xFF000000 + | Mth.hsvToRgb(ClientTickCounter.getTotal() * 2 % 360 / 360F, 0.75F, 1F); } var tag = this.readIotaTag(stack); @@ -90,18 +93,14 @@ default int getColor(ItemStack stack) { */ boolean writeable(ItemStack stack); - /** - * Write {@code null} to indicate erasing - */ + /** Write {@code null} to indicate erasing */ boolean canWrite(ItemStack stack, @Nullable Iota iota); - /** - * Write {@code null} to indicate erasing - */ + /** Write {@code null} to indicate erasing */ void writeDatum(ItemStack stack, @Nullable Iota iota); - static void appendHoverText(IotaHolderItem self, ItemStack stack, List components, - TooltipFlag flag) { + static void appendHoverText( + IotaHolderItem self, ItemStack stack, List components, TooltipFlag flag) { var datumTag = self.readIotaTag(stack); if (datumTag != null) { var cmp = IotaType.getDisplay(datumTag); @@ -111,8 +110,11 @@ static void appendHoverText(IotaHolderItem self, ItemStack stack, List - * On both the Forge and Fabric sides, the registry will be scanned for all items which implement this interface, - * and the appropriate cap/CC will be attached. + * + *

On both the Forge and Fabric sides, the registry will be scanned for all items which implement + * this interface, and the appropriate cap/CC will be attached. */ @ApiStatus.OverrideOnly public interface MediaHolderItem { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/PigmentItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/PigmentItem.java index 06829c4b16..c3e4335fd0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/PigmentItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/PigmentItem.java @@ -1,16 +1,18 @@ package at.petrak.hexcasting.api.item; import at.petrak.hexcasting.api.pigment.ColorProvider; + import net.minecraft.world.item.ItemStack; + import org.jetbrains.annotations.ApiStatus; import java.util.UUID; /** * Items which can be used as a colorizer can implement this interface. - *

- * On both the Forge and Fabric sides, the registry will be scanned for all items which implement this interface, - * and the appropriate cap/CC will be attached. + * + *

On both the Forge and Fabric sides, the registry will be scanned for all items which implement + * this interface, and the appropriate cap/CC will be attached. */ @ApiStatus.OverrideOnly public interface PigmentItem { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java index 6bdca2d2d7..8312b3975c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/VariantItem.java @@ -1,13 +1,15 @@ package at.petrak.hexcasting.api.item; import at.petrak.hexcasting.api.utils.NBTHelper; + import net.minecraft.world.item.ItemStack; /** - * Items that have multiple different otherwise identical visual variants can implement this interface. - *

- * On both the Forge and Fabric sides, the registry will be scanned for all items which implement this interface, - * and the appropriate cap/CC will be attached. + * Items that have multiple different otherwise identical visual variants can implement this + * interface. + * + *

On both the Forge and Fabric sides, the registry will be scanned for all items which implement + * this interface, and the appropriate cap/CC will be attached. */ public interface VariantItem { String TAG_VARIANT = "variant"; @@ -23,10 +25,8 @@ default void setVariant(ItemStack stack, int variant) { } default int clampVariant(int variant) { - if (variant < 0) - return 0; - if (variant >= numVariants()) - return numVariants() - 1; + if (variant < 0) return 0; + if (variant >= numVariants()) return numVariants() - 1; return variant; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/DiscoveryHandlers.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/DiscoveryHandlers.java index d94f526066..0da8c62bee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/DiscoveryHandlers.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/misc/DiscoveryHandlers.java @@ -8,7 +8,8 @@ import java.util.function.BiFunction; public class DiscoveryHandlers { - private static final List> DEBUG_DISCOVERER = new ArrayList<>(); + private static final List> DEBUG_DISCOVERER = + new ArrayList<>(); public static ItemStack findDebugItem(Player player, String type) { for (var discoverer : DEBUG_DISCOVERER) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/Result.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/Result.java index 3dfcc73c23..e669f7d936 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/Result.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/misc/Result.java @@ -5,9 +5,7 @@ import java.util.function.Consumer; import java.util.function.Function; -/** - * I'm sick and tired of not having a result class god dammit - */ +/** I'm sick and tired of not having a result class god dammit */ public abstract sealed class Result { public static final class Ok extends Result { public final T ok; @@ -61,15 +59,14 @@ public Result match(Function okBranch, Function e public void matchVoid(Consumer okBranch, Consumer errBranch) { this.match( - ok -> { - okBranch.accept(ok); - return Unit.INSTANCE; - }, - err -> { - errBranch.accept(err); - return Unit.INSTANCE; - } - ); + ok -> { + okBranch.accept(ok); + return Unit.INSTANCE; + }, + err -> { + errBranch.accept(err); + return Unit.INSTANCE; + }); } public U collapse(Function okBranch, Function errBranch) { diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/TriPredicate.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/TriPredicate.java index 04f70220ee..f15e772918 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/TriPredicate.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/misc/TriPredicate.java @@ -1,8 +1,6 @@ package at.petrak.hexcasting.api.misc; -/** - * Society if java actually had first-class function support - */ +/** Society if java actually had first-class function support */ @FunctionalInterface public interface TriPredicate { boolean test(A a, B b, C c); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java index 19458cbc8e..bf439c8229 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexConfig.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.api.misc.MediaConstants; + import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Tier; @@ -35,7 +36,6 @@ public interface CommonConfigAccess { int DEFAULT_CYPHER_COOLDOWN = 8; int DEFAULT_TRINKET_COOLDOWN = 5; int DEFAULT_ARTIFACT_COOLDOWN = 3; - } public interface ClientConfigAccess { @@ -57,7 +57,8 @@ public interface ClientConfigAccess { } public interface ServerConfigAccess { - int opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort(); + int + opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort(); int maxOpCount(); @@ -69,7 +70,8 @@ public interface ServerConfigAccess { boolean doVillagersTakeOffenseAtMindMurder(); - // fun fact, although dimension keys are a RegistryHolder, they aren't a registry, so i can't do tags + // fun fact, although dimension keys are a RegistryHolder, they aren't a registry, so i + // can't do tags boolean canTeleportInThisDimension(ResourceKey dimension); boolean trueNameHasAmbit(); @@ -85,7 +87,8 @@ public interface ServerConfigAccess { boolean DEFAULT_TRUE_NAME_HAS_AMBIT = true; default Tier opBreakHarvestLevel() { - return switch (this.opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort()) { + return switch (this + .opBreakHarvestLevelBecauseForgeThoughtItWasAGoodIdeaToImplementHarvestTiersUsingAnHonestToGodTopoSort()) { case 0 -> Tiers.WOOD; case 1 -> Tiers.STONE; case 2 -> Tiers.IRON; @@ -113,7 +116,8 @@ public static boolean noneMatch(List keys, ResourceLocation ke return !anyMatch(keys, key); } - public static boolean anyMatchResLoc(List keys, ResourceLocation key) { + public static boolean anyMatchResLoc( + List keys, ResourceLocation key) { return keys.stream().anyMatch(key::equals); } @@ -136,24 +140,30 @@ public static ServerConfigAccess server() { public static void setCommon(CommonConfigAccess access) { if (common != null) { - HexAPI.LOGGER.warn("CommonConfigAccess was replaced! Old {} New {}", - common.getClass().getName(), access.getClass().getName()); + HexAPI.LOGGER.warn( + "CommonConfigAccess was replaced! Old {} New {}", + common.getClass().getName(), + access.getClass().getName()); } common = access; } public static void setClient(ClientConfigAccess access) { if (client != null) { - HexAPI.LOGGER.warn("ClientConfigAccess was replaced! Old {} New {}", - client.getClass().getName(), access.getClass().getName()); + HexAPI.LOGGER.warn( + "ClientConfigAccess was replaced! Old {} New {}", + client.getClass().getName(), + access.getClass().getName()); } client = access; } public static void setServer(ServerConfigAccess access) { if (server != null) { - HexAPI.LOGGER.warn("ServerConfigAccess was replaced! Old {} New {}", - server.getClass().getName(), access.getClass().getName()); + HexAPI.LOGGER.warn( + "ServerConfigAccess was replaced! Old {} New {}", + server.getClass().getName(), + access.getClass().getName()); } server = access; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java index fd38fdc7bb..e0b16fbbbe 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexStatistics.java @@ -1,21 +1,32 @@ package at.petrak.hexcasting.api.mod; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.api.misc.MediaConstants; + import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.stats.StatFormatter; import net.minecraft.stats.Stats; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - public class HexStatistics { - public static final ResourceLocation MEDIA_USED = makeCustomStat("media_used", - mediamount -> StatFormatter.DEFAULT.format((int) (mediamount / MediaConstants.DUST_UNIT))); - public static final ResourceLocation MEDIA_OVERCAST = makeCustomStat("media_overcast", - mediamount -> StatFormatter.DEFAULT.format((int) (mediamount / MediaConstants.DUST_UNIT))); - public static final ResourceLocation PATTERNS_DRAWN = makeCustomStat("patterns_drawn", StatFormatter.DEFAULT); - public static final ResourceLocation SPELLS_CAST = makeCustomStat("spells_cast", StatFormatter.DEFAULT); + public static final ResourceLocation MEDIA_USED = + makeCustomStat( + "media_used", + mediamount -> + StatFormatter.DEFAULT.format( + (int) (mediamount / MediaConstants.DUST_UNIT))); + public static final ResourceLocation MEDIA_OVERCAST = + makeCustomStat( + "media_overcast", + mediamount -> + StatFormatter.DEFAULT.format( + (int) (mediamount / MediaConstants.DUST_UNIT))); + public static final ResourceLocation PATTERNS_DRAWN = + makeCustomStat("patterns_drawn", StatFormatter.DEFAULT); + public static final ResourceLocation SPELLS_CAST = + makeCustomStat("spells_cast", StatFormatter.DEFAULT); public static void register() { // wake up java diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java index 238afae719..6a66ce0e86 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexTags.java @@ -1,7 +1,10 @@ package at.petrak.hexcasting.api.mod; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.api.casting.ActionRegistryEntry; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; @@ -9,20 +12,20 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - public class HexTags { public static final class Items { public static final TagKey EDIFIED_LOGS = create("edified_logs"); public static final TagKey EDIFIED_PLANKS = create("edified_planks"); public static final TagKey STAVES = create("staves"); public static final TagKey PHIAL_BASE = create("phial_base"); - public static final TagKey GRANTS_ROOT_ADVANCEMENT = create("grants_root_advancement"); + public static final TagKey GRANTS_ROOT_ADVANCEMENT = + create("grants_root_advancement"); public static final TagKey SEAL_MATERIALS = create("seal_materials"); public static final TagKey IMPETI = create("impeti"); public static final TagKey DIRECTRICES = create("directrices"); - public static final TagKey MINDFLAYED_CIRCLE_COMPONENTS = create("brainswept_circle_components"); + public static final TagKey MINDFLAYED_CIRCLE_COMPONENTS = + create("brainswept_circle_components"); public static TagKey create(String name) { return create(modLoc(name)); @@ -37,10 +40,10 @@ public static final class Blocks { public static final TagKey EDIFIED_LOGS = create("edified_logs"); public static final TagKey EDIFIED_PLANKS = create("edified_planks"); - public static final TagKey IMPETI = create("impeti"); public static final TagKey DIRECTRICES = create("directrices"); - public static final TagKey MINDFLAYED_CIRCLE_COMPONENTS = create("brainswept_circle_components"); + public static final TagKey MINDFLAYED_CIRCLE_COMPONENTS = + create("brainswept_circle_components"); // Used to determine what blocks should be replaced with air by OpDestroyFluid public static final TagKey WATER_PLANTS = create("water_plants"); @@ -65,22 +68,23 @@ public static TagKey> create(String name) { public static final class Actions { /** - * Actions with this tag can't be used until the caster is enlightened and send the - * "am I not skilled enough" message + * Actions with this tag can't be used until the caster is enlightened and send the "am I + * not skilled enough" message */ - public static final TagKey REQUIRES_ENLIGHTENMENT = create("requires_enlightenment"); - /** - * Actions where the pattern is calculated per-world - */ - public static final TagKey PER_WORLD_PATTERN = create("per_world_pattern"); + public static final TagKey REQUIRES_ENLIGHTENMENT = + create("requires_enlightenment"); - /** - * Actions that can cause Blind Diversion - */ - public static final TagKey CAN_START_ENLIGHTEN = create("can_start_enlighten"); + /** Actions where the pattern is calculated per-world */ + public static final TagKey PER_WORLD_PATTERN = + create("per_world_pattern"); + + /** Actions that can cause Blind Diversion */ + public static final TagKey CAN_START_ENLIGHTEN = + create("can_start_enlighten"); public static TagKey create(String name) { - return TagKey.create(IXplatAbstractions.INSTANCE.getActionRegistry().key(), modLoc(name)); + return TagKey.create( + IXplatAbstractions.INSTANCE.getActionRegistry().key(), modLoc(name)); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/pigment/ColorProvider.java b/Common/src/main/java/at/petrak/hexcasting/api/pigment/ColorProvider.java index 8c0611db2e..f781ea6ad3 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/pigment/ColorProvider.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/pigment/ColorProvider.java @@ -1,13 +1,12 @@ package at.petrak.hexcasting.api.pigment; import at.petrak.hexcasting.api.addldata.ADPigment; + import net.minecraft.util.FastColor; import net.minecraft.world.phys.Vec3; public abstract class ColorProvider { - /** - * Implers, impl this function - */ + /** Implers, impl this function */ protected abstract int getRawColor(float time, Vec3 position); private static final int[] MINIMUM_LUMINANCE_COLOR_WHEEL = { @@ -17,7 +16,7 @@ public abstract class ColorProvider { /** * Gets a color with a minimum luminance applied. * - * @param time absolute world time in ticks + * @param time absolute world time in ticks * @param position a position for the icosahedron, a randomish number for particles. * @return an AARRGGBB color. */ @@ -27,11 +26,17 @@ public final int getColor(float time, Vec3 position) { var r = FastColor.ARGB32.red(raw); var g = FastColor.ARGB32.green(raw); var b = FastColor.ARGB32.blue(raw); - double luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 0xFF; // Standard relative luminance calculation + double luminance = + (0.2126 * r + 0.7152 * g + 0.0722 * b) + / 0xFF; // Standard relative luminance calculation if (luminance < 0.05) { - int rawMod = ADPigment.morphBetweenColors(MINIMUM_LUMINANCE_COLOR_WHEEL, new Vec3(0.1, 0.1, 0.1), - time / 20 / 20, position); + int rawMod = + ADPigment.morphBetweenColors( + MINIMUM_LUMINANCE_COLOR_WHEEL, + new Vec3(0.1, 0.1, 0.1), + time / 20 / 20, + position); r += FastColor.ARGB32.red(rawMod); g += FastColor.ARGB32.green(rawMod); @@ -41,10 +46,11 @@ public final int getColor(float time, Vec3 position) { return 0xff_000000 | (r << 16) | (g << 8) | b; } - public static final ColorProvider MISSING = new ColorProvider() { - @Override - protected int getRawColor(float time, Vec3 position) { - return 0xFF_ff00dc; - } - }; + public static final ColorProvider MISSING = + new ColorProvider() { + @Override + protected int getRawColor(float time, Vec3 position) { + return 0xFF_ff00dc; + } + }; } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java b/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java index f5cd478e0e..c470377c8b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/pigment/FrozenPigment.java @@ -2,6 +2,7 @@ import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import net.minecraft.Util; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; @@ -11,9 +12,9 @@ /** * A snapshot of a pigment item and its owner. - *

- * Due to capabilities being really slow to query many times a tick on Forge, this returns a colorizer supplier. - * Get it once, and then query it a lot. + * + *

Due to capabilities being really slow to query many times a tick on Forge, this returns a + * colorizer supplier. Get it once, and then query it a lot. */ public record FrozenPigment(ItemStack item, UUID owner) { @@ -21,7 +22,7 @@ public record FrozenPigment(ItemStack item, UUID owner) { public static final String TAG_OWNER = "owner"; public static final Supplier DEFAULT = - () -> new FrozenPigment(new ItemStack(HexItems.DEFAULT_PIGMENT), Util.NIL_UUID); + () -> new FrozenPigment(new ItemStack(HexItems.DEFAULT_PIGMENT), Util.NIL_UUID); public CompoundTag serializeToNBT() { var out = new CompoundTag(); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java b/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java index 304a02121d..be7bb9fac1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/player/AltioraAbility.java @@ -1,10 +1,10 @@ package at.petrak.hexcasting.api.player; /** - * Note that this just keeps track of state, actually giving the player the elytra ability is handled - * differently per platform + * Note that this just keeps track of state, actually giving the player the elytra ability is + * handled differently per platform * - * @param gracePeriod so the flight isn't immediately removed because the player started on the ground + * @param gracePeriod so the flight isn't immediately removed because the player started on the + * ground */ -public record AltioraAbility(int gracePeriod) { -} +public record AltioraAbility(int gracePeriod) {} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/player/FlightAbility.java b/Common/src/main/java/at/petrak/hexcasting/api/player/FlightAbility.java index 7980a561be..1544e29ebc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/player/FlightAbility.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/player/FlightAbility.java @@ -6,7 +6,7 @@ /** * @param timeLeft sentinel of -1 for infinite - * @param radius sentinel of negative for infinite + * @param radius sentinel of negative for infinite */ -public record FlightAbility(int timeLeft, ResourceKey dimension, Vec3 origin, double radius) { -} +public record FlightAbility( + int timeLeft, ResourceKey dimension, Vec3 origin, double radius) {} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java b/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java index 867b4fca34..c0c795dfee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/player/Sentinel.java @@ -4,8 +4,5 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; -/** - * A null sentinel means no sentinel - */ -public record Sentinel(boolean extendsRange, Vec3 position, ResourceKey dimension) { -} +/** A null sentinel means no sentinel */ +public record Sentinel(boolean extendsRange, Vec3 position, ResourceKey dimension) {} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt index 209297766a..0039f0f4b0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/HexUtils.kt @@ -6,6 +6,13 @@ import at.petrak.hexcasting.api.casting.iota.Iota import at.petrak.hexcasting.api.casting.iota.IotaType import at.petrak.hexcasting.api.casting.iota.ListIota import at.petrak.hexcasting.api.casting.math.HexCoord +import java.lang.ref.WeakReference +import java.util.* +import kotlin.math.absoluteValue +import kotlin.math.max +import kotlin.math.min +import kotlin.math.roundToInt +import kotlin.reflect.KProperty import net.minecraft.ChatFormatting import net.minecraft.core.Registry import net.minecraft.nbt.* @@ -19,13 +26,6 @@ import net.minecraft.world.InteractionHand import net.minecraft.world.item.ItemStack import net.minecraft.world.phys.Vec2 import net.minecraft.world.phys.Vec3 -import java.lang.ref.WeakReference -import java.util.* -import kotlin.math.absoluteValue -import kotlin.math.max -import kotlin.math.min -import kotlin.math.roundToInt -import kotlin.reflect.KProperty const val TAU = Math.PI * 2.0 const val SQRT_3 = 1.7320508f @@ -38,27 +38,25 @@ fun Vec3.serializeToNBT(): CompoundTag { return tag } -fun vecFromNBT(tag: LongArray): Vec3 = if (tag.size != 3) Vec3.ZERO else - Vec3( - Double.fromBits(tag[0]), - Double.fromBits(tag[1]), - Double.fromBits(tag[2]) - ) +fun vecFromNBT(tag: LongArray): Vec3 = + if (tag.size != 3) Vec3.ZERO + else Vec3(Double.fromBits(tag[0]), Double.fromBits(tag[1]), Double.fromBits(tag[2])) + fun vecFromNBT(tag: CompoundTag): Vec3 { - return if (!tag.contains("x") || !tag.contains("y") || !tag.contains("z")) - Vec3.ZERO - else - Vec3(tag.getDouble("x"), tag.getDouble("y"), tag.getDouble("z")) + return if (!tag.contains("x") || !tag.contains("y") || !tag.contains("z")) Vec3.ZERO + else Vec3(tag.getDouble("x"), tag.getDouble("y"), tag.getDouble("z")) } fun Vec2.serializeToNBT(): LongArrayTag = LongArrayTag(longArrayOf(this.x.toDouble().toRawBits(), this.y.toDouble().toRawBits())) -fun vec2FromNBT(tag: LongArray): Vec2 = if (tag.size != 2) Vec2.ZERO else - Vec2( - Double.fromBits(tag[0]).toFloat(), - Double.fromBits(tag[1]).toFloat(), - ) +fun vec2FromNBT(tag: LongArray): Vec2 = + if (tag.size != 2) Vec2.ZERO + else + Vec2( + Double.fromBits(tag[0]).toFloat(), + Double.fromBits(tag[1]).toFloat(), + ) fun otherHand(hand: InteractionHand) = if (hand == InteractionHand.MAIN_HAND) InteractionHand.OFF_HAND else InteractionHand.MAIN_HAND @@ -77,17 +75,13 @@ fun findCenter(points: List): Vec2 { maxX = max(maxX, pos.x) maxY = max(maxY, pos.y) } - return Vec2( - (minX + maxX) / 2f, - (minY + maxY) / 2f - ) + return Vec2((minX + maxX) / 2f, (minY + maxY) / 2f) } fun coordToPx(coord: HexCoord, size: Float, offset: Vec2): Vec2 = - Vec2( - SQRT_3 * coord.q.toFloat() + SQRT_3 / 2.0f * coord.r.toFloat(), - 1.5f * coord.r.toFloat() - ).scale(size).add(offset) + Vec2(SQRT_3 * coord.q.toFloat() + SQRT_3 / 2.0f * coord.r.toFloat(), 1.5f * coord.r.toFloat()) + .scale(size) + .add(offset) fun pxToCoord(px: Vec2, size: Float, offset: Vec2): HexCoord { val offsetted = px.add(offset.negated()) @@ -98,10 +92,8 @@ fun pxToCoord(px: Vec2, size: Float, offset: Vec2): HexCoord { val r = rf.roundToInt() qf -= q rf -= r - return if (q.absoluteValue >= r.absoluteValue) - HexCoord(q + (qf + 0.5f * rf).roundToInt(), r) - else - HexCoord(q, r + (rf + 0.5 * qf).roundToInt()) + return if (q.absoluteValue >= r.absoluteValue) HexCoord(q + (qf + 0.5f * rf).roundToInt(), r) + else HexCoord(q, r + (rf + 0.5 * qf).roundToInt()) } @JvmOverloads @@ -111,99 +103,156 @@ fun > Array.getSafe(key: String, default: T = this[0]): T { } @JvmOverloads -fun > Array.getSafe(index: Byte, default: T = this[0]) = getSafe(index.toInt(), default) +fun > Array.getSafe(index: Byte, default: T = this[0]) = + getSafe(index.toInt(), default) @JvmOverloads -fun > Array.getSafe(index: Int, default: T = this[0]) = if (index in indices) this[index] else default +fun > Array.getSafe(index: Int, default: T = this[0]) = + if (index in indices) this[index] else default fun String.withStyle(op: (Style) -> Style): MutableComponent = asTextComponent.withStyle(op) -fun String.withStyle(style: Style): MutableComponent = asTextComponent.withStyle(style) -fun String.withStyle(formatting: ChatFormatting): MutableComponent = asTextComponent.withStyle(formatting) -fun String.withStyle(vararg formatting: ChatFormatting): MutableComponent = asTextComponent.withStyle(*formatting) - -infix fun String.styledWith(op: (Style) -> Style) = withStyle(op) -infix fun String.styledWith(style: Style) = withStyle(style) -infix fun String.styledWith(formatting: ChatFormatting) = withStyle(formatting) - -infix fun MutableComponent.styledWith(op: (Style) -> Style): MutableComponent = withStyle(op) -infix fun MutableComponent.styledWith(style: Style): MutableComponent = withStyle(style) -infix fun MutableComponent.styledWith(formatting: ChatFormatting): MutableComponent = withStyle(formatting) - -val String.black get() = this styledWith ChatFormatting.BLACK -val MutableComponent.black get() = this styledWith ChatFormatting.BLACK - -val String.darkBlue get() = this styledWith ChatFormatting.DARK_BLUE -val MutableComponent.darkBlue get() = this styledWith ChatFormatting.DARK_BLUE - -val String.darkGreen get() = this styledWith ChatFormatting.DARK_GREEN -val MutableComponent.darkGreen get() = this styledWith ChatFormatting.DARK_GREEN - -val String.darkAqua get() = this styledWith ChatFormatting.DARK_AQUA -val MutableComponent.darkAqua get() = this styledWith ChatFormatting.DARK_AQUA - -val String.darkRed get() = this styledWith ChatFormatting.DARK_RED -val MutableComponent.darkRed get() = this styledWith ChatFormatting.DARK_RED - -val String.darkPurple get() = this styledWith ChatFormatting.DARK_PURPLE -val MutableComponent.darkPurple get() = this styledWith ChatFormatting.DARK_PURPLE - -val String.gold get() = this styledWith ChatFormatting.GOLD -val MutableComponent.gold get() = this styledWith ChatFormatting.GOLD - -val String.gray get() = this styledWith ChatFormatting.GRAY -val MutableComponent.gray get() = this styledWith ChatFormatting.GRAY - -val String.darkGray get() = this styledWith ChatFormatting.DARK_GRAY -val MutableComponent.darkGray get() = this styledWith ChatFormatting.DARK_GRAY - -val String.blue get() = this styledWith ChatFormatting.BLUE -val MutableComponent.blue get() = this styledWith ChatFormatting.BLUE - -val String.green get() = this styledWith ChatFormatting.GREEN -val MutableComponent.green get() = this styledWith ChatFormatting.GREEN -val String.aqua get() = this styledWith ChatFormatting.AQUA -val MutableComponent.aqua get() = this styledWith ChatFormatting.AQUA - -val String.red get() = this styledWith ChatFormatting.RED -val MutableComponent.red get() = this styledWith ChatFormatting.RED +fun String.withStyle(style: Style): MutableComponent = asTextComponent.withStyle(style) -val String.lightPurple get() = this styledWith ChatFormatting.LIGHT_PURPLE -val MutableComponent.lightPurple get() = this styledWith ChatFormatting.LIGHT_PURPLE +fun String.withStyle(formatting: ChatFormatting): MutableComponent = + asTextComponent.withStyle(formatting) -val String.yellow get() = this styledWith ChatFormatting.YELLOW -val MutableComponent.yellow get() = this styledWith ChatFormatting.YELLOW +fun String.withStyle(vararg formatting: ChatFormatting): MutableComponent = + asTextComponent.withStyle(*formatting) -val String.white get() = this styledWith ChatFormatting.WHITE -val MutableComponent.white get() = this styledWith ChatFormatting.WHITE +infix fun String.styledWith(op: (Style) -> Style) = withStyle(op) -val String.obfuscated get() = this styledWith ChatFormatting.OBFUSCATED -val MutableComponent.obfuscated get() = this styledWith ChatFormatting.OBFUSCATED +infix fun String.styledWith(style: Style) = withStyle(style) -val String.bold get() = this styledWith ChatFormatting.BOLD -val MutableComponent.bold get() = this styledWith ChatFormatting.BOLD +infix fun String.styledWith(formatting: ChatFormatting) = withStyle(formatting) -val String.strikethrough get() = this styledWith ChatFormatting.STRIKETHROUGH -val MutableComponent.strikethrough get() = this styledWith ChatFormatting.STRIKETHROUGH +infix fun MutableComponent.styledWith(op: (Style) -> Style): MutableComponent = withStyle(op) -val String.underline get() = this styledWith ChatFormatting.UNDERLINE -val MutableComponent.underline get() = this styledWith ChatFormatting.UNDERLINE +infix fun MutableComponent.styledWith(style: Style): MutableComponent = withStyle(style) -val String.italic get() = this styledWith ChatFormatting.ITALIC -val MutableComponent.italic get() = this styledWith ChatFormatting.ITALIC +infix fun MutableComponent.styledWith(formatting: ChatFormatting): MutableComponent = + withStyle(formatting) + +val String.black + get() = this styledWith ChatFormatting.BLACK +val MutableComponent.black + get() = this styledWith ChatFormatting.BLACK + +val String.darkBlue + get() = this styledWith ChatFormatting.DARK_BLUE +val MutableComponent.darkBlue + get() = this styledWith ChatFormatting.DARK_BLUE + +val String.darkGreen + get() = this styledWith ChatFormatting.DARK_GREEN +val MutableComponent.darkGreen + get() = this styledWith ChatFormatting.DARK_GREEN + +val String.darkAqua + get() = this styledWith ChatFormatting.DARK_AQUA +val MutableComponent.darkAqua + get() = this styledWith ChatFormatting.DARK_AQUA + +val String.darkRed + get() = this styledWith ChatFormatting.DARK_RED +val MutableComponent.darkRed + get() = this styledWith ChatFormatting.DARK_RED + +val String.darkPurple + get() = this styledWith ChatFormatting.DARK_PURPLE +val MutableComponent.darkPurple + get() = this styledWith ChatFormatting.DARK_PURPLE + +val String.gold + get() = this styledWith ChatFormatting.GOLD +val MutableComponent.gold + get() = this styledWith ChatFormatting.GOLD + +val String.gray + get() = this styledWith ChatFormatting.GRAY +val MutableComponent.gray + get() = this styledWith ChatFormatting.GRAY + +val String.darkGray + get() = this styledWith ChatFormatting.DARK_GRAY +val MutableComponent.darkGray + get() = this styledWith ChatFormatting.DARK_GRAY + +val String.blue + get() = this styledWith ChatFormatting.BLUE +val MutableComponent.blue + get() = this styledWith ChatFormatting.BLUE + +val String.green + get() = this styledWith ChatFormatting.GREEN +val MutableComponent.green + get() = this styledWith ChatFormatting.GREEN + +val String.aqua + get() = this styledWith ChatFormatting.AQUA +val MutableComponent.aqua + get() = this styledWith ChatFormatting.AQUA + +val String.red + get() = this styledWith ChatFormatting.RED +val MutableComponent.red + get() = this styledWith ChatFormatting.RED + +val String.lightPurple + get() = this styledWith ChatFormatting.LIGHT_PURPLE +val MutableComponent.lightPurple + get() = this styledWith ChatFormatting.LIGHT_PURPLE + +val String.yellow + get() = this styledWith ChatFormatting.YELLOW +val MutableComponent.yellow + get() = this styledWith ChatFormatting.YELLOW + +val String.white + get() = this styledWith ChatFormatting.WHITE +val MutableComponent.white + get() = this styledWith ChatFormatting.WHITE + +val String.obfuscated + get() = this styledWith ChatFormatting.OBFUSCATED +val MutableComponent.obfuscated + get() = this styledWith ChatFormatting.OBFUSCATED + +val String.bold + get() = this styledWith ChatFormatting.BOLD +val MutableComponent.bold + get() = this styledWith ChatFormatting.BOLD + +val String.strikethrough + get() = this styledWith ChatFormatting.STRIKETHROUGH +val MutableComponent.strikethrough + get() = this styledWith ChatFormatting.STRIKETHROUGH + +val String.underline + get() = this styledWith ChatFormatting.UNDERLINE +val MutableComponent.underline + get() = this styledWith ChatFormatting.UNDERLINE + +val String.italic + get() = this styledWith ChatFormatting.ITALIC +val MutableComponent.italic + get() = this styledWith ChatFormatting.ITALIC operator fun MutableComponent.plusAssign(component: Component) { append(component) } -val String.asTextComponent: MutableComponent get() = Component.literal(this) -val String.asTranslatedComponent: MutableComponent get() = Component.translatable(this) +val String.asTextComponent: MutableComponent + get() = Component.literal(this) +val String.asTranslatedComponent: MutableComponent + get() = Component.translatable(this) -fun String.asTranslatedComponent(vararg args: Any): MutableComponent = Component.translatable(this, *args) +fun String.asTranslatedComponent(vararg args: Any): MutableComponent = + Component.translatable(this, *args) /** - * Represents a value that the garbage collector is still allowed to collect. - * To create an instance of a [WeakValue], use [weakReference] or [weakMapped]. + * Represents a value that the garbage collector is still allowed to collect. To create an instance + * of a [WeakValue], use [weakReference] or [weakMapped]. */ interface WeakValue { var value: T? @@ -212,8 +261,8 @@ interface WeakValue { /** * A weakly referenced value that relies directly on a [WeakReference]. * - * This means that if there are no other places where the contained object is referenced, - * the reference will expire, and value contained within this reference will become null. + * This means that if there are no other places where the contained object is referenced, the + * reference will expire, and value contained within this reference will become null. */ private class WeakReferencedValue(var reference: WeakReference?) : WeakValue { override var value: T? @@ -226,8 +275,9 @@ private class WeakReferencedValue(var reference: WeakReference?) : WeakVal /** * A weakly referenced value that relies on a [WeakHashMap]. * - * Unlike [WeakReferencedValue], it relies on the continued existence of something else (obtained by [keyGen]). - * For example, this can be used to hold an entity, and have the reference expire when the world it's in is unloaded. + * Unlike [WeakReferencedValue], it relies on the continued existence of something else (obtained by + * [keyGen]). For example, this can be used to hold an entity, and have the reference expire when + * the world it's in is unloaded. */ private class WeakMappedValue(val keyGen: (T) -> K) : WeakValue { val reference = WeakHashMap() @@ -240,12 +290,15 @@ private class WeakMappedValue(val keyGen: (T) -> K) : WeakValue { } /** - * Creates a [WeakReferencedValue], the contents of which will expire when nothing else is referencing them. + * Creates a [WeakReferencedValue], the contents of which will expire when nothing else is + * referencing them. */ -fun weakReference(value: T? = null): WeakValue = WeakReferencedValue(value?.let { WeakReference(it) }) +fun weakReference(value: T? = null): WeakValue = + WeakReferencedValue(value?.let { WeakReference(it) }) /** - * Creates a [WeakMappedValue], the contents of which will expire when nothing else is referencing the value returned by [keyGen]. + * Creates a [WeakMappedValue], the contents of which will expire when nothing else is referencing + * the value returned by [keyGen]. */ fun weakMapped(keyGen: (T) -> K): WeakValue = WeakMappedValue(keyGen) @@ -258,14 +311,9 @@ inline operator fun WeakValue.setValue(thisRef: Any?, property: KProperty this.value = value } -/** - * Returns an empty list if it's too complicated. - */ +/** Returns an empty list if it's too complicated. */ fun Iterable.serializeToNBT() = - if (IotaType.isTooLargeToSerialize(this)) - ListTag() - else - ListIota(this.toList()).serialize() + if (IotaType.isTooLargeToSerialize(this)) ListTag() else ListIota(this.toList()).serialize() fun Iterable.serializeToNBT(): ByteArrayTag { val out = ByteArray(if (this is Collection<*>) this.size else 10) @@ -297,12 +345,12 @@ fun Tag.downcast(type: TagType): T { return this as T } else { throw IllegalArgumentException( - "Expected this tag to be of type ${type.name}, but found ${this.type.name}." - ) + "Expected this tag to be of type ${type.name}, but found ${this.type.name}.") } } const val ERROR_COLOR = 0xff_f800f8.toInt() + fun isOfTag(registry: Registry, key: ResourceKey, tag: TagKey): Boolean { val maybeHolder = registry.getHolder(key) val holder = if (maybeHolder.isPresent) maybeHolder.get() else return false @@ -310,6 +358,6 @@ fun isOfTag(registry: Registry, key: ResourceKey, tag: TagKey): Boo } fun isOfTag(registry: Registry, loc: ResourceLocation, tag: TagKey): Boolean { - val key = ResourceKey.create(registry.key(), loc); + val key = ResourceKey.create(registry.key(), loc) return isOfTag(registry, key, tag) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt index 84448cc394..b325bf844b 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/MathUtils.kt @@ -1,15 +1,13 @@ package at.petrak.hexcasting.api.utils +import kotlin.math.* import org.joml.Quaternionf import org.joml.Vector3f -import kotlin.math.* object MathUtils { @JvmStatic - fun clamp(long: Long, min: Long, max: Long): Long - = if (long <= min) min - else if (long >= max) max - else long + fun clamp(long: Long, min: Long, max: Long): Long = + if (long <= min) min else if (long >= max) max else long } object QuaternionfUtils { @@ -19,7 +17,10 @@ object QuaternionfUtils { @JvmStatic fun fromXYZDegrees(vector3f: Vector3f): Quaternionf { - return fromXYZ(Math.toRadians(vector3f.x().toDouble()).toFloat(), Math.toRadians(vector3f.y().toDouble()).toFloat(), Math.toRadians(vector3f.z().toDouble()).toFloat()) + return fromXYZ( + Math.toRadians(vector3f.x().toDouble()).toFloat(), + Math.toRadians(vector3f.y().toDouble()).toFloat(), + Math.toRadians(vector3f.z().toDouble()).toFloat()) } @JvmStatic @@ -35,4 +36,4 @@ object QuaternionfUtils { quaternion.mul(Quaternionf(0.0f, 0.0f, sin((h / 2.0f)), cos((h / 2.0f)))) return quaternion } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt index c237ac52be..92e5544f9c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/MediaHelper.kt @@ -5,23 +5,23 @@ package at.petrak.hexcasting.api.utils import at.petrak.hexcasting.api.HexAPI import at.petrak.hexcasting.api.addldata.ADMediaHolder import at.petrak.hexcasting.xplat.IXplatAbstractions +import kotlin.math.roundToInt import net.minecraft.server.level.ServerPlayer import net.minecraft.util.Mth import net.minecraft.world.item.ItemStack -import kotlin.math.roundToInt fun isMediaItem(stack: ItemStack): Boolean { val mediaHolder = IXplatAbstractions.INSTANCE.findMediaHolder(stack) ?: return false - if (!mediaHolder.canProvide()) - return false + if (!mediaHolder.canProvide()) return false return mediaHolder.withdrawMedia(-1, true) > 0 } /** - * Extract [cost] media from [stack]. If [cost] is less than zero, extract all media instead. - * This may mutate [stack] (and may consume it) unless [simulate] is set. + * Extract [cost] media from [stack]. If [cost] is less than zero, extract all media instead. This + * may mutate [stack] (and may consume it) unless [simulate] is set. * - * If [drainForBatteries] is true, this will only consider forms of media that can be used to make new batteries. + * If [drainForBatteries] is true, this will only consider forms of media that can be used to make + * new batteries. * * Return the amount of media extracted. This may be over [cost] if media is wasted. */ @@ -38,10 +38,11 @@ fun extractMedia( } /** - * Extract [cost] media from [holder]. If [cost] is less than zero, extract all media instead. - * This may mutate the stack underlying [holder] (and may consume it) unless [simulate] is set. + * Extract [cost] media from [holder]. If [cost] is less than zero, extract all media instead. This + * may mutate the stack underlying [holder] (and may consume it) unless [simulate] is set. * - * If [drainForBatteries] is true, this will only consider forms of media that can be used to make new batteries. + * If [drainForBatteries] is true, this will only consider forms of media that can be used to make + * new batteries. * * Return the amount of media extracted. This may be over [cost] if media is wasted. */ @@ -51,15 +52,14 @@ fun extractMedia( drainForBatteries: Boolean = false, simulate: Boolean = false ): Long { - if (drainForBatteries && !holder.canConstructBattery()) - return 0 + if (drainForBatteries && !holder.canConstructBattery()) return 0 return holder.withdrawMedia(cost, simulate) } /** - * Convenience function to scan the player's inventory, curios, etc for media sources, - * and then sorts them + * Convenience function to scan the player's inventory, curios, etc for media sources, and then + * sorts them */ fun scanPlayerForMediaStuff(player: ServerPlayer): List { val sources = mutableListOf() @@ -76,24 +76,23 @@ fun scanPlayerForMediaStuff(player: ServerPlayer): List { return sources } -/** - * Sorted from least important to most important - */ +/** Sorted from least important to most important */ fun compareMediaItem(aMedia: ADMediaHolder, bMedia: ADMediaHolder): Int { val priority = aMedia.consumptionPriority - bMedia.consumptionPriority - if (priority != 0) - return priority + if (priority != 0) return priority return (aMedia.withdrawMedia(-1, true) - bMedia.withdrawMedia(-1, true)) - .coerceIn(Int.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong()).toInt() + .coerceIn(Int.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong()) + .toInt() } fun mediaBarColor(media: Long, maxMedia: Long): Int { - val amt = if (maxMedia == 0L) { - 0f - } else { - media.toFloat() / maxMedia.toFloat() - } + val amt = + if (maxMedia == 0L) { + 0f + } else { + media.toFloat() / maxMedia.toFloat() + } val r = Mth.lerp(amt, 84f, 254f) val g = Mth.lerp(amt, 57f, 203f) @@ -102,10 +101,11 @@ fun mediaBarColor(media: Long, maxMedia: Long): Int { } fun mediaBarWidth(media: Long, maxMedia: Long): Int { - val amt = if (maxMedia == 0L) { - 0f - } else { - media.toFloat() / maxMedia.toFloat() - } + val amt = + if (maxMedia == 0L) { + 0f + } else { + media.toFloat() / maxMedia.toFloat() + } return (13f * amt).roundToInt() } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTDsl.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTDsl.kt index 1c427b4c1e..94ca2616d6 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTDsl.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTDsl.kt @@ -6,13 +6,14 @@ import net.minecraft.nbt.* // https://github.com/TeamWizardry/LibrarianLib/blob/9cfb2cf3e35685568942ad41395265a2edc27d30/modules/core/src/main/kotlin/com/teamwizardry/librarianlib/core/util/kotlin/NbtBuilder.kt -@DslMarker -internal annotation class NBTDslMarker +@DslMarker internal annotation class NBTDslMarker @NBTDslMarker object NBTBuilder { inline operator fun invoke(block: NbtCompoundBuilder.() -> Unit) = compound(block) - inline operator fun invoke(tag: CompoundTag, block: NbtCompoundBuilder.() -> Unit) = use(tag, block) + + inline operator fun invoke(tag: CompoundTag, block: NbtCompoundBuilder.() -> Unit) = + use(tag, block) inline fun use(tag: CompoundTag, block: NbtCompoundBuilder.() -> Unit): CompoundTag = NbtCompoundBuilder(tag).apply(block).tag @@ -24,33 +25,59 @@ object NBTBuilder { NbtListBuilder(ListTag()).apply(block).tag inline fun list(vararg elements: Tag, block: NbtListBuilder.() -> Unit): ListTag = - NbtListBuilder(ListTag()).also { - it.addAll(elements.toList()) - it.block() - }.tag + NbtListBuilder(ListTag()) + .also { + it.addAll(elements.toList()) + it.block() + } + .tag inline fun list(vararg elements: Tag): ListTag = ListTag().also { it.addAll(elements) } + inline fun list(elements: Collection): ListTag = ListTag().also { it.addAll(elements) } - inline fun list(elements: Collection, mapper: (T) -> Tag): ListTag = ListTag().also { it.addAll(elements.map(mapper)) } + + inline fun list(elements: Collection, mapper: (T) -> Tag): ListTag = + ListTag().also { it.addAll(elements.map(mapper)) } inline fun double(value: Number): DoubleTag = DoubleTag.valueOf(value.toDouble()) + inline fun float(value: Number): FloatTag = FloatTag.valueOf(value.toFloat()) + inline fun long(value: Number): LongTag = LongTag.valueOf(value.toLong()) + inline fun int(value: Number): IntTag = IntTag.valueOf(value.toInt()) + inline fun short(value: Number): ShortTag = ShortTag.valueOf(value.toShort()) + inline fun byte(value: Number): ByteTag = ByteTag.valueOf(value.toByte()) inline fun string(value: String): StringTag = StringTag.valueOf(value) - inline fun byteArray(value: Collection): ByteArrayTag = ByteArrayTag(value.map { it.toByte() }) - inline fun byteArray(vararg value: Int): ByteArrayTag = ByteArrayTag(ByteArray(value.size) { value[it].toByte() }) + inline fun byteArray(value: Collection): ByteArrayTag = + ByteArrayTag(value.map { it.toByte() }) + + inline fun byteArray(vararg value: Int): ByteArrayTag = + ByteArrayTag(ByteArray(value.size) { value[it].toByte() }) + inline fun byteArray(vararg value: Byte): ByteArrayTag = ByteArrayTag(value) - inline fun byteArray(): ByteArrayTag = ByteArrayTag(byteArrayOf()) // avoiding overload ambiguity - inline fun longArray(value: Collection): LongArrayTag = LongArrayTag(value.map { it.toLong() }) - inline fun longArray(vararg value: Int): LongArrayTag = LongArrayTag(LongArray(value.size) { value[it].toLong() }) + + inline fun byteArray(): ByteArrayTag = + ByteArrayTag(byteArrayOf()) // avoiding overload ambiguity + + inline fun longArray(value: Collection): LongArrayTag = + LongArrayTag(value.map { it.toLong() }) + + inline fun longArray(vararg value: Int): LongArrayTag = + LongArrayTag(LongArray(value.size) { value[it].toLong() }) + inline fun longArray(vararg value: Long): LongArrayTag = LongArrayTag(value) - inline fun longArray(): LongArrayTag = LongArrayTag(longArrayOf()) // avoiding overload ambiguity - inline fun intArray(value: Collection): IntArrayTag = IntArrayTag(value.map { it.toInt() }) + + inline fun longArray(): LongArrayTag = + LongArrayTag(longArrayOf()) // avoiding overload ambiguity + + inline fun intArray(value: Collection): IntArrayTag = + IntArrayTag(value.map { it.toInt() }) + inline fun intArray(vararg value: Int): IntArrayTag = IntArrayTag(value) } @@ -96,33 +123,59 @@ value class NbtCompoundBuilder(val tag: CompoundTag) { NbtListBuilder(ListTag()).apply(block).tag inline fun list(vararg elements: Tag, block: NbtListBuilder.() -> Unit): ListTag = - NbtListBuilder(ListTag()).also { - it.addAll(elements.toList()) - it.block() - }.tag + NbtListBuilder(ListTag()) + .also { + it.addAll(elements.toList()) + it.block() + } + .tag inline fun list(vararg elements: Tag): ListTag = ListTag().also { it.addAll(elements) } + inline fun list(elements: Collection): ListTag = ListTag().also { it.addAll(elements) } - inline fun list(elements: Collection, mapper: (T) -> Tag): ListTag = ListTag().also { it.addAll(elements.map(mapper)) } + + inline fun list(elements: Collection, mapper: (T) -> Tag): ListTag = + ListTag().also { it.addAll(elements.map(mapper)) } inline fun double(value: Number): DoubleTag = DoubleTag.valueOf(value.toDouble()) + inline fun float(value: Number): FloatTag = FloatTag.valueOf(value.toFloat()) + inline fun long(value: Number): LongTag = LongTag.valueOf(value.toLong()) + inline fun int(value: Number): IntTag = IntTag.valueOf(value.toInt()) + inline fun short(value: Number): ShortTag = ShortTag.valueOf(value.toShort()) + inline fun byte(value: Number): ByteTag = ByteTag.valueOf(value.toByte()) inline fun string(value: String): StringTag = StringTag.valueOf(value) - inline fun byteArray(value: Collection): ByteArrayTag = ByteArrayTag(value.map { it.toByte() }) - inline fun byteArray(vararg value: Int): ByteArrayTag = ByteArrayTag(ByteArray(value.size) { value[it].toByte() }) + inline fun byteArray(value: Collection): ByteArrayTag = + ByteArrayTag(value.map { it.toByte() }) + + inline fun byteArray(vararg value: Int): ByteArrayTag = + ByteArrayTag(ByteArray(value.size) { value[it].toByte() }) + inline fun byteArray(vararg value: Byte): ByteArrayTag = ByteArrayTag(value) - inline fun byteArray(): ByteArrayTag = ByteArrayTag(byteArrayOf()) // avoiding overload ambiguity - inline fun longArray(value: Collection): LongArrayTag = LongArrayTag(value.map { it.toLong() }) - inline fun longArray(vararg value: Int): LongArrayTag = LongArrayTag(LongArray(value.size) { value[it].toLong() }) + + inline fun byteArray(): ByteArrayTag = + ByteArrayTag(byteArrayOf()) // avoiding overload ambiguity + + inline fun longArray(value: Collection): LongArrayTag = + LongArrayTag(value.map { it.toLong() }) + + inline fun longArray(vararg value: Int): LongArrayTag = + LongArrayTag(LongArray(value.size) { value[it].toLong() }) + inline fun longArray(vararg value: Long): LongArrayTag = LongArrayTag(value) - inline fun longArray(): LongArrayTag = LongArrayTag(longArrayOf()) // avoiding overload ambiguity - inline fun intArray(value: Collection): IntArrayTag = IntArrayTag(value.map { it.toInt() }) + + inline fun longArray(): LongArrayTag = + LongArrayTag(longArrayOf()) // avoiding overload ambiguity + + inline fun intArray(value: Collection): IntArrayTag = + IntArrayTag(value.map { it.toInt() }) + inline fun intArray(vararg value: Int): IntArrayTag = IntArrayTag(value) } @@ -131,23 +184,19 @@ value class NbtCompoundBuilder(val tag: CompoundTag) { value class NbtListBuilder(val tag: ListTag) { // configuring this tag - /** - * Add the given tag to this list - */ + /** Add the given tag to this list */ inline operator fun Tag.unaryPlus() { tag.add(this) } - /** - * Add the given tags to this list - */ + /** Add the given tags to this list */ inline operator fun Collection.unaryPlus() { tag.addAll(this) } /** - * Add the given tag to this list. This is explicitly defined for [ListTag] because otherwise there is overload - * ambiguity between the [Tag] and [Collection] methods. + * Add the given tag to this list. This is explicitly defined for [ListTag] because otherwise + * there is overload ambiguity between the [Tag] and [Collection] methods. */ inline operator fun ListTag.unaryPlus() { tag.add(this) @@ -170,45 +219,84 @@ value class NbtListBuilder(val tag: ListTag) { NbtListBuilder(ListTag()).apply(block).tag inline fun list(vararg elements: Tag, block: NbtListBuilder.() -> Unit): ListTag = - NbtListBuilder(ListTag()).also { - it.addAll(elements.toList()) - it.block() - }.tag + NbtListBuilder(ListTag()) + .also { + it.addAll(elements.toList()) + it.block() + } + .tag inline fun list(vararg elements: Tag): ListTag = ListTag().also { it.addAll(elements) } + inline fun list(elements: Collection): ListTag = ListTag().also { it.addAll(elements) } - inline fun list(elements: Collection, mapper: (T) -> Tag): ListTag = ListTag().also { it.addAll(elements.map(mapper)) } + + inline fun list(elements: Collection, mapper: (T) -> Tag): ListTag = + ListTag().also { it.addAll(elements.map(mapper)) } inline fun double(value: Number): DoubleTag = DoubleTag.valueOf(value.toDouble()) + inline fun float(value: Number): FloatTag = FloatTag.valueOf(value.toFloat()) + inline fun long(value: Number): LongTag = LongTag.valueOf(value.toLong()) + inline fun int(value: Number): IntTag = IntTag.valueOf(value.toInt()) + inline fun short(value: Number): ShortTag = ShortTag.valueOf(value.toShort()) + inline fun byte(value: Number): ByteTag = ByteTag.valueOf(value.toByte()) inline fun string(value: String): StringTag = StringTag.valueOf(value) - inline fun byteArray(value: Collection): ByteArrayTag = ByteArrayTag(value.map { it.toByte() }) - inline fun byteArray(vararg value: Int): ByteArrayTag = ByteArrayTag(ByteArray(value.size) { value[it].toByte() }) + inline fun byteArray(value: Collection): ByteArrayTag = + ByteArrayTag(value.map { it.toByte() }) + + inline fun byteArray(vararg value: Int): ByteArrayTag = + ByteArrayTag(ByteArray(value.size) { value[it].toByte() }) + inline fun byteArray(vararg value: Byte): ByteArrayTag = ByteArrayTag(value) - inline fun byteArray(): ByteArrayTag = ByteArrayTag(byteArrayOf()) // avoiding overload ambiguity - inline fun longArray(value: Collection): LongArrayTag = LongArrayTag(value.map { it.toLong() }) - inline fun longArray(vararg value: Int): LongArrayTag = LongArrayTag(LongArray(value.size) { value[it].toLong() }) + + inline fun byteArray(): ByteArrayTag = + ByteArrayTag(byteArrayOf()) // avoiding overload ambiguity + + inline fun longArray(value: Collection): LongArrayTag = + LongArrayTag(value.map { it.toLong() }) + + inline fun longArray(vararg value: Int): LongArrayTag = + LongArrayTag(LongArray(value.size) { value[it].toLong() }) + inline fun longArray(vararg value: Long): LongArrayTag = LongArrayTag(value) - inline fun longArray(): LongArrayTag = LongArrayTag(longArrayOf()) // avoiding overload ambiguity - inline fun intArray(value: Collection): IntArrayTag = IntArrayTag(value.map { it.toInt() }) + + inline fun longArray(): LongArrayTag = + LongArrayTag(longArrayOf()) // avoiding overload ambiguity + + inline fun intArray(value: Collection): IntArrayTag = + IntArrayTag(value.map { it.toInt() }) + inline fun intArray(vararg value: Int): IntArrayTag = IntArrayTag(value) - inline fun doubles(vararg value: Int): List = value.map { DoubleTag.valueOf(it.toDouble()) } + inline fun doubles(vararg value: Int): List = + value.map { DoubleTag.valueOf(it.toDouble()) } + inline fun doubles(vararg value: Double): List = value.map { DoubleTag.valueOf(it) } - inline fun floats(vararg value: Int): List = value.map { FloatTag.valueOf(it.toFloat()) } + + inline fun floats(vararg value: Int): List = + value.map { FloatTag.valueOf(it.toFloat()) } + inline fun floats(vararg value: Float): List = value.map { FloatTag.valueOf(it) } + inline fun longs(vararg value: Int): List = value.map { LongTag.valueOf(it.toLong()) } + inline fun longs(vararg value: Long): List = value.map { LongTag.valueOf(it) } + inline fun ints(vararg value: Int): List = value.map { IntTag.valueOf(it) } - inline fun shorts(vararg value: Int): List = value.map { ShortTag.valueOf(it.toShort()) } + + inline fun shorts(vararg value: Int): List = + value.map { ShortTag.valueOf(it.toShort()) } + inline fun shorts(vararg value: Short): List = value.map { ShortTag.valueOf(it) } + inline fun bytes(vararg value: Int): List = value.map { ByteTag.valueOf(it.toByte()) } + inline fun bytes(vararg value: Byte): List = value.map { ByteTag.valueOf(it) } fun strings(vararg value: String): List = value.map { StringTag.valueOf(it) } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt b/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt index ef9a757c01..bfea7326b1 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt +++ b/Common/src/main/java/at/petrak/hexcasting/api/utils/NBTHelper.kt @@ -2,16 +2,23 @@ package at.petrak.hexcasting.api.utils +import java.util.* import net.minecraft.nbt.* import net.minecraft.world.item.ItemStack -import java.util.* - -private inline fun T?.getIf(key: K, predicate: T?.(K) -> Boolean, get: T.(K) -> E): E? = - getIf(key, predicate, get, null) -private inline fun T?.getIf(key: K, predicate: T?.(K) -> Boolean, get: T.(K) -> E, default: E): E { - if (this != null && predicate(key)) - return get(key) +private inline fun T?.getIf( + key: K, + predicate: T?.(K) -> Boolean, + get: T.(K) -> E +): E? = getIf(key, predicate, get, null) + +private inline fun T?.getIf( + key: K, + predicate: T?.(K) -> Boolean, + get: T.(K) -> E, + default: E +): E { + if (this != null && predicate(key)) return get(key) return default } @@ -20,19 +27,33 @@ private inline fun T?.getIf(key: K, predicate: T?.(K) -> Boolean // Checks for containment fun CompoundTag?.hasNumber(key: String) = contains(key, Tag.TAG_ANY_NUMERIC) + fun CompoundTag?.hasByte(key: String) = contains(key, Tag.TAG_BYTE) + fun CompoundTag?.hasShort(key: String) = contains(key, Tag.TAG_SHORT) + fun CompoundTag?.hasInt(key: String) = contains(key, Tag.TAG_INT) + fun CompoundTag?.hasLong(key: String) = contains(key, Tag.TAG_LONG) + fun CompoundTag?.hasFloat(key: String) = contains(key, Tag.TAG_FLOAT) + fun CompoundTag?.hasDouble(key: String) = contains(key, Tag.TAG_DOUBLE) + fun CompoundTag?.hasLongArray(key: String) = contains(key, Tag.TAG_LONG_ARRAY) + fun CompoundTag?.hasIntArray(key: String) = contains(key, Tag.TAG_INT_ARRAY) + fun CompoundTag?.hasByteArray(key: String) = contains(key, Tag.TAG_BYTE_ARRAY) + fun CompoundTag?.hasCompound(key: String) = contains(key, Tag.TAG_COMPOUND) + fun CompoundTag?.hasString(key: String) = contains(key, Tag.TAG_STRING) + fun CompoundTag?.hasList(key: String) = contains(key, Tag.TAG_LIST) + fun CompoundTag?.hasList(key: String, objType: Int) = hasList(key, objType.toByte()) + fun CompoundTag?.hasList(key: String, objType: Byte): Boolean { if (!hasList(key)) return false val lt = get(key) as ListTag @@ -42,25 +63,41 @@ fun CompoundTag?.hasList(key: String, objType: Byte): Boolean { fun CompoundTag?.hasUUID(key: String) = this != null && hasUUID(key) fun CompoundTag?.contains(key: String, id: Byte) = contains(key, id.toInt()) + fun CompoundTag?.contains(key: String, id: Int) = this != null && contains(key, id) + fun CompoundTag?.contains(key: String) = this != null && contains(key) // Puts fun CompoundTag?.putBoolean(key: String, value: Boolean) = this?.putBoolean(key, value) + fun CompoundTag?.putByte(key: String, value: Byte) = this?.putByte(key, value) + fun CompoundTag?.putShort(key: String, value: Short) = this?.putShort(key, value) + fun CompoundTag?.putInt(key: String, value: Int) = this?.putInt(key, value) + fun CompoundTag?.putLong(key: String, value: Long) = this?.putLong(key, value) + fun CompoundTag?.putFloat(key: String, value: Float) = this?.putFloat(key, value) + fun CompoundTag?.putDouble(key: String, value: Double) = this?.putDouble(key, value) + fun CompoundTag?.putLongArray(key: String, value: LongArray) = this?.putLongArray(key, value) + fun CompoundTag?.putIntArray(key: String, value: IntArray) = this?.putIntArray(key, value) + fun CompoundTag?.putByteArray(key: String, value: ByteArray) = this?.putByteArray(key, value) + fun CompoundTag?.putCompound(key: String, value: CompoundTag) = put(key, value) + fun CompoundTag?.putString(key: String, value: String) = this?.putString(key, value) + fun CompoundTag?.putList(key: String, value: ListTag) = put(key, value) + fun CompoundTag?.putUUID(key: String, value: UUID) = this?.putUUID(key, value) + fun CompoundTag?.put(key: String, value: Tag) = this?.put(key, value) // Remove @@ -97,16 +134,28 @@ fun CompoundTag?.getFloat(key: String, defaultExpected: Float = 0f) = fun CompoundTag?.getDouble(key: String, defaultExpected: Double = 0.0) = getIf(key, CompoundTag?::hasNumber, CompoundTag::getDouble, defaultExpected) -fun CompoundTag?.getLongArray(key: String) = getIf(key, CompoundTag?::hasLongArray, CompoundTag::getLongArray) -fun CompoundTag?.getIntArray(key: String) = getIf(key, CompoundTag?::hasIntArray, CompoundTag::getIntArray) -fun CompoundTag?.getByteArray(key: String) = getIf(key, CompoundTag?::hasByteArray, CompoundTag::getByteArray) +fun CompoundTag?.getLongArray(key: String) = + getIf(key, CompoundTag?::hasLongArray, CompoundTag::getLongArray) + +fun CompoundTag?.getIntArray(key: String) = + getIf(key, CompoundTag?::hasIntArray, CompoundTag::getIntArray) + +fun CompoundTag?.getByteArray(key: String) = + getIf(key, CompoundTag?::hasByteArray, CompoundTag::getByteArray) + fun CompoundTag?.getCompound(key: String): CompoundTag? = getIf(key, CompoundTag?::hasCompound, CompoundTag::getCompound) -fun CompoundTag?.getString(key: String) = getIf(key, CompoundTag?::hasString, CompoundTag::getString) +fun CompoundTag?.getString(key: String) = + getIf(key, CompoundTag?::hasString, CompoundTag::getString) + fun CompoundTag?.getList(key: String, objType: Byte) = getList(key, objType.toInt()) -fun CompoundTag?.getList(key: String, objType: Int) = getIf(key, { hasList(key, objType) }) { getList(it, objType) } + +fun CompoundTag?.getList(key: String, objType: Int) = + getIf(key, { hasList(key, objType) }) { getList(it, objType) } + fun CompoundTag?.getUUID(key: String) = getIf(key, CompoundTag?::hasUUID, CompoundTag::getUUID) + fun CompoundTag?.get(key: String) = getIf(key, CompoundTag?::contains, CompoundTag::get) @JvmSynthetic @@ -115,118 +164,158 @@ fun CompoundTag.getList(key: String, objType: Byte): ListTag = getList(key, objT // Get-or-create -fun CompoundTag.getOrCreateCompound(key: String): CompoundTag = getCompound(key) ?: CompoundTag().also { putCompound(key, it) } +fun CompoundTag.getOrCreateCompound(key: String): CompoundTag = + getCompound(key) ?: CompoundTag().also { putCompound(key, it) } + fun CompoundTag.getOrCreateList(key: String, objType: Byte) = getOrCreateList(key, objType.toInt()) -fun CompoundTag.getOrCreateList(key: String, objType: Int): ListTag = if (hasList(key, objType)) getList(key, objType) else ListTag().also { putList(key, it) } + +fun CompoundTag.getOrCreateList(key: String, objType: Int): ListTag = + if (hasList(key, objType)) getList(key, objType) else ListTag().also { putList(key, it) } // ================================================================================================================ Tag -val Tag.asBoolean get() = asByte == 0.toByte() -val Tag.asByte get() = (this as? NumericTag)?.asByte ?: 0.toByte() -val Tag.asShort get() = (this as? NumericTag)?.asShort ?: 0.toShort() -val Tag.asInt get() = (this as? NumericTag)?.asInt ?: 0 -val Tag.asLong get() = (this as? NumericTag)?.asLong ?: 0L -val Tag.asFloat get() = (this as? NumericTag)?.asFloat ?: 0F -val Tag.asDouble get() = (this as? NumericTag)?.asDouble ?: 0.0 +val Tag.asBoolean + get() = asByte == 0.toByte() +val Tag.asByte + get() = (this as? NumericTag)?.asByte ?: 0.toByte() +val Tag.asShort + get() = (this as? NumericTag)?.asShort ?: 0.toShort() +val Tag.asInt + get() = (this as? NumericTag)?.asInt ?: 0 +val Tag.asLong + get() = (this as? NumericTag)?.asLong ?: 0L +val Tag.asFloat + get() = (this as? NumericTag)?.asFloat ?: 0F +val Tag.asDouble + get() = (this as? NumericTag)?.asDouble ?: 0.0 val Tag.asLongArray: LongArray - get() = when (this) { - is LongArrayTag -> this.asLongArray - is IntArrayTag -> { - val array = this.asIntArray - LongArray(array.size) { array[it].toLong() } - } - is ByteArrayTag -> { - val array = this.asByteArray - LongArray(array.size) { array[it].toLong() } + get() = + when (this) { + is LongArrayTag -> this.asLongArray + is IntArrayTag -> { + val array = this.asIntArray + LongArray(array.size) { array[it].toLong() } + } + is ByteArrayTag -> { + val array = this.asByteArray + LongArray(array.size) { array[it].toLong() } + } + else -> LongArray(0) } - else -> LongArray(0) - } val Tag.asIntArray: IntArray - get() = when (this) { - is IntArrayTag -> this.asIntArray - is LongArrayTag -> { - val array = this.asLongArray - IntArray(array.size) { array[it].toInt() } + get() = + when (this) { + is IntArrayTag -> this.asIntArray + is LongArrayTag -> { + val array = this.asLongArray + IntArray(array.size) { array[it].toInt() } + } + is ByteArrayTag -> { + val array = this.asByteArray + IntArray(array.size) { array[it].toInt() } + } + else -> IntArray(0) } - is ByteArrayTag -> { - val array = this.asByteArray - IntArray(array.size) { array[it].toInt() } - } - else -> IntArray(0) - } val Tag.asByteArray: ByteArray - get() = when (this) { - is ByteArrayTag -> this.asByteArray - is LongArrayTag -> { - val array = this.asLongArray - ByteArray(array.size) { array[it].toByte() } - } - is IntArrayTag -> { - val array = this.asIntArray - ByteArray(array.size) { array[it].toByte() } + get() = + when (this) { + is ByteArrayTag -> this.asByteArray + is LongArrayTag -> { + val array = this.asLongArray + ByteArray(array.size) { array[it].toByte() } + } + is IntArrayTag -> { + val array = this.asIntArray + ByteArray(array.size) { array[it].toByte() } + } + else -> ByteArray(0) } - else -> ByteArray(0) - } -val Tag.asCompound get() = this as? CompoundTag ?: CompoundTag() +val Tag.asCompound + get() = this as? CompoundTag ?: CompoundTag() // asString is defined in Tag -val Tag.asList get() = this as? ListTag ?: ListTag() -val Tag.asUUID: UUID get() = if (this is IntArrayTag && this.size == 4) NbtUtils.loadUUID(this) else UUID(0, 0) +val Tag.asList + get() = this as? ListTag ?: ListTag() +val Tag.asUUID: UUID + get() = if (this is IntArrayTag && this.size == 4) NbtUtils.loadUUID(this) else UUID(0, 0) // ========================================================================================================== ItemStack // Checks for containment fun ItemStack.hasNumber(key: String) = tag.hasNumber(key) + fun ItemStack.hasByte(key: String) = tag.hasByte(key) + fun ItemStack.hasShort(key: String) = tag.hasShort(key) + fun ItemStack.hasInt(key: String) = tag.hasInt(key) + fun ItemStack.hasLong(key: String) = tag.hasLong(key) + fun ItemStack.hasFloat(key: String) = tag.hasFloat(key) + fun ItemStack.hasDouble(key: String) = tag.hasDouble(key) + fun ItemStack.hasLongArray(key: String) = tag.hasLongArray(key) + fun ItemStack.hasIntArray(key: String) = tag.hasIntArray(key) + fun ItemStack.hasByteArray(key: String) = tag.hasByteArray(key) + fun ItemStack.hasCompound(key: String) = tag.hasCompound(key) + fun ItemStack.hasString(key: String) = tag.hasString(key) + fun ItemStack.hasList(key: String) = tag.hasList(key) + fun ItemStack.hasList(key: String, objType: Int) = tag.hasList(key, objType) + fun ItemStack.hasList(key: String, objType: Byte) = tag.hasList(key, objType) + fun ItemStack.hasUUID(key: String) = tag.hasUUID(key) -@JvmName("contains") -fun ItemStack.containsTag(key: String) = tag.contains(key) +@JvmName("contains") fun ItemStack.containsTag(key: String) = tag.contains(key) -@JvmName("contains") -fun ItemStack.containsTag(key: String, id: Byte) = tag.contains(key, id) +@JvmName("contains") fun ItemStack.containsTag(key: String, id: Byte) = tag.contains(key, id) -@JvmName("contains") -fun ItemStack.containsTag(key: String, id: Int) = tag.contains(key, id) +@JvmName("contains") fun ItemStack.containsTag(key: String, id: Int) = tag.contains(key, id) // Puts fun ItemStack.putBoolean(key: String, value: Boolean) = orCreateTag.putBoolean(key, value) + fun ItemStack.putByte(key: String, value: Byte) = orCreateTag.putByte(key, value) + fun ItemStack.putShort(key: String, value: Short) = orCreateTag.putShort(key, value) + fun ItemStack.putInt(key: String, value: Int) = orCreateTag.putInt(key, value) + fun ItemStack.putLong(key: String, value: Long) = orCreateTag.putLong(key, value) + fun ItemStack.putFloat(key: String, value: Float) = orCreateTag.putFloat(key, value) + fun ItemStack.putDouble(key: String, value: Double) = orCreateTag.putDouble(key, value) fun ItemStack.putLongArray(key: String, value: LongArray) = orCreateTag.putLongArray(key, value) + fun ItemStack.putIntArray(key: String, value: IntArray) = orCreateTag.putIntArray(key, value) + fun ItemStack.putByteArray(key: String, value: ByteArray) = orCreateTag.putByteArray(key, value) + fun ItemStack.putCompound(key: String, value: CompoundTag) = putTag(key, value) + fun ItemStack.putString(key: String, value: String) = orCreateTag.putString(key, value) + fun ItemStack.putList(key: String, value: ListTag) = putTag(key, value) + fun ItemStack.putUUID(key: String, value: UUID) = orCreateTag.putUUID(key, value) -@JvmName("put") -fun ItemStack.putTag(key: String, value: Tag) = orCreateTag.put(key, value) +@JvmName("put") fun ItemStack.putTag(key: String, value: Tag) = orCreateTag.put(key, value) // Remove @@ -235,7 +324,8 @@ fun ItemStack.remove(key: String) = removeTagKey(key) // Gets @JvmOverloads -fun ItemStack.getBoolean(key: String, defaultExpected: Boolean = false) = tag.getBoolean(key, defaultExpected) +fun ItemStack.getBoolean(key: String, defaultExpected: Boolean = false) = + tag.getBoolean(key, defaultExpected) @JvmOverloads fun ItemStack.getByte(key: String, defaultExpected: Byte = 0) = tag.getByte(key, defaultExpected) @@ -250,24 +340,34 @@ fun ItemStack.getInt(key: String, defaultExpected: Int = 0) = tag.getInt(key, de fun ItemStack.getLong(key: String, defaultExpected: Long = 0) = tag.getLong(key, defaultExpected) @JvmOverloads -fun ItemStack.getFloat(key: String, defaultExpected: Float = 0f) = tag.getFloat(key, defaultExpected) +fun ItemStack.getFloat(key: String, defaultExpected: Float = 0f) = + tag.getFloat(key, defaultExpected) @JvmOverloads -fun ItemStack.getDouble(key: String, defaultExpected: Double = 0.0) = tag.getDouble(key, defaultExpected) +fun ItemStack.getDouble(key: String, defaultExpected: Double = 0.0) = + tag.getDouble(key, defaultExpected) fun ItemStack.getLongArray(key: String) = tag.getLongArray(key) + fun ItemStack.getIntArray(key: String) = tag.getIntArray(key) + fun ItemStack.getByteArray(key: String) = tag.getByteArray(key) + fun ItemStack.getCompound(key: String) = tag.getCompound(key) + fun ItemStack.getString(key: String) = tag.getString(key) + fun ItemStack.getList(key: String, objType: Int) = tag.getList(key, objType) + fun ItemStack.getUUID(key: String) = tag.getUUID(key) -@JvmName("get") -fun ItemStack.getTag(key: String) = tag.get(key) +@JvmName("get") fun ItemStack.getTag(key: String) = tag.get(key) // Get-or-create fun ItemStack.getOrCreateCompound(key: String): CompoundTag = getOrCreateTagElement(key) -fun ItemStack.getOrCreateList(key: String, objType: Byte) = orCreateTag.getOrCreateList(key, objType) + +fun ItemStack.getOrCreateList(key: String, objType: Byte) = + orCreateTag.getOrCreateList(key, objType) + fun ItemStack.getOrCreateList(key: String, objType: Int) = orCreateTag.getOrCreateList(key, objType) diff --git a/Common/src/main/java/at/petrak/hexcasting/client/ClientTickCounter.java b/Common/src/main/java/at/petrak/hexcasting/client/ClientTickCounter.java index e45ba75643..90086757ee 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/ClientTickCounter.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/ClientTickCounter.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.client; import at.petrak.hexcasting.client.render.GaslightingTracker; + import net.minecraft.client.Minecraft; public class ClientTickCounter { diff --git a/Common/src/main/java/at/petrak/hexcasting/client/PatternShapeMatcher.java b/Common/src/main/java/at/petrak/hexcasting/client/PatternShapeMatcher.java index dbe366ceb9..b8867c5aa2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/PatternShapeMatcher.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/PatternShapeMatcher.java @@ -1,4 +1,3 @@ package at.petrak.hexcasting.client; -public class PatternShapeMatcher { -} +public class PatternShapeMatcher {} diff --git a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java index 75658fa63a..950c7b62a2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java @@ -1,5 +1,7 @@ package at.petrak.hexcasting.client; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.api.casting.iota.IotaType; import at.petrak.hexcasting.api.item.IotaHolderItem; import at.petrak.hexcasting.api.item.MediaHolderItem; @@ -24,13 +26,13 @@ import at.petrak.hexcasting.common.lib.HexBlocks; import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; + import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBakery; -import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; @@ -39,65 +41,80 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; + import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.function.*; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - public class RegisterClientStuff { public static Map> QUENCHED_ALLAY_VARIANTS = new HashMap<>(); - private static final Map QUENCHED_ALLAY_TYPES = Map.of( - HexBlocks.QUENCHED_ALLAY, false, - HexBlocks.QUENCHED_ALLAY_TILES, true, - HexBlocks.QUENCHED_ALLAY_BRICKS, true, - HexBlocks.QUENCHED_ALLAY_BRICKS_SMALL, true); + private static final Map QUENCHED_ALLAY_TYPES = + Map.of( + HexBlocks.QUENCHED_ALLAY, false, + HexBlocks.QUENCHED_ALLAY_TILES, true, + HexBlocks.QUENCHED_ALLAY_BRICKS, true, + HexBlocks.QUENCHED_ALLAY_BRICKS_SMALL, true); public static void init() { - registerSealableDataHolderOverrides(HexItems.FOCUS, - stack -> HexItems.FOCUS.readIotaTag(stack) != null, - ItemFocus::isSealed); - registerSealableDataHolderOverrides(HexItems.SPELLBOOK, - stack -> HexItems.SPELLBOOK.readIotaTag(stack) != null, - ItemSpellbook::isSealed); + registerSealableDataHolderOverrides( + HexItems.FOCUS, + stack -> HexItems.FOCUS.readIotaTag(stack) != null, + ItemFocus::isSealed); + registerSealableDataHolderOverrides( + HexItems.SPELLBOOK, + stack -> HexItems.SPELLBOOK.readIotaTag(stack) != null, + ItemSpellbook::isSealed); registerVariantOverrides(HexItems.FOCUS, HexItems.FOCUS::getVariant); registerVariantOverrides(HexItems.SPELLBOOK, HexItems.SPELLBOOK::getVariant); registerVariantOverrides(HexItems.CYPHER, HexItems.CYPHER::getVariant); registerVariantOverrides(HexItems.TRINKET, HexItems.TRINKET::getVariant); registerVariantOverrides(HexItems.ARTIFACT, HexItems.ARTIFACT::getVariant); - IClientXplatAbstractions.INSTANCE.registerItemProperty(HexItems.THOUGHT_KNOT, ItemThoughtKnot.WRITTEN_PRED, - (stack, level, holder, holderID) -> { - if (NBTHelper.contains(stack, ItemThoughtKnot.TAG_DATA)) { - return 1; - } else { - return 0; - } - }); + IClientXplatAbstractions.INSTANCE.registerItemProperty( + HexItems.THOUGHT_KNOT, + ItemThoughtKnot.WRITTEN_PRED, + (stack, level, holder, holderID) -> { + if (NBTHelper.contains(stack, ItemThoughtKnot.TAG_DATA)) { + return 1; + } else { + return 0; + } + }); registerPackagedSpellOverrides(HexItems.CYPHER); registerPackagedSpellOverrides(HexItems.TRINKET); registerPackagedSpellOverrides(HexItems.ARTIFACT); var x = IClientXplatAbstractions.INSTANCE; - x.registerItemProperty(HexItems.BATTERY, ItemMediaBattery.MEDIA_PREDICATE, - (stack, level, holder, holderID) -> { - var item = (MediaHolderItem) stack.getItem(); - return item.getMediaFullness(stack); - }); - x.registerItemProperty(HexItems.BATTERY, ItemMediaBattery.MAX_MEDIA_PREDICATE, - (stack, level, holder, holderID) -> { - var item = (ItemMediaBattery) stack.getItem(); - var max = item.getMaxMedia(stack); - return 1.049658f * (float) Math.log((float) max / MediaConstants.CRYSTAL_UNIT + 9.06152f) - 2.1436f; - }); + x.registerItemProperty( + HexItems.BATTERY, + ItemMediaBattery.MEDIA_PREDICATE, + (stack, level, holder, holderID) -> { + var item = (MediaHolderItem) stack.getItem(); + return item.getMediaFullness(stack); + }); + x.registerItemProperty( + HexItems.BATTERY, + ItemMediaBattery.MAX_MEDIA_PREDICATE, + (stack, level, holder, holderID) -> { + var item = (ItemMediaBattery) stack.getItem(); + var max = item.getMaxMedia(stack); + return 1.049658f + * (float) + Math.log( + (float) max / MediaConstants.CRYSTAL_UNIT + + 9.06152f) + - 2.1436f; + }); registerScrollOverrides(HexItems.SCROLL_SMOL); registerScrollOverrides(HexItems.SCROLL_MEDIUM); registerScrollOverrides(HexItems.SCROLL_LARGE); - x.registerItemProperty(HexItems.SLATE, ItemSlate.WRITTEN_PRED, - (stack, level, holder, holderID) -> ItemSlate.hasPattern(stack) ? 1f : 0f); + x.registerItemProperty( + HexItems.SLATE, + ItemSlate.WRITTEN_PRED, + (stack, level, holder, holderID) -> ItemSlate.hasPattern(stack) ? 1f : 0f); registerWandOverrides(HexItems.STAFF_OAK); registerWandOverrides(HexItems.STAFF_BIRCH); @@ -132,49 +149,59 @@ public static void init() { x.registerEntityRenderer(HexEntities.WALL_SCROLL, WallScrollRenderer::new); -// for (var tex : new ResourceLocation[]{ -// PatternTooltipComponent.PRISTINE_BG, -// PatternTooltipComponent.ANCIENT_BG, -// PatternTooltipComponent.SLATE_BG -// }) { -// Minecraft.getInstance().getTextureManager().bindForSetup(tex); -// } + // for (var tex : new ResourceLocation[]{ + // PatternTooltipComponent.PRISTINE_BG, + // PatternTooltipComponent.ANCIENT_BG, + // PatternTooltipComponent.SLATE_BG + // }) { + // Minecraft.getInstance().getTextureManager().bindForSetup(tex); + // } ScryingLensOverlays.addScryingLensStuff(); } private static void registerGaslight4(Item item) { - IClientXplatAbstractions.INSTANCE.registerItemProperty(item, - GaslightingTracker.GASLIGHTING_PRED, (stack, level, holder, holderID) -> - Math.abs(GaslightingTracker.getGaslightingAmount() % 4)); + IClientXplatAbstractions.INSTANCE.registerItemProperty( + item, + GaslightingTracker.GASLIGHTING_PRED, + (stack, level, holder, holderID) -> + Math.abs(GaslightingTracker.getGaslightingAmount() % 4)); } - public static void registerColorProviders(BiConsumer itemColorRegistry, - BiConsumer blockColorRegistry) { - itemColorRegistry.accept(makeIotaStorageColorizer(HexItems.FOCUS::getColor), HexItems.FOCUS); - itemColorRegistry.accept(makeIotaStorageColorizer(HexItems.SPELLBOOK::getColor), HexItems.SPELLBOOK); - itemColorRegistry.accept(makeIotaStorageColorizer(HexItems.THOUGHT_KNOT::getColor), HexItems.THOUGHT_KNOT); - - blockColorRegistry.accept((bs, level, pos, idx) -> { - if (!bs.getValue(BlockAkashicBookshelf.HAS_BOOKS) || level == null || pos == null) { - return 0xff_ffffff; - } - var tile = level.getBlockEntity(pos); - if (!(tile instanceof BlockEntityAkashicBookshelf beas)) { - // this gets called for particles for some irritating reason - return 0xff_ffffff; - } - var iotaTag = beas.getIotaTag(); - if (iotaTag == null) { - return 0xff_ffffff; - } - return IotaType.getColor(iotaTag); - }, HexBlocks.AKASHIC_BOOKSHELF); + public static void registerColorProviders( + BiConsumer itemColorRegistry, + BiConsumer blockColorRegistry) { + itemColorRegistry.accept( + makeIotaStorageColorizer(HexItems.FOCUS::getColor), HexItems.FOCUS); + itemColorRegistry.accept( + makeIotaStorageColorizer(HexItems.SPELLBOOK::getColor), HexItems.SPELLBOOK); + itemColorRegistry.accept( + makeIotaStorageColorizer(HexItems.THOUGHT_KNOT::getColor), HexItems.THOUGHT_KNOT); + + blockColorRegistry.accept( + (bs, level, pos, idx) -> { + if (!bs.getValue(BlockAkashicBookshelf.HAS_BOOKS) + || level == null + || pos == null) { + return 0xff_ffffff; + } + var tile = level.getBlockEntity(pos); + if (!(tile instanceof BlockEntityAkashicBookshelf beas)) { + // this gets called for particles for some irritating reason + return 0xff_ffffff; + } + var iotaTag = beas.getIotaTag(); + if (iotaTag == null) { + return 0xff_ffffff; + } + return IotaType.getColor(iotaTag); + }, + HexBlocks.AKASHIC_BOOKSHELF); } /** - * Helper function to colorize the layers of an item that stores an iota, in the manner of foci and spellbooks. - *
+ * Helper function to colorize the layers of an item that stores an iota, in the manner of foci + * and spellbooks.
* 0 = base; 1 = overlay */ public static ItemColor makeIotaStorageColorizer(ToIntFunction getColor) { @@ -186,83 +213,97 @@ public static ItemColor makeIotaStorageColorizer(ToIntFunction getCol }; } - private static void registerSealableDataHolderOverrides(IotaHolderItem item, Predicate hasIota, - Predicate isSealed) { - IClientXplatAbstractions.INSTANCE.registerItemProperty((Item) item, ItemFocus.OVERLAY_PRED, - (stack, level, holder, holderID) -> { - if (!hasIota.test(stack) && !NBTHelper.hasString(stack, IotaHolderItem.TAG_OVERRIDE_VISUALLY)) { - return 0; - } - if (!isSealed.test(stack)) { - return 1; - } - return 2; - }); + private static void registerSealableDataHolderOverrides( + IotaHolderItem item, Predicate hasIota, Predicate isSealed) { + IClientXplatAbstractions.INSTANCE.registerItemProperty( + (Item) item, + ItemFocus.OVERLAY_PRED, + (stack, level, holder, holderID) -> { + if (!hasIota.test(stack) + && !NBTHelper.hasString(stack, IotaHolderItem.TAG_OVERRIDE_VISUALLY)) { + return 0; + } + if (!isSealed.test(stack)) { + return 1; + } + return 2; + }); } - private static void registerVariantOverrides(VariantItem item, Function variant) { - IClientXplatAbstractions.INSTANCE.registerItemProperty((Item) item, ItemFocus.VARIANT_PRED, + private static void registerVariantOverrides( + VariantItem item, Function variant) { + IClientXplatAbstractions.INSTANCE.registerItemProperty( + (Item) item, + ItemFocus.VARIANT_PRED, (stack, level, holder, holderID) -> variant.apply(stack)); } private static void registerScrollOverrides(ItemScroll scroll) { - IClientXplatAbstractions.INSTANCE.registerItemProperty(scroll, ItemScroll.ANCIENT_PREDICATE, - (stack, level, holder, holderID) -> NBTHelper.hasString(stack, ItemScroll.TAG_OP_ID) ? 1f : 0f); + IClientXplatAbstractions.INSTANCE.registerItemProperty( + scroll, + ItemScroll.ANCIENT_PREDICATE, + (stack, level, holder, holderID) -> + NBTHelper.hasString(stack, ItemScroll.TAG_OP_ID) ? 1f : 0f); } private static void registerPackagedSpellOverrides(ItemPackagedHex item) { - IClientXplatAbstractions.INSTANCE.registerItemProperty(item, ItemPackagedHex.HAS_PATTERNS_PRED, - (stack, level, holder, holderID) -> - item.hasHex(stack) ? 1f : 0f - ); + IClientXplatAbstractions.INSTANCE.registerItemProperty( + item, + ItemPackagedHex.HAS_PATTERNS_PRED, + (stack, level, holder, holderID) -> item.hasHex(stack) ? 1f : 0f); } private static void registerWandOverrides(ItemStaff item) { - IClientXplatAbstractions.INSTANCE.registerItemProperty(item, ItemStaff.FUNNY_LEVEL_PREDICATE, - (stack, level, holder, holderID) -> { - if (!stack.hasCustomHoverName()) { - return 0; - } - var name = stack.getHoverName().getString().toLowerCase(Locale.ROOT); - if (name.contains("old")) { - return 1f; - } else if (name.contains("cherry")) { - return 2f; - } else { - return 0f; - } - }); + IClientXplatAbstractions.INSTANCE.registerItemProperty( + item, + ItemStaff.FUNNY_LEVEL_PREDICATE, + (stack, level, holder, holderID) -> { + if (!stack.hasCustomHoverName()) { + return 0; + } + var name = stack.getHoverName().getString().toLowerCase(Locale.ROOT); + if (name.contains("old")) { + return 1f; + } else if (name.contains("cherry")) { + return 2f; + } else { + return 0f; + } + }); } - public static void registerBlockEntityRenderers(@NotNull BlockEntityRendererRegisterererer registerer) { - registerer.registerBlockEntityRenderer(HexBlockEntities.SLATE_TILE, BlockEntitySlateRenderer::new); - registerer.registerBlockEntityRenderer(HexBlockEntities.AKASHIC_BOOKSHELF_TILE, - BlockEntityAkashicBookshelfRenderer::new); - registerer.registerBlockEntityRenderer(HexBlockEntities.QUENCHED_ALLAY_TILE, - BlockEntityQuenchedAllayRenderer::new); - registerer.registerBlockEntityRenderer(HexBlockEntities.QUENCHED_ALLAY_TILES_TILE, - BlockEntityQuenchedAllayRenderer::new); - registerer.registerBlockEntityRenderer(HexBlockEntities.QUENCHED_ALLAY_BRICKS_TILE, - BlockEntityQuenchedAllayRenderer::new); - registerer.registerBlockEntityRenderer(HexBlockEntities.QUENCHED_ALLAY_BRICKS_SMALL_TILE, + public static void registerBlockEntityRenderers( + @NotNull BlockEntityRendererRegisterererer registerer) { + registerer.registerBlockEntityRenderer( + HexBlockEntities.SLATE_TILE, BlockEntitySlateRenderer::new); + registerer.registerBlockEntityRenderer( + HexBlockEntities.AKASHIC_BOOKSHELF_TILE, BlockEntityAkashicBookshelfRenderer::new); + registerer.registerBlockEntityRenderer( + HexBlockEntities.QUENCHED_ALLAY_TILE, BlockEntityQuenchedAllayRenderer::new); + registerer.registerBlockEntityRenderer( + HexBlockEntities.QUENCHED_ALLAY_TILES_TILE, BlockEntityQuenchedAllayRenderer::new); + registerer.registerBlockEntityRenderer( + HexBlockEntities.QUENCHED_ALLAY_BRICKS_TILE, BlockEntityQuenchedAllayRenderer::new); + registerer.registerBlockEntityRenderer( + HexBlockEntities.QUENCHED_ALLAY_BRICKS_SMALL_TILE, BlockEntityQuenchedAllayRenderer::new); } @FunctionalInterface public interface BlockEntityRendererRegisterererer { - void registerBlockEntityRenderer(BlockEntityType type, - BlockEntityRendererProvider berp); + void registerBlockEntityRenderer( + BlockEntityType type, BlockEntityRendererProvider berp); } - public static void onModelRegister(ResourceManager recMan, Consumer extraModels) { + public static void onModelRegister( + ResourceManager recMan, Consumer extraModels) { for (var type : QUENCHED_ALLAY_TYPES.entrySet()) { var blockLoc = BuiltInRegistries.BLOCK.getKey(type.getKey()); var locStart = "block/"; - if (type.getValue()) - locStart += "deco/"; + if (type.getValue()) locStart += "deco/"; for (int i = 0; i < BlockQuenchedAllay.VARIANTS; i++) { - extraModels.accept(modLoc( locStart + blockLoc.getPath() + "_" + i)); + extraModels.accept(modLoc(locStart + blockLoc.getPath() + "_" + i)); } } } @@ -271,8 +312,7 @@ public static void onModelBake(ModelBakery loader, Map(); for (int i = 0; i < BlockQuenchedAllay.VARIANTS; i++) { diff --git a/Common/src/main/java/at/petrak/hexcasting/client/ShiftScrollListener.java b/Common/src/main/java/at/petrak/hexcasting/client/ShiftScrollListener.java index c6073517cc..73efb2079f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/ShiftScrollListener.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/ShiftScrollListener.java @@ -4,6 +4,7 @@ import at.petrak.hexcasting.common.lib.HexItems; import at.petrak.hexcasting.common.msgs.MsgShiftScrollC2S; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; + import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.item.Item; @@ -45,9 +46,12 @@ public static boolean onScroll(double delta, boolean needsSneaking) { public static void clientTickEnd() { if (mainHandDelta != 0 || offHandDelta != 0) { IClientXplatAbstractions.INSTANCE.sendPacketToServer( - new MsgShiftScrollC2S(mainHandDelta, offHandDelta, Minecraft.getInstance().options.keySprint.isDown(), - HexConfig.client().invertSpellbookScrollDirection(), - HexConfig.client().invertAbacusScrollDirection())); + new MsgShiftScrollC2S( + mainHandDelta, + offHandDelta, + Minecraft.getInstance().options.keySprint.isDown(), + HexConfig.client().invertSpellbookScrollDirection(), + HexConfig.client().invertAbacusScrollDirection())); mainHandDelta = 0; offHandDelta = 0; } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java index d17e617cd9..0f2f6058df 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java @@ -1,11 +1,15 @@ package at.petrak.hexcasting.client.entity; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.client.render.WorldlyPatternRenderHelpers; import at.petrak.hexcasting.common.entities.EntityWallScroll; + import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Axis; + import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; @@ -14,18 +18,23 @@ import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.resources.ResourceLocation; + import org.joml.Matrix3f; import org.joml.Matrix4f; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - public class WallScrollRenderer extends EntityRenderer { - private static final ResourceLocation PRISTINE_BG_LARGE = modLoc("textures/entity/scroll_large.png"); - private static final ResourceLocation PRISTINE_BG_MEDIUM = modLoc("textures/entity/scroll_medium.png"); - private static final ResourceLocation PRISTINE_BG_SMOL = modLoc("textures/block/scroll_paper.png"); - private static final ResourceLocation ANCIENT_BG_LARGE = modLoc("textures/entity/scroll_ancient_large.png"); - private static final ResourceLocation ANCIENT_BG_MEDIUM = modLoc("textures/entity/scroll_ancient_medium.png"); - private static final ResourceLocation ANCIENT_BG_SMOL = modLoc("textures/block/ancient_scroll_paper.png"); + private static final ResourceLocation PRISTINE_BG_LARGE = + modLoc("textures/entity/scroll_large.png"); + private static final ResourceLocation PRISTINE_BG_MEDIUM = + modLoc("textures/entity/scroll_medium.png"); + private static final ResourceLocation PRISTINE_BG_SMOL = + modLoc("textures/block/scroll_paper.png"); + private static final ResourceLocation ANCIENT_BG_LARGE = + modLoc("textures/entity/scroll_ancient_large.png"); + private static final ResourceLocation ANCIENT_BG_MEDIUM = + modLoc("textures/entity/scroll_ancient_medium.png"); + private static final ResourceLocation ANCIENT_BG_SMOL = + modLoc("textures/block/ancient_scroll_paper.png"); public WallScrollRenderer(EntityRendererProvider.Context p_174008_) { super(p_174008_); @@ -33,8 +42,13 @@ public WallScrollRenderer(EntityRendererProvider.Context p_174008_) { // I do as the PaintingRenderer guides @Override - public void render(EntityWallScroll wallScroll, float yaw, float partialTicks, PoseStack ps, - MultiBufferSource bufSource, int packedLight) { + public void render( + EntityWallScroll wallScroll, + float yaw, + float partialTicks, + PoseStack ps, + MultiBufferSource bufSource, + int packedLight) { RenderSystem.setShader(GameRenderer::getPositionTexShader); @@ -95,8 +109,15 @@ public void render(EntityWallScroll wallScroll, float yaw, float partialTicks, P ps.popPose(); - if(wallScroll.pattern != null) - WorldlyPatternRenderHelpers.renderPatternForScroll(wallScroll.pattern, wallScroll, ps, bufSource, light, wallScroll.blockSize, wallScroll.getShowsStrokeOrder()); + if (wallScroll.pattern != null) + WorldlyPatternRenderHelpers.renderPatternForScroll( + wallScroll.pattern, + wallScroll, + ps, + bufSource, + light, + wallScroll.blockSize, + wallScroll.getShowsStrokeOrder()); } ps.popPose(); @@ -124,12 +145,24 @@ public ResourceLocation getTextureLocation(EntityWallScroll wallScroll) { } } - private static void vertex(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts, float x, float y, - float z, float u, - float v, float nx, float ny, float nz) { + private static void vertex( + Matrix4f mat, + Matrix3f normal, + int light, + VertexConsumer verts, + float x, + float y, + float z, + float u, + float v, + float nx, + float ny, + float nz) { verts.vertex(mat, x, y, z) .color(0xffffffff) - .uv(u, v).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(light) + .uv(u, v) + .overlayCoords(OverlayTexture.NO_OVERLAY) + .uv2(light) .normal(normal, nx, ny, nz) .endVertex(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt index 0a9f66cd2b..066c92fca8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/gui/GuiSpellcasting.kt @@ -22,6 +22,7 @@ import at.petrak.hexcasting.common.msgs.MsgNewSpellPatternC2S import at.petrak.hexcasting.xplat.IClientXplatAbstractions import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.PoseStack +import kotlin.math.* import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.screens.Screen @@ -34,10 +35,10 @@ import net.minecraft.util.FormattedCharSequence import net.minecraft.util.Mth import net.minecraft.world.InteractionHand import net.minecraft.world.phys.Vec2 -import kotlin.math.* // TODO winfy: fix this class to use ExecutionClientView -class GuiSpellcasting constructor( +class GuiSpellcasting +constructor( private val handOpenedWith: InteractionHand, private var patterns: MutableList, private var cachedStack: List, @@ -70,11 +71,13 @@ class GuiSpellcasting constructor( // TODO this is the kinda hacky bit if (info.resolutionType == ResolvedPatternType.UNDONE) { - this.patterns.reversed().drop(1).firstOrNull { it.type == ResolvedPatternType.ESCAPED }?.let { it.type = ResolvedPatternType.UNDONE } + this.patterns + .reversed() + .drop(1) + .firstOrNull { it.type == ResolvedPatternType.ESCAPED } + ?.let { it.type = ResolvedPatternType.UNDONE } this.patterns.getOrNull(index)?.let { it.type = ResolvedPatternType.EVALUATED } - } else this.patterns.getOrNull(index)?.let { - it.type = info.resolutionType - } + } else this.patterns.getOrNull(index)?.let { it.type = info.resolutionType } this.cachedStack = info.stackDescs this.cachedRavenmind = info.ravenmind @@ -85,22 +88,21 @@ class GuiSpellcasting constructor( val mc = Minecraft.getInstance() val width = (this.width * LHS_IOTAS_ALLOCATION).toInt() this.stackDescs = - this.cachedStack.map { IotaType.getDisplayWithMaxWidth(it, width, mc.font) } + this.cachedStack + .map { IotaType.getDisplayWithMaxWidth(it, width, mc.font) } .asReversed() -// this.parenDescs = if (this.cachedParens.isNotEmpty()) -// this.cachedParens.flatMap { HexIotaTypes.getDisplayWithMaxWidth(it, width, mc.font) } -// else if (this.parenCount > 0) -// listOf("...".gold.visualOrderText) -// else -// emptyList() + // this.parenDescs = if (this.cachedParens.isNotEmpty()) + // this.cachedParens.flatMap { HexIotaTypes.getDisplayWithMaxWidth(it, width, + // mc.font) } + // else if (this.parenCount > 0) + // listOf("...".gold.visualOrderText) + // else + // emptyList() this.parenDescs = emptyList() this.ravenmind = this.cachedRavenmind?.let { IotaType.getDisplayWithMaxWidth( - it, - (this.width * RHS_IOTAS_ALLOCATION).toInt(), - mc.font - ) + it, (this.width * RHS_IOTAS_ALLOCATION).toInt(), mc.font) } } @@ -122,8 +124,7 @@ class GuiSpellcasting constructor( val player = minecraft.player if (player != null) { val heldItem = player.getItemInHand(handOpenedWith) - if (heldItem.isEmpty || !heldItem.`is`(HexTags.Items.STAVES)) - closeForReal() + if (heldItem.isEmpty || !heldItem.`is`(HexTags.Items.STAVES)) closeForReal() } } @@ -132,10 +133,8 @@ class GuiSpellcasting constructor( return true } if (HexConfig.client().clickingTogglesDrawing()) { - return if (this.drawState is PatternDrawState.BetweenPatterns) - drawStart(mxOut, myOut) - else - drawEnd() + return if (this.drawState is PatternDrawState.BetweenPatterns) drawStart(mxOut, myOut) + else drawEnd() } return drawStart(mxOut, myOut) } @@ -147,18 +146,19 @@ class GuiSpellcasting constructor( val coord = this.pxToCoord(Vec2(mx.toFloat(), my.toFloat())) if (!this.usedSpots.contains(coord)) { this.drawState = PatternDrawState.JustStarted(coord) - Minecraft.getInstance().soundManager.play( - SimpleSoundInstance( - HexSounds.START_PATTERN, - SoundSource.PLAYERS, - 0.25f, - 1f, - randSrc, - this.ambianceSoundInstance!!.x, - this.ambianceSoundInstance!!.y, - this.ambianceSoundInstance!!.z, - ) - ) + Minecraft.getInstance() + .soundManager + .play( + SimpleSoundInstance( + HexSounds.START_PATTERN, + SoundSource.PLAYERS, + 0.25f, + 1f, + randSrc, + this.ambianceSoundInstance!!.x, + this.ambianceSoundInstance!!.y, + this.ambianceSoundInstance!!.z, + )) } } @@ -168,16 +168,22 @@ class GuiSpellcasting constructor( override fun mouseMoved(mxOut: Double, myOut: Double) { super.mouseMoved(mxOut, myOut) - if (HexConfig.client().clickingTogglesDrawing() && this.drawState !is PatternDrawState.BetweenPatterns) + if (HexConfig.client().clickingTogglesDrawing() && + this.drawState !is PatternDrawState.BetweenPatterns) drawMove(mxOut, myOut) } - override fun mouseDragged(mxOut: Double, myOut: Double, pButton: Int, pDragX: Double, pDragY: Double): Boolean { + override fun mouseDragged( + mxOut: Double, + myOut: Double, + pButton: Int, + pDragX: Double, + pDragY: Double + ): Boolean { if (super.mouseDragged(mxOut, myOut, pButton, pDragX, pDragY)) { return true } - if (HexConfig.client().clickingTogglesDrawing()) - return false + if (HexConfig.client().clickingTogglesDrawing()) return false return drawMove(mxOut, myOut) } @@ -185,16 +191,21 @@ class GuiSpellcasting constructor( val mx = Mth.clamp(mxOut, 0.0, this.width.toDouble()) val my = Mth.clamp(myOut, 0.0, this.height.toDouble()) - val anchorCoord = when (this.drawState) { - PatternDrawState.BetweenPatterns -> null - is PatternDrawState.JustStarted -> (this.drawState as PatternDrawState.JustStarted).start - is PatternDrawState.Drawing -> (this.drawState as PatternDrawState.Drawing).current - } + val anchorCoord = + when (this.drawState) { + PatternDrawState.BetweenPatterns -> null + is PatternDrawState.JustStarted -> + (this.drawState as PatternDrawState.JustStarted).start + is PatternDrawState.Drawing -> (this.drawState as PatternDrawState.Drawing).current + } if (anchorCoord != null) { val anchor = this.coordToPx(anchorCoord) val mouse = Vec2(mx.toFloat(), my.toFloat()) val snapDist = - this.hexSize() * this.hexSize() * 2.0 * Mth.clamp(HexConfig.client().gridSnapThreshold(), 0.5, 1.0) + this.hexSize() * + this.hexSize() * + 2.0 * + Mth.clamp(HexConfig.client().gridSnapThreshold(), 0.5, 1.0) if (anchor.distanceToSqr(mouse) >= snapDist) { val delta = mouse.add(anchor.negated()) val angle = atan2(delta.y, delta.x) @@ -235,18 +246,19 @@ class GuiSpellcasting constructor( } if (playSound) { - Minecraft.getInstance().soundManager.play( - SimpleSoundInstance( - HexSounds.ADD_TO_PATTERN, - SoundSource.PLAYERS, - 0.25f, - 1f + (Math.random().toFloat() - 0.5f) * 0.1f, - randSrc, - this.ambianceSoundInstance!!.x, - this.ambianceSoundInstance!!.y, - this.ambianceSoundInstance!!.z, - ) - ) + Minecraft.getInstance() + .soundManager + .play( + SimpleSoundInstance( + HexSounds.ADD_TO_PATTERN, + SoundSource.PLAYERS, + 0.25f, + 1f + (Math.random().toFloat() - 0.5f) * 0.1f, + randSrc, + this.ambianceSoundInstance!!.x, + this.ambianceSoundInstance!!.y, + this.ambianceSoundInstance!!.z, + )) } } } @@ -258,8 +270,7 @@ class GuiSpellcasting constructor( if (super.mouseReleased(mx, my, pButton)) { return true } - if (HexConfig.client().clickingTogglesDrawing()) - return false + if (HexConfig.client().clickingTogglesDrawing()) return false return drawEnd() } @@ -279,12 +290,7 @@ class GuiSpellcasting constructor( this.usedSpots.addAll(pat.positions(start)) IClientXplatAbstractions.INSTANCE.sendPacketToServer( - MsgNewSpellPatternC2S( - this.handOpenedWith, - pat, - this.patterns - ) - ) + MsgNewSpellPatternC2S(this.handOpenedWith, pat, this.patterns)) } } @@ -296,7 +302,8 @@ class GuiSpellcasting constructor( val mouseHandler = Minecraft.getInstance().mouseHandler - if (mouseHandler.accumulatedScroll != 0.0 && sign(pDelta) != sign(mouseHandler.accumulatedScroll)) { + if (mouseHandler.accumulatedScroll != 0.0 && + sign(pDelta) != sign(mouseHandler.accumulatedScroll)) { mouseHandler.accumulatedScroll = 0.0 } @@ -314,10 +321,8 @@ class GuiSpellcasting constructor( } override fun onClose() { - if (drawState == PatternDrawState.BetweenPatterns) - closeForReal() - else - drawState = PatternDrawState.BetweenPatterns + if (drawState == PatternDrawState.BetweenPatterns) closeForReal() + else drawState = PatternDrawState.BetweenPatterns } fun closeForReal() { @@ -326,7 +331,6 @@ class GuiSpellcasting constructor( super.onClose() } - override fun render(graphics: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTick: Float) { super.render(graphics, pMouseX, pMouseY, pPartialTick) @@ -351,13 +355,15 @@ class GuiSpellcasting constructor( val dotPx = this.coordToPx(dotCoord) val delta = dotPx.add(mousePos.negated()).length() // when right on top of the cursor, 1.0 - // when at the full radius, 0! this is so we don't have dots suddenly appear/disappear. - // we subtract size from delta so there's a little "island" of 100% bright points by the mouse - val scaledDist = Mth.clamp( - 1.0f - ((delta - this.hexSize()) / (radius.toFloat() * this.hexSize())), - 0f, - 1f - ) + // when at the full radius, 0! this is so we don't have dots suddenly + // appear/disappear. + // we subtract size from delta so there's a little "island" of 100% bright points by + // the mouse + val scaledDist = + Mth.clamp( + 1.0f - ((delta - this.hexSize()) / (radius.toFloat() * this.hexSize())), + 0f, + 1f) drawSpot( mat, dotPx, @@ -365,8 +371,7 @@ class GuiSpellcasting constructor( Mth.lerp(scaledDist, 0.4f, 0.5f), Mth.lerp(scaledDist, 0.8f, 1.0f), Mth.lerp(scaledDist, 0.7f, 0.9f), - scaledDist - ) + scaledDist) } } RenderSystem.defaultBlendFunc() @@ -375,10 +380,7 @@ class GuiSpellcasting constructor( val (pat, origin, valid) = elts drawPatternFromPoints( mat, - pat.toLines( - this.hexSize(), - this.coordToPx(origin) - ), + pat.toLines(this.hexSize(), this.coordToPx(origin)), findDupIndices(pat.positions()), true, valid.color or (0xC8 shl 24), @@ -386,8 +388,7 @@ class GuiSpellcasting constructor( if (valid.success) 0.2f else 0.9f, DEFAULT_READABILITY_OFFSET, 1f, - idx.toDouble() - ) + idx.toDouble()) } // Now draw the currently WIP pattern @@ -408,8 +409,10 @@ class GuiSpellcasting constructor( } points.add(mousePos) - // Use the size of the patterns as the seed so that way when this one is added the zappies don't jump - drawPatternFromPoints(mat, + // Use the size of the patterns as the seed so that way when this one is added the + // zappies don't jump + drawPatternFromPoints( + mat, points, dupIndices, false, @@ -428,23 +431,24 @@ class GuiSpellcasting constructor( ps.pushPose() ps.translate(10.0, 10.0, 0.0) -// if (this.parenCount > 0) { -// val boxHeight = (this.parenDescs.size + 1f) * 10f -// RenderSystem.setShader(GameRenderer::getPositionColorShader) -// RenderSystem.defaultBlendFunc() -// drawBox(ps, 0f, 0f, (this.width * LHS_IOTAS_ALLOCATION + 5).toFloat(), boxHeight, 7.5f) -// ps.translate(0.0, 0.0, 1.0) -// -// val time = ClientTickCounter.getTotal() * 0.16f -// val opacity = (Mth.map(cos(time), -1f, 1f, 200f, 255f)).toInt() -// val color = 0x00_ffffff or (opacity shl 24) -// RenderSystem.setShader { prevShader } -// for (desc in this.parenDescs) { -// font.draw(ps, desc, 10f, 7f, color) -// ps.translate(0.0, 10.0, 0.0) -// } -// ps.translate(0.0, 15.0, 0.0) -// } + // if (this.parenCount > 0) { + // val boxHeight = (this.parenDescs.size + 1f) * 10f + // RenderSystem.setShader(GameRenderer::getPositionColorShader) + // RenderSystem.defaultBlendFunc() + // drawBox(ps, 0f, 0f, (this.width * LHS_IOTAS_ALLOCATION + 5).toFloat(), + // boxHeight, 7.5f) + // ps.translate(0.0, 0.0, 1.0) + // + // val time = ClientTickCounter.getTotal() * 0.16f + // val opacity = (Mth.map(cos(time), -1f, 1f, 200f, 255f)).toInt() + // val color = 0x00_ffffff or (opacity shl 24) + // RenderSystem.setShader { prevShader } + // for (desc in this.parenDescs) { + // font.draw(ps, desc, 10f, 7f, color) + // ps.translate(0.0, 10.0, 0.0) + // } + // ps.translate(0.0, 15.0, 0.0) + // } if (this.stackDescs.isNotEmpty()) { val boxHeight = (this.stackDescs.size + 1f) * 10f @@ -469,8 +473,11 @@ class GuiSpellcasting constructor( RenderSystem.setShader(GameRenderer::getPositionColorShader) RenderSystem.enableBlend() drawBox( - ps, 0f, 0f, - (this.width * RHS_IOTAS_ALLOCATION * addlScale).toFloat(), boxHeight * addlScale, + ps, + 0f, + 0f, + (this.width * RHS_IOTAS_ALLOCATION * addlScale).toFloat(), + boxHeight * addlScale, ) ps.translate(5.0, 5.0, 1.0) ps.scale(addlScale, addlScale, 1f) @@ -492,9 +499,11 @@ class GuiSpellcasting constructor( /** Distance between adjacent hex centers */ fun hexSize(): Float { - val scaleModifier = Minecraft.getInstance().player!!.getAttributeValue(HexAttributes.GRID_ZOOM) + val scaleModifier = + Minecraft.getInstance().player!!.getAttributeValue(HexAttributes.GRID_ZOOM) - // Originally, we allowed 32 dots across. Assuming a 1920x1080 screen this allowed like 500-odd area. + // Originally, we allowed 32 dots across. Assuming a 1920x1080 screen this allowed like + // 500-odd area. // Let's be generous and give them 512. val baseScale = sqrt(this.width.toDouble() * this.height / 512.0) return (baseScale / scaleModifier).toFloat() @@ -505,8 +514,8 @@ class GuiSpellcasting constructor( fun coordToPx(coord: HexCoord) = at.petrak.hexcasting.api.utils.coordToPx(coord, this.hexSize(), this.coordsOffset()) - fun pxToCoord(px: Vec2) = at.petrak.hexcasting.api.utils.pxToCoord(px, this.hexSize(), this.coordsOffset()) - + fun pxToCoord(px: Vec2) = + at.petrak.hexcasting.api.utils.pxToCoord(px, this.hexSize(), this.coordsOffset()) private sealed class PatternDrawState { /** We're waiting on the player to right-click again */ @@ -516,14 +525,22 @@ class GuiSpellcasting constructor( data class JustStarted(val start: HexCoord) : PatternDrawState() /** We've started drawing a pattern for real. */ - data class Drawing(val start: HexCoord, var current: HexCoord, val wipPattern: HexPattern) : PatternDrawState() + data class Drawing(val start: HexCoord, var current: HexCoord, val wipPattern: HexPattern) : + PatternDrawState() } companion object { const val LHS_IOTAS_ALLOCATION = 0.7 const val RHS_IOTAS_ALLOCATION = 0.15 - fun drawBox(ps: PoseStack, x: Float, y: Float, w: Float, h: Float, leftMargin: Float = 2.5f) { + fun drawBox( + ps: PoseStack, + x: Float, + y: Float, + w: Float, + h: Float, + leftMargin: Float = 2.5f + ) { RenderSystem.setShader(GameRenderer::getPositionColorShader) RenderSystem.enableBlend() renderQuad(ps, x, y, w, h, 0x50_303030) diff --git a/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java b/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java index c6f7da11d8..d5f59e9ddd 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/gui/PatternTooltipComponent.java @@ -1,19 +1,22 @@ package at.petrak.hexcasting.client.gui; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.client.render.PatternColors; import at.petrak.hexcasting.client.render.PatternRenderer; import at.petrak.hexcasting.client.render.WorldlyPatternRenderHelpers; import at.petrak.hexcasting.common.misc.PatternTooltip; + import com.mojang.blaze3d.systems.RenderSystem; + import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.inventory.tooltip.TooltipComponent; -import org.jetbrains.annotations.Nullable; -import static at.petrak.hexcasting.api.HexAPI.modLoc; +import org.jetbrains.annotations.Nullable; // https://github.com/VazkiiMods/Botania/blob/95bd2d3fbc857b7c102687554e1d1b112f8af436/Xplat/src/main/java/vazkii/botania/client/gui/ManaBarTooltipComponent.java // yoink @@ -49,7 +52,8 @@ public static ClientTooltipComponent tryConvert(TooltipComponent cmp) { public void renderImage(Font font, int mouseX, int mouseY, GuiGraphics graphics) { var ps = graphics.pose(); - // far as i can tell "mouseX" and "mouseY" are actually the positions of the corner of the tooltip + // far as i can tell "mouseX" and "mouseY" are actually the positions of the corner of the + // tooltip ps.pushPose(); ps.translate(mouseX, mouseY, 500); RenderSystem.enableBlend(); @@ -59,22 +63,33 @@ public void renderImage(Font font, int mouseX, int mouseY, GuiGraphics graphics) ps.translate(0, 0, 100); ps.scale(RENDER_SIZE, RENDER_SIZE, 1); - PatternRenderer.renderPattern(pattern, ps, WorldlyPatternRenderHelpers.READABLE_SCROLL_SETTINGS, - (PatternRenderer.shouldDoStrokeGradient() ? PatternColors.DEFAULT_GRADIENT_COLOR : PatternColors.DEFAULT_PATTERN_COLOR) + PatternRenderer.renderPattern( + pattern, + ps, + WorldlyPatternRenderHelpers.READABLE_SCROLL_SETTINGS, + (PatternRenderer.shouldDoStrokeGradient() + ? PatternColors.DEFAULT_GRADIENT_COLOR + : PatternColors.DEFAULT_PATTERN_COLOR) .withDots(true, true), - 0, 512); + 0, + 512); ps.popPose(); } private static void renderBG(GuiGraphics graphics, ResourceLocation background) { graphics.blit( - background, // texture - 0, 0, // x, y - (int) RENDER_SIZE, (int) RENDER_SIZE, // renderWidth, renderHeight - 0f, 0f, // u, v (textureCoords) - TEXTURE_SIZE, TEXTURE_SIZE, // regionWidth, regionHeight (texture sample dimensions) - TEXTURE_SIZE, TEXTURE_SIZE); // textureWidth, textureHeight (total dimensions of texture) + background, // texture + 0, + 0, // x, y + (int) RENDER_SIZE, + (int) RENDER_SIZE, // renderWidth, renderHeight + 0f, + 0f, // u, v (textureCoords) + TEXTURE_SIZE, + TEXTURE_SIZE, // regionWidth, regionHeight (texture sample dimensions) + TEXTURE_SIZE, + TEXTURE_SIZE); // textureWidth, textureHeight (total dimensions of texture) } @Override diff --git a/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt b/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt index 5863d7f050..21df40f0a5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/ktxt/ClientAccessorWrappers.kt @@ -1,4 +1,5 @@ @file:JvmName("ClientAccessorWrappers") + package at.petrak.hexcasting.client.ktxt import at.petrak.hexcasting.mixin.accessor.client.AccessorMouseHandler diff --git a/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java b/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java index a354d6eba3..ea0b3cd1b2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/model/AltioraLayer.java @@ -1,8 +1,12 @@ package at.petrak.hexcasting.client.model; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import at.petrak.hexcasting.xplat.IXplatAbstractions; + import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; + import net.minecraft.client.model.ElytraModel; import net.minecraft.client.model.EntityModel; import net.minecraft.client.model.geom.EntityModelSet; @@ -17,9 +21,8 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.Items; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - -public class AltioraLayer> extends RenderLayer { +public class AltioraLayer> + extends RenderLayer { private static final ResourceLocation TEX_LOC = modLoc("textures/misc/altiora.png"); private final ElytraModel elytraModel; @@ -30,21 +33,33 @@ public AltioraLayer(RenderLayerParent renderer, EntityM } @Override - public void render(PoseStack ps, MultiBufferSource buffer, int packedLight, AbstractClientPlayer player, - float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, - float headPitch) { + public void render( + PoseStack ps, + MultiBufferSource buffer, + int packedLight, + AbstractClientPlayer player, + float limbSwing, + float limbSwingAmount, + float partialTick, + float ageInTicks, + float netHeadYaw, + float headPitch) { var altiora = IXplatAbstractions.INSTANCE.getAltiora(player); - // do a best effort to not render over other elytra, although we can never patch up everything + // do a best effort to not render over other elytra, although we can never patch up + // everything var chestSlot = player.getItemBySlot(EquipmentSlot.CHEST); if (altiora != null && !chestSlot.is(Items.ELYTRA)) { ps.pushPose(); ps.translate(0.0, 0.0, 0.125); this.getParentModel().copyPropertiesTo(this.elytraModel); - this.elytraModel.setupAnim(player, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); - VertexConsumer verts = ItemRenderer.getArmorFoilBuffer( - buffer, RenderType.armorCutoutNoCull(TEX_LOC), false, true); - this.elytraModel.renderToBuffer(ps, verts, packedLight, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + this.elytraModel.setupAnim( + player, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); + VertexConsumer verts = + ItemRenderer.getArmorFoilBuffer( + buffer, RenderType.armorCutoutNoCull(TEX_LOC), false, true); + this.elytraModel.renderToBuffer( + ps, verts, packedLight, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); ps.popPose(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/model/HexModelLayers.java b/Common/src/main/java/at/petrak/hexcasting/client/model/HexModelLayers.java index 11dc412327..57616a7c22 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/model/HexModelLayers.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/model/HexModelLayers.java @@ -1,5 +1,7 @@ package at.petrak.hexcasting.client.model; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import net.minecraft.client.model.ElytraModel; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.builders.LayerDefinition; @@ -7,8 +9,6 @@ import java.util.function.BiConsumer; import java.util.function.Supplier; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - // https://github.com/VazkiiMods/Botania/blob/1.19.x/Xplat/src/main/java/vazkii/botania/client/model/BotaniaModelLayers.java public class HexModelLayers { public static final ModelLayerLocation ALTIORA = make("altiora"); diff --git a/Common/src/main/java/at/petrak/hexcasting/client/model/HexRobesModels.java b/Common/src/main/java/at/petrak/hexcasting/client/model/HexRobesModels.java index 7f35494cab..b410595a96 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/model/HexRobesModels.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/model/HexRobesModels.java @@ -4,67 +4,183 @@ // Exported for Minecraft version 1.17 or later with Mojang mappings // Paste this class into your mod and generate all required imports +import static at.petrak.hexcasting.api.HexAPI.modLoc; + import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.PartPose; import net.minecraft.client.model.geom.builders.*; -import static at.petrak.hexcasting.api.HexAPI.modLoc; - public class HexRobesModels { - // This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into + // This layer location should be baked with EntityRendererProvider.Context in the entity + // renderer and passed into // this model's constructor - public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(modLoc("robes"), "main"); + public static final ModelLayerLocation LAYER_LOCATION = + new ModelLayerLocation(modLoc("robes"), "main"); public static LayerDefinition variant1() { MeshDefinition meshdefinition = new MeshDefinition(); PartDefinition partdefinition = meshdefinition.getRoot(); - PartDefinition Hood = partdefinition.addOrReplaceChild("Hood", - CubeListBuilder.create() - .texOffs(0, 0).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F)) - .texOffs(0, 16).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F)), - PartPose.offset(4.0F, -8.0F, -4.0F)); + PartDefinition Hood = + partdefinition.addOrReplaceChild( + "Hood", + CubeListBuilder.create() + .texOffs(0, 0) + .addBox( + -8.0F, + 0.0F, + 0.0F, + 8.0F, + 8.0F, + 8.0F, + new CubeDeformation(0.0F)) + .texOffs(0, 16) + .addBox( + -8.0F, + 0.0F, + 0.0F, + 8.0F, + 8.0F, + 8.0F, + new CubeDeformation(0.0F)), + PartPose.offset(4.0F, -8.0F, -4.0F)); - PartDefinition Horns = partdefinition.addOrReplaceChild("Horns", - CubeListBuilder.create() - .texOffs(24, 0).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 4.0F, 0.0F, new CubeDeformation(0.0F)) - .texOffs(24, 0).mirror().addBox(9.5F, 0.0F, 0.0F, 8.0F, 4.0F, 0.0F, new CubeDeformation(0.0F)) - .mirror(false), - PartPose.offset(-4.8F, -8.2F, 0.0F)); + PartDefinition Horns = + partdefinition.addOrReplaceChild( + "Horns", + CubeListBuilder.create() + .texOffs(24, 0) + .addBox( + -8.0F, + 0.0F, + 0.0F, + 8.0F, + 4.0F, + 0.0F, + new CubeDeformation(0.0F)) + .texOffs(24, 0) + .mirror() + .addBox( + 9.5F, + 0.0F, + 0.0F, + 8.0F, + 4.0F, + 0.0F, + new CubeDeformation(0.0F)) + .mirror(false), + PartPose.offset(-4.8F, -8.2F, 0.0F)); - PartDefinition Torso = partdefinition.addOrReplaceChild("Torso", - CubeListBuilder.create() - .texOffs(40, 0).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)) - .texOffs(40, 16).addBox(-8.0F, 0.0F, 0.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)), - PartPose.offset(4.0F, 0.0F, -2.0F)); + PartDefinition Torso = + partdefinition.addOrReplaceChild( + "Torso", + CubeListBuilder.create() + .texOffs(40, 0) + .addBox( + -8.0F, + 0.0F, + 0.0F, + 8.0F, + 12.0F, + 4.0F, + new CubeDeformation(0.0F)) + .texOffs(40, 16) + .addBox( + -8.0F, + 0.0F, + 0.0F, + 8.0F, + 12.0F, + 4.0F, + new CubeDeformation(0.0F)), + PartPose.offset(4.0F, 0.0F, -2.0F)); - PartDefinition Arms = partdefinition.addOrReplaceChild("Arms", - CubeListBuilder.create() - .texOffs(0, 32).addBox(-4.0F, 0.0F, 0.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)) - .texOffs(0, 32).mirror().addBox(8.0F, 0.0F, 0.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)) - .mirror(false), - PartPose.offset(-4.0F, 0.0F, -2.0F)); + PartDefinition Arms = + partdefinition.addOrReplaceChild( + "Arms", + CubeListBuilder.create() + .texOffs(0, 32) + .addBox( + -4.0F, + 0.0F, + 0.0F, + 4.0F, + 12.0F, + 4.0F, + new CubeDeformation(0.0F)) + .texOffs(0, 32) + .mirror() + .addBox( + 8.0F, + 0.0F, + 0.0F, + 4.0F, + 12.0F, + 4.0F, + new CubeDeformation(0.0F)) + .mirror(false), + PartPose.offset(-4.0F, 0.0F, -2.0F)); - PartDefinition Skirt = partdefinition.addOrReplaceChild("Skirt", CubeListBuilder.create(), - PartPose.offset(0.0F, 12.0F, -2.0F)); + PartDefinition Skirt = + partdefinition.addOrReplaceChild( + "Skirt", CubeListBuilder.create(), PartPose.offset(0.0F, 12.0F, -2.0F)); - PartDefinition Left_r1 = Skirt.addOrReplaceChild("Left_r1", - CubeListBuilder.create() - .texOffs(48, 32).mirror().addBox(0.1F, 0.0F, -4.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)) - .mirror(false), - PartPose.offsetAndRotation(0.0F, 0.0F, 4.0F, 0.0F, 0.0F, -0.1309F)); + PartDefinition Left_r1 = + Skirt.addOrReplaceChild( + "Left_r1", + CubeListBuilder.create() + .texOffs(48, 32) + .mirror() + .addBox( + 0.1F, + 0.0F, + -4.0F, + 4.0F, + 12.0F, + 4.0F, + new CubeDeformation(0.0F)) + .mirror(false), + PartPose.offsetAndRotation(0.0F, 0.0F, 4.0F, 0.0F, 0.0F, -0.1309F)); - PartDefinition Right_r1 = Skirt.addOrReplaceChild("Right_r1", - CubeListBuilder.create() - .texOffs(48, 32).addBox(-4.0F, 0.0F, -4.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)), - PartPose.offsetAndRotation(0.0F, 0.0F, 4.0F, 0.0F, 0.0F, 0.1309F)); + PartDefinition Right_r1 = + Skirt.addOrReplaceChild( + "Right_r1", + CubeListBuilder.create() + .texOffs(48, 32) + .addBox( + -4.0F, + 0.0F, + -4.0F, + 4.0F, + 12.0F, + 4.0F, + new CubeDeformation(0.0F)), + PartPose.offsetAndRotation(0.0F, 0.0F, 4.0F, 0.0F, 0.0F, 0.1309F)); - PartDefinition Legs = partdefinition.addOrReplaceChild("Legs", - CubeListBuilder.create().texOffs(16, 41) - .addBox(-4.0F, 0.0F, 0.0F, 4.0F, 3.0F, 4.0F, new CubeDeformation(0.0F)) - .texOffs(16, 41).addBox(0.0F, 0.0F, 0.0F, 4.0F, 3.0F, 4.0F, new CubeDeformation(0.0F)), - PartPose.offset(0.0F, 21.0F, -2.0F)); + PartDefinition Legs = + partdefinition.addOrReplaceChild( + "Legs", + CubeListBuilder.create() + .texOffs(16, 41) + .addBox( + -4.0F, + 0.0F, + 0.0F, + 4.0F, + 3.0F, + 4.0F, + new CubeDeformation(0.0F)) + .texOffs(16, 41) + .addBox( + 0.0F, + 0.0F, + 0.0F, + 4.0F, + 3.0F, + 4.0F, + new CubeDeformation(0.0F)), + PartPose.offset(0.0F, 21.0F, -2.0F)); return LayerDefinition.create(meshdefinition, 64, 64); } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java b/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java index fc63fcdf72..564acd6506 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/model/MyOwnArmorModelWithBlackjackAndHookers.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; + import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.world.entity.EquipmentSlot; @@ -20,8 +21,13 @@ public MyOwnArmorModelWithBlackjackAndHookers(ModelPart root, EquipmentSlot slot // [VanillaCopy] ArmorStandArmorModel.setupAnim because armor stands are dumb // This fixes the armor "breathing" and helmets always facing south on armor stands @Override - public void setupAnim(LivingEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, - float netHeadYaw, float headPitch) { + public void setupAnim( + LivingEntity entity, + float limbSwing, + float limbSwingAmount, + float ageInTicks, + float netHeadYaw, + float headPitch) { if (!(entity instanceof ArmorStand entityIn)) { super.setupAnim(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch); return; @@ -52,8 +58,15 @@ public void setupAnim(LivingEntity entity, float limbSwing, float limbSwingAmoun } @Override - public void renderToBuffer(PoseStack ms, VertexConsumer buffer, int light, int overlay, float r, float g, float b - , float a) { + public void renderToBuffer( + PoseStack ms, + VertexConsumer buffer, + int light, + int overlay, + float r, + float g, + float b, + float a) { setPartVisibility(slot); super.renderToBuffer(ms, buffer, light, overlay, r, g, b, a); } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java b/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java index 122e536e75..7d003fb737 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/particles/ConjureParticle.java @@ -3,18 +3,21 @@ import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.particles.ConjureParticleOptions; import at.petrak.hexcasting.xplat.IClientXplatAbstractions; + import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; + import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.particle.*; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.FastColor; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,8 +28,16 @@ public class ConjureParticle extends TextureSheetParticle { private final SpriteSet sprites; - ConjureParticle(ClientLevel pLevel, double x, double y, double z, double dx, double dy, double dz, - SpriteSet pSprites, int color) { + ConjureParticle( + ClientLevel pLevel, + double x, + double y, + double z, + double dx, + double dy, + double dz, + SpriteSet pSprites, + int color) { super(pLevel, x, y, z, dx, dy, dz); this.quadSize *= 0.9f; this.setParticleSpeed(dx, dy, dz); @@ -81,10 +92,17 @@ public Provider(SpriteSet pSprites) { @Nullable @Override - public Particle createParticle(ConjureParticleOptions type, ClientLevel level, - double pX, double pY, double pZ, - double pXSpeed, double pYSpeed, double pZSpeed) { - return new ConjureParticle(level, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, this.sprite, type.color()); + public Particle createParticle( + ConjureParticleOptions type, + ClientLevel level, + double pX, + double pY, + double pZ, + double pXSpeed, + double pYSpeed, + double pZSpeed) { + return new ConjureParticle( + level, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, this.sprite, type.color()); } } @@ -95,7 +113,8 @@ public void begin(BufferBuilder buf, TextureManager texMan) { Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer(); RenderSystem.depthMask(false); RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); + RenderSystem.blendFunc( + GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_PARTICLES); var tex = texMan.getTexture(TextureAtlas.LOCATION_PARTICLES); @@ -108,8 +127,9 @@ public void begin(BufferBuilder buf, TextureManager texMan) { public void end(Tesselator tess) { tess.end(); IClientXplatAbstractions.INSTANCE.restoreLastFilter( - Minecraft.getInstance().getTextureManager().getTexture(TextureAtlas.LOCATION_PARTICLES) - ); + Minecraft.getInstance() + .getTextureManager() + .getTexture(TextureAtlas.LOCATION_PARTICLES)); RenderSystem.disableBlend(); RenderSystem.depthMask(true); } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/GaslightingTracker.java b/Common/src/main/java/at/petrak/hexcasting/client/render/GaslightingTracker.java index c57a5abd49..b59b484d16 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/GaslightingTracker.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/GaslightingTracker.java @@ -1,9 +1,9 @@ package at.petrak.hexcasting.client.render; -import net.minecraft.resources.ResourceLocation; - import static at.petrak.hexcasting.api.HexAPI.modLoc; +import net.minecraft.resources.ResourceLocation; + // *nothing* that changes can be looked at for changes public class GaslightingTracker { private static int GASLIGHTING_AMOUNT = 0; diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java index 1861a9b8fb..866e0439cc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexAdditionalRenderers.java @@ -6,6 +6,7 @@ import at.petrak.hexcasting.client.ClientTickCounter; import at.petrak.hexcasting.common.lib.HexAttributes; import at.petrak.hexcasting.xplat.IXplatAbstractions; + import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; @@ -14,6 +15,7 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.datafixers.util.Pair; + import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.multiplayer.ClientLevel; @@ -27,6 +29,7 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; + import org.joml.Vector3f; import java.util.List; @@ -47,8 +50,8 @@ public static void overlayGui(GuiGraphics graphics, float partialTicks) { tryRenderScryingLensOverlay(graphics, partialTicks); } - private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, - PoseStack ps, float partialTicks) { + private static void renderSentinel( + Sentinel sentinel, LocalPlayer owner, PoseStack ps, float partialTicks) { ps.pushPose(); // zero vector is the player @@ -56,9 +59,9 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, var camera = mc.gameRenderer.getMainCamera(); var playerPos = camera.getPosition(); ps.translate( - sentinel.position().x - playerPos.x, - sentinel.position().y - playerPos.y, - sentinel.position().z - playerPos.z); + sentinel.position().x - playerPos.x, + sentinel.position().y - playerPos.y, + sentinel.position().z - playerPos.z); var time = ClientTickCounter.getTotal() / 2; var bobSpeed = 1f / 20; @@ -73,7 +76,6 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, float scale = 0.5f; ps.scale(scale, scale, scale); - var tess = Tesselator.getInstance(); var buf = tess.getBuilder(); var neo = ps.last().pose(); @@ -81,25 +83,28 @@ private static void renderSentinel(Sentinel sentinel, LocalPlayer owner, RenderSystem.setShader(GameRenderer::getRendertypeLinesShader); RenderSystem.disableDepthTest(); RenderSystem.disableCull(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + RenderSystem.blendFunc( + GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.lineWidth(5f); var pigment = IXplatAbstractions.INSTANCE.getPigment(owner); var colProvider = pigment.getColorProvider(); - BiConsumer v = (l, r) -> { - int lcolor = colProvider.getColor(time, new Vec3(l[0], l[1], l[2])), - rcolor = colProvider.getColor(time, new Vec3(r[0], r[1], r[2])); - var normal = new Vector3f(r[0] - l[0], r[1] - l[1], r[2] - l[2]); - normal.normalize(); - buf.vertex(neo, l[0], l[1], l[2]) - .color(lcolor) - .normal(ps.last().normal(), normal.x(), normal.y(), normal.z()) - .endVertex(); - buf.vertex(neo, r[0], r[1], r[2]) - .color(rcolor) - .normal(ps.last().normal(), -normal.x(), -normal.y(), -normal.z()) - .endVertex(); - }; + BiConsumer v = + (l, r) -> { + int lcolor = colProvider.getColor(time, new Vec3(l[0], l[1], l[2])), + rcolor = colProvider.getColor(time, new Vec3(r[0], r[1], r[2])); + var normal = new Vector3f(r[0] - l[0], r[1] - l[1], r[2] - l[2]); + normal.normalize(); + buf.vertex(neo, l[0], l[1], l[2]) + .color(lcolor) + .normal(ps.last().normal(), normal.x(), normal.y(), normal.z()) + .endVertex(); + buf.vertex(neo, r[0], r[1], r[2]) + .color(rcolor) + .normal(ps.last().normal(), -normal.x(), -normal.y(), -normal.z()) + .endVertex(); + }; // Icosahedron inscribed inside the unit sphere buf.begin(VertexFormat.Mode.LINES, DefaultVertexFormat.POSITION_COLOR_NORMAL); @@ -143,8 +148,8 @@ private static class Icos { var x = Mth.cos(theta) * Mth.cos(phi); var y = Mth.sin(theta); var z = Mth.cos(theta) * Mth.sin(phi); - TOP_RING[i] = new float[]{x, y, z}; - BOTTOM_RING[i] = new float[]{-x, -y, -z}; + TOP_RING[i] = new float[] {x, y, z}; + BOTTOM_RING[i] = new float[] {-x, -y, -z}; } } } @@ -159,8 +164,7 @@ private static void tryRenderScryingLensOverlay(GuiGraphics graphics, float part return; } - if (player.getAttributeValue(HexAttributes.SCRY_SIGHT) <= 0.0) - return; + if (player.getAttributeValue(HexAttributes.SCRY_SIGHT) <= 0.0) return; var hitRes = mc.hitResult; if (hitRes != null && hitRes.getType() == HitResult.Type.BLOCK) { @@ -168,7 +172,8 @@ private static void tryRenderScryingLensOverlay(GuiGraphics graphics, float part var pos = bhr.getBlockPos(); var bs = level.getBlockState(pos); - var lines = ScryingLensOverlayRegistry.getLines(bs, pos, player, level, bhr.getDirection()); + var lines = + ScryingLensOverlayRegistry.getLines(bs, pos, player, level, bhr.getDirection()); int totalHeight = 8; List>> actualLines = Lists.newArrayList(); diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java index 1b82992398..62bec0809a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternLike.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.client.render; import at.petrak.hexcasting.api.casting.math.HexPattern; + import net.minecraft.world.phys.Vec2; import java.util.List; @@ -10,8 +11,8 @@ /** * A simple wrapper around the parts of HexPattern that are actually used for rendering. * - * This lets the pattern renderer work on arbitrary lists of vecs - this is never used in base hex but is included - * to future-proof and for if addons or something wants to use it. + *

This lets the pattern renderer work on arbitrary lists of vecs - this is never used in base + * hex but is included to future-proof and for if addons or something wants to use it. */ public interface HexPatternLike { List getNonZappyPoints(); @@ -20,51 +21,58 @@ public interface HexPatternLike { Set getDups(); - static HexPatternLike of(HexPattern pat){ + static HexPatternLike of(HexPattern pat) { return new HexPatternLikeBecauseItsActuallyAHexPattern(pat); } - static HexPatternLike of(List lines, String name){ + static HexPatternLike of(List lines, String name) { return new PureLines(lines, name); } - record HexPatternLikeBecauseItsActuallyAHexPattern(HexPattern pat) implements HexPatternLike{ - public List getNonZappyPoints(){ + record HexPatternLikeBecauseItsActuallyAHexPattern(HexPattern pat) implements HexPatternLike { + public List getNonZappyPoints() { return pat.toLines(1, Vec2.ZERO); } - public String getName(){ + public String getName() { return pat.getStartDir() + "-" + pat.anglesSignature(); } - public Set getDups(){ + public Set getDups() { return RenderLib.findDupIndices(pat.positions()); } } - record PureLines(List lines, String name) implements HexPatternLike{ + record PureLines(List lines, String name) implements HexPatternLike { - public List getNonZappyPoints(){ + public List getNonZappyPoints() { return lines; } - public String getName(){ + public String getName() { return name; } - public Set getDups(){ + public Set getDups() { return RenderLib.findDupIndices( - lines().stream().map(p -> - // I hate mojang - new Vec2(p.x, p.y){ - @Override public boolean equals(Object other){ - if(other instanceof Vec2 otherVec) return p.equals(otherVec); - return false; - } - - @Override public int hashCode(){ return Objects.hash(p.x, p.y); } - }).toList() - ); + lines().stream() + .map( + p -> + // I hate mojang + new Vec2(p.x, p.y) { + @Override + public boolean equals(Object other) { + if (other instanceof Vec2 otherVec) + return p.equals(otherVec); + return false; + } + + @Override + public int hashCode() { + return Objects.hash(p.x, p.y); + } + }) + .toList()); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java index 1a55d06b5e..975691b39a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.client.render; import com.google.common.collect.ImmutableList; + import net.minecraft.world.phys.Vec2; import java.util.ArrayList; @@ -9,8 +10,8 @@ import java.util.concurrent.ConcurrentMap; /** - * static points making up a hex pattern to be rendered. It's used primarily for positioning, so we keep a - * number of extra values here to avoid recomputing them. + * static points making up a hex pattern to be rendered. It's used primarily for positioning, so we + * keep a number of extra values here to avoid recomputing them. */ public class HexPatternPoints { public final ImmutableList zappyPoints; @@ -31,7 +32,8 @@ public class HexPatternPoints { private final double offsetX; private final double offsetY; - private static final ConcurrentMap CACHED_STATIC_POINTS = new ConcurrentHashMap<>(); + private static final ConcurrentMap CACHED_STATIC_POINTS = + new ConcurrentHashMap<>(); private HexPatternPoints(HexPatternLike patternlike, PatternSettings patSets, double seed) { @@ -39,10 +41,17 @@ private HexPatternPoints(HexPatternLike patternlike, PatternSettings patSets, do // always do space calculations with the static version of the pattern // so that it doesn't jump around resizing itself. - List zappyPoints = RenderLib.makeZappy(dots, patternlike.getDups(), - patSets.getHops(), patSets.getVariance(), 0f, patSets.getFlowIrregular(), - patSets.getReadabilityOffset(), patSets.getLastSegmentProp(), seed); - + List zappyPoints = + RenderLib.makeZappy( + dots, + patternlike.getDups(), + patSets.getHops(), + patSets.getVariance(), + 0f, + patSets.getFlowIrregular(), + patSets.getReadabilityOffset(), + patSets.getLastSegmentProp(), + seed); this.zappyPoints = ImmutableList.copyOf(zappyPoints); double maxY = Double.MIN_VALUE; @@ -64,22 +73,37 @@ private HexPatternPoints(HexPatternLike patternlike, PatternSettings patSets, do double baseHeight = rangeY * baseScale; // make sure that the scale fits within our min sizes - double scale = Math.max(1.0, Math.max( - (patSets.getMinWidth() - patSets.getStrokeWidthGuess()) / baseWidth, - (patSets.getMinHeight() - patSets.getStrokeWidthGuess()) / baseHeight) - ); + double scale = + Math.max( + 1.0, + Math.max( + (patSets.getMinWidth() - patSets.getStrokeWidthGuess()) / baseWidth, + (patSets.getMinHeight() - patSets.getStrokeWidthGuess()) + / baseHeight)); boolean vertFit = patSets.getVertAlignment().fit; boolean horFit = patSets.getHorAlignment().fit; // scale down if needed to fit in vertical space - if(vertFit){ - scale = Math.min(scale, (patSets.getTargetHeight() - 2 * patSets.getVertPadding() - patSets.getStrokeWidthGuess())/(baseHeight)); + if (vertFit) { + scale = + Math.min( + scale, + (patSets.getTargetHeight() + - 2 * patSets.getVertPadding() + - patSets.getStrokeWidthGuess()) + / (baseHeight)); } // scale down if needed to fit in horizontal space - if(horFit){ - scale = Math.min(scale, (patSets.getTargetWidth() - 2 * patSets.getHorPadding() - patSets.getStrokeWidthGuess())/(baseWidth)); + if (horFit) { + scale = + Math.min( + scale, + (patSets.getTargetWidth() + - 2 * patSets.getHorPadding() + - patSets.getStrokeWidthGuess()) + / (baseWidth)); } finalScale = baseScale * scale; @@ -96,21 +120,24 @@ private HexPatternPoints(HexPatternLike patternlike, PatternSettings patSets, do this.fullHeight = inherentHeight + heightDiff; // center in inherent space and put extra space according to alignment stuff - offsetX = ((inherentWidth - baseWidth * scale) / 2) + (widthDiff * patSets.getHorAlignment().amtInFront / 2); - offsetY = ((inherentHeight - baseHeight * scale) / 2) + (heightDiff * patSets.getVertAlignment().amtInFront / 2); + offsetX = + ((inherentWidth - baseWidth * scale) / 2) + + (widthDiff * patSets.getHorAlignment().amtInFront / 2); + offsetY = + ((inherentHeight - baseHeight * scale) / 2) + + (heightDiff * patSets.getVertAlignment().amtInFront / 2); this.zappyPointsScaled = ImmutableList.copyOf(scaleVecs(zappyPoints)); this.dotsScaled = ImmutableList.copyOf(scaleVecs(dots)); } - public Vec2 scaleVec(Vec2 point){ + public Vec2 scaleVec(Vec2 point) { return new Vec2( (float) (((point.x - this.minX) * this.finalScale) + this.offsetX), - (float) (((point.y - this.minY) * this.finalScale) + this.offsetY) - ); + (float) (((point.y - this.minY) * this.finalScale) + this.offsetY)); } - public List scaleVecs(List points){ + public List scaleVecs(List points) { List scaledPoints = new ArrayList<>(); for (Vec2 point : points) { scaledPoints.add(scaleVec(point)); @@ -118,17 +145,17 @@ public List scaleVecs(List points){ return scaledPoints; } - /** * Gets the static points for the given pattern, settings, and seed. This is cached. * - * This is used in rendering static patterns and positioning non-static patterns. - * + *

This is used in rendering static patterns and positioning non-static patterns. */ - public static HexPatternPoints getStaticPoints(HexPatternLike patternlike, PatternSettings patSets, double seed){ + public static HexPatternPoints getStaticPoints( + HexPatternLike patternlike, PatternSettings patSets, double seed) { String cacheKey = patSets.getCacheKey(patternlike, seed); - return CACHED_STATIC_POINTS.computeIfAbsent(cacheKey, (key) -> new HexPatternPoints(patternlike, patSets, seed) ); + return CACHED_STATIC_POINTS.computeIfAbsent( + cacheKey, (key) -> new HexPatternPoints(patternlike, patSets, seed)); } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternColors.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternColors.java index fb64669834..385442ba39 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternColors.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternColors.java @@ -2,67 +2,91 @@ /** * An immutable wrapper for pattern colors. - *

- * This is separate from PatternRenderSettings because it does not affect the shape of the pattern, so we can re-use - * those parts for different colors. + * + *

This is separate from PatternRenderSettings because it does not affect the shape of the + * pattern, so we can re-use those parts for different colors. */ -public record PatternColors(int innerStartColor, int innerEndColor, int outerStartColor, int outerEndColor, - int startingDotColor, int gridDotsColor){ +public record PatternColors( + int innerStartColor, + int innerEndColor, + int outerStartColor, + int outerEndColor, + int startingDotColor, + int gridDotsColor) { // keep some handy frequently used colors here. - public static final PatternColors DEFAULT_PATTERN_COLOR = new PatternColors(0xff_554d54, 0xff_d2c8c8); + public static final PatternColors DEFAULT_PATTERN_COLOR = + new PatternColors(0xff_554d54, 0xff_d2c8c8); public static final PatternColors DIMMED_COLOR = new PatternColors(0xFF_B4AAAA, 0xff_d2c8c8); - public static final PatternColors DEFAULT_GRADIENT_COLOR = DEFAULT_PATTERN_COLOR.withGradientEnds(DIMMED_COLOR); + public static final PatternColors DEFAULT_GRADIENT_COLOR = + DEFAULT_PATTERN_COLOR.withGradientEnds(DIMMED_COLOR); public static final int STARTING_DOT = 0xff_5b7bd7; public static final int GRID_DOTS = 0x80_d2c8c8; - public static final PatternColors READABLE_SCROLL_COLORS = DEFAULT_PATTERN_COLOR.withDots(true, false); - public static final PatternColors READABLE_GRID_SCROLL_COLORS = DEFAULT_PATTERN_COLOR.withDots(true, true); + public static final PatternColors READABLE_SCROLL_COLORS = + DEFAULT_PATTERN_COLOR.withDots(true, false); + public static final PatternColors READABLE_GRID_SCROLL_COLORS = + DEFAULT_PATTERN_COLOR.withDots(true, true); - public static final PatternColors SLATE_WOBBLY_COLOR = glowyStroke( 0xff_64c8ff); // old blue color - public static final PatternColors SLATE_WOBBLY_PURPLE_COLOR = glowyStroke(0xff_cfa0f3); // shiny new purple one :) + public static final PatternColors SLATE_WOBBLY_COLOR = + glowyStroke(0xff_64c8ff); // old blue color + public static final PatternColors SLATE_WOBBLY_PURPLE_COLOR = + glowyStroke(0xff_cfa0f3); // shiny new purple one :) // no gradient - public PatternColors(int innerColor, int outerColor){ + public PatternColors(int innerColor, int outerColor) { this(innerColor, innerColor, outerColor, outerColor, 0, 0); } // single color -- no inner layer - public static PatternColors singleStroke(int color){ + public static PatternColors singleStroke(int color) { return new PatternColors(0, color); } // makes a stroke color similar to the glowy effect that slates have. - public static PatternColors glowyStroke(int color){ + public static PatternColors glowyStroke(int color) { return new PatternColors(RenderLib.screenCol(color), color); } - public static PatternColors gradientStrokes(int innerStartColor, int innerEndColor, int outerStartColor, int outerEndColor){ - return new PatternColors(innerStartColor, innerEndColor, outerStartColor, outerEndColor, 0, 0); + public static PatternColors gradientStrokes( + int innerStartColor, int innerEndColor, int outerStartColor, int outerEndColor) { + return new PatternColors( + innerStartColor, innerEndColor, outerStartColor, outerEndColor, 0, 0); } // a single stroke with a gradient -- no inner layer. - public static PatternColors gradientStroke(int startColor, int endColor){ + public static PatternColors gradientStroke(int startColor, int endColor) { return PatternColors.gradientStrokes(0, 0, startColor, endColor); } - public PatternColors withGradientEnds(int endColorInner, int endColorOuter){ - return new PatternColors(this.innerStartColor, endColorInner, this.outerStartColor, endColorOuter, this.startingDotColor, this.gridDotsColor); + public PatternColors withGradientEnds(int endColorInner, int endColorOuter) { + return new PatternColors( + this.innerStartColor, + endColorInner, + this.outerStartColor, + endColorOuter, + this.startingDotColor, + this.gridDotsColor); } - public PatternColors withGradientEnds(PatternColors end){ + public PatternColors withGradientEnds(PatternColors end) { return withGradientEnds(end.innerEndColor, end.outerEndColor); } // add dots -- note, this is how you tell the renderer to make dots - public PatternColors withDotColors(int startingDotColor, int gridDotsColor){ - return new PatternColors(this.innerStartColor, this.innerEndColor, this.outerStartColor, this.outerEndColor, - startingDotColor, gridDotsColor); + public PatternColors withDotColors(int startingDotColor, int gridDotsColor) { + return new PatternColors( + this.innerStartColor, + this.innerEndColor, + this.outerStartColor, + this.outerEndColor, + startingDotColor, + gridDotsColor); } // adds dots with the default colors. - public PatternColors withDots(boolean startingDot, boolean gridDots){ + public PatternColors withDots(boolean startingDot, boolean gridDots) { return withDotColors(startingDot ? STARTING_DOT : 0, gridDots ? GRID_DOTS : 0); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternRenderer.java index 8fd307a9a4..d3e87bebc5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternRenderer.java @@ -1,11 +1,12 @@ package at.petrak.hexcasting.client.render; - import at.petrak.hexcasting.api.casting.math.HexPattern; + import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexFormat; + import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.resources.ResourceLocation; @@ -13,67 +14,118 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; -import javax.annotation.Nullable; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import javax.annotation.Nullable; + public class PatternRenderer { - public static void renderPattern(HexPattern pattern, PoseStack ps, PatternSettings patSets, PatternColors patColors, double seed, int resPerUnit) { + public static void renderPattern( + HexPattern pattern, + PoseStack ps, + PatternSettings patSets, + PatternColors patColors, + double seed, + int resPerUnit) { renderPattern(pattern, ps, null, patSets, patColors, seed, resPerUnit); } - public static void renderPattern(HexPattern pattern, PoseStack ps, @Nullable WorldlyBits worldlyBits, PatternSettings patSets, PatternColors patColors, double seed, int resPerUnit) { - renderPattern(HexPatternLike.of(pattern), ps, worldlyBits, patSets, patColors, seed, resPerUnit); + public static void renderPattern( + HexPattern pattern, + PoseStack ps, + @Nullable WorldlyBits worldlyBits, + PatternSettings patSets, + PatternColors patColors, + double seed, + int resPerUnit) { + renderPattern( + HexPatternLike.of(pattern), ps, worldlyBits, patSets, patColors, seed, resPerUnit); } /** * Renders a pattern (or rather a pattern-like) according to the given settings. + * * @param patternlike the pattern (or more generally the lines) to render. - * @param ps pose/matrix stack to render based on. (0,0) is treated as the top left corner. The size of the render is determined by patSets. - * @param worldlyBits used for rendering with light/normals/render-layers if possible. This is optional and probably shouldn't be used for UI rendering. + * @param ps pose/matrix stack to render based on. (0,0) is treated as the top left corner. The + * size of the render is determined by patSets. + * @param worldlyBits used for rendering with light/normals/render-layers if possible. This is + * optional and probably shouldn't be used for UI rendering. * @param patSets settings that control how the pattern is drawn. * @param patColors colors to use for drawing the pattern and dots. * @param seed seed to use for zappy wobbles. - * @param resPerUnit the texture resolution per pose unit space to be used *if* the texture renderer is used. + * @param resPerUnit the texture resolution per pose unit space to be used *if* the texture + * renderer is used. */ - public static void renderPattern(HexPatternLike patternlike, PoseStack ps, @Nullable WorldlyBits worldlyBits, PatternSettings patSets, PatternColors patColors, double seed, int resPerUnit){ + public static void renderPattern( + HexPatternLike patternlike, + PoseStack ps, + @Nullable WorldlyBits worldlyBits, + PatternSettings patSets, + PatternColors patColors, + double seed, + int resPerUnit) { var oldShader = RenderSystem.getShader(); - HexPatternPoints staticPoints = HexPatternPoints.getStaticPoints(patternlike, patSets, seed); + HexPatternPoints staticPoints = + HexPatternPoints.getStaticPoints(patternlike, patSets, seed); boolean shouldRenderDynamic = true; // only do texture rendering if it's static and has solid colors - if(patSets.getSpeed() == 0 && PatternTextureManager.useTextures && patColors.innerStartColor() == patColors.innerEndColor() - && patColors.outerStartColor() == patColors.outerEndColor()){ - boolean didRender = renderPatternTexture(patternlike, ps, worldlyBits, patSets, patColors, seed, resPerUnit); - if(didRender) shouldRenderDynamic = false; + if (patSets.getSpeed() == 0 + && PatternTextureManager.useTextures + && patColors.innerStartColor() == patColors.innerEndColor() + && patColors.outerStartColor() == patColors.outerEndColor()) { + boolean didRender = + renderPatternTexture( + patternlike, ps, worldlyBits, patSets, patColors, seed, resPerUnit); + if (didRender) shouldRenderDynamic = false; } - if(shouldRenderDynamic){ + if (shouldRenderDynamic) { List zappyPattern; - if(patSets.getSpeed() == 0) { + if (patSets.getSpeed() == 0) { // re-use our static points if we're rendering a static pattern anyway zappyPattern = staticPoints.zappyPoints; } else { List nonzappyLines = patternlike.getNonZappyPoints(); Set dupIndices = RenderLib.findDupIndices(nonzappyLines); - zappyPattern = RenderLib.makeZappy(nonzappyLines, dupIndices, - patSets.getHops(), patSets.getVariance(), patSets.getSpeed(), patSets.getFlowIrregular(), - patSets.getReadabilityOffset(), patSets.getLastSegmentProp(), seed); + zappyPattern = + RenderLib.makeZappy( + nonzappyLines, + dupIndices, + patSets.getHops(), + patSets.getVariance(), + patSets.getSpeed(), + patSets.getFlowIrregular(), + patSets.getReadabilityOffset(), + patSets.getLastSegmentProp(), + seed); } List zappyRenderSpace = staticPoints.scaleVecs(zappyPattern); - if(FastColor.ARGB32.alpha(patColors.outerEndColor()) != 0 && FastColor.ARGB32.alpha(patColors.outerStartColor()) != 0){ - RenderLib.drawLineSeq(ps.last().pose(), zappyRenderSpace, (float)patSets.getOuterWidth(staticPoints.finalScale), - patColors.outerStartColor(), patColors.outerEndColor(), VCDrawHelper.getHelper(worldlyBits, ps,outerZ)); + if (FastColor.ARGB32.alpha(patColors.outerEndColor()) != 0 + && FastColor.ARGB32.alpha(patColors.outerStartColor()) != 0) { + RenderLib.drawLineSeq( + ps.last().pose(), + zappyRenderSpace, + (float) patSets.getOuterWidth(staticPoints.finalScale), + patColors.outerStartColor(), + patColors.outerEndColor(), + VCDrawHelper.getHelper(worldlyBits, ps, outerZ)); } - if(FastColor.ARGB32.alpha(patColors.innerEndColor()) != 0 && FastColor.ARGB32.alpha(patColors.innerStartColor()) != 0) { - RenderLib.drawLineSeq(ps.last().pose(), zappyRenderSpace, (float)patSets.getInnerWidth(staticPoints.finalScale), - patColors.innerStartColor(), patColors.innerEndColor(), VCDrawHelper.getHelper(worldlyBits, ps,innerZ)); + if (FastColor.ARGB32.alpha(patColors.innerEndColor()) != 0 + && FastColor.ARGB32.alpha(patColors.innerStartColor()) != 0) { + RenderLib.drawLineSeq( + ps.last().pose(), + zappyRenderSpace, + (float) patSets.getInnerWidth(staticPoints.finalScale), + patColors.innerStartColor(), + patColors.innerEndColor(), + VCDrawHelper.getHelper(worldlyBits, ps, innerZ)); } } @@ -81,16 +133,24 @@ public static void renderPattern(HexPatternLike patternlike, PoseStack ps, @Null float dotZ = 0.0011f; - if(FastColor.ARGB32.alpha(patColors.startingDotColor()) != 0) { - RenderLib.drawSpot(ps.last().pose(), staticPoints.dotsScaled.get(0), (float)patSets.getStartDotRadius(staticPoints.finalScale), - patColors.startingDotColor(), VCDrawHelper.getHelper(worldlyBits, ps, dotZ)); + if (FastColor.ARGB32.alpha(patColors.startingDotColor()) != 0) { + RenderLib.drawSpot( + ps.last().pose(), + staticPoints.dotsScaled.get(0), + (float) patSets.getStartDotRadius(staticPoints.finalScale), + patColors.startingDotColor(), + VCDrawHelper.getHelper(worldlyBits, ps, dotZ)); } - if(FastColor.ARGB32.alpha(patColors.gridDotsColor()) != 0) { - for(int i = 1; i < staticPoints.dotsScaled.size(); i++){ + if (FastColor.ARGB32.alpha(patColors.gridDotsColor()) != 0) { + for (int i = 1; i < staticPoints.dotsScaled.size(); i++) { Vec2 gridDot = staticPoints.dotsScaled.get(i); - RenderLib.drawSpot(ps.last().pose(), gridDot, (float)patSets.getGridDotsRadius(staticPoints.finalScale), - patColors.gridDotsColor(), VCDrawHelper.getHelper(worldlyBits, ps, dotZ)); + RenderLib.drawSpot( + ps.last().pose(), + gridDot, + (float) patSets.getGridDotsRadius(staticPoints.finalScale), + patColors.gridDotsColor(), + VCDrawHelper.getHelper(worldlyBits, ps, dotZ)); } } @@ -100,41 +160,82 @@ public static void renderPattern(HexPatternLike patternlike, PoseStack ps, @Null private static final float outerZ = 0.0005f; private static final float innerZ = 0.001f; - private static boolean renderPatternTexture(HexPatternLike patternlike, PoseStack ps, @Nullable WorldlyBits worldlyBits, PatternSettings patSets, PatternColors patColors, double seed, int resPerUnit){ - Optional> maybeTextures = PatternTextureManager.getTextures(patternlike, patSets, seed, resPerUnit); - if(maybeTextures.isEmpty()){ + private static boolean renderPatternTexture( + HexPatternLike patternlike, + PoseStack ps, + @Nullable WorldlyBits worldlyBits, + PatternSettings patSets, + PatternColors patColors, + double seed, + int resPerUnit) { + Optional> maybeTextures = + PatternTextureManager.getTextures(patternlike, patSets, seed, resPerUnit); + if (maybeTextures.isEmpty()) { return false; } Map textures = maybeTextures.get(); - HexPatternPoints staticPoints = HexPatternPoints.getStaticPoints(patternlike, patSets, seed); + HexPatternPoints staticPoints = + HexPatternPoints.getStaticPoints(patternlike, patSets, seed); VertexConsumer vc; - if(FastColor.ARGB32.alpha(patColors.outerStartColor()) != 0) { - VCDrawHelper vcHelper = VCDrawHelper.getHelper(worldlyBits, ps, outerZ, textures.get("outer")); + if (FastColor.ARGB32.alpha(patColors.outerStartColor()) != 0) { + VCDrawHelper vcHelper = + VCDrawHelper.getHelper(worldlyBits, ps, outerZ, textures.get("outer")); vc = vcHelper.vcSetupAndSupply(VertexFormat.Mode.QUADS); int cl = patColors.outerStartColor(); vcHelper.vertex(vc, cl, new Vec2(0, 0), new Vec2(0, 0), ps.last().pose()); - vcHelper.vertex(vc, cl, new Vec2(0, (float) staticPoints.fullHeight), new Vec2(0, 1), ps.last().pose()); - vcHelper.vertex(vc, cl, new Vec2((float) staticPoints.fullWidth, (float) staticPoints.fullHeight), new Vec2(1, 1), ps.last().pose()); - vcHelper.vertex(vc, cl, new Vec2((float) staticPoints.fullWidth, 0), new Vec2(1, 0), ps.last().pose()); + vcHelper.vertex( + vc, + cl, + new Vec2(0, (float) staticPoints.fullHeight), + new Vec2(0, 1), + ps.last().pose()); + vcHelper.vertex( + vc, + cl, + new Vec2((float) staticPoints.fullWidth, (float) staticPoints.fullHeight), + new Vec2(1, 1), + ps.last().pose()); + vcHelper.vertex( + vc, + cl, + new Vec2((float) staticPoints.fullWidth, 0), + new Vec2(1, 0), + ps.last().pose()); vcHelper.vcEndDrawer(vc); } - if(FastColor.ARGB32.alpha(patColors.innerStartColor()) != 0) { - VCDrawHelper vcHelper = VCDrawHelper.getHelper(worldlyBits, ps, innerZ, textures.get("inner")); + if (FastColor.ARGB32.alpha(patColors.innerStartColor()) != 0) { + VCDrawHelper vcHelper = + VCDrawHelper.getHelper(worldlyBits, ps, innerZ, textures.get("inner")); vc = vcHelper.vcSetupAndSupply(VertexFormat.Mode.QUADS); int cl = patColors.innerStartColor(); vcHelper.vertex(vc, cl, new Vec2(0, 0), new Vec2(0, 0), ps.last().pose()); - vcHelper.vertex(vc, cl, new Vec2(0, (float) staticPoints.fullHeight), new Vec2(0, 1), ps.last().pose()); - vcHelper.vertex(vc, cl, new Vec2((float) staticPoints.fullWidth, (float) staticPoints.fullHeight), new Vec2(1, 1), ps.last().pose()); - vcHelper.vertex(vc, cl, new Vec2((float) staticPoints.fullWidth, 0), new Vec2(1, 0), ps.last().pose()); + vcHelper.vertex( + vc, + cl, + new Vec2(0, (float) staticPoints.fullHeight), + new Vec2(0, 1), + ps.last().pose()); + vcHelper.vertex( + vc, + cl, + new Vec2((float) staticPoints.fullWidth, (float) staticPoints.fullHeight), + new Vec2(1, 1), + ps.last().pose()); + vcHelper.vertex( + vc, + cl, + new Vec2((float) staticPoints.fullWidth, 0), + new Vec2(1, 0), + ps.last().pose()); vcHelper.vcEndDrawer(vc); } @@ -143,9 +244,9 @@ private static boolean renderPatternTexture(HexPatternLike patternlike, PoseStac } // TODO did we want to un-hardcode this for accessibility reasons ? - public static boolean shouldDoStrokeGradient(){ + public static boolean shouldDoStrokeGradient() { return Screen.hasControlDown(); } - public record WorldlyBits(@Nullable MultiBufferSource provider, Integer light, Vec3 normal){} + public record WorldlyBits(@Nullable MultiBufferSource provider, Integer light, Vec3 normal) {} } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternSettings.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternSettings.java index 4cb223f6f6..5590309392 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternSettings.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternSettings.java @@ -3,12 +3,16 @@ /** * A class holding settings for shaping and positioning patterns. * - * By default, it's a simple wrapper of 3 records, however some use cases may require extending and overriding getters. - * This is done to keep the complexity of the records a bit lower. + *

By default, it's a simple wrapper of 3 records, however some use cases may require extending + * and overriding getters. This is done to keep the complexity of the records a bit lower. */ public class PatternSettings { - public PatternSettings(String name, PositionSettings posSets, StrokeSettings strokeSets, ZappySettings zapSets){ + public PatternSettings( + String name, + PositionSettings posSets, + StrokeSettings strokeSets, + ZappySettings zapSets) { this.name = name; this.posSets = posSets; this.strokeSets = strokeSets; @@ -16,40 +20,61 @@ public PatternSettings(String name, PositionSettings posSets, StrokeSettings str } /** - * Settings for positioning the pattern and defining its general size/render area. All values are in 'pose units', - * meaning we use them directly with the pose/matrix stack given to the renderer. + * Settings for positioning the pattern and defining its general size/render area. All values + * are in 'pose units', meaning we use them directly with the pose/matrix stack given to the + * renderer. * - *

- * We do a first pass at the pattern scale using baseScale. We then make sure it's larger than minWidth and - * minHeight. Then on each axis, if that axis is has a FIT alignment then we may scale down the pattern to make sure it - * fits. Note that the padding is not scaled and is always respected. - *

+ *

We do a first pass at the pattern scale using baseScale. We then make sure it's larger + * than minWidth and minHeight. Then on each axis, if that axis is has a FIT alignment then we + * may scale down the pattern to make sure it fits. Note that the padding is not scaled and is + * always respected. */ - public record PositionSettings(double spaceWidth, double spaceHeight, double hPadding, double vPadding, - AxisAlignment hAxis, AxisAlignment vAxis, double baseScale, double minWidth, double minHeight){ + public record PositionSettings( + double spaceWidth, + double spaceHeight, + double hPadding, + double vPadding, + AxisAlignment hAxis, + AxisAlignment vAxis, + double baseScale, + double minWidth, + double minHeight) { /** - * Makes settings ideal for rendering in a square. This helper exists because this is the most common positioning - * pattern. + * Makes settings ideal for rendering in a square. This helper exists because this is the + * most common positioning pattern. + * * @param padding a value 0-0.5 for how much padding should go on each side. - * @return a PositionSettings object in a 1x1 space with the given padding value such that the pattern is centered + * @return a PositionSettings object in a 1x1 space with the given padding value such that + * the pattern is centered */ - public static PositionSettings paddedSquare(double padding){ + public static PositionSettings paddedSquare(double padding) { return paddedSquare(padding, 0.25, 0); } - public static PositionSettings paddedSquare(double padding, double baseScale, double minSize){ - return new PositionSettings(1.0, 1.0, padding, padding, AxisAlignment.CENTER_FIT, AxisAlignment.CENTER_FIT, baseScale, minSize, minSize); + public static PositionSettings paddedSquare( + double padding, double baseScale, double minSize) { + return new PositionSettings( + 1.0, + 1.0, + padding, + padding, + AxisAlignment.CENTER_FIT, + AxisAlignment.CENTER_FIT, + baseScale, + minSize, + minSize); } } /** - * Settings for stroke and dot sizings. If you want to *not* render dots or inner/outer you should prefer setting - * alpha to 0 in PatternColors. + * Settings for stroke and dot sizings. If you want to *not* render dots or inner/outer you + * should prefer setting alpha to 0 in PatternColors. */ - public record StrokeSettings(double innerWidth, double outerWidth, - double startDotRadius, double gridDotsRadius){ - public static StrokeSettings fromStroke(double stroke){ - return new StrokeSettings(stroke * 2.0/5.0, stroke, 0.8 * stroke * 2.0 / 5.0, 0.4 * stroke * 2.0 / 5.0); + public record StrokeSettings( + double innerWidth, double outerWidth, double startDotRadius, double gridDotsRadius) { + public static StrokeSettings fromStroke(double stroke) { + return new StrokeSettings( + stroke * 2.0 / 5.0, stroke, 0.8 * stroke * 2.0 / 5.0, 0.4 * stroke * 2.0 / 5.0); } } @@ -61,22 +86,30 @@ public static StrokeSettings fromStroke(double stroke){ * @param speed how fast the pulses go * @param flowIrregular randomness of pulse travel * @param readabilityOffset how curved inward the corners are - * @param lastSegmentLenProportion length of the last segment relative to the others. used for increased readability. + * @param lastSegmentLenProportion length of the last segment relative to the others. used for + * increased readability. */ - public record ZappySettings(int hops, float variance, float speed, float flowIrregular, float readabilityOffset, float lastSegmentLenProportion){ + public record ZappySettings( + int hops, + float variance, + float speed, + float flowIrregular, + float readabilityOffset, + float lastSegmentLenProportion) { public static float READABLE_OFFSET = 0.2f; public static float READABLE_SEGMENT = 0.8f; public static ZappySettings STATIC = new ZappySettings(10, 0.5f, 0f, 0.2f, 0, 1f); - public static ZappySettings READABLE = new ZappySettings(10, 0.5f, 0f, 0.2f, READABLE_OFFSET, READABLE_SEGMENT); + public static ZappySettings READABLE = + new ZappySettings(10, 0.5f, 0f, 0.2f, READABLE_OFFSET, READABLE_SEGMENT); public static ZappySettings WOBBLY = new ZappySettings(10, 2.5f, 0.1f, 0.2f, 0, 1f); } - public String getCacheKey(HexPatternLike patternlike, double seed){ + public String getCacheKey(HexPatternLike patternlike, double seed) { return (patternlike.getName() + "-" + getName() + "-" + seed).toLowerCase(); } // determines how the pattern is fit and aligned on a given axis - public enum AxisAlignment{ + public enum AxisAlignment { // These 3 scale the pattern down to fit if needed. BEGIN_FIT(true, 0), CENTER_FIT(true, 1), @@ -89,54 +122,111 @@ public enum AxisAlignment{ public final boolean fit; public final int amtInFront; // how many halves go in front. yes it's a weird way to do it. - AxisAlignment(boolean fit, int amtInFront){ + AxisAlignment(boolean fit, int amtInFront) { this.fit = fit; this.amtInFront = amtInFront; } } private final String name; - // leaving these public for more convenient chaining. Should prefer using the getters for overrideability. + // leaving these public for more convenient chaining. Should prefer using the getters for + // overrideability. public final PositionSettings posSets; public final StrokeSettings strokeSets; public final ZappySettings zapSets; - public String getName(){ return name; } + public String getName() { + return name; + } - public double getTargetWidth(){ return posSets.spaceWidth; } - public double getTargetHeight(){ return posSets.spaceHeight; } + public double getTargetWidth() { + return posSets.spaceWidth; + } - public double getHorPadding(){ return posSets.hPadding; } - public double getVertPadding(){ return posSets.vPadding; } + public double getTargetHeight() { + return posSets.spaceHeight; + } - public AxisAlignment getHorAlignment(){ return posSets.hAxis; } - public AxisAlignment getVertAlignment(){ return posSets.vAxis; } + public double getHorPadding() { + return posSets.hPadding; + } - public double getBaseScale(){ return posSets.baseScale; } - public double getMinWidth(){ return posSets.minWidth; } - public double getMinHeight(){ return posSets.minHeight; } + public double getVertPadding() { + return posSets.vPadding; + } + + public AxisAlignment getHorAlignment() { + return posSets.hAxis; + } + + public AxisAlignment getVertAlignment() { + return posSets.vAxis; + } + + public double getBaseScale() { + return posSets.baseScale; + } + + public double getMinWidth() { + return posSets.minWidth; + } + + public double getMinHeight() { + return posSets.minHeight; + } /* these sizing getters take in the final pattern scale so that patterns can vary their stroke width when squished. * the records keep a static value since that's fine for *most* use cases, override these methods if you need to use them. * note that these widths are still in pose space units. */ - public double getInnerWidth(double scale){ return strokeSets.innerWidth; } - public double getOuterWidth(double scale){ return strokeSets.outerWidth; } + public double getInnerWidth(double scale) { + return strokeSets.innerWidth; + } - public double getStartDotRadius(double scale){ return strokeSets.startDotRadius; } - public double getGridDotsRadius(double scale){ return strokeSets.gridDotsRadius; } + public double getOuterWidth(double scale) { + return strokeSets.outerWidth; + } - public double getStrokeWidth(double scale){ return Math.max(getOuterWidth(scale), getInnerWidth(scale)); } + public double getStartDotRadius(double scale) { + return strokeSets.startDotRadius; + } + + public double getGridDotsRadius(double scale) { + return strokeSets.gridDotsRadius; + } + + public double getStrokeWidth(double scale) { + return Math.max(getOuterWidth(scale), getInnerWidth(scale)); + } + + // we have a stroke guess getter so that we can *try* to account for the stroke size when + // fitting the pattern. + public double getStrokeWidthGuess() { + return Math.max(strokeSets.outerWidth, strokeSets.innerWidth); + } + + public int getHops() { + return zapSets.hops; + } + + public float getVariance() { + return zapSets.variance; + } + + public float getFlowIrregular() { + return zapSets.flowIrregular; + } - // we have a stroke guess getter so that we can *try* to account for the stroke size when fitting the pattern. - public double getStrokeWidthGuess(){ return Math.max(strokeSets.outerWidth, strokeSets.innerWidth); } + public float getReadabilityOffset() { + return zapSets.readabilityOffset; + } - public int getHops(){ return zapSets.hops; } - public float getVariance(){ return zapSets.variance; } - public float getFlowIrregular(){ return zapSets.flowIrregular; } - public float getReadabilityOffset(){ return zapSets.readabilityOffset; } - public float getLastSegmentProp(){ return zapSets.lastSegmentLenProportion; } + public float getLastSegmentProp() { + return zapSets.lastSegmentLenProportion; + } - public float getSpeed(){ return zapSets.speed; } + public float getSpeed() { + return zapSets.speed; + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java index 8486124920..17e03cb500 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.client.render; import com.mojang.blaze3d.platform.NativeImage; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.resources.ResourceLocation; @@ -9,24 +10,28 @@ import java.awt.*; import java.awt.image.BufferedImage; -import java.util.List; import java.util.*; +import java.util.List; import java.util.concurrent.*; public class PatternTextureManager { - //TODO: remove if not needed anymore for comparison + // TODO: remove if not needed anymore for comparison public static boolean useTextures = true; public static int repaintIndex = 0; - private static final ConcurrentMap> patternTexturesToAdd = new ConcurrentHashMap<>(); + private static final ConcurrentMap> patternTexturesToAdd = + new ConcurrentHashMap<>(); private static final Set inProgressPatterns = new HashSet<>(); // basically newCachedThreadPool, but with a max pool size - private static final ExecutorService executor = new ThreadPoolExecutor(0, 16, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); + private static final ExecutorService executor = + new ThreadPoolExecutor(0, 16, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); - private static final HashMap> patternTextures = new HashMap<>(); + private static final HashMap> patternTextures = + new HashMap<>(); - public static Optional> getTextures(HexPatternLike patternlike, PatternSettings patSets, double seed, int resPerUnit) { + public static Optional> getTextures( + HexPatternLike patternlike, PatternSettings patSets, double seed, int resPerUnit) { String patCacheKey = patSets.getCacheKey(patternlike, seed) + "_" + resPerUnit; // move textures from concurrent map to normal hashmap as needed @@ -35,66 +40,114 @@ public static Optional> getTextures(HexPatternLike var oldPatternTexture = patternTextures.put(patCacheKey, patternTexture); inProgressPatterns.remove(patCacheKey); if (oldPatternTexture != null) // TODO: is this needed? when does this ever happen? - for(ResourceLocation oldPatternTextureSingle : oldPatternTexture.values()) - Minecraft.getInstance().getTextureManager().getTexture(oldPatternTextureSingle).close(); + for (ResourceLocation oldPatternTextureSingle : oldPatternTexture.values()) + Minecraft.getInstance() + .getTextureManager() + .getTexture(oldPatternTextureSingle) + .close(); return Optional.empty(); // try not giving it immediately to avoid flickering? } if (patternTextures.containsKey(patCacheKey)) return Optional.of(patternTextures.get(patCacheKey)); - // render a higher-resolution texture in a background thread so it eventually becomes all nice nice and pretty - if(!inProgressPatterns.contains(patCacheKey)){ + // render a higher-resolution texture in a background thread so it eventually becomes all + // nice nice and pretty + if (!inProgressPatterns.contains(patCacheKey)) { inProgressPatterns.add(patCacheKey); - executor.submit(() -> { - var slowTextures = createTextures(patternlike, patSets, seed, resPerUnit); - - // TextureManager#register doesn't look very thread-safe, so move back to the main thread after the slow part is done - Minecraft.getInstance().execute(() -> { - registerTextures(patCacheKey, slowTextures); - }); - }); + executor.submit( + () -> { + var slowTextures = createTextures(patternlike, patSets, seed, resPerUnit); + + // TextureManager#register doesn't look very thread-safe, so move back to + // the main thread after the slow part is done + Minecraft.getInstance() + .execute( + () -> { + registerTextures(patCacheKey, slowTextures); + }); + }); } return Optional.empty(); } - private static Map createTextures(HexPatternLike patternlike, PatternSettings patSets, double seed, int resPerUnit) { - HexPatternPoints staticPoints = HexPatternPoints.getStaticPoints(patternlike, patSets, seed); + private static Map createTextures( + HexPatternLike patternlike, PatternSettings patSets, double seed, int resPerUnit) { + HexPatternPoints staticPoints = + HexPatternPoints.getStaticPoints(patternlike, patSets, seed); List zappyRenderSpace = staticPoints.scaleVecs(staticPoints.zappyPoints); Map patTexts = new HashMap<>(); - NativeImage innerLines = drawLines(zappyRenderSpace, staticPoints, (float)patSets.getInnerWidth((staticPoints.finalScale)), resPerUnit); + NativeImage innerLines = + drawLines( + zappyRenderSpace, + staticPoints, + (float) patSets.getInnerWidth((staticPoints.finalScale)), + resPerUnit); patTexts.put("inner", new DynamicTexture(innerLines)); - NativeImage outerLines = drawLines(zappyRenderSpace, staticPoints, (float)patSets.getOuterWidth((staticPoints.finalScale)), resPerUnit); + NativeImage outerLines = + drawLines( + zappyRenderSpace, + staticPoints, + (float) patSets.getOuterWidth((staticPoints.finalScale)), + resPerUnit); patTexts.put("outer", new DynamicTexture(outerLines)); return patTexts; } - private static Map registerTextures(String patTextureKeyBase, Map dynamicTextures) { + private static Map registerTextures( + String patTextureKeyBase, Map dynamicTextures) { Map resLocs = new HashMap<>(); - for(Map.Entry textureEntry : dynamicTextures.entrySet()){ - String name = "hex_pattern_texture_" + patTextureKeyBase + "_" + textureEntry.getKey() + "_" + repaintIndex + ".png"; - ResourceLocation resourceLocation = Minecraft.getInstance().getTextureManager().register(name, textureEntry.getValue()); + for (Map.Entry textureEntry : dynamicTextures.entrySet()) { + String name = + "hex_pattern_texture_" + + patTextureKeyBase + + "_" + + textureEntry.getKey() + + "_" + + repaintIndex + + ".png"; + ResourceLocation resourceLocation = + Minecraft.getInstance() + .getTextureManager() + .register(name, textureEntry.getValue()); resLocs.put(textureEntry.getKey(), resourceLocation); } patternTexturesToAdd.put(patTextureKeyBase, resLocs); return resLocs; } - private static NativeImage drawLines(List points, HexPatternPoints staticPoints, float unscaledLineWidth, int resPerUnit) { - BufferedImage img = new BufferedImage((int)(staticPoints.fullWidth*resPerUnit), (int)(staticPoints.fullHeight*resPerUnit), BufferedImage.TYPE_INT_ARGB); + private static NativeImage drawLines( + List points, + HexPatternPoints staticPoints, + float unscaledLineWidth, + int resPerUnit) { + BufferedImage img = + new BufferedImage( + (int) (staticPoints.fullWidth * resPerUnit), + (int) (staticPoints.fullHeight * resPerUnit), + BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = img.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setColor(new Color(0xFF_FFFFFF)); // set it to white so we can reuse the texture with different colors - g2d.setStroke(new BasicStroke(unscaledLineWidth * resPerUnit, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + g2d.setColor( + new Color( + 0xFF_FFFFFF)); // set it to white so we can reuse the texture with different + // colors + g2d.setStroke( + new BasicStroke( + unscaledLineWidth * resPerUnit, + BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND)); for (int i = 0; i < points.size() - 1; i++) { - Tuple pointFrom = getTextureCoordinates(points.get(i), staticPoints, resPerUnit); - Tuple pointTo = getTextureCoordinates(points.get(i+1), staticPoints, resPerUnit); + Tuple pointFrom = + getTextureCoordinates(points.get(i), staticPoints, resPerUnit); + Tuple pointTo = + getTextureCoordinates(points.get(i + 1), staticPoints, resPerUnit); g2d.drawLine(pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB()); } g2d.dispose(); @@ -105,13 +158,15 @@ private static NativeImage drawLines(List points, HexPatternPoints staticP return nativeImage; } - private static Tuple getTextureCoordinates(Vec2 point, HexPatternPoints staticPoints, int resPerUnit) { - int x = (int) ( point.x * resPerUnit); - int y = (int) ( point.y * resPerUnit); + private static Tuple getTextureCoordinates( + Vec2 point, HexPatternPoints staticPoints, int resPerUnit) { + int x = (int) (point.x * resPerUnit); + int y = (int) (point.y * resPerUnit); return new Tuple<>(x, y); } - // keeping this around just in case we ever decide to put the dots in the textures instead of dynamic + // keeping this around just in case we ever decide to put the dots in the textures instead of + // dynamic private static void drawHexagon(Graphics2D g2d, int x, int y, int radius) { int fracOfCircle = 6; Polygon hexagon = new Polygon(); @@ -131,4 +186,4 @@ public static void repaint() { patternTexturesToAdd.clear(); patternTextures.clear(); } -} \ No newline at end of file +} diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt b/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt index 823068439f..69de2023db 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/RenderLib.kt @@ -12,6 +12,10 @@ import com.mojang.blaze3d.vertex.PoseStack import com.mojang.blaze3d.vertex.Tesselator import com.mojang.blaze3d.vertex.VertexFormat import com.mojang.math.Axis +import kotlin.math.abs +import kotlin.math.min +import kotlin.math.roundToInt +import kotlin.math.sin import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.screens.Screen @@ -25,15 +29,12 @@ import net.minecraft.world.level.levelgen.SingleThreadedRandomSource import net.minecraft.world.level.levelgen.synth.SimplexNoise import net.minecraft.world.phys.Vec2 import org.joml.Matrix4f -import kotlin.math.abs -import kotlin.math.min -import kotlin.math.roundToInt -import kotlin.math.sin val NOISE: SimplexNoise = SimplexNoise(SingleThreadedRandomSource(9001L)) // see the test; perlin noise seems to output almost exclusively between -0.5 and 0.5 -// i could probably impl this "properly" with some kind of exponent but it's faster and easier to divide +// i could probably impl this "properly" with some kind of exponent but it's faster and easier to +// divide fun getNoise(x: Double, y: Double, z: Double): Double = NOISE.getValue(x * 0.6, y * 0.6, z * 0.6) / 2.0 @@ -42,15 +43,7 @@ const val CAP_THETA = 180f / 10f const val DEFAULT_READABILITY_OFFSET = 0.2f const val DEFAULT_LAST_SEGMENT_LEN_PROP = 0.8f - -fun drawLineSeq( - mat: Matrix4f, - points: List, - width: Float, - z: Float, - tail: Int, - head: Int -) { +fun drawLineSeq(mat: Matrix4f, points: List, width: Float, z: Float, tail: Int, head: Int) { return drawLineSeq(mat, points, width, tail, head, VCDrawHelper.Basic(z)) } @@ -74,10 +67,9 @@ fun drawLineSeq( val b1 = FastColor.ARGB32.blue(tail).toFloat() val a = FastColor.ARGB32.alpha(tail) val a1 = a.toFloat() - val headSource = if (Screen.hasControlDown() != HexConfig.client().ctrlTogglesOffStrokeOrder()) - head - else - tail + val headSource = + if (Screen.hasControlDown() != HexConfig.client().ctrlTogglesOffStrokeOrder()) head + else tail val r2 = FastColor.ARGB32.red(headSource).toFloat() val g2 = FastColor.ARGB32.green(headSource).toFloat() val b2 = FastColor.ARGB32.blue(headSource).toFloat() @@ -95,7 +87,9 @@ fun drawLineSeq( val prev = p1.add(p0.negated()) val next = p2.add(p1.negated()) val angle = - Mth.atan2((prev.x * next.y - prev.y * next.x).toDouble(), (prev.x * next.x + prev.y * next.y).toDouble()) + Mth.atan2( + (prev.x * next.y - prev.y * next.x).toDouble(), + (prev.x * next.x + prev.y * next.y).toDouble()) .toFloat() joinAngles[i - 1] = angle val clamp = prev.length().coerceAtMost(next.length()) / (width * 0.5f) @@ -112,15 +106,19 @@ fun drawLineSeq( val normal = Vec2(-tangent.y, tangent.x) fun color(time: Float): Int = - FastColor.ARGB32.color(Mth.lerp(time, a1, a2).toInt(), Mth.lerp(time, r1, r2).toInt(), - Mth.lerp(time, g1, g2).toInt(), Mth.lerp(time, b1, b2).toInt()) + FastColor.ARGB32.color( + Mth.lerp(time, a1, a2).toInt(), + Mth.lerp(time, r1, r2).toInt(), + Mth.lerp(time, g1, g2).toInt(), + Mth.lerp(time, b1, b2).toInt()) val color1 = color(i.toFloat() / n) val color2 = color((i + 1f) / n) val jlow = joinOffsets[i] val jhigh = joinOffsets[i + 1] // Draw the line segment as a hexagon, sort of - // I can't imagine what the hell alwinfy is up to but this is implementing what TRIANGLE_FAN does + // I can't imagine what the hell alwinfy is up to but this is implementing what TRIANGLE_FAN + // does // using normal triangles so we can send the entire segment to the buffer at once val p1Down = p1.add(tangent.scale(Math.max(0f, jlow))).add(normal) val p1Up = p1.add(tangent.scale(Math.max(0f, -jlow))).add(normal.negated()) @@ -194,10 +192,10 @@ fun drawLineSeq( vcHelper.vcEndDrawer(vc) } drawCaps(ARGB32.color(a1.toInt(), r1.toInt(), g1.toInt(), b1.toInt()), points[0], points[1]) - drawCaps(ARGB32.color(a2.toInt(), r2.toInt(), g2.toInt(), b2.toInt()), points[n - 1], points[n - 2]) + drawCaps( + ARGB32.color(a2.toInt(), r2.toInt(), g2.toInt(), b2.toInt()), points[n - 1], points[n - 2]) } - fun rotate(vec: Vec2, theta: Float): Vec2 { val cos = Mth.cos(theta) val sin = Mth.sin(theta) @@ -220,12 +218,23 @@ fun drawPatternFromPoints( lastSegmentLenProportion: Float, seed: Double ) { - val zappyPts = makeZappy(points, dupIndices, 10, 2.5f, 0.1f, flowIrregular, readabilityOffset, lastSegmentLenProportion, seed) - val nodes = if (drawLast) { - points - } else { - points.dropLast(1) - } + val zappyPts = + makeZappy( + points, + dupIndices, + 10, + 2.5f, + 0.1f, + flowIrregular, + readabilityOffset, + lastSegmentLenProportion, + seed) + val nodes = + if (drawLast) { + points + } else { + points.dropLast(1) + } drawLineSeq(mat, zappyPts, 5f, 0f, tail, head) drawLineSeq(mat, zappyPts, 2f, 1f, screenCol(tail), screenCol(head)) for (node in nodes) { @@ -236,19 +245,26 @@ fun drawPatternFromPoints( dodge(FastColor.ARGB32.red(head)) / 255f, dodge(FastColor.ARGB32.green(head)) / 255f, dodge(FastColor.ARGB32.blue(head)) / 255f, - FastColor.ARGB32.alpha(head) / 255f - ) + FastColor.ARGB32.alpha(head) / 255f) } } /** * Split up a sequence of linePoints with a lightning effect + * * @param hops: rough number of points to subdivide each segment into * @param speed: rate at which the lightning effect should move/shake/etc */ fun makeZappy( - barePoints: List, dupIndices: Set?, hops: Int, variance: Float, speed: Float, flowIrregular: Float, - readabilityOffset: Float, lastSegmentLenProportion: Float, seed: Double + barePoints: List, + dupIndices: Set?, + hops: Int, + variance: Float, + speed: Float, + flowIrregular: Float, + readabilityOffset: Float, + lastSegmentLenProportion: Float, + seed: Double ): List { // Nothing in, nothing out if (barePoints.isEmpty()) { @@ -271,9 +287,10 @@ fun makeZappy( // for a list of length n, there will be n-1 pairs, // and so the last index will be (n-1)-1 - val maxJ = if (truncateLast && i == points.size - 2) { - (lastSegmentLenProportion * hops.toFloat()).roundToInt() - } else hops + val maxJ = + if (truncateLast && i == points.size - 2) { + (lastSegmentLenProportion * hops.toFloat()).roundToInt() + } else hops for (j in 1..maxJ) { val progress = j.toDouble() / (hops + 1) @@ -283,16 +300,14 @@ fun makeZappy( // (We use i, j (segment #, subsegment #) as seeds for the Perlin noise, // and zSeed (i.e. time elapsed) to perturb the shape gradually over time) val minorPerturb = getNoise(i.toDouble(), j.toDouble(), sin(zSeed)) * flowIrregular - val theta = (3 * getNoise( - i + progress + minorPerturb - zSeed, - 1337.0, - seed - ) * TAU).toFloat() - val r = (getNoise( - i + progress - zSeed, - 69420.0, - seed - ) * maxVariance * scaleVariance(progress)).toFloat() + val theta = + (3 * getNoise(i + progress + minorPerturb - zSeed, 1337.0, seed) * TAU) + .toFloat() + val r = + (getNoise(i + progress - zSeed, 69420.0, seed) * + maxVariance * + scaleVariance(progress)) + .toFloat() val randomHop = Vec2(r * Mth.cos(theta), r * Mth.sin(theta)) // Then record the new location. zappyPts.add(pos.add(randomHop)) @@ -349,15 +364,20 @@ fun findDupIndices(pts: Iterable): Set { } /** - * Draw a little circle, because Minecraft rendering code is a nightmare and doesn't - * include primitive drawing code... + * Draw a little circle, because Minecraft rendering code is a nightmare and doesn't include + * primitive drawing code... */ fun drawSpot(mat: Matrix4f, point: Vec2, radius: Float, r: Float, g: Float, b: Float, a: Float) { - drawSpot(mat, point, radius, ARGB32.color((a*255).toInt(), (r*255).toInt(), (g*255).toInt(), (b*255).toInt()), VCDrawHelper.Basic(1f)) + drawSpot( + mat, + point, + radius, + ARGB32.color((a * 255).toInt(), (r * 255).toInt(), (g * 255).toInt(), (b * 255).toInt()), + VCDrawHelper.Basic(1f)) } fun drawSpot(mat: Matrix4f, point: Vec2, radius: Float, color: Int, vcHelper: VCDrawHelper) { - var vc = vcHelper.vcSetupAndSupply(VertexFormat.Mode.TRIANGLE_FAN); + var vc = vcHelper.vcSetupAndSupply(VertexFormat.Mode.TRIANGLE_FAN) vcHelper.vertex(vc, color, point, mat) // https://github.com/not-fl3/macroquad/blob/master/src/shapes.rs#L98 @@ -384,12 +404,16 @@ fun screenCol(n: Int): Int { } fun screen(n: Int) = (n + 255) / 2 + fun dodge(n: Int) = n * 0.9f -/** - * Return the scale and dots formed by the pattern when centered. - */ -fun getCenteredPattern(pattern: HexPattern, width: Float, height: Float, minSize: Float): Pair> { +/** Return the scale and dots formed by the pattern when centered. */ +fun getCenteredPattern( + pattern: HexPattern, + width: Float, + height: Float, + minSize: Float +): Pair> { // Do two passes: one with a random size to find a good COM and one with the real calculation val com1: Vec2 = pattern.getCenter(1f) val lines1: List = pattern.toLines(1f, Vec2.ZERO) @@ -405,8 +429,7 @@ fun getCenteredPattern(pattern: HexPattern, width: Float, height: Float, minSize maxDy = dy } } - val scale = - min(minSize, min(width / 3f / maxDx, height / 3f / maxDy)) + val scale = min(minSize, min(width / 3f / maxDx, height / 3f / maxDy)) val com2: Vec2 = pattern.getCenter(scale) val lines2: List = pattern.toLines(scale, com2.negated()) return scale to lines2 @@ -414,14 +437,20 @@ fun getCenteredPattern(pattern: HexPattern, width: Float, height: Float, minSize @JvmOverloads fun renderEntity( - graphics: GuiGraphics, entity: Entity, world: Level, x: Float, y: Float, rotation: Float, - renderScale: Float, offset: Float, + graphics: GuiGraphics, + entity: Entity, + world: Level, + x: Float, + y: Float, + rotation: Float, + renderScale: Float, + offset: Float, bufferTransformer: (MultiBufferSource) -> MultiBufferSource = { it -> it } ) { val rotation = if (Screen.hasShiftDown()) 0.0f else rotation // TODO: Figure out why this is here and whether removing it will break things -// entity.level = world + // entity.level = world val ps = graphics.pose() ps.pushPose() @@ -439,27 +468,15 @@ fun renderEntity( ps.popPose() } -/** - * Make sure you have the `PositionColorShader` set - */ -fun renderQuad( - ps: PoseStack, x: Float, y: Float, w: Float, h: Float, color: Int -) { +/** Make sure you have the `PositionColorShader` set */ +fun renderQuad(ps: PoseStack, x: Float, y: Float, w: Float, h: Float, color: Int) { val mat = ps.last().pose() val tess = Tesselator.getInstance() val buf = tess.builder buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) - buf.vertex(mat, x, y, 0f) - .color(color) - .endVertex() - buf.vertex(mat, x, y + h, 0f) - .color(color) - .endVertex() - buf.vertex(mat, x + w, y + h, 0f) - .color(color) - .endVertex() - buf.vertex(mat, x + w, y, 0f) - .color(color) - .endVertex() + buf.vertex(mat, x, y, 0f).color(color).endVertex() + buf.vertex(mat, x, y + h, 0f).color(color).endVertex() + buf.vertex(mat, x + w, y + h, 0f).color(color).endVertex() + buf.vertex(mat, x + w, y, 0f).color(color).endVertex() tess.end() } diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java b/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java index 32aed05c7a..d8e814dab5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/ScryingLensOverlays.java @@ -6,7 +6,9 @@ import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry; import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf; import at.petrak.hexcasting.common.lib.HexBlocks; + import com.mojang.datafixers.util.Pair; + import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -29,108 +31,141 @@ public class ScryingLensOverlays { public static void addScryingLensStuff() { ScryingLensOverlayRegistry.addPredicateDisplayer( - (state, pos, observer, world, direction) -> state.getBlock() instanceof BlockAbstractImpetus, - (lines, state, pos, observer, world, direction) -> { - if (world.getBlockEntity(pos) instanceof BlockEntityAbstractImpetus beai) { - beai.applyScryingLensOverlay(lines, state, pos, observer, world, direction); - } - }); + (state, pos, observer, world, direction) -> + state.getBlock() instanceof BlockAbstractImpetus, + (lines, state, pos, observer, world, direction) -> { + if (world.getBlockEntity(pos) instanceof BlockEntityAbstractImpetus beai) { + beai.applyScryingLensOverlay(lines, state, pos, observer, world, direction); + } + }); - ScryingLensOverlayRegistry.addDisplayer(Blocks.NOTE_BLOCK, - (lines, state, pos, observer, world, direction) -> { - int note = state.getValue(NoteBlock.NOTE); + ScryingLensOverlayRegistry.addDisplayer( + Blocks.NOTE_BLOCK, + (lines, state, pos, observer, world, direction) -> { + int note = state.getValue(NoteBlock.NOTE); - float rCol = Math.max(0.0F, Mth.sin((note / 24F + 0.0F) * Mth.TWO_PI) * 0.65F + 0.35F); - float gCol = Math.max(0.0F, Mth.sin((note / 24F + 0.33333334F) * Mth.TWO_PI) * 0.65F + 0.35F); - float bCol = Math.max(0.0F, Mth.sin((note / 24F + 0.6666667F) * Mth.TWO_PI) * 0.65F + 0.35F); + float rCol = + Math.max( + 0.0F, + Mth.sin((note / 24F + 0.0F) * Mth.TWO_PI) * 0.65F + 0.35F); + float gCol = + Math.max( + 0.0F, + Mth.sin((note / 24F + 0.33333334F) * Mth.TWO_PI) * 0.65F + + 0.35F); + float bCol = + Math.max( + 0.0F, + Mth.sin((note / 24F + 0.6666667F) * Mth.TWO_PI) * 0.65F + + 0.35F); - int noteColor = 0xFF_000000 | Mth.color(rCol, gCol, bCol); + int noteColor = 0xFF_000000 | Mth.color(rCol, gCol, bCol); - var instrument = state.getValue(NoteBlock.INSTRUMENT); + var instrument = state.getValue(NoteBlock.INSTRUMENT); - lines.add(new Pair<>( - new ItemStack(Items.MUSIC_DISC_CHIRP), - Component.literal(String.valueOf(instrument.ordinal())) - .withStyle(color(instrumentColor(instrument))))); - lines.add(new Pair<>( - new ItemStack(Items.NOTE_BLOCK), - Component.literal(String.valueOf(note)) - .withStyle(color(noteColor)))); - }); + lines.add( + new Pair<>( + new ItemStack(Items.MUSIC_DISC_CHIRP), + Component.literal(String.valueOf(instrument.ordinal())) + .withStyle(color(instrumentColor(instrument))))); + lines.add( + new Pair<>( + new ItemStack(Items.NOTE_BLOCK), + Component.literal(String.valueOf(note)) + .withStyle(color(noteColor)))); + }); - ScryingLensOverlayRegistry.addDisplayer(HexBlocks.AKASHIC_BOOKSHELF, - (lines, state, pos, observer, world, direction) -> { - if (world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile) { - var iotaTag = tile.getIotaTag(); - if (iotaTag != null) { - var display = IotaType.getDisplay(iotaTag); - lines.add(new Pair<>(new ItemStack(Items.BOOK), display)); + ScryingLensOverlayRegistry.addDisplayer( + HexBlocks.AKASHIC_BOOKSHELF, + (lines, state, pos, observer, world, direction) -> { + if (world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile) { + var iotaTag = tile.getIotaTag(); + if (iotaTag != null) { + var display = IotaType.getDisplay(iotaTag); + lines.add(new Pair<>(new ItemStack(Items.BOOK), display)); + } } - } - }); + }); - ScryingLensOverlayRegistry.addDisplayer(Blocks.COMPARATOR, - (lines, state, pos, observer, world, direction) -> { - int comparatorValue = state.getAnalogOutputSignal(world, pos); - lines.add(new Pair<>( - new ItemStack(Items.REDSTONE), - Component.literal(comparatorValue == -1 ? "" : String.valueOf(comparatorValue)) - .withStyle(redstoneColor(comparatorValue)))); + ScryingLensOverlayRegistry.addDisplayer( + Blocks.COMPARATOR, + (lines, state, pos, observer, world, direction) -> { + int comparatorValue = state.getAnalogOutputSignal(world, pos); + lines.add( + new Pair<>( + new ItemStack(Items.REDSTONE), + Component.literal( + comparatorValue == -1 + ? "" + : String.valueOf(comparatorValue)) + .withStyle(redstoneColor(comparatorValue)))); - boolean compare = state.getValue(ComparatorBlock.MODE) == ComparatorMode.COMPARE; + boolean compare = + state.getValue(ComparatorBlock.MODE) == ComparatorMode.COMPARE; - lines.add(new Pair<>( - new ItemStack(Items.REDSTONE_TORCH), - Component.literal(compare ? ">=" : "-") - .withStyle(redstoneColor(compare ? 0 : 15)))); - }); + lines.add( + new Pair<>( + new ItemStack(Items.REDSTONE_TORCH), + Component.literal(compare ? ">=" : "-") + .withStyle(redstoneColor(compare ? 0 : 15)))); + }); - ScryingLensOverlayRegistry.addDisplayer(Blocks.POWERED_RAIL, - (lines, state, pos, observer, world, direction) -> { - int power = getPoweredRailStrength(world, pos, state); - lines.add(new Pair<>( - new ItemStack(Items.POWERED_RAIL), - Component.literal(String.valueOf(power)) - .withStyle(redstoneColor(power, 9)))); - }); + ScryingLensOverlayRegistry.addDisplayer( + Blocks.POWERED_RAIL, + (lines, state, pos, observer, world, direction) -> { + int power = getPoweredRailStrength(world, pos, state); + lines.add( + new Pair<>( + new ItemStack(Items.POWERED_RAIL), + Component.literal(String.valueOf(power)) + .withStyle(redstoneColor(power, 9)))); + }); - ScryingLensOverlayRegistry.addDisplayer(Blocks.REPEATER, - (lines, state, pos, observer, world, direction) -> lines.add(new Pair<>( - new ItemStack(Items.CLOCK), - Component.literal(String.valueOf(state.getValue(RepeaterBlock.DELAY))) - .withStyle(ChatFormatting.YELLOW)))); + ScryingLensOverlayRegistry.addDisplayer( + Blocks.REPEATER, + (lines, state, pos, observer, world, direction) -> + lines.add( + new Pair<>( + new ItemStack(Items.CLOCK), + Component.literal( + String.valueOf( + state.getValue( + RepeaterBlock.DELAY))) + .withStyle(ChatFormatting.YELLOW)))); ScryingLensOverlayRegistry.addPredicateDisplayer( - (state, pos, observer, world, direction) -> state.isSignalSource() && !state.is( - Blocks.COMPARATOR), - (lines, state, pos, observer, world, direction) -> { - int signalStrength = 0; - if (state.getBlock() instanceof RedStoneWireBlock) { - signalStrength = state.getValue(RedStoneWireBlock.POWER); - } else { - for (Direction dir : Direction.values()) { - signalStrength = Math.max(signalStrength, state.getSignal(world, pos, dir)); + (state, pos, observer, world, direction) -> + state.isSignalSource() && !state.is(Blocks.COMPARATOR), + (lines, state, pos, observer, world, direction) -> { + int signalStrength = 0; + if (state.getBlock() instanceof RedStoneWireBlock) { + signalStrength = state.getValue(RedStoneWireBlock.POWER); + } else { + for (Direction dir : Direction.values()) { + signalStrength = + Math.max(signalStrength, state.getSignal(world, pos, dir)); + } } - } - lines.add(0, new Pair<>( - new ItemStack(Items.REDSTONE), - Component.literal(String.valueOf(signalStrength)) - .withStyle(redstoneColor(signalStrength)))); - }); + lines.add( + 0, + new Pair<>( + new ItemStack(Items.REDSTONE), + Component.literal(String.valueOf(signalStrength)) + .withStyle(redstoneColor(signalStrength)))); + }); } private static int getPoweredRailStrength(Level level, BlockPos pos, BlockState state) { - if (level.hasNeighborSignal(pos)) - return 9; + if (level.hasNeighborSignal(pos)) return 9; int positiveValue = findPoweredRailSignal(level, pos, state, true, 0); int negativeValue = findPoweredRailSignal(level, pos, state, false, 0); return Math.max(positiveValue, negativeValue); } // Copypasta from PoweredRailBlock.class - private static int findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean travelPositive, - int depth) { + private static int findPoweredRailSignal( + Level level, BlockPos pos, BlockState state, boolean travelPositive, int depth) { if (depth >= 8) { return 0; } else { @@ -199,21 +234,20 @@ private static int findPoweredRailSignal(Level level, BlockPos pos, BlockState s shape = RailShape.NORTH_SOUTH; } - int power = getPowerFromRail(level, new BlockPos(x, y, z), travelPositive, depth, - shape); + int power = + getPowerFromRail(level, new BlockPos(x, y, z), travelPositive, depth, shape); if (power > 0) { return power; } else if (descending) { - return getPowerFromRail(level, new BlockPos(x, y - 1, z), travelPositive, depth, - shape); + return getPowerFromRail( + level, new BlockPos(x, y - 1, z), travelPositive, depth, shape); } else { return 0; } } } - private static UnaryOperator