// Path: src/main/java/com/legobmw99/stormlight/modules/powers/PowersSetup.java
// public class PowersSetup {
// 
//     public static final DeferredRegister<MobEffect> EFFECTS = DeferredRegister.create(ForgeRegistries.MOB_EFFECTS, Stormlight.MODID);
// 
//     public static final RegistryObject<MobEffect> STORMLIGHT = EFFECTS.register("stormlight", () -> new GenericEffect(MobEffectCategory.BENEFICIAL, 0));
//     public static final RegistryObject<MobEffect> SLICKING = EFFECTS.register("slicking", () -> new StormlightEffect(16737535));
//     public static final RegistryObject<MobEffect> STICKING = EFFECTS.register("sticking", () -> new StormlightEffect(6579455));
//     public static final RegistryObject<MobEffect> COHESION = EFFECTS.register("cohesion", () -> new StormlightEffect(16777010));
//     public static final RegistryObject<MobEffect> TENSION = EFFECTS.register("tension", () -> new StormlightEffect(16711780));
//     public static final RegistryObject<MobEffect> GRAVITATION = EFFECTS.register("gravitation",
//                                                                                  () -> new StormlightEffect(6605055).addAttributeModifier(ForgeMod.ENTITY_GRAVITY.get(),
//                                                                                                                                           "a81758d2-c355-11eb-8529-0242ac130003",
//                                                                                                                                           -0.08,
//                                                                                                                                           AttributeModifier.Operation.ADDITION));
// 
// 
//     public static void register() {
//         EFFECTS.register(FMLJavaModLoadingContext.get().getModEventBus());
//     }
// 
// 
//     public static void init(final FMLCommonSetupEvent e) {
//         ArgumentTypes.register("stormlight_ideal", StormlightArgType.IdealType.class, new EmptyArgumentSerializer<>(() -> StormlightArgType.IdealType.INSTANCE));
//         ArgumentTypes.register("stormlight_order", StormlightArgType.OrderType.class, new EmptyArgumentSerializer<>(() -> StormlightArgType.OrderType.INSTANCE));
// 
//         MinecraftForge.EVENT_BUS.register(PowersEventHandler.class);
//     }
// }
// 
// Path: src/main/java/com/legobmw99/stormlight/modules/powers/data/SurgebindingCapability.java
// public class SurgebindingCapability {
// 
//     public static final Capability<ISurgebindingData> PLAYER_CAP = CapabilityManager.get(new CapabilityToken<>() {
//     });
// 
//     public static final ResourceLocation IDENTIFIER = new ResourceLocation(Stormlight.MODID, "surgebinding_data");
// 
// 
//     public static void registerCapability(final RegisterCapabilitiesEvent event) {
//         event.register(ISurgebindingData.class);
//     }
// 
// }
// 
// Path: src/main/java/com/legobmw99/stormlight/util/Surge.java
// public enum Surge {
//     ADHESION(Surges::adhesion, 25, true, SurgeEffects::adhesionEffect),
//     GRAVITATION(Surges::gravitation),
//     DIVISION(Surges::division),
//     ABRASION(Surges::abrasion),
//     PROGRESSION(Surges::progression, SurgeEffects::progressionEffect),
//     ILLUMINATION(Surges::illumination),
//     TRANSFORMATION(Surges::transformation),
//     TRANSPORTATION(Surges::transportation, 40F),
//     COHESION(Surges::cohesion),
//     TENSION(Surges::tension);
// 
//     private final ISurgePower surge;
//     private final ISurgeEffect effect;
//     private final float range;
//     private final boolean repeating;
// 
//     Surge(ISurgePower surge) {
//         this(surge, 30F, false, null);
//     }
// 
//     Surge(ISurgePower surge, float range) {
//         this(surge, range, false, null);
//     }
// 
//     Surge(ISurgePower surge, float range, boolean repeating) {
//         this(surge, range, repeating, null);
//     }
// 
//     Surge(ISurgePower surge, ISurgeEffect effect) {
//         this(surge, 30F, false, effect);
//     }
// 
//     Surge(ISurgePower surge, float range, boolean repeating, ISurgeEffect effect) {
//         this.surge = surge;
//         this.range = range;
//         this.repeating = repeating;
//         this.effect = effect;
//     }
// 
// 
//     public boolean hasEffect() {
//         return effect != null;
//     }
// 
//     public boolean isRepeating() {return repeating;}
// 
//     public float getRange() {
//         return range;
//     }
// 
//     public void fire(ServerPlayer player, @Nullable BlockPos looking, boolean modified) {
//         surge.fire(player, looking, modified);
//     }
// 
//     public void displayEffect(BlockPos looking, boolean modified) {
//         if (hasEffect()) {
//             effect.fire(looking, modified);
//         }
//     }
// 
// }


