From 74690580f6645df18cb33957ab601904177f4f3b Mon Sep 17 00:00:00 2001 From: "petrak@" Date: Fri, 17 Feb 2023 19:30:41 -0600 Subject: [PATCH] woo, altiora works on fabric and forge --- .../casting/operators/spells/OpFlight.kt | 25 +++++++++------- .../hexcasting/xplat/IXplatAbstractions.java | 2 +- .../assets/hexcasting/lang/en_us.json | 12 ++++++-- .../{flight.json => altiora.json} | 6 ++-- .../en_us/entries/patterns/spells/flight.json | 30 +++++++++++++++++++ .../hexcasting/fabric/FabricHexInitializer.kt | 4 +-- .../hexcasting/fabric/cc/CCAltiora.java | 9 +++--- .../fabric/cc/HexCardinalComponents.java | 3 ++ .../fabric/xplat/FabricXplatImpl.java | 3 +- .../forge/xplat/ForgeXplatImpl.java | 8 ++++- 10 files changed, 76 insertions(+), 26 deletions(-) rename Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/{flight.json => altiora.json} (78%) create mode 100644 Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/flight.json diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpFlight.kt b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpFlight.kt index 679e791b..586966fe 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpFlight.kt +++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/operators/spells/OpFlight.kt @@ -36,8 +36,8 @@ class OpFlight(val type: Type) : SpellAction { val cost = when (this.type) { Type.LimitRange -> theArg * MediaConstants.DUST_UNIT - // A minute of flight should cost a charged crystal? - Type.LimitTime -> theArg / 60.0 * MediaConstants.CRYSTAL_UNIT + // A second of flight should cost 1 shard + Type.LimitTime -> theArg * MediaConstants.SHARD_UNIT }.roundToInt() // Convert to ticks @@ -73,22 +73,16 @@ class OpFlight(val type: Type) : SpellAction { IXplatAbstractions.INSTANCE.setFlight(target, flight) target.abilities.mayfly = true - target.abilities.flying = true - // On fabric it only seems to make them actually fly once every other time so let's try this target.onUpdateAbilities() - target.onUpdateAbilities() - // Launch the player into the air to really emphasize the flight - target.push(0.0, 1.0, 0.0) - target.hurtMarked = true // Whyyyyy } } companion object { - // danger particles up to 1 block from the edge - private val DIST_DANGER_THRESHOLD = 2.0 + // blocks from the edge + private val DIST_DANGER_THRESHOLD = 4.0 - // danger particles up to 7 seconds from the limit + // seconds left private val TIME_DANGER_THRESHOLD = 7.0 * 20.0 @JvmStatic @@ -155,6 +149,15 @@ class OpFlight(val type: Type) : SpellAction { if (player.level.random.nextFloat() < 0.02) player.level.playSound(null, player.x, player.y, player.z, HexSounds.FLIGHT_AMBIENCE, SoundSource.PLAYERS, 0.2f, 1f) + + if (flight.radius >= 0.0) { + // Show the origin + val spoofedOrigin = flight.origin.add(0.0, 1.0, 0.0) + ParticleSpray(spoofedOrigin, Vec3(0.0, 1.0, 0.0), 0.5, Math.PI * 0.1, count = 5) + .sprayParticles(player.getLevel(), color) + ParticleSpray(spoofedOrigin, Vec3(0.0, -1.0, 0.0), 1.5, Math.PI * 0.25, count = 5) + .sprayParticles(player.getLevel(), color) + } } } } 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 e83f204e..46e4b818 100644 --- a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java +++ b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java @@ -90,7 +90,7 @@ public interface IXplatAbstractions { @Nullable FlightAbility getFlight(ServerPlayer player); - @Nullable AltioraAbility getAltiora(ServerPlayer player); + @Nullable AltioraAbility getAltiora(Player player); FrozenColorizer getColorizer(Player player); diff --git a/Common/src/main/resources/assets/hexcasting/lang/en_us.json b/Common/src/main/resources/assets/hexcasting/lang/en_us.json index 8843f9da..d27e079a 100644 --- a/Common/src/main/resources/assets/hexcasting/lang/en_us.json +++ b/Common/src/main/resources/assets/hexcasting/lang/en_us.json @@ -1136,6 +1136,14 @@ "hexcasting.page.colorize": "I must be holding a $(l:items/pigments)$(item)Pigment/$ in my other hand to cast this spell. When I do, it will consume the dye and permanently change my mind's coloration (at least, until I cast the spell again). Costs about one $(l:items/amethyst)$(item)Amethyst Dust/$.", + "hexcasting.entry.flights": "Flight", + "hexcasting.page.flights.1": "Although it seems that true, limitless flight is out of my grasp, I have nonetheless found some methods of holding one in the sky, each with their respective drawbacks.$(br2)All forms produce a shimmer of excess _media; as the spell gets closer to ending, the sparks are shot through with more red and black.", + "hexcasting.page.flights.2": "Other forms of flight do exist, of course. For example, a combination of $(l:patterns/spells/basic#hexcasting:add_motion)$(action)Impulse/$ and $(l:patterns/spells/nadirs#hexcasting:potion/levitation)$(action)Blue Sun's Nadir/$ has been used since antiquity for a flight of sorts.$(br2)I've also heard tell of a thin membrane worn on the back that allows the ability to glide. From my research, I believe the Great spell $(l:patterns/great_spells/altiora)$(action)Altiora/$ may be used to mimic it.", + "hexcasting.page.flights.range.1": "A flight limited in its range.", + "hexcasting.page.flights.range.2": "The second argument is a horizontal radius, in meters, in which the spell is stable. Moving outside of that radius will end the spell, dropping me out of the sky. As long as I stay inside the safe zone, however, the spell lasts indefinitely. An additional shimmer of _media marks the origin point of the safe zone. $(br2)Costs about 1 $(l:items/amethyst)$(item)Amethyst Dust/$ per meter of safety.", + "hexcasting.page.flights.time.1": "A flight limited in its duration.", + "hexcasting.page.flights.time.2": "The second argument is an amount of time in seconds for which the spell is stable. After that time, the spell ends and I am dropped from the sky. $(br2)It is relatively expensive at about 1 $(l:items/amethyst)$(item)Charged Crystal/$ per second of flight; I believe it is best suited for travel.", + "hexcasting.page.create_lava.1": "Summon a block of lava (or insert up to a bucket's worth) into a block at the given position. Costs about one $(l:items/amethyst)$(item)Charged Amethyst/$.", "hexcasting.page.create_lava.2": "It may be advisable to keep my knowledge of this spell secret. A certain faction of botanists get... touchy about it, or so I've heard.$(br2)Well, no one said tracing the deep secrets of the universe was going to be an easy time.", @@ -1144,8 +1152,8 @@ "hexcasting.page.weather_manip.summon_rain": "I control the clouds! This spell will summon rain across the world I cast it upon. Costs about one $(l:items/amethyst)$(item)Charged Amethyst/$. Does nothing if it is already raining.", "hexcasting.page.weather_manip.dispel_rain": "A counterpart to summoning rain. This spell will dispel rain across the world I cast it upon. Costs about one $(l:items/amethyst)$(item)Amethyst Shard/$. Does nothing if the skies are already clear.", - "hexcasting.page.flight.1": "The power of flight! I have wrestled Nature to its knees. But Nature is vengeful, and itches for me to break its contract so it may break my shins.", - "hexcasting.page.flight.2": "The entity (which must be a player) will be endowed with flight. The first number is the number of seconds they may fly for, and the second number is the radius of the zone they may fly in. If the recipient exits that zone, or their timer runs out while midair, the gravity that they spurned will get its revenge. Painfully.$(br2)It costs one quarter of an $(l:items/amethyst)$(item)Amethyst Dust/$, per meter of radius, per second in flight.", + "hexcasting.page.altiora.1": "Summon a sheaf of _media about me in the shape of wings, endowed with enough substance to allow gliding.", + "hexcasting.page.altiora.2": "Using them is identical to using $(item)Elytra/$; the target (which must be a player) is lofted into the air, after which pressing $(k:jump) will deploy the wings. The wings are fragile, and break upon touching any surface. Longer flights may benefit from $(l:patterns/spells/basic#hexcasting:add_motion)$(action)Impulse/$ or (for the foolhardy) $(item)Fireworks/$.$(br2)Costs about one $(l:items/amethyst)$(item)Charged Crystal/$.", "hexcasting.page.teleport.1": "Far more powerful than $(l:patterns/spells/basic#hexcasting:blink)$(action)Blink/$, this spell lets me teleport nearly anywhere in the entire world! There does seem to be a limit, but it is $(italic)much/$ greater than the normal radius of influence I am used to.", "hexcasting.page.teleport.2": "The entity will be teleported by the given vector, which is an offset from its given position. No matter the distance, it always seems to cost about ten $(l:items/amethyst)$(item)Charged Amethyst/$.$(br2)The transference is not perfect, and it seems when teleporting something as complex as a player, their inventory doesn't $(italic)quite/$ stay attached, and tends to splatter everywhere at the destination. In addition, the target will be forcibly removed from anything inanimate they are riding or sitting on ... but I've read scraps that suggest animals can come along for the ride, so to speak.", diff --git a/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/flight.json b/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/altiora.json similarity index 78% rename from Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/flight.json rename to Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/altiora.json index 537a7caa..19412a00 100644 --- a/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/flight.json +++ b/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/great_spells/altiora.json @@ -1,7 +1,7 @@ { "name": "hexcasting.action.hexcasting:flight", "category": "hexcasting:patterns/great_spells", - "icon": "minecraft:feather", + "icon": "minecraft:elytra", "sortnum": 2, "advancement": "hexcasting:root", "read_by_default": true, @@ -12,11 +12,11 @@ "anchor": "hexcasting:flight", "input": "entity, number, number", "output": "", - "text": "hexcasting.page.flight.1" + "text": "hexcasting.page.altiora.1" }, { "type": "patchouli:text", - "text": "hexcasting.page.flight.2" + "text": "hexcasting.page.altiora.2" } ] } diff --git a/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/flight.json b/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/flight.json new file mode 100644 index 00000000..5f06e65e --- /dev/null +++ b/Common/src/main/resources/data/hexcasting/patchouli_books/thehexbook/en_us/entries/patterns/spells/flight.json @@ -0,0 +1,30 @@ +{ + "name": "hexcasting.entry.flights", + "category": "hexcasting:patterns/spells", + "icon": "minecraft:feather", + "advancement": "hexcasting:root", + "sortnum": 6, + "read_by_default": true, + "pages": [ + "hexcasting.page.flights.1", + "hexcasting.page.flights.2", + { + "type": "hexcasting:pattern", + "op_id": "hexcasting:flight/range", + "anchor": "hexcasting:flight/range", + "input": "entity, number", + "output": "", + "text": "hexcasting.page.flights.range.1" + }, + "hexcasting.page.flights.range.2", + { + "type": "hexcasting:pattern", + "op_id": "hexcasting:flight/time", + "anchor": "hexcasting:flight/time", + "input": "entity, number", + "output": "", + "text": "hexcasting.page.flights.time.1" + }, + "hexcasting.page.flights.time.2" + ] +} diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexInitializer.kt b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexInitializer.kt index 8b8a7ac2..736b01a7 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexInitializer.kt +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/FabricHexInitializer.kt @@ -49,8 +49,8 @@ import net.fabricmc.fabric.api.registry.FlammableBlockRegistry import net.minecraft.commands.synchronization.SingletonArgumentInfo import net.minecraft.core.Registry import net.minecraft.resources.ResourceLocation -import net.minecraft.server.level.ServerPlayer import net.minecraft.world.InteractionResult +import net.minecraft.world.entity.player.Player import java.util.function.BiConsumer object FabricHexInitializer : ModInitializer { @@ -108,7 +108,7 @@ object FabricHexInitializer : ModInitializer { } EntityElytraEvents.CUSTOM.register { target, _ -> - if (target is ServerPlayer) { + if (target is Player) { val altiora = IXplatAbstractions.INSTANCE.getAltiora(target) altiora != null } else { diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCAltiora.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCAltiora.java index 8e84a732..1ac0721d 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCAltiora.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/CCAltiora.java @@ -2,21 +2,20 @@ package at.petrak.hexcasting.fabric.cc; import at.petrak.hexcasting.api.player.AltioraAbility; 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.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; import org.jetbrains.annotations.Nullable; -public class CCAltiora implements Component { +public class CCAltiora implements Component, AutoSyncedComponent { public static final String TAG_ALLOWED = "allowed", TAG_GRACE = "grace_period"; - private final ServerPlayer owner; @Nullable private AltioraAbility altiora = null; - public CCAltiora(ServerPlayer owner) { - this.owner = owner; + public CCAltiora(Player owner) { } 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 index f7d1f519..697e1ce7 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/HexCardinalComponents.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/cc/HexCardinalComponents.java @@ -69,6 +69,9 @@ public class HexCardinalComponents implements EntityComponentInitializer, ItemCo registry.registerFor(ServerPlayer.class, HARNESS, CCHarness::new); registry.registerFor(ServerPlayer.class, PATTERNS, CCPatterns::new); + // On Fabric, this is needed on the client because the c/s need to agree on when wings are being deployed + registry.registerForPlayers(ALTIORA, CCAltiora::new, RespawnCopyStrategy.LOSSLESS_ONLY); + registry.registerFor(ItemEntity.class, IOTA_HOLDER, wrapItemEntityDelegate( ItemDelegatingEntityIotaHolder.ToItemEntity::new)); registry.registerFor(ItemFrame.class, IOTA_HOLDER, wrapItemEntityDelegate( diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricXplatImpl.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricXplatImpl.java index 539187d5..e1d9c4ce 100644 --- a/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricXplatImpl.java +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricXplatImpl.java @@ -169,6 +169,7 @@ public class FabricXplatImpl implements IXplatAbstractions { public void setAltiora(ServerPlayer target, @Nullable AltioraAbility altiora) { var cc = HexCardinalComponents.ALTIORA.get(target); cc.setAltiora(altiora); + HexCardinalComponents.ALTIORA.sync(target); } @Override @@ -196,7 +197,7 @@ public class FabricXplatImpl implements IXplatAbstractions { } @Override - public @Nullable AltioraAbility getAltiora(ServerPlayer player) { + public @Nullable AltioraAbility getAltiora(Player player) { var cc = HexCardinalComponents.ALTIORA.get(player); return cc.getAltiora(); } 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 933493a1..1d008567 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 @@ -167,6 +167,7 @@ public class ForgeXplatImpl implements IXplatAbstractions { tag.remove(TAG_ALTIORA_ALLOWED); } + // The elytra ability is done with an event on fabric var elytraing = CaelusApi.getInstance().getFlightAttribute(); var inst = player.getAttributes().getInstance(elytraing); if (altiora != null) { @@ -243,7 +244,12 @@ public class ForgeXplatImpl implements IXplatAbstractions { } @Override - public AltioraAbility getAltiora(ServerPlayer player) { + public AltioraAbility getAltiora(Player anyPlayer) { + if (!(anyPlayer instanceof ServerPlayer player)) { + // the check only needs to happen client-side on fabric + // which is great, cause it's not even synced on forge + return null; + } CompoundTag tag = player.getPersistentData(); boolean allowed = tag.getBoolean(TAG_ALTIORA_ALLOWED); if (allowed) {