diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/Colorizer.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/Colorizer.java new file mode 100644 index 00000000..17453a16 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/Colorizer.java @@ -0,0 +1,37 @@ +package at.petrak.hexcasting.api.addldata; + +import net.minecraft.util.FastColor; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; + +import java.util.UUID; + +public interface Colorizer { + int color(UUID owner, float time, Vec3 position); + + static int morphBetweenColors(int[] colors, Vec3 gradientDir, float time, Vec3 position) { + 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); + int start = colors[baseIdx % colors.length]; + int end = colors[(baseIdx + 1) % colors.length]; + + var r1 = FastColor.ARGB32.red(start); + var g1 = FastColor.ARGB32.green(start); + var b1 = FastColor.ARGB32.blue(start); + var a1 = FastColor.ARGB32.alpha(start); + var r2 = FastColor.ARGB32.red(end); + var g2 = FastColor.ARGB32.green(end); + var b2 = FastColor.ARGB32.blue(end); + var a2 = FastColor.ARGB32.alpha(end); + + var r = Mth.lerp(t, r1, r2); + var g = Mth.lerp(t, g1, g2); + var b = Mth.lerp(t, b1, b2); + var a = Mth.lerp(t, a1, a2); + + return FastColor.ARGB32.color((int) a, (int) r, (int) g, (int) b); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/DataHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/DataHolder.java new file mode 100644 index 00000000..87b5e770 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/DataHolder.java @@ -0,0 +1,28 @@ +package at.petrak.hexcasting.api.addldata; + +import at.petrak.hexcasting.api.spell.SpellDatum; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import org.jetbrains.annotations.Nullable; + +public interface DataHolder { + @Nullable + CompoundTag readRawDatum(); + + @Nullable + default SpellDatum readDatum(ServerLevel world) { + var tag = readRawDatum(); + if (tag != null) { + return SpellDatum.DeserializeFromNBT(tag, world); + } else { + return null; + } + } + + @Nullable + default SpellDatum emptyDatum() { + return null; + } + + boolean writeDatum(@Nullable SpellDatum datum, boolean simulate); +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/addldata/ManaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ManaHolder.java new file mode 100644 index 00000000..ee1792c3 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/addldata/ManaHolder.java @@ -0,0 +1,30 @@ +package at.petrak.hexcasting.api.addldata; + +public interface ManaHolder { + + int getMana(); + + int getMaxMana(); + + void setMana(int mana); + + boolean canRecharge(); + + boolean canProvide(); + + int getConsumptionPriority(); + + boolean canConstructBattery(); + + default int withdrawMana(int cost, boolean simulate) { + var manaHere = getMana(); + if (cost < 0) { + cost = manaHere; + } + if (!simulate) { + var manaLeft = manaHere - cost; + setMana(manaLeft); + } + return Math.min(cost, manaHere); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/cap/Colorizer.java b/Common/src/main/java/at/petrak/hexcasting/api/cap/Colorizer.java deleted file mode 100644 index 13c07c34..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/cap/Colorizer.java +++ /dev/null @@ -1,37 +0,0 @@ -package at.petrak.hexcasting.api.cap; - -import net.minecraft.util.FastColor; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.Vec3; - -import java.util.UUID; - -public interface Colorizer { - int color(UUID owner, float time, Vec3 position); - - static int morphBetweenColors(int[] colors, Vec3 gradientDir, float time, Vec3 position) { - 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); - int start = colors[baseIdx % colors.length]; - int end = colors[(baseIdx + 1) % colors.length]; - - var r1 = FastColor.ARGB32.red(start); - var g1 = FastColor.ARGB32.green(start); - var b1 = FastColor.ARGB32.blue(start); - var a1 = FastColor.ARGB32.alpha(start); - var r2 = FastColor.ARGB32.red(end); - var g2 = FastColor.ARGB32.green(end); - var b2 = FastColor.ARGB32.blue(end); - var a2 = FastColor.ARGB32.alpha(end); - - var r = Mth.lerp(t, r1, r2); - var g = Mth.lerp(t, g1, g2); - var b = Mth.lerp(t, b1, b2); - var a = Mth.lerp(t, a1, a2); - - return FastColor.ARGB32.color((int) a, (int) r, (int) g, (int) b); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/cap/DataHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/cap/DataHolder.java deleted file mode 100644 index 40a39e50..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/cap/DataHolder.java +++ /dev/null @@ -1,29 +0,0 @@ -package at.petrak.hexcasting.api.cap; - -import at.petrak.hexcasting.api.spell.SpellDatum; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerLevel; -import org.jetbrains.annotations.Nullable; - -public interface DataHolder { - - @Nullable - CompoundTag readRawDatum(); - - @Nullable - default SpellDatum readDatum(ServerLevel world) { - var tag = readRawDatum(); - if (tag != null) { - return SpellDatum.DeserializeFromNBT(tag, world); - } else { - return null; - } - } - - @Nullable - default SpellDatum emptyDatum() { - return null; - } - - boolean writeDatum(@Nullable SpellDatum datum, boolean simulate); -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/cap/HexCapabilities.java b/Common/src/main/java/at/petrak/hexcasting/api/cap/HexCapabilities.java index c920dc2e..c4fa5176 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/cap/HexCapabilities.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/cap/HexCapabilities.java @@ -1,17 +1,20 @@ package at.petrak.hexcasting.api.cap; +import at.petrak.hexcasting.api.addldata.Colorizer; +import at.petrak.hexcasting.api.addldata.DataHolder; +import at.petrak.hexcasting.api.addldata.ManaHolder; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityToken; public final class HexCapabilities { - public static final Capability MANA = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability DATUM = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability SPELL = CapabilityManager.get(new CapabilityToken<>() { - }); - public static final Capability COLOR = CapabilityManager.get(new CapabilityToken<>() { - }); + public static final Capability MANA = CapabilityManager.get(new CapabilityToken<>() { + }); + public static final Capability DATUM = CapabilityManager.get(new CapabilityToken<>() { + }); + public static final Capability SPELL = CapabilityManager.get(new CapabilityToken<>() { + }); + public static final Capability COLOR = CapabilityManager.get(new CapabilityToken<>() { + }); } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/cap/HexHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/cap/HexHolder.java new file mode 100644 index 00000000..3b468384 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/api/cap/HexHolder.java @@ -0,0 +1,18 @@ +package at.petrak.hexcasting.api.cap; + +import at.petrak.hexcasting.api.spell.math.HexPattern; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public interface HexHolder { + + boolean canDrawManaFromInventory(); + + @Nullable + List getPatterns(); + + void writePatterns(List patterns, int mana); + + void clearPatterns(); +} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/cap/ManaHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/cap/ManaHolder.java deleted file mode 100644 index 7c465dbc..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/cap/ManaHolder.java +++ /dev/null @@ -1,26 +0,0 @@ -package at.petrak.hexcasting.api.cap; - -public interface ManaHolder { - - int getMana(); - int getMaxMana(); - void setMana(int mana); - - boolean canRecharge(); - boolean canProvide(); - - int getConsumptionPriority(); - - boolean canConstructBattery(); - - default int withdrawMana(int cost, boolean simulate) { - var manaHere = getMana(); - if (cost < 0) - cost = manaHere; - if (!simulate) { - var manaLeft = manaHere - cost; - setMana(manaLeft); - } - return Math.min(cost, manaHere); - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/cap/SpellHolder.java b/Common/src/main/java/at/petrak/hexcasting/api/cap/SpellHolder.java deleted file mode 100644 index 23667a42..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/cap/SpellHolder.java +++ /dev/null @@ -1,18 +0,0 @@ -package at.petrak.hexcasting.api.cap; - -import at.petrak.hexcasting.api.spell.math.HexPattern; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public interface SpellHolder { - - boolean canDrawManaFromInventory(); - - @Nullable - List getPatterns(); - - void writePatterns(List patterns, int mana); - - void clearPatterns(); -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/item/SpellHolderItem.java b/Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java similarity index 88% rename from Common/src/main/java/at/petrak/hexcasting/api/item/SpellHolderItem.java rename to Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java index 14b6d084..4bbe8720 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/item/SpellHolderItem.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/item/HexHolderItem.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -public interface SpellHolderItem extends ManaHolderItem { +public interface HexHolderItem extends ManaHolderItem { boolean canDrawManaFromInventory(ItemStack stack); diff --git a/Common/src/main/java/at/petrak/hexcasting/api/misc/FrozenColorizer.java b/Common/src/main/java/at/petrak/hexcasting/api/misc/FrozenColorizer.java index 616e0a64..db524af2 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/misc/FrozenColorizer.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/misc/FrozenColorizer.java @@ -1,6 +1,6 @@ package at.petrak.hexcasting.api.misc; -import at.petrak.hexcasting.api.cap.Colorizer; +import at.petrak.hexcasting.api.addldata.Colorizer; import at.petrak.hexcasting.api.cap.HexCapabilities; import at.petrak.hexcasting.api.mod.HexApiItems; import net.minecraft.Util; @@ -21,14 +21,14 @@ import java.util.function.Supplier; public record FrozenColorizer(ItemStack item, UUID owner) { private static final int[] MINIMUM_LUMINANCE_COLOR_WHEEL = { - 0xFF200000, 0xFF202000, 0xFF002000, 0xFF002020, 0xFF000020, 0xFF200020 + 0xFF200000, 0xFF202000, 0xFF002000, 0xFF002020, 0xFF000020, 0xFF200020 }; public static final String TAG_STACK = "stack"; public static final String TAG_OWNER = "owner"; public static final Supplier DEFAULT = - () -> new FrozenColorizer(new ItemStack(HexApiItems.COLORIZER_WHITE), Util.NIL_UUID); + () -> new FrozenColorizer(new ItemStack(HexApiItems.COLORIZER_WHITE), Util.NIL_UUID); public CompoundTag serialize() { var out = new CompoundTag(); @@ -38,8 +38,9 @@ public record FrozenColorizer(ItemStack item, UUID owner) { } public static FrozenColorizer deserialize(CompoundTag tag) { - if (tag.isEmpty()) + if (tag.isEmpty()) { return FrozenColorizer.DEFAULT.get(); + } try { ItemStack item; if (tag.contains("item", Tag.TAG_STRING) && !tag.contains(TAG_STACK, Tag.TAG_COMPOUND)) { @@ -60,6 +61,7 @@ public record FrozenColorizer(ItemStack item, UUID owner) { /** * Gets a color with a minimum luminance applied. + * * @param time absolute world time in ticks * @param position a position for the icosahedron, a randomish number for particles. * @return an AARRGGBB color. @@ -70,10 +72,11 @@ public record FrozenColorizer(ItemStack item, UUID owner) { 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 = Colorizer.morphBetweenColors(MINIMUM_LUMINANCE_COLOR_WHEEL, new Vec3(0.1, 0.1, 0.1), time / 20 / 20, position); + int rawMod = Colorizer.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); 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 6a1e5347..cadb52f0 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 @@ -9,16 +9,12 @@ public class HexConfig { public interface CommonConfigAccess { int dustManaAmount(); - int shardManaAmount(); - int chargedCrystalManaAmount(); - double manaToHealthRate(); - int DEFAULT_DUST_MANA_AMOUNT = 10_000; int DEFAULT_SHARD_MANA_AMOUNT = 50_000; int DEFAULT_CHARGED_MANA_AMOUNT = 100_000; @@ -28,8 +24,7 @@ public class HexConfig { public interface ClientConfigAccess { double patternPointSpeedMultiplier(); - - + boolean ctrlTogglesOffStrokeOrder(); double DEFAULT_PATTERN_POINT_SPEED_MULTIPLIER = 1; diff --git a/Common/src/main/java/at/petrak/hexcasting/api/player/HexPlayerDataHelper.java b/Common/src/main/java/at/petrak/hexcasting/api/player/HexPlayerDataHelper.java deleted file mode 100644 index acd7fc6b..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/api/player/HexPlayerDataHelper.java +++ /dev/null @@ -1,193 +0,0 @@ -package at.petrak.hexcasting.api.player; - -import at.petrak.hexcasting.api.misc.FrozenColorizer; -import at.petrak.hexcasting.api.mod.HexApiMessages; -import at.petrak.hexcasting.api.spell.casting.CastingContext; -import at.petrak.hexcasting.api.spell.casting.CastingHarness; -import at.petrak.hexcasting.api.spell.casting.ResolvedPattern; -import at.petrak.hexcasting.api.utils.HexUtils; -import net.minecraft.core.Registry; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.player.Player; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.network.PacketDistributor; - -import java.util.ArrayList; -import java.util.List; - -public class HexPlayerDataHelper { - public static final String TAG_SENTINEL_EXISTS = "hexcasting:sentinel_exists"; - public static final String TAG_SENTINEL_GREATER = "hexcasting:sentinel_extends_range"; - public static final String TAG_SENTINEL_POSITION = "hexcasting:sentinel_position"; - public static final String TAG_SENTINEL_DIMENSION = "hexcasting:sentinel_dimension"; - - public static final String TAG_COLOR = "hexcasting:colorizer"; - - public static final String TAG_FLIGHT_ALLOWED = "hexcasting:flight_allowed"; - public static final String TAG_FLIGHT_TIME = "hexcasting:flight_time"; - public static final String TAG_FLIGHT_ORIGIN = "hexcasting:flight_origin"; - public static final String TAG_FLIGHT_DIMENSION = "hexcasting:flight_origin"; - public static final String TAG_FLIGHT_RADIUS = "hexcasting:flight_radius"; - - public static final String TAG_HARNESS = "hexcasting:spell_harness"; - public static final String TAG_PATTERNS = "hexcasting:spell_patterns"; - - - @SubscribeEvent - public static void copyDataOnDeath(PlayerEvent.Clone evt) { - var eitherSidePlayer = evt.getPlayer(); - // this apparently defines it in outside scope. the more you know. - if (!(eitherSidePlayer instanceof ServerPlayer player)) { - return; - } - - var eitherSideProto = evt.getOriginal(); - if (!(eitherSideProto instanceof ServerPlayer proto)) { - return; - } - - // Copy data from this to new player - setFlight(player, getFlight(proto)); - setSentinel(player, getSentinel(proto)); - setColorizer(player, getColorizer(proto)); - setHarness(player, getHarness(proto, InteractionHand.MAIN_HAND)); - setPatterns(player, getPatterns(proto)); - } - - @SubscribeEvent - public static void syncDataOnLogin(PlayerEvent.PlayerLoggedInEvent evt) { - if (!(evt.getPlayer() instanceof ServerPlayer player)) { - return; - } - - syncSentinel(player); - syncColorizer(player); - } - - @SubscribeEvent - public static void syncDataOnRejoin(PlayerEvent.PlayerRespawnEvent evt) { - if (!(evt.getPlayer() instanceof ServerPlayer player)) { - return; - } - - syncSentinel(player); - syncColorizer(player); - } - - private static void syncSentinel(ServerPlayer player) { - HexApiMessages.getChannel().send(PacketDistributor.PLAYER.with(() -> player), HexApiMessages.getSentinelMessage(getSentinel(player))); - } - - private static void syncColorizer(ServerPlayer player) { - HexApiMessages.getChannel().send(PacketDistributor.PLAYER.with(() -> player), HexApiMessages.getColorizerMessage(getColorizer(player))); - } - - public static void setFlight(ServerPlayer player, FlightAbility flight) { - CompoundTag tag = player.getPersistentData(); - tag.putBoolean(TAG_FLIGHT_ALLOWED, flight.allowed()); - if (flight.allowed()) { - tag.putInt(TAG_FLIGHT_TIME, flight.timeLeft()); - tag.put(TAG_FLIGHT_ORIGIN, HexUtils.serializeToNBT(flight.origin())); - tag.putString(TAG_FLIGHT_DIMENSION, flight.dimension().location().toString()); - tag.putDouble(TAG_FLIGHT_RADIUS, flight.radius()); - } else { - tag.remove(TAG_FLIGHT_TIME); - tag.remove(TAG_FLIGHT_ORIGIN); - tag.remove(TAG_FLIGHT_RADIUS); - } - } - - public static void setColorizer(Player player, FrozenColorizer colorizer) { - CompoundTag tag = player.getPersistentData(); - tag.put(TAG_COLOR, colorizer.serialize()); - - if (player instanceof ServerPlayer serverPlayer) - syncColorizer(serverPlayer); - } - - public static void setSentinel(Player player, Sentinel sentinel) { - CompoundTag tag = player.getPersistentData(); - tag.putBoolean(TAG_SENTINEL_EXISTS, sentinel.hasSentinel()); - if (sentinel.hasSentinel()) { - tag.putBoolean(TAG_SENTINEL_GREATER, sentinel.extendsRange()); - tag.put(TAG_SENTINEL_POSITION, HexUtils.serializeToNBT(sentinel.position())); - tag.putString(TAG_SENTINEL_DIMENSION, sentinel.dimension().location().toString()); - } else { - tag.remove(TAG_SENTINEL_GREATER); - tag.remove(TAG_SENTINEL_POSITION); - tag.remove(TAG_SENTINEL_DIMENSION); - } - - if (player instanceof ServerPlayer serverPlayer) - syncSentinel(serverPlayer); - } - - public static void setHarness(ServerPlayer player, CastingHarness harness) { - player.getPersistentData().put(TAG_HARNESS, harness == null ? new CompoundTag() : harness.serializeToNBT()); - } - - public static void setPatterns(ServerPlayer player, List patterns) { - var listTag = new ListTag(); - for (ResolvedPattern pattern : patterns) { - listTag.add(pattern.serializeToNBT()); - } - player.getPersistentData().put(TAG_PATTERNS, listTag); - } - - public static FlightAbility getFlight(ServerPlayer player) { - CompoundTag tag = player.getPersistentData(); - boolean allowed = tag.getBoolean(TAG_FLIGHT_ALLOWED); - if (allowed) { - var timeLeft = tag.getInt(TAG_FLIGHT_TIME); - var origin = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_FLIGHT_ORIGIN)); - var radius = tag.getDouble(TAG_FLIGHT_RADIUS); - var dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(tag.getString(TAG_SENTINEL_DIMENSION))); - return new FlightAbility(true, timeLeft, dimension, origin, radius); - } - return FlightAbility.deny(); - } - - public static FrozenColorizer getColorizer(Player player) { - return FrozenColorizer.deserialize(player.getPersistentData().getCompound(TAG_COLOR)); - } - - public static Sentinel getSentinel(Player player) { - CompoundTag tag = player.getPersistentData(); - var exists = tag.getBoolean(TAG_SENTINEL_EXISTS); - if (!exists) - return Sentinel.none(); - var extendsRange = tag.getBoolean(TAG_SENTINEL_GREATER); - var position = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_SENTINEL_POSITION)); - var dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(tag.getString(TAG_SENTINEL_DIMENSION))); - - return new Sentinel(true, extendsRange, position, dimension); - } - - public static CastingHarness getHarness(ServerPlayer player, InteractionHand hand) { - var ctx = new CastingContext(player, hand); - return CastingHarness.DeserializeFromNBT(player.getPersistentData().getCompound(TAG_HARNESS), ctx); - } - - public static List getPatterns(ServerPlayer player) { - ListTag patternsTag = player.getPersistentData().getList(TAG_PATTERNS, Tag.TAG_COMPOUND); - - List patterns = new ArrayList<>(patternsTag.size()); - - for (int i = 0; i < patternsTag.size(); i++) { - patterns.add(ResolvedPattern.DeserializeFromNBT(patternsTag.getCompound(i))); - } - return patterns; - } - - public static void clearCastingData(ServerPlayer player) { - player.getPersistentData().remove(TAG_HARNESS); - player.getPersistentData().remove(TAG_PATTERNS); - } -} 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 f32cb91d..7419d20e 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 @@ -5,8 +5,10 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; public record Sentinel(boolean hasSentinel, boolean extendsRange, Vec3 position, - ResourceKey dimension) { + ResourceKey dimension) { public static Sentinel none() { return new Sentinel(false, false, Vec3.ZERO, Level.OVERWORLD); } + + } 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 12260dcb..de8e0df5 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/RegisterClientStuff.java @@ -19,7 +19,7 @@ import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicRecord; import at.petrak.hexcasting.common.entities.HexEntities; import at.petrak.hexcasting.common.items.*; import at.petrak.hexcasting.common.items.magic.ItemManaBattery; -import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell; +import at.petrak.hexcasting.common.items.magic.ItemPackagedHex; import at.petrak.hexcasting.common.particles.HexParticles; import com.mojang.datafixers.util.Pair; import net.minecraft.ChatFormatting; @@ -211,8 +211,8 @@ public class RegisterClientStuff { (stack, level, holder, holderID) -> item.canWrite(stack, SpellDatum.make(Widget.NULL)) ? 0f : 1f); } - private static void registerPackagedSpellOverrides(ItemPackagedSpell item) { - ItemProperties.register(item, ItemPackagedSpell.HAS_PATTERNS_PRED, + private static void registerPackagedSpellOverrides(ItemPackagedHex item) { + ItemProperties.register(item, ItemPackagedHex.HAS_PATTERNS_PRED, (stack, level, holder, holderID) -> item.getPatterns(stack) != null ? 1f : 0f ); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/blocks/HexBlocks.java b/Common/src/main/java/at/petrak/hexcasting/common/blocks/HexBlocks.java index 474854f6..61fc4549 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/blocks/HexBlocks.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/blocks/HexBlocks.java @@ -1,6 +1,5 @@ package at.petrak.hexcasting.common.blocks; -import at.petrak.hexcasting.HexMod; import at.petrak.hexcasting.api.circle.BlockAbstractImpetus; import at.petrak.hexcasting.api.spell.DatumType; import at.petrak.hexcasting.common.blocks.akashic.*; @@ -15,6 +14,8 @@ import at.petrak.hexcasting.common.blocks.decoration.BlockAxis; import at.petrak.hexcasting.common.blocks.decoration.BlockSconce; import at.petrak.hexcasting.common.blocks.decoration.BlockStrippable; import at.petrak.hexcasting.common.items.HexItems; +import com.mojang.datafixers.util.Pair; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; @@ -22,38 +23,28 @@ import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.MaterialColor; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; -import java.util.function.Supplier; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; public class HexBlocks { - public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, HexMod.MOD_ID); + public static void registerBlocks(BiConsumer r) { + for (var e : BLOCKS.entrySet()) { + r.accept(e.getValue(), e.getKey()); + } + } - public static final RegistryObject CONJURED_LIGHT = blockNoItem("conjured", - () -> new BlockConjuredLight( - BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.NONE) - .sound(SoundType.AMETHYST) - .lightLevel((state) -> 15) - .noDrops() - .isValidSpawn(HexBlocks::never) - .instabreak() - .noCollission() - .isSuffocating(HexBlocks::never) - .isViewBlocking(HexBlocks::never))); + public static void registerBlockItems(BiConsumer r) { + for (var e : BLOCK_ITEMS.entrySet()) { + r.accept(new BlockItem(e.getValue().getFirst(), e.getValue().getSecond()), e.getKey()); + } + } - public static final RegistryObject CONJURED_BLOCK = blockNoItem("conjured_block", - () -> new BlockConjured( - BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.NONE) - .sound(SoundType.AMETHYST) - .lightLevel((state) -> 2) - .noDrops() - .isValidSpawn(HexBlocks::never) - .instabreak() - .noOcclusion() - .isSuffocating(HexBlocks::never) - .isViewBlocking(HexBlocks::never))); + private static final Map BLOCKS = new LinkedHashMap<>(); + private static final Map> BLOCK_ITEMS = new LinkedHashMap<>(); private static BlockBehaviour.Properties slateish() { return BlockBehaviour.Properties @@ -100,111 +91,140 @@ public class HexBlocks { .isViewBlocking(HexBlocks::never); } - public static final RegistryObject SLATE = BLOCKS.register("slate", - () -> new BlockSlate(slateish())); + // we give these faux items so Patchi can have an item to view with + public static final Block CONJURED_LIGHT = blockItem("conjured", + new BlockConjuredLight( + BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.NONE) + .sound(SoundType.AMETHYST) + .lightLevel((state) -> 15) + .noDrops() + .isValidSpawn(HexBlocks::never) + .instabreak() + .noCollission() + .isSuffocating(HexBlocks::never) + .isViewBlocking(HexBlocks::never)), + new Item.Properties()); + public static final Block CONJURED_BLOCK = blockItem("conjured_block", + new BlockConjured( + BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.NONE) + .sound(SoundType.AMETHYST) + .lightLevel((state) -> 2) + .noDrops() + .isValidSpawn(HexBlocks::never) + .instabreak() + .noOcclusion() + .isSuffocating(HexBlocks::never) + .isViewBlocking(HexBlocks::never)), + new Item.Properties()); - public static final RegistryObject EMPTY_IMPETUS = blockItem("empty_impetus", - () -> new BlockEmptyImpetus(slateish())); + // "no" item because we add it manually + public static final BlockSlate SLATE = blockNoItem("slate", new BlockSlate(slateish())); - public static final RegistryObject IMPETUS_RIGHTCLICK = blockItem( - "impetus_rightclick", - () -> new BlockRightClickImpetus(slateish() + public static final BlockEmptyImpetus EMPTY_IMPETUS = blockItem("empty_impetus", new BlockEmptyImpetus(slateish())); + public static final BlockRightClickImpetus IMPETUS_RIGHTCLICK = blockItem("impetus_rightclick", + new BlockRightClickImpetus(slateish() .lightLevel(bs -> bs.getValue(BlockAbstractImpetus.ENERGIZED) ? 15 : 0))); - public static final RegistryObject IMPETUS_LOOK = blockItem( - "impetus_look", - () -> new BlockLookingImpetus(slateish() + public static final BlockLookingImpetus IMPETUS_LOOK = blockItem("impetus_look", + new BlockLookingImpetus(slateish() .lightLevel(bs -> bs.getValue(BlockAbstractImpetus.ENERGIZED) ? 15 : 0))); - public static final RegistryObject IMPETUS_STOREDPLAYER = blockItem( - "impetus_storedplayer", - () -> new BlockStoredPlayerImpetus(slateish() + public static final BlockStoredPlayerImpetus IMPETUS_STOREDPLAYER = blockItem("impetus_storedplayer", + new BlockStoredPlayerImpetus(slateish() .lightLevel(bs -> bs.getValue(BlockAbstractImpetus.ENERGIZED) ? 15 : 0))); - public static final RegistryObject EMPTY_DIRECTRIX = blockItem("empty_directrix", - () -> new BlockEmptyDirectrix(slateish())); - public static final RegistryObject DIRECTRIX_REDSTONE = blockItem("directrix_redstone", - () -> new BlockRedstoneDirectrix(slateish())); + public static final BlockEmptyDirectrix EMPTY_DIRECTRIX = blockItem("empty_directrix", + new BlockEmptyDirectrix(slateish())); + public static final BlockRedstoneDirectrix DIRECTRIX_REDSTONE = blockItem("directrix_redstone", + new BlockRedstoneDirectrix(slateish())); - public static final RegistryObject AKASHIC_RECORD = blockItem("akashic_record", - () -> new BlockAkashicRecord(akashicWoodyHard().lightLevel(bs -> 15))); - public static final RegistryObject AKASHIC_BOOKSHELF = blockItem("akashic_bookshelf", - () -> new BlockAkashicBookshelf(akashicWoodyHard() + public static final BlockAkashicRecord AKASHIC_RECORD = blockItem("akashic_record", + new BlockAkashicRecord(akashicWoodyHard().lightLevel(bs -> 15))); + public static final BlockAkashicBookshelf AKASHIC_BOOKSHELF = blockItem("akashic_bookshelf", + new BlockAkashicBookshelf(akashicWoodyHard() .lightLevel(bs -> (bs.getValue(BlockAkashicBookshelf.DATUM_TYPE) == DatumType.EMPTY) ? 0 : 4))); - public static final RegistryObject AKASHIC_CONNECTOR = blockItem("akashic_connector", - () -> new BlockAkashicFloodfiller(akashicWoodyHard().lightLevel(bs -> 10))); + public static final BlockAkashicFloodfiller AKASHIC_CONNECTOR = blockItem("akashic_connector", + new BlockAkashicFloodfiller(akashicWoodyHard().lightLevel(bs -> 10))); // Decoration?! - public static final RegistryObject SLATE_BLOCK = blockItem("slate_block", - () -> new Block(slateish().strength(2f, 4f))); - public static final RegistryObject AMETHYST_DUST_BLOCK = blockItem("amethyst_dust_block", - () -> new SandBlock(0xff_b38ef3, BlockBehaviour.Properties.of(Material.SAND, MaterialColor.COLOR_PURPLE) + public static final Block SLATE_BLOCK = blockItem("slate_block", new Block(slateish().strength(2f, 4f))); + public static final SandBlock AMETHYST_DUST_BLOCK = blockItem("amethyst_dust_block", + new SandBlock(0xff_b38ef3, BlockBehaviour.Properties.of(Material.SAND, MaterialColor.COLOR_PURPLE) .strength(0.5f).sound(SoundType.SAND))); - public static final RegistryObject AMETHYST_TILES = blockItem("amethyst_tiles", - () -> new AmethystBlock(BlockBehaviour.Properties.copy(Blocks.AMETHYST_BLOCK))); - public static final RegistryObject SCROLL_PAPER = blockItem("scroll_paper", - () -> new BlockBurns(papery(MaterialColor.TERRACOTTA_WHITE), 100, 60)); - public static final RegistryObject ANCIENT_SCROLL_PAPER = blockItem("ancient_scroll_paper", - () -> new BlockBurns(papery(MaterialColor.TERRACOTTA_ORANGE), 100, 60)); - public static final RegistryObject SCROLL_PAPER_LANTERN = blockItem("scroll_paper_lantern", - () -> new BlockBurns(papery(MaterialColor.TERRACOTTA_WHITE).lightLevel($ -> 15), 100, 60)); - public static final RegistryObject ANCIENT_SCROLL_PAPER_LANTERN = blockItem( + public static final AmethystBlock AMETHYST_TILES = blockItem("amethyst_tiles", + new AmethystBlock(BlockBehaviour.Properties.copy(Blocks.AMETHYST_BLOCK))); + public static final Block SCROLL_PAPER = blockItem("scroll_paper", + new BlockBurns(papery(MaterialColor.TERRACOTTA_WHITE), 100, 60)); + public static final Block ANCIENT_SCROLL_PAPER = blockItem("ancient_scroll_paper", + new BlockBurns(papery(MaterialColor.TERRACOTTA_ORANGE), 100, 60)); + public static final Block SCROLL_PAPER_LANTERN = blockItem("scroll_paper_lantern", + new BlockBurns(papery(MaterialColor.TERRACOTTA_WHITE).lightLevel($ -> 15), 100, 60)); + public static final Block ANCIENT_SCROLL_PAPER_LANTERN = blockItem( "ancient_scroll_paper_lantern", - () -> new BlockBurns(papery(MaterialColor.TERRACOTTA_ORANGE).lightLevel($ -> 12), 100, 60)); - public static final RegistryObject SCONCE = blockItem("amethyst_sconce", - () -> new BlockSconce(BlockBehaviour.Properties.of(Material.AMETHYST, MaterialColor.COLOR_PURPLE) + new BlockBurns(papery(MaterialColor.TERRACOTTA_ORANGE).lightLevel($ -> 12), 100, 60)); + public static final BlockSconce SCONCE = blockItem("amethyst_sconce", + new BlockSconce(BlockBehaviour.Properties.of(Material.AMETHYST, MaterialColor.COLOR_PURPLE) .sound(SoundType.AMETHYST) .strength(1f) .lightLevel($ -> 15))); - public static final RegistryObject AKASHIC_LOG_STRIPPED = blockItem("akashic_log_stripped", - () -> new BlockAkashicLog(akashicWoody())); - public static final RegistryObject AKASHIC_LOG = blockItem("akashic_log", - () -> new BlockAkashicWood(akashicWoody(), AKASHIC_LOG_STRIPPED)); - public static final RegistryObject AKASHIC_WOOD_STRIPPED = blockItem("akashic_wood_stripped", - () -> new BlockBurns(akashicWoody(), 5, 5)); - public static final RegistryObject AKASHIC_WOOD = blockItem("akashic_wood", - () -> new BlockStrippable(akashicWoody(), AKASHIC_WOOD_STRIPPED)); - public static final RegistryObject AKASHIC_PLANKS = blockItem("akashic_planks", - () -> new BlockBurns(akashicWoody(), 20, 5)); - public static final RegistryObject AKASHIC_PANEL = blockItem("akashic_panel", - () -> new BlockBurns(akashicWoody(), 20, 5)); - public static final RegistryObject AKASHIC_TILE = blockItem("akashic_tile", - () -> new BlockBurns(akashicWoody(), 20, 5)); - public static final RegistryObject AKASHIC_DOOR = blockItem("akashic_door", - () -> new DoorBlock(akashicWoody().noOcclusion())); - public static final RegistryObject AKASHIC_TRAPDOOR = blockItem("akashic_trapdoor", - () -> new TrapDoorBlock(akashicWoody().noOcclusion())); - public static final RegistryObject AKASHIC_STAIRS = blockItem("akashic_stairs", - () -> new StairBlock(() -> AKASHIC_PLANKS.get().defaultBlockState(), akashicWoody().noOcclusion())); - public static final RegistryObject AKASHIC_SLAB = blockItem("akashic_slab", - () -> new SlabBlock(akashicWoody().noOcclusion())); - public static final RegistryObject AKASHIC_BUTTON = blockItem("akashic_button", - () -> new WoodButtonBlock(akashicWoody().noOcclusion())); - public static final RegistryObject AKASHIC_PRESSURE_PLATE = blockItem("akashic_pressure_plate", - () -> new PressurePlateBlock(PressurePlateBlock.Sensitivity.EVERYTHING, akashicWoody().noOcclusion())); - public static final RegistryObject AKASHIC_LEAVES1 = blockItem("akashic_leaves1", - () -> new BlockAkashicLeaves(leaves(MaterialColor.COLOR_PURPLE))); - public static final RegistryObject AKASHIC_LEAVES2 = blockItem("akashic_leaves2", - () -> new BlockAkashicLeaves(leaves(MaterialColor.COLOR_BLUE))); - public static final RegistryObject AKASHIC_LEAVES3 = blockItem("akashic_leaves3", - () -> new BlockAkashicLeaves(leaves(MaterialColor.COLOR_YELLOW))); + + public static final BlockAxis AKASHIC_LOG_STRIPPED = blockItem("akashic_log_stripped", + new BlockAkashicLog(akashicWoody())); + public static final BlockStrippable AKASHIC_LOG = blockItem("akashic_log", + new BlockAkashicWood(akashicWoody(), () -> AKASHIC_LOG_STRIPPED)); + public static final Block AKASHIC_WOOD_STRIPPED = blockItem("akashic_wood_stripped", + new BlockBurns(akashicWoody(), 5, 5)); + public static final BlockStrippable AKASHIC_WOOD = blockItem("akashic_wood", + new BlockStrippable(akashicWoody(), () -> AKASHIC_WOOD_STRIPPED)); + public static final Block AKASHIC_PLANKS = blockItem("akashic_planks", + new BlockBurns(akashicWoody(), 20, 5)); + public static final Block AKASHIC_PANEL = blockItem("akashic_panel", + new BlockBurns(akashicWoody(), 20, 5)); + public static final Block AKASHIC_TILE = blockItem("akashic_tile", + new BlockBurns(akashicWoody(), 20, 5)); + // todo: mixin? AT? + public static final DoorBlock AKASHIC_DOOR = blockItem("akashic_door", + new DoorBlock(akashicWoody().noOcclusion())); + public static final TrapDoorBlock AKASHIC_TRAPDOOR = blockItem("akashic_trapdoor", + new TrapDoorBlock(akashicWoody().noOcclusion())); + public static final StairBlock AKASHIC_STAIRS = blockItem("akashic_stairs", + new StairBlock(AKASHIC_PLANKS.defaultBlockState(), akashicWoody().noOcclusion())); + public static final SlabBlock AKASHIC_SLAB = blockItem("akashic_slab", + new SlabBlock(akashicWoody().noOcclusion())); + public static final WoodButtonBlock AKASHIC_BUTTON = blockItem("akashic_button", + new WoodButtonBlock(akashicWoody().noOcclusion())); + public static final PressurePlateBlock AKASHIC_PRESSURE_PLATE = blockItem("akashic_pressure_plate", + new PressurePlateBlock(PressurePlateBlock.Sensitivity.EVERYTHING, akashicWoody().noOcclusion())); + public static final BlockAkashicLeaves AKASHIC_LEAVES1 = blockItem("akashic_leaves1", + new BlockAkashicLeaves(leaves(MaterialColor.COLOR_PURPLE))); + public static final BlockAkashicLeaves AKASHIC_LEAVES2 = blockItem("akashic_leaves2", + new BlockAkashicLeaves(leaves(MaterialColor.COLOR_BLUE))); + public static final BlockAkashicLeaves AKASHIC_LEAVES3 = blockItem("akashic_leaves3", + new BlockAkashicLeaves(leaves(MaterialColor.COLOR_YELLOW))); private static boolean never(Object... args) { return false; } - private static RegistryObject blockNoItem(String name, Supplier block) { - return BLOCKS.register(name, block); + private static T blockNoItem(String name, T block) { + var old = BLOCKS.put(modLoc(name), block); + if (old != null) { + throw new IllegalArgumentException("Typo? Duplicate id " + name); + } + return block; } - private static RegistryObject blockItem(String name, Supplier block) { + private static T blockItem(String name, T block) { + blockNoItem(name, block); return blockItem(name, block, HexItems.props()); } - private static RegistryObject blockItem(String name, Supplier block, - Item.Properties props) { - var out = BLOCKS.register(name, block); - HexItems.ITEMS.register(name, () -> new BlockItem(out.get(), props)); - return out; + private static T blockItem(String name, T block, Item.Properties props) { + blockNoItem(name, block); + var old = BLOCK_ITEMS.put(modLoc(name), new Pair<>(block, props)); + if (old != null) { + throw new IllegalArgumentException("Typo? Duplicate id " + name); + } + return block; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt index 896736f8..bfa557c8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpMakePackagedSpell.kt @@ -12,11 +12,11 @@ import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidIota import at.petrak.hexcasting.api.utils.ManaHelper -import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell +import at.petrak.hexcasting.common.items.magic.ItemPackagedHex import net.minecraft.network.chat.TranslatableComponent import net.minecraft.world.entity.item.ItemEntity -class OpMakePackagedSpell(val itemType: T, val cost: Int) : SpellOperator { +class OpMakePackagedSpell(val itemType: T, val cost: Int) : SpellOperator { override val argc = 2 override fun execute( args: List>, diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/HexItems.java b/Common/src/main/java/at/petrak/hexcasting/common/items/HexItems.java index adbc13bd..545a2eb0 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/HexItems.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/HexItems.java @@ -1,29 +1,40 @@ package at.petrak.hexcasting.common.items; -import at.petrak.hexcasting.HexMod; +import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.blocks.HexBlocks; import at.petrak.hexcasting.common.items.colorizer.ItemDyeColorizer; import at.petrak.hexcasting.common.items.colorizer.ItemPrideColorizer; import at.petrak.hexcasting.common.items.colorizer.ItemUUIDColorizer; import at.petrak.hexcasting.common.items.magic.*; import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; import java.util.EnumMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + +// https://github.com/VazkiiMods/Botania/blob/2c4f7fdf9ebf0c0afa1406dfe1322841133d75fa/Common/src/main/java/vazkii/botania/common/item/ModItems.java public class HexItems { - public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, HexMod.MOD_ID); - public static final CreativeModeTab TAB = new CreativeModeTab(HexMod.MOD_ID) { + public static void registerItems(BiConsumer r) { + for (var e : ITEMS.entrySet()) { + r.accept(e.getValue(), e.getKey()); + } + } + + private static final Map ITEMS = new LinkedHashMap<>(); // preserve insertion order + + public static final CreativeModeTab TAB = new CreativeModeTab(HexAPI.MOD_ID) { @Override public ItemStack makeIcon() { - return new ItemStack(SPELLBOOK::get); + return new ItemStack(SPELLBOOK); } @Override @@ -38,83 +49,64 @@ public class HexItems { 1_000_000_000, }; for (int manamount : manamounts) { - var stack = new ItemStack(BATTERY.get()); + var stack = new ItemStack(BATTERY); items.add(ItemManaHolder.withMana(stack, manamount, manamount)); } } }; - public static final RegistryObject WAND_OAK = ITEMS.register("wand_oak", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_SPRUCE = ITEMS.register("wand_spruce", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_BIRCH = ITEMS.register("wand_birch", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_JUNGLE = ITEMS.register("wand_jungle", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_ACACIA = ITEMS.register("wand_acacia", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_DARK_OAK = ITEMS.register("wand_dark_oak", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_CRIMSON = ITEMS.register("wand_crimson", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_WARPED = ITEMS.register("wand_warped", - () -> new ItemWand(unstackable())); - public static final RegistryObject WAND_AKASHIC = ITEMS.register("wand_akashic", - () -> new ItemWand(unstackable())); - public static final RegistryObject AMETHYST_DUST = ITEMS.register("amethyst_dust", - () -> new Item(props())); - public static final RegistryObject CHARGED_AMETHYST = ITEMS.register("charged_amethyst", - () -> new Item(props())); + public static final Item AMETHYST_DUST = make("amethyst_dust", new Item(props())); + public static final Item CHARGED_AMETHYST = make("charged_amethyst", new Item(props())); - public static final RegistryObject SCRYING_LENS = ITEMS.register("lens", - () -> new ItemLens(unstackable())); - public static final RegistryObject SCROLL = ITEMS.register("scroll", - () -> new ItemScroll(props())); + public static final ItemWand WAND_OAK = make("wand_oak", new ItemWand(unstackable())); + public static final ItemWand WAND_SPRUCE = make("wand_spruce", new ItemWand(unstackable())); + public static final ItemWand WAND_BIRCH = make("wand_birch", new ItemWand(unstackable())); + public static final ItemWand WAND_JUNGLE = make("wand_jungle", new ItemWand(unstackable())); + public static final ItemWand WAND_ACACIA = make("wand_acacia", new ItemWand(unstackable())); + public static final ItemWand WAND_DARK_OAK = make("wand_dark_oak", new ItemWand(unstackable())); + public static final ItemWand WAND_CRIMSON = make("wand_crimson", new ItemWand(unstackable())); + public static final ItemWand WAND_WARPED = make("wand_warped", new ItemWand(unstackable())); + public static final ItemWand WAND_AKASHIC = make("wand_akashic", new ItemWand(unstackable())); - public static final RegistryObject FOCUS = ITEMS.register("focus", - () -> new ItemFocus(unstackable())); - public static final RegistryObject ABACUS = ITEMS.register("abacus", - () -> new ItemAbacus(unstackable())); - public static final RegistryObject SPELLBOOK = ITEMS.register("spellbook", - () -> new ItemSpellbook(unstackable())); + public static final ItemLens SCRYING_LENS = make("lens", new ItemLens(unstackable())); - public static final RegistryObject CYPHER = ITEMS.register("cypher", - () -> new ItemCypher(unstackable())); - public static final RegistryObject TRINKET = ITEMS.register("trinket", - () -> new ItemTrinket(unstackable())); - public static final RegistryObject ARTIFACT = ITEMS.register("artifact", - () -> new ItemArtifact(unstackable())); + public static final ItemAbacus ABACUS = make("abacus", new ItemAbacus(unstackable())); + public static final ItemFocus FOCUS = make("focus", new ItemFocus(unstackable())); + public static final ItemSpellbook SPELLBOOK = make("spellbook", new ItemSpellbook(unstackable())); - public static final RegistryObject BATTERY = ITEMS.register("battery", - () -> new ItemManaBattery(new Item.Properties().stacksTo(1))); + public static final ItemCypher CYPHER = make("cypher", new ItemCypher(unstackable())); + public static final ItemTrinket TRINKET = make("trinket", new ItemTrinket(unstackable())); + public static final ItemArtifact ARTIFACT = make("artifact", new ItemArtifact(unstackable())); - public static final EnumMap> DYE_COLORIZERS = new EnumMap<>( + + public static final ItemScroll SCROLL = make("scroll", new ItemScroll(props())); + + public static final ItemSlate SLATE = make("slate", new ItemSlate(HexBlocks.SLATE, props())); + + public static final ItemManaBattery BATTERY = make("battery", + new ItemManaBattery(new Item.Properties().stacksTo(1))); + + public static final EnumMap DYE_COLORIZERS = new EnumMap<>( DyeColor.class); - public static final RegistryObject[] PRIDE_COLORIZERS = new RegistryObject[14]; + public static final ItemPrideColorizer[] PRIDE_COLORIZERS = new ItemPrideColorizer[14]; static { for (var dye : DyeColor.values()) { - DYE_COLORIZERS.put(dye, ITEMS.register("dye_colorizer_" + dye.getName(), - () -> new ItemDyeColorizer(dye, unstackable()))); + DYE_COLORIZERS.put(dye, make("dye_colorizer_" + dye.getName(), new ItemDyeColorizer(dye, unstackable()))); } for (int i = 0; i < PRIDE_COLORIZERS.length; i++) { - final var finalI = i; - PRIDE_COLORIZERS[i] = ITEMS.register("pride_colorizer_" + i, - () -> new ItemPrideColorizer(finalI, unstackable())); + PRIDE_COLORIZERS[i] = make("pride_colorizer_" + i, new ItemPrideColorizer(i, unstackable())); } } - public static final RegistryObject UUID_COLORIZER = ITEMS.register("uuid_colorizer", - () -> new ItemUUIDColorizer(unstackable())); + public static final Item UUID_COLORIZER = make("uuid_colorizer", new ItemUUIDColorizer(unstackable())); // BUFF SANDVICH - public static final RegistryObject SUBMARINE_SANDWICH = ITEMS.register("sub_sandwich", - () -> new Item(props().food(new FoodProperties.Builder().nutrition(14).saturationMod(1.2f).build()))); + public static final Item SUBMARINE_SANDWICH = make("sub_sandwich", + new Item(props().food(new FoodProperties.Builder().nutrition(14).saturationMod(1.2f).build()))); - public static final RegistryObject SLATE = ITEMS.register("slate", - () -> new ItemSlate(HexBlocks.SLATE.get(), props())); + // public static Item.Properties props() { return new Item.Properties().tab(TAB); @@ -123,4 +115,16 @@ public class HexItems { public static Item.Properties unstackable() { return props().stacksTo(1); } + + private static T make(ResourceLocation id, T item) { + var old = ITEMS.put(id, item); + if (old != null) { + throw new IllegalArgumentException("Typo? Duplicate id " + id); + } + return item; + } + + private static T make(String id, T item) { + return make(modLoc(id), item); + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemPrideColorizer.java b/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemPrideColorizer.java index 4b772b7e..e6d1d874 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemPrideColorizer.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemPrideColorizer.java @@ -1,6 +1,6 @@ package at.petrak.hexcasting.common.items.colorizer; -import at.petrak.hexcasting.api.cap.Colorizer; +import at.petrak.hexcasting.api.addldata.Colorizer; import at.petrak.hexcasting.api.item.ColorizerItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemUUIDColorizer.java b/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemUUIDColorizer.java index 26225a83..bc3562ed 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemUUIDColorizer.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/colorizer/ItemUUIDColorizer.java @@ -1,6 +1,6 @@ package at.petrak.hexcasting.common.items.colorizer; -import at.petrak.hexcasting.api.cap.Colorizer; +import at.petrak.hexcasting.api.addldata.Colorizer; import at.petrak.hexcasting.api.item.ColorizerItem; import at.petrak.paucal.api.contrib.Contributors; import net.minecraft.world.item.Item; diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemArtifact.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemArtifact.java index 094d05cc..02cd3a2f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemArtifact.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemArtifact.java @@ -2,7 +2,7 @@ package at.petrak.hexcasting.common.items.magic; import net.minecraft.world.item.ItemStack; -public class ItemArtifact extends ItemPackagedSpell { +public class ItemArtifact extends ItemPackagedHex { public ItemArtifact(Properties pProperties) { super(pProperties); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCypher.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCypher.java index 8507f086..004e6075 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCypher.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemCypher.java @@ -2,7 +2,7 @@ package at.petrak.hexcasting.common.items.magic; import net.minecraft.world.item.ItemStack; -public class ItemCypher extends ItemPackagedSpell { +public class ItemCypher extends ItemPackagedHex { public ItemCypher(Properties pProperties) { super(pProperties); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedSpell.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java similarity index 92% rename from Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedSpell.java rename to Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java index 60d6c3bb..3e539f41 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedSpell.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemPackagedHex.java @@ -1,7 +1,7 @@ package at.petrak.hexcasting.common.items.magic; import at.petrak.hexcasting.HexMod; -import at.petrak.hexcasting.api.item.SpellHolderItem; +import at.petrak.hexcasting.api.item.HexHolderItem; import at.petrak.hexcasting.api.spell.casting.CastingContext; import at.petrak.hexcasting.api.spell.casting.CastingHarness; import at.petrak.hexcasting.common.lib.HexSounds; @@ -28,11 +28,11 @@ import java.util.List; /** * Item that holds a list of patterns in it ready to be cast */ -public abstract class ItemPackagedSpell extends ItemManaHolder implements SpellHolderItem { +public abstract class ItemPackagedHex extends ItemManaHolder implements HexHolderItem { public static final String TAG_PATTERNS = "patterns"; public static final ResourceLocation HAS_PATTERNS_PRED = new ResourceLocation(HexMod.MOD_ID, "has_patterns"); - public ItemPackagedSpell(Properties pProperties) { + public ItemPackagedHex(Properties pProperties) { super(pProperties); } @@ -70,14 +70,14 @@ public abstract class ItemPackagedSpell extends ItemManaHolder implements SpellH for (HexPattern pat : patterns) patsTag.add(pat.serializeToNBT()); - stack.getOrCreateTag().put(ItemPackagedSpell.TAG_PATTERNS, patsTag); + stack.getOrCreateTag().put(ItemPackagedHex.TAG_PATTERNS, patsTag); withMana(stack, mana, mana); } @Override public void clearPatterns(ItemStack stack) { - stack.removeTagKey(ItemPackagedSpell.TAG_PATTERNS); + stack.removeTagKey(ItemPackagedHex.TAG_PATTERNS); withMana(stack, 0, 0); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemTrinket.java b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemTrinket.java index 1c568c9b..c6291e52 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemTrinket.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/items/magic/ItemTrinket.java @@ -2,7 +2,7 @@ package at.petrak.hexcasting.common.items.magic; import net.minecraft.world.item.ItemStack; -public class ItemTrinket extends ItemPackagedSpell { +public class ItemTrinket extends ItemPackagedHex { public ItemTrinket(Properties pProperties) { super(pProperties); } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexStringKeys.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexStringKeys.java deleted file mode 100644 index 558a4a8c..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexStringKeys.java +++ /dev/null @@ -1,9 +0,0 @@ -package at.petrak.hexcasting.common.lib; - -/** - * Tags, capability keys, etc that need to be used in more than one place - * (for example, across platforms, or between an item and block). - */ -public class HexStringKeys { - public static final String BRAINSWEPT = "hexcasting:brainswept"; -} diff --git a/Common/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java b/Common/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java index 0c301eea..8f5981bb 100644 --- a/Common/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java +++ b/Common/src/main/java/at/petrak/hexcasting/datagen/HexItemModels.java @@ -4,7 +4,7 @@ import at.petrak.hexcasting.HexMod; import at.petrak.hexcasting.common.blocks.HexBlocks; import at.petrak.hexcasting.common.items.*; import at.petrak.hexcasting.common.items.magic.ItemManaBattery; -import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell; +import at.petrak.hexcasting.common.items.magic.ItemPackagedHex; import at.petrak.paucal.api.datagen.PaucalItemModelProvider; import net.minecraft.data.DataGenerator; import net.minecraft.resources.ResourceLocation; @@ -180,11 +180,11 @@ public class HexItemModels extends PaucalItemModelProvider { simpleItem(modLoc(name + "_filled")); getBuilder(item.getRegistryName().getPath()) .override() - .predicate(ItemPackagedSpell.HAS_PATTERNS_PRED, -0.01f) + .predicate(ItemPackagedHex.HAS_PATTERNS_PRED, -0.01f) .model(new ModelFile.UncheckedModelFile(modLoc("item/" + name))) .end() .override() - .predicate(ItemPackagedSpell.HAS_PATTERNS_PRED, 1f - 0.01f) + .predicate(ItemPackagedHex.HAS_PATTERNS_PRED, 1f - 0.01f) .model(new ModelFile.UncheckedModelFile(modLoc("item/" + name + "_filled"))) .end(); } diff --git a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java index 976fe8ad..83386f62 100644 --- a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java +++ b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java @@ -1,13 +1,23 @@ package at.petrak.hexcasting.xplat; import at.petrak.hexcasting.api.HexAPI; +import at.petrak.hexcasting.api.misc.FrozenColorizer; +import at.petrak.hexcasting.api.player.FlightAbility; +import at.petrak.hexcasting.api.player.Sentinel; +import at.petrak.hexcasting.api.spell.casting.CastingHarness; +import at.petrak.hexcasting.api.spell.casting.ResolvedPattern; import at.petrak.hexcasting.common.command.PatternResLocArgument; import at.petrak.hexcasting.common.network.IMessage; +import at.petrak.hexcasting.common.network.MsgColorizerUpdateAck; +import at.petrak.hexcasting.common.network.MsgSentinelStatusUpdateAck; import net.minecraft.commands.synchronization.ArgumentTypes; import net.minecraft.commands.synchronization.EmptyArgumentSerializer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import java.util.List; import java.util.ServiceLoader; import java.util.stream.Collectors; @@ -16,14 +26,47 @@ public interface IXplatAbstractions { boolean isPhysicalClient(); - void brainsweep(LivingEntity e); - - boolean isBrainswept(LivingEntity e); void sendPacketToPlayer(ServerPlayer target, IMessage packet); void sendPacketToServer(IMessage packet); + // Things that used to be caps + + void brainsweep(LivingEntity e); + + void setColorizer(Player target, FrozenColorizer colorizer); + + void setSentinel(Player target, Sentinel sentinel); + + void setFlight(ServerPlayer target, FlightAbility flight); + + void setHarness(ServerPlayer target, CastingHarness harness); + + void setPatterns(ServerPlayer target, List patterns); + + boolean isBrainswept(LivingEntity e); + + FlightAbility getFlight(ServerPlayer player); + + FrozenColorizer getColorizer(Player player); + + Sentinel getSentinel(Player player); + + CastingHarness getHarness(ServerPlayer player, InteractionHand hand); + + List getPatterns(ServerPlayer player); + + void clearCastingData(ServerPlayer player); + + default void syncSentinel(ServerPlayer player) { + this.sendPacketToPlayer(player, new MsgSentinelStatusUpdateAck(this.getSentinel(player))); + } + + default void syncColorizer(ServerPlayer player) { + this.sendPacketToPlayer(player, new MsgColorizerUpdateAck(this.getColorizer(player))); + } + default void init() { HexAPI.LOGGER.info("Hello Hexcasting! This is {}!", this.platform()); diff --git a/Fabric/build.gradle b/Fabric/build.gradle index 95b24693..5c9a2ab8 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -9,6 +9,9 @@ archivesBaseName = "${modName}-fabric-${minecraftVersion}" repositories { mavenCentral() maven { url "https://maven.shedaniel.me/" } + maven { + url 'https://ladysnake.jfrog.io/artifactory/mods' + } } dependencies { @@ -21,11 +24,12 @@ dependencies { annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' - // compileOnly fg.deobf("at.petra-k.paucal:paucal-$minecraftVersion:$paucalVersion") modImplementation("vazkii.patchouli:Patchouli:$minecraftVersion-$patchouliVersion:api") modImplementation("net.fabricmc:fabric-language-kotlin:1.7.4+kotlin.1.6.21") implementation "me.zeroeightsix:fiber:$fiberVersion" + + modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-api:$cardinalComponentsVersion" } loom { diff --git a/Fabric/gradle.properties b/Fabric/gradle.properties index e7729f72..b84bf785 100644 --- a/Fabric/gradle.properties +++ b/Fabric/gradle.properties @@ -1 +1,2 @@ -fiberVersion=0.23.0-2 \ No newline at end of file +fiberVersion=0.23.0-2 +cardinalComponentsVersion=4.1.4 \ No newline at end of file diff --git a/Fabric/src/main/java/at/petrak/hexcasting/FabricHexInitializer.kt b/Fabric/src/main/java/at/petrak/hexcasting/FabricHexInitializer.kt index 3a380074..d6853750 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/FabricHexInitializer.kt +++ b/Fabric/src/main/java/at/petrak/hexcasting/FabricHexInitializer.kt @@ -1,12 +1,36 @@ +import at.petrak.hexcasting.common.blocks.HexBlocks +import at.petrak.hexcasting.common.items.HexItems +import at.petrak.hexcasting.common.misc.Brainsweeping import at.petrak.hexcasting.fabric.FabricHexConfig import at.petrak.hexcasting.fabric.network.FabricPacketHandler import at.petrak.hexcasting.xplat.IXplatAbstractions import net.fabricmc.api.ModInitializer +import net.fabricmc.fabric.api.event.player.UseEntityCallback +import net.minecraft.core.Registry +import net.minecraft.resources.ResourceLocation +import java.util.function.BiConsumer object FabricHexInitializer : ModInitializer { override fun onInitialize() { IXplatAbstractions.INSTANCE.init() FabricPacketHandler.init() FabricHexConfig.setup() + + initListeners() + + initRegistries() } + + fun initListeners() { + UseEntityCallback.EVENT.register(Brainsweeping::tradeWithVillager) + } + + fun initRegistries() { + HexBlocks.registerBlocks(bind(Registry.BLOCK)) + HexBlocks.registerBlockItems(bind(Registry.ITEM)) + HexItems.registerItems(bind(Registry.ITEM)) + } + + private fun bind(registry: Registry): BiConsumer = + BiConsumer { t, id -> Registry.register(registry, id, t) } } \ No newline at end of file diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCBrainswept.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCBrainswept.java new file mode 100644 index 00000000..e9df52d6 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCBrainswept.java @@ -0,0 +1,37 @@ +package at.petrak.hexcasting.fabric.cc; + +import dev.onyxstudios.cca.api.v3.component.Component; +import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.LivingEntity; + +public class CCBrainswept implements Component, AutoSyncedComponent { + public static final String TAG_BRAINSWEPT = "brainswept"; + + private final LivingEntity owner; + + public CCBrainswept(LivingEntity owner) { + this.owner = owner; + } + + private boolean brainswept = false; + + public boolean isBrainswept() { + return this.brainswept; + } + + public void setBrainswept(boolean brainswept) { + this.brainswept = brainswept; + HexCardinalComponents.BRAINSWEPT.sync(this.owner); + } + + @Override + public void readFromNbt(CompoundTag tag) { + this.brainswept = tag.getBoolean(TAG_BRAINSWEPT); + } + + @Override + public void writeToNbt(CompoundTag tag) { + tag.putBoolean(TAG_BRAINSWEPT, this.brainswept); + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCColorizer.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCColorizer.java new file mode 100644 index 00000000..ee62b59e --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCColorizer.java @@ -0,0 +1,36 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.addldata.Colorizer; +import at.petrak.hexcasting.api.item.ColorizerItem; +import dev.onyxstudios.cca.api.v3.item.ItemComponent; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; + +import java.util.UUID; + +/** + * The colorizer itself + */ +public abstract class CCColorizer extends ItemComponent implements Colorizer { + public CCColorizer(ItemStack stack) { + super(stack, HexCardinalComponents.COLORIZER); + } + + public static class ItemBased extends CCColorizer { + private final ColorizerItem item; + + public ItemBased(ItemStack owner) { + super(owner); + var item = owner.getItem(); + if (!(item instanceof ColorizerItem col)) { + throw new IllegalStateException("item is not a colorizer: " + owner); + } + this.item = col; + } + + @Override + public int color(UUID owner, float time, Vec3 position) { + return item.color(this.stack, owner, time, position); + } + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCDataHolder.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCDataHolder.java new file mode 100644 index 00000000..14b07778 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCDataHolder.java @@ -0,0 +1,66 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.addldata.DataHolder; +import at.petrak.hexcasting.api.item.DataHolderItem; +import at.petrak.hexcasting.api.spell.SpellDatum; +import dev.onyxstudios.cca.api.v3.item.ItemComponent; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +public abstract class CCDataHolder extends ItemComponent implements DataHolder { + public CCDataHolder(ItemStack stack) { + super(stack, HexCardinalComponents.DATA_HOLDER); + } + + public static class ItemBased extends CCDataHolder { + private final DataHolderItem dataHolder; + + public ItemBased(ItemStack stack) { + super(stack); + if (!(stack.getItem() instanceof DataHolderItem data)) { + throw new IllegalStateException("item is not a data holder: " + stack); + } + this.dataHolder = data; + } + + @Override + public @Nullable CompoundTag readRawDatum() { + return this.dataHolder.readDatumTag(this.stack); + } + + @Override + public boolean writeDatum(@Nullable SpellDatum datum, boolean simulate) { + var canWrite = this.dataHolder.canWrite(this.stack, datum); + if (!canWrite) { + return false; + } + if (!simulate) { + this.dataHolder.writeDatum(this.stack, datum); + } + return true; + } + } + + public static class Static extends CCDataHolder { + private final Function> provider; + + public Static(ItemStack stack, Function> provider) { + super(stack); + this.provider = provider; + } + + @Override + public @Nullable CompoundTag readRawDatum() { + SpellDatum datum = this.provider.apply(this.stack); + return datum == null ? null : datum.serializeToNBT(); + } + + @Override + public boolean writeDatum(@Nullable SpellDatum datum, boolean simulate) { + return false; + } + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCFavoredColorizer.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCFavoredColorizer.java new file mode 100644 index 00000000..ae4a1be9 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCFavoredColorizer.java @@ -0,0 +1,41 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.misc.FrozenColorizer; +import dev.onyxstudios.cca.api.v3.component.Component; +import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.player.Player; + +/** + * Holds the colorizer item favored by the player + */ +public class CCFavoredColorizer implements Component, AutoSyncedComponent { + public static final String TAG_COLORIZER = "colorizer"; + + private final Player owner; + + public CCFavoredColorizer(Player owner) { + this.owner = owner; + } + + private FrozenColorizer colorizer = FrozenColorizer.DEFAULT.get(); + + public FrozenColorizer getColorizer() { + return colorizer; + } + + public void setColorizer(FrozenColorizer colorizer) { + this.colorizer = colorizer; + HexCardinalComponents.FAVORED_COLORIZER.sync(this.owner); + } + + @Override + public void readFromNbt(CompoundTag tag) { + this.colorizer = FrozenColorizer.deserialize(tag.getCompound(TAG_COLORIZER)); + } + + @Override + public void writeToNbt(CompoundTag tag) { + tag.put(TAG_COLORIZER, this.colorizer.serialize()); + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCFlight.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCFlight.java new file mode 100644 index 00000000..b3324da3 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCFlight.java @@ -0,0 +1,63 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.player.FlightAbility; +import at.petrak.hexcasting.api.utils.HexUtils; +import dev.onyxstudios.cca.api.v3.component.Component; +import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; + +public class CCFlight implements Component, AutoSyncedComponent { + public static final String + TAG_ALLOWED = "allowed", + TAG_TIME_LEFT = "time_left", + TAG_DIMENSION = "dimension", + TAG_ORIGIN = "origin", + TAG_RADIUS = "radius"; + + private final Player owner; + private FlightAbility flight = FlightAbility.deny(); + + public CCFlight(Player owner) { + this.owner = owner; + } + + + public FlightAbility getFlight() { + return flight; + } + + public void setFlight(FlightAbility flight) { + this.flight = flight; + HexCardinalComponents.FLIGHT.sync(this.owner); + } + + @Override + public void readFromNbt(CompoundTag tag) { + var allowed = tag.getBoolean(TAG_ALLOWED); + if (!allowed) { + this.flight = FlightAbility.deny(); + } else { + var timeLeft = tag.getInt(TAG_TIME_LEFT); + var dim = ResourceKey.create(Registry.DIMENSION_REGISTRY, + new ResourceLocation(tag.getString(TAG_DIMENSION))); + var origin = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_ORIGIN)); + var radius = tag.getDouble(TAG_RADIUS); + this.flight = new FlightAbility(true, timeLeft, dim, origin, radius); + } + } + + @Override + public void writeToNbt(CompoundTag tag) { + tag.putBoolean(TAG_ALLOWED, this.flight.allowed()); + if (this.flight.allowed()) { + tag.putInt(TAG_TIME_LEFT, this.flight.timeLeft()); + tag.putString(TAG_DIMENSION, this.flight.dimension().location().toString()); + tag.put(TAG_ORIGIN, HexUtils.serializeToNBT(this.flight.origin())); + tag.putDouble(TAG_RADIUS, this.flight.radius()); + } + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCHexHolder.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCHexHolder.java new file mode 100644 index 00000000..b50b5227 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCHexHolder.java @@ -0,0 +1,53 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.cap.HexHolder; +import at.petrak.hexcasting.api.item.HexHolderItem; +import at.petrak.hexcasting.api.spell.math.HexPattern; +import dev.onyxstudios.cca.api.v3.item.ItemComponent; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * The colorizer itself + */ +public abstract class CCHexHolder extends ItemComponent implements HexHolder { + public CCHexHolder(ItemStack stack) { + super(stack, HexCardinalComponents.HEX_HOLDER); + } + + public static class ItemBased extends CCHexHolder { + private final HexHolderItem spellHolder; + + public ItemBased(ItemStack owner) { + super(owner); + var item = owner.getItem(); + if (!(item instanceof HexHolderItem hexHolderItem)) { + throw new IllegalStateException("item is not a colorizer: " + owner); + } + this.spellHolder = hexHolderItem; + } + + + @Override + public boolean canDrawManaFromInventory() { + return this.spellHolder.canDrawManaFromInventory(this.stack); + } + + @Override + public @Nullable List getPatterns() { + return this.spellHolder.getPatterns(this.stack); + } + + @Override + public void writePatterns(List patterns, int mana) { + this.spellHolder.writePatterns(this.stack, patterns, mana); + } + + @Override + public void clearPatterns() { + this.spellHolder.clearPatterns(this.stack); + } + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCManaHolder.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCManaHolder.java new file mode 100644 index 00000000..af96afeb --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCManaHolder.java @@ -0,0 +1,121 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.addldata.ManaHolder; +import at.petrak.hexcasting.api.item.ManaHolderItem; +import dev.onyxstudios.cca.api.v3.item.ItemComponent; +import net.minecraft.world.item.ItemStack; + +import java.util.function.Supplier; + +public abstract class CCManaHolder extends ItemComponent implements ManaHolder { + public CCManaHolder(ItemStack stack) { + super(stack, HexCardinalComponents.MANA_HOLDER); + } + + public static class ItemBased extends CCManaHolder { + private final ManaHolderItem manaHolder; + + public ItemBased(ItemStack stack) { + super(stack); + if (!(stack.getItem() instanceof ManaHolderItem mana)) { + throw new IllegalStateException("item is not a mana holder: " + stack); + } + this.manaHolder = mana; + } + + @Override + public int getMana() { + return this.manaHolder.getMana(this.stack); + } + + @Override + public int getMaxMana() { + return this.manaHolder.getMaxMana(this.stack); + } + + @Override + public void setMana(int mana) { + this.manaHolder.setMana(this.stack, mana); + } + + @Override + public boolean canRecharge() { + return this.manaHolder.canRecharge(this.stack); + } + + @Override + public boolean canProvide() { + return this.manaHolder.manaProvider(this.stack); + } + + @Override + public int getConsumptionPriority() { + return 40; + } + + @Override + public boolean canConstructBattery() { + return false; + } + } + + public static class Static extends CCManaHolder { + private final Supplier baseWorth; + private final int consumptionPriority; + + public Static(Supplier baseWorth, int consumptionPriority, ItemStack stack) { + super(stack); + this.baseWorth = baseWorth; + this.consumptionPriority = consumptionPriority; + } + + @Override + public int getMana() { + return baseWorth.get() * stack.getCount(); + } + + @Override + public int getMaxMana() { + return getMana(); + } + + @Override + public void setMana(int mana) { + // NO-OP + } + + @Override + public boolean canRecharge() { + return false; + } + + @Override + public boolean canProvide() { + return true; + } + + @Override + public int getConsumptionPriority() { + return consumptionPriority; + } + + @Override + public boolean canConstructBattery() { + return true; + } + + @Override + public int withdrawMana(int cost, boolean simulate) { + int worth = baseWorth.get(); + if (cost < 0) { + cost = worth * stack.getCount(); + } + double itemsRequired = cost / (double) worth; + int itemsUsed = Math.min((int) Math.ceil(itemsRequired), stack.getCount()); + if (!simulate) { + stack.shrink(itemsUsed); + } + return itemsUsed * worth; + } + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCSentinel.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCSentinel.java new file mode 100644 index 00000000..b0cadef5 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCSentinel.java @@ -0,0 +1,59 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.player.Sentinel; +import at.petrak.hexcasting.api.utils.HexUtils; +import dev.onyxstudios.cca.api.v3.component.Component; +import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; + +public class CCSentinel implements Component, AutoSyncedComponent { + public static final String + TAG_HAS_SENTINEL = "has_sentinel", + TAG_EXTENDS_RANGE = "extends_range", + TAG_POSITION = "position", + TAG_DIMENSION = "dimension"; + + private final Player owner; + private Sentinel sentinel = Sentinel.none(); + + public CCSentinel(Player owner) { + this.owner = owner; + } + + public Sentinel getSentinel() { + return sentinel; + } + + public void setSentinel(Sentinel sentinel) { + this.sentinel = sentinel; + HexCardinalComponents.SENTINEL.sync(this.owner); + } + + @Override + public void readFromNbt(CompoundTag tag) { + var hasSentinel = tag.getBoolean(TAG_HAS_SENTINEL); + if (hasSentinel) { + var extendsRange = tag.getBoolean(TAG_EXTENDS_RANGE); + var position = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_POSITION)); + var dim = ResourceKey.create(Registry.DIMENSION_REGISTRY, + new ResourceLocation(tag.getString(TAG_DIMENSION))); + this.sentinel = new Sentinel(true, extendsRange, position, dim); + } else { + this.sentinel = Sentinel.none(); + } + } + + @Override + public void writeToNbt(CompoundTag tag) { + tag.putBoolean(TAG_HAS_SENTINEL, this.sentinel.hasSentinel()); + if (this.sentinel.hasSentinel()) { + tag.putBoolean(TAG_EXTENDS_RANGE, this.sentinel.extendsRange()); + tag.put(TAG_POSITION, HexUtils.serializeToNBT(this.sentinel.position())); + tag.putString(TAG_DIMENSION, this.sentinel.dimension().location().toString()); + } + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/HexCardinalComponents.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/HexCardinalComponents.java new file mode 100644 index 00000000..811e62e3 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/HexCardinalComponents.java @@ -0,0 +1,73 @@ +package at.petrak.hexcasting.fabric.cc; + +import at.petrak.hexcasting.api.item.ColorizerItem; +import at.petrak.hexcasting.api.item.DataHolderItem; +import at.petrak.hexcasting.api.item.HexHolderItem; +import at.petrak.hexcasting.api.item.ManaHolderItem; +import at.petrak.hexcasting.api.mod.HexConfig; +import at.petrak.hexcasting.api.spell.SpellDatum; +import at.petrak.hexcasting.common.items.HexItems; +import dev.onyxstudios.cca.api.v3.component.ComponentKey; +import dev.onyxstudios.cca.api.v3.component.ComponentRegistry; +import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry; +import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer; +import dev.onyxstudios.cca.api.v3.item.ItemComponentFactoryRegistry; +import dev.onyxstudios.cca.api.v3.item.ItemComponentInitializer; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Items; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; + +public class HexCardinalComponents implements EntityComponentInitializer, ItemComponentInitializer { + // entities + public static final ComponentKey BRAINSWEPT = ComponentRegistry.getOrCreate(modLoc("brainswept"), + CCBrainswept.class); + public static final ComponentKey FAVORED_COLORIZER = ComponentRegistry.getOrCreate( + modLoc("favored_colorizer"), CCFavoredColorizer.class); + public static final ComponentKey SENTINEL = ComponentRegistry.getOrCreate(modLoc("sentinel"), + CCSentinel.class); + public static final ComponentKey FLIGHT = ComponentRegistry.getOrCreate(modLoc("flight"), + CCFlight.class); + + public static final ComponentKey COLORIZER = ComponentRegistry.getOrCreate(modLoc("colorizer"), + CCColorizer.class); + public static final ComponentKey DATA_HOLDER = ComponentRegistry.getOrCreate(modLoc("data_holder"), + CCDataHolder.class); + public static final ComponentKey MANA_HOLDER = ComponentRegistry.getOrCreate(modLoc("mana_holder"), + CCManaHolder.class); + public static final ComponentKey HEX_HOLDER = ComponentRegistry.getOrCreate(modLoc("hex_holder"), + CCHexHolder.class); + + @Override + public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) { + registry.registerFor(LivingEntity.class, BRAINSWEPT, CCBrainswept::new); + registry.registerFor(Player.class, FAVORED_COLORIZER, CCFavoredColorizer::new); + registry.registerFor(Player.class, SENTINEL, CCSentinel::new); + registry.registerFor(Player.class, FLIGHT, CCFlight::new); + } + + @Override + public void registerItemComponentFactories(ItemComponentFactoryRegistry registry) { + registry.register(i -> i instanceof ColorizerItem, COLORIZER, CCColorizer.ItemBased::new); + + registry.register(i -> i instanceof DataHolderItem, DATA_HOLDER, CCDataHolder.ItemBased::new); + // oh havoc, you think you're so funny + // the worst part is you're /right/ + registry.register(Items.PUMPKIN_PIE, DATA_HOLDER, stack -> new CCDataHolder.Static(stack, + s -> SpellDatum.make(Math.PI * s.getCount()))); + + registry.register(i -> i instanceof ManaHolderItem, MANA_HOLDER, CCManaHolder.ItemBased::new); + registry.register(HexItems.AMETHYST_DUST, MANA_HOLDER, s -> new CCManaHolder.Static( + () -> HexConfig.common().dustManaAmount(), 30, s + )); + registry.register(Items.AMETHYST_SHARD, MANA_HOLDER, s -> new CCManaHolder.Static( + () -> HexConfig.common().shardManaAmount(), 20, s + )); + registry.register(HexItems.CHARGED_AMETHYST, MANA_HOLDER, s -> new CCManaHolder.Static( + () -> HexConfig.common().chargedCrystalManaAmount(), 10, s + )); + + registry.register(i -> i instanceof HexHolderItem, HEX_HOLDER, CCHexHolder.ItemBased::new); + } +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricListenersSetup.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricListenersSetup.java deleted file mode 100644 index 58c427d6..00000000 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricListenersSetup.java +++ /dev/null @@ -1,10 +0,0 @@ -package at.petrak.hexcasting.fabric.xplat; - -import at.petrak.hexcasting.common.misc.Brainsweeping; -import net.fabricmc.fabric.api.event.player.UseEntityCallback; - -public class FabricListenersSetup { - public static void init() { - UseEntityCallback.EVENT.register(Brainsweeping::tradeWithVillager); - } -} diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 520b9833..33ebbdca 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -23,6 +23,9 @@ ], "client": [ {"adapter": "kotlin", "value": "at.petrak.hexcasting.FabricHexInitializer"} + ], + "cardinal-components": [ + "at.petrak.hexcasting.fabric.cc.HexCardinalComponents" ] }, "mixins": [ @@ -37,5 +40,19 @@ "fabric-language-kotlin": ">=1.7.4+kotlin.1.6.21", "patchouli": ">=1.18.2-66", "paucal": ">=0.3.4" + }, + + "custom": { + "cardinal-components": [ + "hexcasting:brainswept", + "hexcasting:favored_colorizer", + "hexcasting:sentinel", + "hexcasting:flight", + + "hexcasting:colorizer", + "hexcasting:data_holder", + "hexcasting:mana_holder", + "hexcasting:hex_holder" + ] } } \ No newline at end of file diff --git a/Forge/src/main/java/at/petrak/hexcasting/ForgeHexInitializer.kt b/Forge/src/main/java/at/petrak/hexcasting/ForgeHexInitializer.kt index 0c3850ff..17717468 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/ForgeHexInitializer.kt +++ b/Forge/src/main/java/at/petrak/hexcasting/ForgeHexInitializer.kt @@ -4,18 +4,31 @@ import at.petrak.hexcasting.api.HexAPI import at.petrak.hexcasting.api.PatternRegistry import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers import at.petrak.hexcasting.api.mod.HexConfig +import at.petrak.hexcasting.common.blocks.HexBlocks +import at.petrak.hexcasting.common.items.HexItems +import at.petrak.hexcasting.common.misc.Brainsweeping import at.petrak.hexcasting.forge.ForgeHexConfig +import at.petrak.hexcasting.forge.cap.CapSyncers import at.petrak.hexcasting.forge.network.ForgePacketHandler -import at.petrak.hexcasting.forge.xplat.ForgeListenersSetup import at.petrak.hexcasting.xplat.IXplatAbstractions +import net.minecraft.resources.ResourceLocation import net.minecraftforge.common.ForgeConfigSpec +import net.minecraftforge.event.RegistryEvent +import net.minecraftforge.event.entity.player.PlayerInteractEvent.EntityInteract import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.fml.ModLoadingContext import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.config.ModConfig import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext +import net.minecraftforge.registries.ForgeRegistries +import net.minecraftforge.registries.IForgeRegistry +import net.minecraftforge.registries.IForgeRegistryEntry import org.apache.logging.log4j.Logger +import java.util.function.BiConsumer +import java.util.function.Consumer + @Mod(HexAPI.MOD_ID) object ForgeHexInitializer { @@ -35,18 +48,38 @@ object ForgeHexInitializer { ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, serverConfig.right) ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, clientConfig.right) + initRegistry() + initListeners() + } - ForgeListenersSetup.init() - ForgePacketHandler.init() - - /* + fun initRegistry() { + bind(ForgeRegistries.BLOCKS, HexBlocks::registerBlocks) + bind(ForgeRegistries.ITEMS, HexBlocks::registerBlockItems) + bind(ForgeRegistries.ITEMS, HexItems::registerItems) + } + fun initListeners() { // mod lifecycle val modBus = thedarkcolour.kotlinforforge.forge.MOD_BUS // game events val evBus = thedarkcolour.kotlinforforge.forge.FORGE_BUS - modBus.register(this) + modBus.addListener(this::commonSetup) + + evBus.addListener { evt: EntityInteract -> + val res = Brainsweeping.tradeWithVillager( + evt.player, evt.world, evt.hand, evt.target, + null + ) + if (res.consumesAction()) { + evt.isCanceled = true + evt.cancellationResult = res + } + } + evBus.register(CapSyncers::class.java) + + /* + modBus.register(this) // gotta do it at *some* point modBus.register(RegisterPatterns::class.java) modBus.register(HexDataGenerators::class.java) @@ -81,13 +114,30 @@ object ForgeHexInitializer { evBus.register(HexTooltips::class.java) } } - */ } + private fun > bind( + registry: IForgeRegistry, + source: Consumer> + ) { + FMLJavaModLoadingContext.get().modEventBus.addGenericListener( + registry.registrySuperType + ) { event: RegistryEvent.Register -> + val forgeRegistry = event.registry + source.accept { t, rl -> + t.registryName = rl + forgeRegistry.register(t) + } + } + } + @SubscribeEvent fun commonSetup(evt: FMLCommonSetupEvent) { - evt.enqueueWork { HexAdvancementTriggers.registerTriggers() } + evt.enqueueWork { + HexAdvancementTriggers.registerTriggers() + ForgePacketHandler.init() + } } @JvmStatic diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java new file mode 100644 index 00000000..8ffe4b91 --- /dev/null +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/CapSyncers.java @@ -0,0 +1,51 @@ +package at.petrak.hexcasting.forge.cap; + +import at.petrak.hexcasting.xplat.IXplatAbstractions; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class CapSyncers { + @SubscribeEvent + public static void copyDataOnDeath(PlayerEvent.Clone evt) { + var eitherSidePlayer = evt.getPlayer(); + // this apparently defines it in outside scope. the more you know. + if (!(eitherSidePlayer instanceof ServerPlayer player)) { + return; + } + + var eitherSideProto = evt.getOriginal(); + if (!(eitherSideProto instanceof ServerPlayer proto)) { + return; + } + + // Copy data from this to new player + var x = IXplatAbstractions.INSTANCE; + x.setFlight(player, x.getFlight(proto)); + x.setSentinel(player, x.getSentinel(proto)); + x.setColorizer(player, x.getColorizer(proto)); + x.setHarness(player, x.getHarness(proto, InteractionHand.MAIN_HAND)); + x.setPatterns(player, x.getPatterns(proto)); + } + + @SubscribeEvent + public static void syncDataOnLogin(PlayerEvent.PlayerLoggedInEvent evt) { + if (!(evt.getPlayer() instanceof ServerPlayer player)) { + return; + } + + IXplatAbstractions.INSTANCE.syncSentinel(player); + IXplatAbstractions.INSTANCE.syncColorizer(player); + } + + @SubscribeEvent + public static void syncDataOnRejoin(PlayerEvent.PlayerRespawnEvent evt) { + if (!(evt.getPlayer() instanceof ServerPlayer player)) { + return; + } + + IXplatAbstractions.INSTANCE.syncSentinel(player); + IXplatAbstractions.INSTANCE.syncColorizer(player); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCapabilityHandler.java b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java similarity index 75% rename from Common/src/main/java/at/petrak/hexcasting/common/lib/HexCapabilityHandler.java rename to Forge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java index 69408690..1a57be8d 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCapabilityHandler.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/cap/ForgeCapabilityHandler.java @@ -1,15 +1,18 @@ -package at.petrak.hexcasting.common.lib; +package at.petrak.hexcasting.forge.cap; -import at.petrak.hexcasting.api.cap.Colorizer; -import at.petrak.hexcasting.api.cap.DataHolder; -import at.petrak.hexcasting.api.cap.ManaHolder; -import at.petrak.hexcasting.api.cap.SpellHolder; -import at.petrak.hexcasting.api.mod.HexConfig; -import at.petrak.hexcasting.api.item.*; -import at.petrak.hexcasting.api.spell.SpellDatum; +import at.petrak.hexcasting.api.addldata.Colorizer; +import at.petrak.hexcasting.api.addldata.DataHolder; +import at.petrak.hexcasting.api.addldata.ManaHolder; import at.petrak.hexcasting.api.cap.HexCapabilities; -import at.petrak.hexcasting.common.items.HexItems; +import at.petrak.hexcasting.api.cap.HexHolder; +import at.petrak.hexcasting.api.item.ColorizerItem; +import at.petrak.hexcasting.api.item.DataHolderItem; +import at.petrak.hexcasting.api.item.ManaHolderItem; +import at.petrak.hexcasting.api.item.HexHolderItem; +import at.petrak.hexcasting.api.mod.HexConfig; +import at.petrak.hexcasting.api.spell.SpellDatum; import at.petrak.hexcasting.api.spell.math.HexPattern; +import at.petrak.hexcasting.common.items.HexItems; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; @@ -17,8 +20,9 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.common.capabilities.*; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.NonNullSupplier; import net.minecraftforge.event.AttachCapabilitiesEvent; @@ -29,8 +33,9 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.UUID; import java.util.function.Function; +import java.util.function.Supplier; -public class HexCapabilityHandler { +public class ForgeCapabilityHandler { private static final ResourceLocation DATA_HOLDER_CAPABILITY = new ResourceLocation("hexcasting", "data_holder"); private static final ResourceLocation DATA_ITEM_CAPABILITY = new ResourceLocation("hexcasting", "data_item"); @@ -43,40 +48,45 @@ public class HexCapabilityHandler { public static void registerCaps(RegisterCapabilitiesEvent evt) { evt.register(ManaHolder.class); evt.register(DataHolder.class); - evt.register(SpellHolder.class); + evt.register(HexHolder.class); evt.register(Colorizer.class); } @SubscribeEvent public static void attachCaps(AttachCapabilitiesEvent evt) { ItemStack stack = evt.getObject(); - if (stack.getItem() instanceof ManaHolderItem holder) + if (stack.getItem() instanceof ManaHolderItem holder) { evt.addCapability(MANA_HOLDER_CAPABILITY, provide(HexCapabilities.MANA, - () -> new ItemBasedManaHolder(holder, stack))); - else if (stack.is(HexItems.AMETHYST_DUST.get())) + () -> new ItemBasedManaHolder(holder, stack))); + } else if (stack.is(HexItems.AMETHYST_DUST)) { evt.addCapability(MANA_ITEM_CAPABILITY, provide(HexCapabilities.MANA, - () -> new StaticManaHolder(HexConfig.dustManaAmount, 3, stack))); - else if (stack.is(Items.AMETHYST_SHARD)) + () -> new StaticManaHolder(() -> HexConfig.common().dustManaAmount(), 30, stack))); + } else if (stack.is(Items.AMETHYST_SHARD)) { evt.addCapability(MANA_ITEM_CAPABILITY, provide(HexCapabilities.MANA, - () -> new StaticManaHolder(HexConfig.shardManaAmount, 2, stack))); - else if (stack.is(HexItems.CHARGED_AMETHYST.get())) + () -> new StaticManaHolder(() -> HexConfig.common().shardManaAmount(), 20, stack))); + } else if (stack.is(HexItems.CHARGED_AMETHYST)) { evt.addCapability(MANA_ITEM_CAPABILITY, provide(HexCapabilities.MANA, - () -> new StaticManaHolder(HexConfig.chargedCrystalManaAmount, 1, stack))); + () -> new StaticManaHolder(() -> HexConfig.common().chargedCrystalManaAmount(), 10, stack))); + } - if (stack.getItem() instanceof DataHolderItem holder) + if (stack.getItem() instanceof DataHolderItem holder) { evt.addCapability(DATA_HOLDER_CAPABILITY, provide(HexCapabilities.DATUM, - () -> new ItemBasedDataHolder(holder, stack))); - else if (stack.is(Items.PUMPKIN_PIE)) // haha yes + () -> new ItemBasedDataHolder(holder, stack))); + } else if (stack.is(Items.PUMPKIN_PIE)) // haha yes + { evt.addCapability(DATA_ITEM_CAPABILITY, provide(HexCapabilities.DATUM, - () -> new StaticDatumHolder((s) -> SpellDatum.make(Math.PI * s.getCount()), stack))); + () -> new StaticDatumHolder((s) -> SpellDatum.make(Math.PI * s.getCount()), stack))); + } - if (stack.getItem() instanceof SpellHolderItem holder) + if (stack.getItem() instanceof HexHolderItem holder) { evt.addCapability(SPELL_HOLDER_CAPABILITY, provide(HexCapabilities.SPELL, - () -> new ItemBasedSpellHolder(holder, stack))); + () -> new ItemBasedHexHolder(holder, stack))); + } - if (stack.getItem() instanceof ColorizerItem colorizer) + if (stack.getItem() instanceof ColorizerItem colorizer) { evt.addCapability(COLORIZER_CAPABILITY, provide(HexCapabilities.COLOR, - () -> new ItemBasedColorizer(colorizer, stack))); + () -> new ItemBasedColorizer(colorizer, stack))); + } } private static SimpleProvider provide(Capability capability, NonNullSupplier supplier) { @@ -93,7 +103,7 @@ public class HexCapabilityHandler { } } - private record StaticManaHolder(ForgeConfigSpec.IntValue baseWorth, + private record StaticManaHolder(Supplier baseWorth, int consumptionPriority, ItemStack stack) implements ManaHolder { @Override @@ -134,12 +144,14 @@ public class HexCapabilityHandler { @Override public int withdrawMana(int cost, boolean simulate) { int worth = baseWorth.get(); - if (cost < 0) + if (cost < 0) { cost = worth * stack.getCount(); + } double itemsRequired = cost / (double) worth; int itemsUsed = Math.min((int) Math.ceil(itemsRequired), stack.getCount()); - if (!simulate) + if (!simulate) { stack.shrink(itemsUsed); + } return itemsUsed * worth; } } @@ -174,7 +186,7 @@ public class HexCapabilityHandler { @Override public int getConsumptionPriority() { - return 4; + return 40; } @Override @@ -189,7 +201,7 @@ public class HexCapabilityHandler { } private record StaticDatumHolder(Function> provider, - ItemStack stack) implements DataHolder { + ItemStack stack) implements DataHolder { @Override public @Nullable CompoundTag readRawDatum() { @@ -228,16 +240,18 @@ public class HexCapabilityHandler { @Override public boolean writeDatum(@Nullable SpellDatum datum, boolean simulate) { - if (!holder.canWrite(stack, datum)) + if (!holder.canWrite(stack, datum)) { return false; - if (!simulate) + } + if (!simulate) { holder.writeDatum(stack, datum); + } return true; } } - private record ItemBasedSpellHolder(SpellHolderItem holder, - ItemStack stack) implements SpellHolder { + private record ItemBasedHexHolder(HexHolderItem holder, + ItemStack stack) implements HexHolder { @Override public boolean canDrawManaFromInventory() { @@ -260,9 +274,8 @@ public class HexCapabilityHandler { } } - private record ItemBasedColorizer(ColorizerItem holder, - ItemStack stack) implements Colorizer { - + public record ItemBasedColorizer(ColorizerItem holder, + ItemStack stack) implements Colorizer { @Override public int color(UUID owner, float time, Vec3 position) { return holder.color(stack, owner, time, position); diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeListenersSetup.java b/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeListenersSetup.java index 2588fd96..87cccd2e 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeListenersSetup.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeListenersSetup.java @@ -1,20 +1,5 @@ package at.petrak.hexcasting.forge.xplat; -import at.petrak.hexcasting.common.misc.Brainsweeping; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; - public class ForgeListenersSetup { - public static void init() { - var evBus = MinecraftForge.EVENT_BUS; - evBus.addListener((PlayerInteractEvent.EntityInteract evt) -> { - var res = Brainsweeping.tradeWithVillager(evt.getPlayer(), evt.getWorld(), evt.getHand(), evt.getTarget(), - null); - if (res.consumesAction()) { - evt.setCanceled(true); - evt.setCancellationResult(res); - } - }); - } } diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java b/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java index b019add6..5e707f05 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeXplatImpl.java @@ -1,23 +1,40 @@ package at.petrak.hexcasting.forge.xplat; -import at.petrak.hexcasting.common.lib.HexStringKeys; +import at.petrak.hexcasting.api.misc.FrozenColorizer; +import at.petrak.hexcasting.api.player.FlightAbility; +import at.petrak.hexcasting.api.player.Sentinel; +import at.petrak.hexcasting.api.spell.casting.CastingContext; +import at.petrak.hexcasting.api.spell.casting.CastingHarness; +import at.petrak.hexcasting.api.spell.casting.ResolvedPattern; +import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.common.network.IMessage; import at.petrak.hexcasting.common.network.MsgBrainsweepAck; import at.petrak.hexcasting.forge.network.ForgePacketHandler; import at.petrak.hexcasting.mixin.AccessorLivingEntity; import at.petrak.hexcasting.xplat.IXplatAbstractions; import at.petrak.hexcasting.xplat.Platform; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.Brain; import net.minecraft.world.entity.npc.Villager; import net.minecraft.world.entity.npc.VillagerDataHolder; +import net.minecraft.world.entity.player.Player; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.network.PacketDistributor; +import java.util.ArrayList; +import java.util.List; + public class ForgeXplatImpl implements IXplatAbstractions { @Override public Platform platform() { @@ -32,7 +49,7 @@ public class ForgeXplatImpl implements IXplatAbstractions { @Override public void brainsweep(LivingEntity entity) { if (entity instanceof VillagerDataHolder) { - entity.getPersistentData().putBoolean(HexStringKeys.BRAINSWEPT, true); + entity.getPersistentData().putBoolean(TAG_BRAINSWEPT, true); if (entity instanceof Mob mob) { mob.removeFreeWill(); @@ -53,9 +70,128 @@ public class ForgeXplatImpl implements IXplatAbstractions { } } + @Override + public void setFlight(ServerPlayer player, FlightAbility flight) { + CompoundTag tag = player.getPersistentData(); + tag.putBoolean(TAG_FLIGHT_ALLOWED, flight.allowed()); + if (flight.allowed()) { + tag.putInt(TAG_FLIGHT_TIME, flight.timeLeft()); + tag.put(TAG_FLIGHT_ORIGIN, HexUtils.serializeToNBT(flight.origin())); + tag.putString(TAG_FLIGHT_DIMENSION, flight.dimension().location().toString()); + tag.putDouble(TAG_FLIGHT_RADIUS, flight.radius()); + } else { + tag.remove(TAG_FLIGHT_TIME); + tag.remove(TAG_FLIGHT_ORIGIN); + tag.remove(TAG_FLIGHT_RADIUS); + } + } + + @Override + public void setColorizer(Player player, FrozenColorizer colorizer) { + CompoundTag tag = player.getPersistentData(); + tag.put(TAG_COLOR, colorizer.serialize()); + + if (player instanceof ServerPlayer serverPlayer) { + this.syncColorizer(serverPlayer); + } + } + + @Override + public void setSentinel(Player player, Sentinel sentinel) { + CompoundTag tag = player.getPersistentData(); + tag.putBoolean(TAG_SENTINEL_EXISTS, sentinel.hasSentinel()); + if (sentinel.hasSentinel()) { + tag.putBoolean(TAG_SENTINEL_GREATER, sentinel.extendsRange()); + tag.put(TAG_SENTINEL_POSITION, HexUtils.serializeToNBT(sentinel.position())); + tag.putString(TAG_SENTINEL_DIMENSION, sentinel.dimension().location().toString()); + } else { + tag.remove(TAG_SENTINEL_GREATER); + tag.remove(TAG_SENTINEL_POSITION); + tag.remove(TAG_SENTINEL_DIMENSION); + } + + if (player instanceof ServerPlayer serverPlayer) { + this.syncSentinel(serverPlayer); + } + } + + @Override + public void setHarness(ServerPlayer player, CastingHarness harness) { + player.getPersistentData().put(TAG_HARNESS, harness == null ? new CompoundTag() : harness.serializeToNBT()); + } + + @Override + public void setPatterns(ServerPlayer player, List patterns) { + var listTag = new ListTag(); + for (ResolvedPattern pattern : patterns) { + listTag.add(pattern.serializeToNBT()); + } + player.getPersistentData().put(TAG_PATTERNS, listTag); + } + + @Override public boolean isBrainswept(LivingEntity e) { - return e instanceof VillagerDataHolder && e.getPersistentData().getBoolean(HexStringKeys.BRAINSWEPT); + return e instanceof VillagerDataHolder && e.getPersistentData().getBoolean(TAG_BRAINSWEPT); + } + + @Override + public FlightAbility getFlight(ServerPlayer player) { + CompoundTag tag = player.getPersistentData(); + boolean allowed = tag.getBoolean(TAG_FLIGHT_ALLOWED); + if (allowed) { + var timeLeft = tag.getInt(TAG_FLIGHT_TIME); + var origin = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_FLIGHT_ORIGIN)); + var radius = tag.getDouble(TAG_FLIGHT_RADIUS); + var dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, + new ResourceLocation(tag.getString(TAG_SENTINEL_DIMENSION))); + return new FlightAbility(true, timeLeft, dimension, origin, radius); + } + return FlightAbility.deny(); + } + + @Override + public FrozenColorizer getColorizer(Player player) { + return FrozenColorizer.deserialize(player.getPersistentData().getCompound(TAG_COLOR)); + } + + @Override + public Sentinel getSentinel(Player player) { + CompoundTag tag = player.getPersistentData(); + var exists = tag.getBoolean(TAG_SENTINEL_EXISTS); + if (!exists) { + return Sentinel.none(); + } + var extendsRange = tag.getBoolean(TAG_SENTINEL_GREATER); + var position = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_SENTINEL_POSITION)); + var dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, + new ResourceLocation(tag.getString(TAG_SENTINEL_DIMENSION))); + + return new Sentinel(true, extendsRange, position, dimension); + } + + @Override + public CastingHarness getHarness(ServerPlayer player, InteractionHand hand) { + var ctx = new CastingContext(player, hand); + return CastingHarness.DeserializeFromNBT(player.getPersistentData().getCompound(TAG_HARNESS), ctx); + } + + @Override + public List getPatterns(ServerPlayer player) { + ListTag patternsTag = player.getPersistentData().getList(TAG_PATTERNS, Tag.TAG_COMPOUND); + + List patterns = new ArrayList<>(patternsTag.size()); + + for (int i = 0; i < patternsTag.size(); i++) { + patterns.add(ResolvedPattern.DeserializeFromNBT(patternsTag.getCompound(i))); + } + return patterns; + } + + @Override + public void clearCastingData(ServerPlayer player) { + player.getPersistentData().remove(TAG_HARNESS); + player.getPersistentData().remove(TAG_PATTERNS); } @Override @@ -67,4 +203,22 @@ public class ForgeXplatImpl implements IXplatAbstractions { public void sendPacketToServer(IMessage packet) { ForgePacketHandler.getNetwork().sendToServer(packet); } + + + public static final String TAG_BRAINSWEPT = "hexcasting:brainswept"; + public static final String TAG_SENTINEL_EXISTS = "hexcasting:sentinel_exists"; + public static final String TAG_SENTINEL_GREATER = "hexcasting:sentinel_extends_range"; + public static final String TAG_SENTINEL_POSITION = "hexcasting:sentinel_position"; + public static final String TAG_SENTINEL_DIMENSION = "hexcasting:sentinel_dimension"; + + public static final String TAG_COLOR = "hexcasting:colorizer"; + + public static final String TAG_FLIGHT_ALLOWED = "hexcasting:flight_allowed"; + public static final String TAG_FLIGHT_TIME = "hexcasting:flight_time"; + public static final String TAG_FLIGHT_ORIGIN = "hexcasting:flight_origin"; + public static final String TAG_FLIGHT_DIMENSION = "hexcasting:flight_origin"; + public static final String TAG_FLIGHT_RADIUS = "hexcasting:flight_radius"; + + public static final String TAG_HARNESS = "hexcasting:spell_harness"; + public static final String TAG_PATTERNS = "hexcasting:spell_patterns"; } \ No newline at end of file