import com.legobmw99.stormlight.modules.powers.PowersSetup;
import com.legobmw99.stormlight.modules.powers.data.SurgebindingCapability;
import com.legobmw99.stormlight.util.Surge;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nullable;
import java.util.function.Supplier;
    }

    public static SurgePacket decode(FriendlyByteBuf buf) {
        return new SurgePacket(buf.readEnum(Surge.class), buf.readBoolean() ? buf.readBlockPos() : null, buf.readBoolean());
    }

    public void encode(FriendlyByteBuf buf) {
        buf.writeEnum(surge);
        boolean hasBlock = looking != null;
        buf.writeBoolean(hasBlock);
        if (hasBlock) {
            buf.writeBlockPos(looking);
        }
        buf.writeBoolean(shiftHeld);
    }


    public void handle(Supplier<NetworkEvent.Context> ctx) {
        if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_CLIENT) {
            ctx.get().enqueueWork(() -> {
                if (looking != null) {
                    surge.displayEffect(looking, shiftHeld);
                }
            });
            ctx.get().setPacketHandled(true);
        } else if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_SERVER) {
            ctx.get().enqueueWork(() -> {
                ServerPlayer player = ctx.get().getSender();
                if (player != null) {
                    if (player.getCapability(SurgebindingCapability.PLAYER_CAP).filter(data -> data.isKnight() && data.canUseSurge(surge)).isPresent() &&
// Path: src/main/java/com/legobmw99/stormlight/modules/powers/PowersSetup.java
// public class PowersSetup {
// 
//     public static final DeferredRegister<MobEffect> EFFECTS = DeferredRegister.create(ForgeRegistries.MOB_EFFECTS, Stormlight.MODID);
// 
//     public static final RegistryObject<MobEffect> STORMLIGHT = EFFECTS.register("stormlight", () -> new GenericEffect(MobEffectCategory.BENEFICIAL, 0));
//     public static final RegistryObject<MobEffect> SLICKING = EFFECTS.register("slicking", () -> new StormlightEffect(16737535));
//     public static final RegistryObject<MobEffect> STICKING = EFFECTS.register("sticking", () -> new StormlightEffect(6579455));
//     public static final RegistryObject<MobEffect> COHESION = EFFECTS.register("cohesion", () -> new StormlightEffect(16777010));
//     public static final RegistryObject<MobEffect> TENSION = EFFECTS.register("tension", () -> new StormlightEffect(16711780));
//     public static final RegistryObject<MobEffect> GRAVITATION = EFFECTS.register("gravitation",
//                                                                                  () -> new StormlightEffect(6605055).addAttributeModifier(ForgeMod.ENTITY_GRAVITY.get(),
//                                                                                                                                           "a81758d2-c355-11eb-8529-0242ac130003",
//                                                                                                                                           -0.08,
//                                                                                                                                           AttributeModifier.Operation.ADDITION));
// 
// 
//     public static void register() {
//         EFFECTS.register(FMLJavaModLoadingContext.get().getModEventBus());
//     }
// 
// 
//     public static void init(final FMLCommonSetupEvent e) {
//         ArgumentTypes.register("stormlight_ideal", StormlightArgType.IdealType.class, new EmptyArgumentSerializer<>(() -> StormlightArgType.IdealType.INSTANCE));
//         ArgumentTypes.register("stormlight_order", StormlightArgType.OrderType.class, new EmptyArgumentSerializer<>(() -> StormlightArgType.OrderType.INSTANCE));
// 
//         MinecraftForge.EVENT_BUS.register(PowersEventHandler.class);
//     }
// }
// 
// Path: src/main/java/com/legobmw99/stormlight/modules/powers/data/SurgebindingCapability.java
// public class SurgebindingCapability {
// 
//     public static final Capability<ISurgebindingData> PLAYER_CAP = CapabilityManager.get(new CapabilityToken<>() {
//     });
// 
//     public static final ResourceLocation IDENTIFIER = new ResourceLocation(Stormlight.MODID, "surgebinding_data");
// 
// 
//     public static void registerCapability(final RegisterCapabilitiesEvent event) {
//         event.register(ISurgebindingData.class);
//     }
// 
// }
// 
// Path: src/main/java/com/legobmw99/stormlight/util/Surge.java
// public enum Surge {
//     ADHESION(Surges::adhesion, 25, true, SurgeEffects::adhesionEffect),
//     GRAVITATION(Surges::gravitation),
//     DIVISION(Surges::division),
//     ABRASION(Surges::abrasion),
//     PROGRESSION(Surges::progression, SurgeEffects::progressionEffect),
//     ILLUMINATION(Surges::illumination),
//     TRANSFORMATION(Surges::transformation),
//     TRANSPORTATION(Surges::transportation, 40F),
//     COHESION(Surges::cohesion),
//     TENSION(Surges::tension);
// 
//     private final ISurgePower surge;
//     private final ISurgeEffect effect;
//     private final float range;
//     private final boolean repeating;
// 
//     Surge(ISurgePower surge) {
//         this(surge, 30F, false, null);
//     }
// 
//     Surge(ISurgePower surge, float range) {
//         this(surge, range, false, null);
//     }
// 
//     Surge(ISurgePower surge, float range, boolean repeating) {
//         this(surge, range, repeating, null);
//     }
// 
//     Surge(ISurgePower surge, ISurgeEffect effect) {
//         this(surge, 30F, false, effect);
//     }
// 
//     Surge(ISurgePower surge, float range, boolean repeating, ISurgeEffect effect) {
//         this.surge = surge;
//         this.range = range;
//         this.repeating = repeating;
//         this.effect = effect;
//     }
// 
// 
//     public boolean hasEffect() {
//         return effect != null;
//     }
// 
//     public boolean isRepeating() {return repeating;}
// 
//     public float getRange() {
//         return range;
//     }
// 
//     public void fire(ServerPlayer player, @Nullable BlockPos looking, boolean modified) {
//         surge.fire(player, looking, modified);
//     }
// 
//     public void displayEffect(BlockPos looking, boolean modified) {
//         if (hasEffect()) {
//             effect.fire(looking, modified);
//         }
//     }
// 
// }


// Path: src/main/java/com/legobmw99/stormlight/network/packets/SurgePacket.java
import com.legobmw99.stormlight.modules.powers.PowersSetup;
import com.legobmw99.stormlight.modules.powers.data.SurgebindingCapability;
import com.legobmw99.stormlight.util.Surge;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nullable;
import java.util.function.Supplier;

    }

    public static SurgePacket decode(FriendlyByteBuf buf) {
        return new SurgePacket(buf.readEnum(Surge.class), buf.readBoolean() ? buf.readBlockPos() : null, buf.readBoolean());
    }

    public void encode(FriendlyByteBuf buf) {
        buf.writeEnum(surge);
        boolean hasBlock = looking != null;
        buf.writeBoolean(hasBlock);
        if (hasBlock) {
            buf.writeBlockPos(looking);
        }
        buf.writeBoolean(shiftHeld);
    }


    public void handle(Supplier<NetworkEvent.Context> ctx) {
        if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_CLIENT) {
            ctx.get().enqueueWork(() -> {
                if (looking != null) {
                    surge.displayEffect(looking, shiftHeld);
                }
            });
            ctx.get().setPacketHandled(true);
        } else if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_SERVER) {
            ctx.get().enqueueWork(() -> {
                ServerPlayer player = ctx.get().getSender();
                if (player != null) {
                    if (player.getCapability(SurgebindingCapability.PLAYER_CAP).filter(data -> data.isKnight() && data.canUseSurge(surge)).isPresent() &&
                        player.hasEffect(PowersSetup.STORMLIGHT.get())) {