woo, altiora works on fabric and forge

This commit is contained in:
petrak@ 2023-02-17 19:30:41 -06:00
parent cefd9439db
commit 74690580f6
10 changed files with 76 additions and 26 deletions

View file

@ -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)
}
}
}
}

View file

@ -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);

View file

@ -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.",

View file

@ -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"
}
]
}

View file

@ -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"
]
}

View file

@ -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 {

View file

@ -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) {
}

View file

@ -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(

View file

@ -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();
}

View file

@ -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) {