diff --git a/Common/src/main/java/at/petrak/hexcasting/HexMod.kt b/Common/src/main/java/at/petrak/hexcasting/HexMod.kt deleted file mode 100644 index 7b9e463d..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/HexMod.kt +++ /dev/null @@ -1,127 +0,0 @@ -package at.petrak.hexcasting - -import at.petrak.hexcasting.api.PatternRegistry -import at.petrak.hexcasting.api.advancements.HexAdvancementTriggers -import at.petrak.hexcasting.api.mod.HexConfig -import at.petrak.hexcasting.api.mod.HexStatistics -import at.petrak.hexcasting.api.player.HexPlayerDataHelper -import at.petrak.hexcasting.client.* -import at.petrak.hexcasting.common.blocks.HexBlockEntities -import at.petrak.hexcasting.common.blocks.HexBlocks -import at.petrak.hexcasting.common.casting.RegisterPatterns -import at.petrak.hexcasting.common.casting.operators.spells.great.OpFlight -import at.petrak.hexcasting.common.command.HexCommands -import at.petrak.hexcasting.common.command.PatternResLocArgument -import at.petrak.hexcasting.common.entities.HexEntities -import at.petrak.hexcasting.common.items.HexItems -import at.petrak.hexcasting.common.lib.HexCapabilityHandler -import at.petrak.hexcasting.common.lib.HexSounds -import at.petrak.hexcasting.common.misc.Brainsweeping -import at.petrak.hexcasting.common.network.HexMessages -import at.petrak.hexcasting.common.particles.HexParticles -import at.petrak.hexcasting.common.recipe.HexComposting -import at.petrak.hexcasting.common.recipe.HexCustomRecipes -import at.petrak.hexcasting.common.recipe.HexRecipeSerializers -import at.petrak.hexcasting.datagen.HexDataGenerators -import at.petrak.hexcasting.datagen.lootmods.HexLootModifiers -import at.petrak.hexcasting.server.TickScheduler -import net.minecraft.commands.synchronization.ArgumentTypes -import net.minecraft.commands.synchronization.EmptyArgumentSerializer -import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.common.ForgeConfigSpec -import net.minecraftforge.eventbus.api.SubscribeEvent -import net.minecraftforge.fml.DistExecutor -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 org.slf4j.Logger -import org.slf4j.LoggerFactory - -@Mod(HexMod.MOD_ID) -object HexMod { - // hmm today I will use a popular logging framework :clueless: - val LOGGER: Logger = LoggerFactory.getLogger(HexMod::class.java) - - val CONFIG_SPEC: ForgeConfigSpec - val SERVER_CONFIG_SPEC: ForgeConfigSpec - val CLIENT_CONFIG_SPEC: ForgeConfigSpec - - // mumblemumble thanks shy mumble mumble - const val MOD_ID = "hexcasting" - - init { - CONFIG_SPEC = ForgeConfigSpec.Builder() - .configure { builder: ForgeConfigSpec.Builder? -> HexConfig(builder) }.right - SERVER_CONFIG_SPEC = ForgeConfigSpec.Builder() - .configure { builder: ForgeConfigSpec.Builder? -> HexConfig.Server(builder) }.right - CLIENT_CONFIG_SPEC = ForgeConfigSpec.Builder() - .configure { builder: ForgeConfigSpec.Builder? -> HexConfig.Client(builder) }.right - - ArgumentTypes.register("hexcasting:pattern", PatternResLocArgument::class.java, EmptyArgumentSerializer(PatternResLocArgument::id)) - - // mod lifecycle - val modBus = thedarkcolour.kotlinforforge.forge.MOD_BUS - // game events - val evBus = thedarkcolour.kotlinforforge.forge.FORGE_BUS - - modBus.register(this) - // gotta do it at *some* point - modBus.register(RegisterPatterns::class.java) - modBus.register(HexDataGenerators::class.java) - - HexItems.ITEMS.register(modBus) - HexBlocks.BLOCKS.register(modBus) - HexBlockEntities.BLOCK_ENTITIES.register(modBus) - HexEntities.ENTITIES.register(modBus) - HexLootModifiers.LOOT_MODS.register(modBus) - HexSounds.SOUNDS.register(modBus) - HexParticles.PARTICLES.register(modBus) - HexCustomRecipes.RECIPES.register(modBus) - HexRecipeSerializers.SERIALIZERS.register(modBus) - modBus.register(HexStatistics::class.java) - modBus.register(HexRecipeSerializers::class.java) - - modBus.register(HexComposting::class.java) - - evBus.register(HexCommands::class.java) - evBus.register(TickScheduler) - evBus.register(HexCapabilityHandler::class.java) - evBus.register(HexPlayerDataHelper::class.java) - evBus.register(OpFlight) - evBus.register(Brainsweeping::class.java) - - DistExecutor.unsafeRunWhenOn(Dist.CLIENT) { - Runnable { - modBus.register(RegisterClientStuff::class.java) - evBus.register(ClientTickCounter::class.java) - evBus.register(HexAdditionalRenderers::class.java) - evBus.register(ShiftScrollListener::class.java) - evBus.register(HexTooltips::class.java) - } - } - - // and then things that don't require busses - HexMessages.register() - - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, CONFIG_SPEC) - ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, SERVER_CONFIG_SPEC) - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, CLIENT_CONFIG_SPEC) - } - - @SubscribeEvent - fun commonSetup(evt: FMLCommonSetupEvent) { - evt.enqueueWork { HexAdvancementTriggers.registerTriggers() } - } - - @JvmStatic - fun getLogger() = this.LOGGER - - @SubscribeEvent - fun printPatternCount(evt: FMLLoadCompleteEvent) { - getLogger().info( - PatternRegistry.getPatternCountInfo() - ) - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java index 26a14c77..e22627dc 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/HexAPI.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.api; import com.google.common.base.Suppliers; +import net.minecraft.resources.ResourceLocation; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -24,4 +25,8 @@ public interface HexAPI { static HexAPI instance() { return INSTANCE.get(); } + + static ResourceLocation modLoc(String s) { + return new ResourceLocation(MOD_ID, s); + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexApiMessages.java b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexApiMessages.java index 260aa586..fea08078 100644 --- a/Common/src/main/java/at/petrak/hexcasting/api/mod/HexApiMessages.java +++ b/Common/src/main/java/at/petrak/hexcasting/api/mod/HexApiMessages.java @@ -1,5 +1,8 @@ package at.petrak.hexcasting.api.mod; +// Don't understand what this does so i commented it all out :gigachad: +/* + import at.petrak.hexcasting.api.misc.FrozenColorizer; import at.petrak.hexcasting.api.player.Sentinel; import at.petrak.hexcasting.api.spell.ParticleSpray; @@ -44,3 +47,5 @@ public final class HexApiMessages { return particleSprayMessage.apply(spray, colorizer); } } + + */ 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 new file mode 100644 index 00000000..558a4a8c --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexStringKeys.java @@ -0,0 +1,9 @@ +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/common/misc/Brainsweeping.java b/Common/src/main/java/at/petrak/hexcasting/common/misc/Brainsweeping.java index 8988420c..db36984c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/misc/Brainsweeping.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/misc/Brainsweeping.java @@ -2,64 +2,50 @@ package at.petrak.hexcasting.common.misc; import at.petrak.hexcasting.common.network.HexMessages; import at.petrak.hexcasting.common.network.MsgBrainsweepAck; -import at.petrak.hexcasting.mixin.AccessorLivingEntity; -import net.minecraft.server.level.ServerLevel; +import at.petrak.hexcasting.xplat.IXplatAbstractions; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; 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.minecraft.world.level.Level; +import net.minecraft.world.phys.EntityHitResult; import net.minecraftforge.event.entity.living.LivingConversionEvent; import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; +import org.jetbrains.annotations.Nullable; public class Brainsweeping { - - public static final String TAG_BRAINSWEPT = "hexcasting:brainswept"; - - public static boolean isBrainswept(LivingEntity entity) { - return entity instanceof VillagerDataHolder && entity.getPersistentData().getBoolean(TAG_BRAINSWEPT); + // Keeping these functions in Brainsweeping just so we have to change less code + public static void brainsweep(LivingEntity entity) { + IXplatAbstractions.INSTANCE.brainsweep(entity); } - public static void brainsweep(LivingEntity entity) { - if (entity instanceof VillagerDataHolder) { - entity.getPersistentData().putBoolean(TAG_BRAINSWEPT, true); - - if (entity instanceof Mob mob) - mob.removeFreeWill(); - - if (entity instanceof Villager villager) { - Brain brain = villager.getBrain(); - if (entity.level instanceof ServerLevel slevel) { - brain.stopAll(slevel, villager); - } - ((AccessorLivingEntity) entity).hex$SetBrain(brain.copyWithoutBehaviors()); - } - - if (entity.level instanceof ServerLevel) { - HexMessages.getNetwork().send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), MsgBrainsweepAck.of(entity)); - } - } + public static boolean isBrainswept(LivingEntity entity) { + return IXplatAbstractions.INSTANCE.isBrainswept(entity); } @SubscribeEvent public static void startTracking(PlayerEvent.StartTracking evt) { Entity target = evt.getTarget(); if (evt.getPlayer() instanceof ServerPlayer serverPlayer && - target instanceof VillagerDataHolder && target instanceof LivingEntity living && isBrainswept(living)) { - HexMessages.getNetwork().send(PacketDistributor.PLAYER.with(() -> serverPlayer), MsgBrainsweepAck.of(living)); + target instanceof VillagerDataHolder && target instanceof LivingEntity living && isBrainswept(living)) { + HexMessages.getNetwork() + .send(PacketDistributor.PLAYER.with(() -> serverPlayer), MsgBrainsweepAck.of(living)); } } - @SubscribeEvent - public static void tradeWithVillager(PlayerInteractEvent.EntityInteract evt) { - if (evt.getTarget() instanceof Villager v && isBrainswept(v)) { - evt.setCanceled(true); + public static InteractionResult tradeWithVillager(Player player, Level world, InteractionHand hand, Entity entity, + @Nullable EntityHitResult hitResult) { + if (entity instanceof Villager v && IXplatAbstractions.INSTANCE.isBrainswept(v)) { + return InteractionResult.FAIL; } + + return InteractionResult.PASS; } @SubscribeEvent @@ -67,7 +53,9 @@ public class Brainsweeping { var outcome = evt.getOutcome(); var original = evt.getEntityLiving(); if (outcome instanceof VillagerDataHolder && original instanceof VillagerDataHolder) { - if (isBrainswept(original)) brainsweep(outcome); + if (isBrainswept(original)) { + brainsweep(outcome); + } } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/ClientPacketHandler.java b/Common/src/main/java/at/petrak/hexcasting/common/network/ClientPacketHandler.java deleted file mode 100644 index d716760a..00000000 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/ClientPacketHandler.java +++ /dev/null @@ -1,166 +0,0 @@ -package at.petrak.hexcasting.common.network; - -import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry; -import at.petrak.hexcasting.api.player.HexPlayerDataHelper; -import at.petrak.hexcasting.client.gui.GuiSpellcasting; -import at.petrak.hexcasting.common.lib.HexSounds; -import at.petrak.hexcasting.common.misc.Brainsweeping; -import at.petrak.hexcasting.common.particles.ConjureParticleOptions; -import net.minecraft.client.Minecraft; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.sounds.SoundSource; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.Random; - -// Ah, java classloading, how I hate thee -public record ClientPacketHandler(Object rawMsg) { - - @OnlyIn(Dist.CLIENT) - public void beep() { - if (!(rawMsg instanceof MsgBeepAck msg)) - return; - - var minecraft = Minecraft.getInstance(); - var world = minecraft.level; - if (world != null){ - float pitch = (float) Math.pow(2, (msg.note() - 12) / 12.0); - world.playLocalSound(msg.target().x, msg.target().y, msg.target().z, msg.instrument().getSoundEvent(), SoundSource.PLAYERS, 3, pitch, false); - world.addParticle(ParticleTypes.NOTE, msg.target().x, msg.target().y + 0.2, msg.target().z, msg.note() / 24.0, 0, 0); - } - } - - @OnlyIn(Dist.CLIENT) - public void blink() { - if (!(rawMsg instanceof MsgBlinkAck msg)) - return; - - var player = Minecraft.getInstance().player; - player.setPos(player.position().add(msg.addedPosition())); - } - - - @OnlyIn(Dist.CLIENT) - public void updateComparator() { - if (!(rawMsg instanceof MsgUpdateComparatorVisualsAck msg)) - return; - - ScryingLensOverlayRegistry.receiveComparatorValue(msg.pos(), msg.value()); - } - - @OnlyIn(Dist.CLIENT) - public void openSpellGui() { - if (!(rawMsg instanceof MsgOpenSpellGuiAck msg)) - return; - - var mc = Minecraft.getInstance(); - mc.setScreen(new GuiSpellcasting(msg.hand(), msg.patterns(), msg.components())); - } - - @OnlyIn(Dist.CLIENT) - public void brainsweep() { - if (!(rawMsg instanceof MsgBrainsweepAck msg)) - return; - - var level = Minecraft.getInstance().level; - if (level != null) { - Entity entity = level.getEntity(msg.target()); - if (entity instanceof LivingEntity living) { - Brainsweeping.brainsweep(living); - } - } - } - - @OnlyIn(Dist.CLIENT) - public void newPattern() { - if (!(rawMsg instanceof MsgNewSpellPatternAck msg)) - return; - - var mc = Minecraft.getInstance(); - if (msg.info().isStackClear()) { - // don't pay attention to the screen, so it also stops when we die - mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getId(), null); - } - var screen = Minecraft.getInstance().screen; - if (screen instanceof GuiSpellcasting spellGui) { - if (msg.info().isStackClear()) { - mc.setScreen(null); - } else { - spellGui.recvServerUpdate(msg.info()); - } - } - } - - @OnlyIn(Dist.CLIENT) - public void updateColorizer() { - if (!(rawMsg instanceof MsgColorizerUpdateAck msg)) - return; - - var player = Minecraft.getInstance().player; - if (player != null) { - HexPlayerDataHelper.setColorizer(player, msg.update()); - } - } - - @OnlyIn(Dist.CLIENT) - public void updateSentinel() { - if (!(rawMsg instanceof MsgSentinelStatusUpdateAck msg)) - return; - - var player = Minecraft.getInstance().player; - if (player != null) { - HexPlayerDataHelper.setSentinel(player, msg.update()); - } - } - - private static final Random RANDOM = new Random(); - - // https://math.stackexchange.com/questions/44689/how-to-find-a-random-axis-or-unit-vector-in-3d - private static Vec3 randomInCircle(double maxTh) { - var th = RANDOM.nextDouble(0.0, maxTh + 0.001); - var z = RANDOM.nextDouble(-1.0, 1.0); - return new Vec3(Math.sqrt(1.0 - z * z) * Math.cos(th), Math.sqrt(1.0 - z * z) * Math.sin(th), z); - } - - @OnlyIn(Dist.CLIENT) - public void particleSpray() { - if (!(rawMsg instanceof MsgCastParticleAck msg)) - return; - - for (int i = 0; i < msg.spray().getCount(); i++) { - // For the colors, pick any random time to get a mix of colors - var color = msg.colorizer().getColor(RANDOM.nextFloat() * 256f, Vec3.ZERO); - - var offset = randomInCircle(Mth.TWO_PI).normalize() - .scale(RANDOM.nextFloat() * msg.spray().getSpread() / 2); - var pos = msg.spray().getPos().add(offset); - - var phi = Math.acos(1.0 - RANDOM.nextDouble() * (1.0 - Math.cos(msg.spray().getSpread()))); - var theta = Math.PI * 2.0 * RANDOM.nextDouble(); - var v = msg.spray().getVel().normalize(); - // pick any old vector to get a vector normal to v with - Vec3 k; - if (v.x == 0.0 && v.y == 0.0) { - // oops, pick a *different* normal - k = new Vec3(1.0, 0.0, 0.0); - } else { - k = v.cross(new Vec3(0.0, 0.0, 1.0)); - } - var velUnlen = v.scale(Math.cos(phi)) - .add(k.scale(Math.sin(phi) * Math.cos(theta))) - .add(v.cross(k).scale(Math.sin(phi) * Math.sin(theta))); - var vel = velUnlen.scale(msg.spray().getVel().length() / 20); - - Minecraft.getInstance().level.addParticle( - new ConjureParticleOptions(color, false), - pos.x, pos.y, pos.z, - vel.x, vel.y, vel.z - ); - } - } -} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/HexMessages.java b/Common/src/main/java/at/petrak/hexcasting/common/network/HexMessages.java index e6052b28..8b6be362 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/HexMessages.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/HexMessages.java @@ -1,50 +1,5 @@ package at.petrak.hexcasting.common.network; -import at.petrak.hexcasting.HexMod; -import at.petrak.hexcasting.api.mod.HexApiMessages; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; - public class HexMessages { - private static final String PROTOCOL_VERSION = "1"; - private static final SimpleChannel NETWORK = NetworkRegistry.newSimpleChannel( - new ResourceLocation(HexMod.MOD_ID, "main"), - () -> PROTOCOL_VERSION, - PROTOCOL_VERSION::equals, - PROTOCOL_VERSION::equals - ); - public static SimpleChannel getNetwork() { - return NETWORK; - } - - public static void register() { - int messageIdx = 0; - - NETWORK.registerMessage(messageIdx++, MsgNewSpellPatternSyn.class, MsgNewSpellPatternSyn::serialize, - MsgNewSpellPatternSyn::deserialize, MsgNewSpellPatternSyn::handle); - NETWORK.registerMessage(messageIdx++, MsgNewSpellPatternAck.class, MsgNewSpellPatternAck::serialize, - MsgNewSpellPatternAck::deserialize, MsgNewSpellPatternAck::handle); - NETWORK.registerMessage(messageIdx++, MsgShiftScrollSyn.class, MsgShiftScrollSyn::serialize, - MsgShiftScrollSyn::deserialize, MsgShiftScrollSyn::handle); - NETWORK.registerMessage(messageIdx++, MsgBlinkAck.class, MsgBlinkAck::serialize, - MsgBlinkAck::deserialize, MsgBlinkAck::handle); - NETWORK.registerMessage(messageIdx++, MsgSentinelStatusUpdateAck.class, MsgSentinelStatusUpdateAck::serialize, - MsgSentinelStatusUpdateAck::deserialize, MsgSentinelStatusUpdateAck::handle); - NETWORK.registerMessage(messageIdx++, MsgColorizerUpdateAck.class, MsgColorizerUpdateAck::serialize, - MsgColorizerUpdateAck::deserialize, MsgColorizerUpdateAck::handle); - NETWORK.registerMessage(messageIdx++, MsgCastParticleAck.class, MsgCastParticleAck::serialize, - MsgCastParticleAck::deserialize, MsgCastParticleAck::handle); - NETWORK.registerMessage(messageIdx++, MsgOpenSpellGuiAck.class, MsgOpenSpellGuiAck::serialize, - MsgOpenSpellGuiAck::deserialize, MsgOpenSpellGuiAck::handle); - NETWORK.registerMessage(messageIdx++, MsgBeepAck.class, MsgBeepAck::serialize, - MsgBeepAck::deserialize, MsgBeepAck::handle); - NETWORK.registerMessage(messageIdx++, MsgBrainsweepAck.class, MsgBrainsweepAck::serialize, - MsgBrainsweepAck::deserialize, MsgBrainsweepAck::handle); - NETWORK.registerMessage(messageIdx++, MsgUpdateComparatorVisualsAck.class, MsgUpdateComparatorVisualsAck::serialize, - MsgUpdateComparatorVisualsAck::deserialize, MsgUpdateComparatorVisualsAck::handle); - - HexApiMessages.setSyncChannel(NETWORK, MsgSentinelStatusUpdateAck::new, MsgColorizerUpdateAck::new, MsgCastParticleAck::new); - } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/IMessage.java b/Common/src/main/java/at/petrak/hexcasting/common/network/IMessage.java new file mode 100644 index 00000000..2f011461 --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/IMessage.java @@ -0,0 +1,24 @@ +package at.petrak.hexcasting.common.network; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; + +// https://github.com/VazkiiMods/Botania/blob/1.18.x/Common/src/main/java/vazkii/botania/network/IPacket.java +// yoink +public interface IMessage { + default FriendlyByteBuf toBuf() { + var ret = new FriendlyByteBuf(Unpooled.buffer()); + serialize(ret); + return ret; + } + + void serialize(FriendlyByteBuf buf); + + /** + * Forge auto-assigns incrementing integers, Fabric requires us to declare an ID + * These are sent using vanilla's custom plugin channel system and thus are written to every single packet. + * So this ID tends to be more terse. + */ + ResourceLocation getFabricId(); +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBeepAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBeepAck.java index fca3e35f..8185b91e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBeepAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBeepAck.java @@ -1,19 +1,24 @@ package at.petrak.hexcasting.common.network; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundSource; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; + +public record MsgBeepAck(Vec3 target, int note, NoteBlockInstrument instrument) implements IMessage { + public static final ResourceLocation ID = modLoc("beep"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } -/** - * Sent server->client to synchronize OpAddMotion when the target is a player. - */ -public record MsgBeepAck(Vec3 target, int note, NoteBlockInstrument instrument) { public static MsgBeepAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); var x = buf.readDouble(); @@ -24,20 +29,29 @@ public record MsgBeepAck(Vec3 target, int note, NoteBlockInstrument instrument) return new MsgBeepAck(new Vec3(x, y, z), note, instrument); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeDouble(this.target.x); buf.writeDouble(this.target.y); buf.writeDouble(this.target.z); buf.writeInt(this.note); buf.writeEnum(instrument); } - - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::beep); + + public static void handle(MsgBeepAck msg) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var minecraft = Minecraft.getInstance(); + var world = minecraft.level; + if (world != null) { + float pitch = (float) Math.pow(2, (msg.note() - 12) / 12.0); + world.playLocalSound(msg.target().x, msg.target().y, msg.target().z, + msg.instrument().getSoundEvent(), SoundSource.PLAYERS, 3, pitch, false); + world.addParticle(ParticleTypes.NOTE, msg.target().x, msg.target().y + 0.2, msg.target().z, + msg.note() / 24.0, 0, 0); + } + } }); - ctx.get().setPacketHandled(true); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBlinkAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBlinkAck.java index 74d12e9a..0fd37688 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBlinkAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBlinkAck.java @@ -1,18 +1,24 @@ package at.petrak.hexcasting.common.network; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to synchronize OpBlink when the target is a player. */ -public record MsgBlinkAck(Vec3 addedPosition) { +public record MsgBlinkAck(Vec3 addedPosition) implements IMessage { + public static final ResourceLocation ID = modLoc("blink"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } + public static MsgBlinkAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); var x = buf.readDouble(); @@ -21,18 +27,20 @@ public record MsgBlinkAck(Vec3 addedPosition) { return new MsgBlinkAck(new Vec3(x, y, z)); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeDouble(this.addedPosition.x); buf.writeDouble(this.addedPosition.y); buf.writeDouble(this.addedPosition.z); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::blink); + public static void handle(MsgBlinkAck self) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var player = Minecraft.getInstance().player; + player.setPos(player.position().add(self.addedPosition())); + } }); - ctx.get().setPacketHandled(true); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBrainsweepAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBrainsweepAck.java index f1600a6a..ed5a990f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBrainsweepAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgBrainsweepAck.java @@ -1,18 +1,26 @@ package at.petrak.hexcasting.common.network; +import at.petrak.hexcasting.common.misc.Brainsweeping; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.world.entity.LivingEntity; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to synchronize the status of a brainswept mob. */ -public record MsgBrainsweepAck(int target) { +public record MsgBrainsweepAck(int target) implements IMessage { + public static final ResourceLocation ID = modLoc("sweep"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } + public static MsgBrainsweepAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -20,8 +28,8 @@ public record MsgBrainsweepAck(int target) { return new MsgBrainsweepAck(target); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeInt(target); } @@ -29,11 +37,18 @@ public record MsgBrainsweepAck(int target) { return new MsgBrainsweepAck(target.getId()); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::brainsweep); + public static void handle(MsgBrainsweepAck msg) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var level = Minecraft.getInstance().level; + if (level != null) { + Entity entity = level.getEntity(msg.target()); + if (entity instanceof LivingEntity living) { + Brainsweeping.brainsweep(living); + } + } + } }); - ctx.get().setPacketHandled(true); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgCastParticleAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgCastParticleAck.java index b170ebaa..9e94a063 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgCastParticleAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgCastParticleAck.java @@ -2,19 +2,28 @@ package at.petrak.hexcasting.common.network; import at.petrak.hexcasting.api.misc.FrozenColorizer; import at.petrak.hexcasting.api.spell.ParticleSpray; +import at.petrak.hexcasting.common.particles.ConjureParticleOptions; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; -import java.util.function.Supplier; +import java.util.Random; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to spray particles everywhere. */ -public record MsgCastParticleAck(ParticleSpray spray, FrozenColorizer colorizer) { +public record MsgCastParticleAck(ParticleSpray spray, FrozenColorizer colorizer) implements IMessage { + public static final ResourceLocation ID = modLoc("cPrtl"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } public static MsgCastParticleAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -34,8 +43,8 @@ public record MsgCastParticleAck(ParticleSpray spray, FrozenColorizer colorizer) colorizer); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeDouble(this.spray.getPos().x); buf.writeDouble(this.spray.getPos().y); buf.writeDouble(this.spray.getPos().z); @@ -48,14 +57,51 @@ public record MsgCastParticleAck(ParticleSpray spray, FrozenColorizer colorizer) buf.writeNbt(this.colorizer.serialize()); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::particleSpray); - }); - ctx.get().setPacketHandled(true); + + private static final Random RANDOM = new Random(); + + // https://math.stackexchange.com/questions/44689/how-to-find-a-random-axis-or-unit-vector-in-3d + private static Vec3 randomInCircle(double maxTh) { + var th = RANDOM.nextDouble(0.0, maxTh + 0.001); + var z = RANDOM.nextDouble(-1.0, 1.0); + return new Vec3(Math.sqrt(1.0 - z * z) * Math.cos(th), Math.sqrt(1.0 - z * z) * Math.sin(th), z); } + public static void handle(MsgCastParticleAck msg) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + for (int i = 0; i < msg.spray().getCount(); i++) { + // For the colors, pick any random time to get a mix of colors + var color = msg.colorizer().getColor(RANDOM.nextFloat() * 256f, Vec3.ZERO); + var offset = randomInCircle(Mth.TWO_PI).normalize() + .scale(RANDOM.nextFloat() * msg.spray().getSpread() / 2); + var pos = msg.spray().getPos().add(offset); + var phi = Math.acos(1.0 - RANDOM.nextDouble() * (1.0 - Math.cos(msg.spray().getSpread()))); + var theta = Math.PI * 2.0 * RANDOM.nextDouble(); + var v = msg.spray().getVel().normalize(); + // pick any old vector to get a vector normal to v with + Vec3 k; + if (v.x == 0.0 && v.y == 0.0) { + // oops, pick a *different* normal + k = new Vec3(1.0, 0.0, 0.0); + } else { + k = v.cross(new Vec3(0.0, 0.0, 1.0)); + } + var velUnlen = v.scale(Math.cos(phi)) + .add(k.scale(Math.sin(phi) * Math.cos(theta))) + .add(v.cross(k).scale(Math.sin(phi) * Math.sin(theta))); + var vel = velUnlen.scale(msg.spray().getVel().length() / 20); + + Minecraft.getInstance().level.addParticle( + new ConjureParticleOptions(color, false), + pos.x, pos.y, pos.z, + vel.x, vel.y, vel.z + ); + } + } + }); + } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgColorizerUpdateAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgColorizerUpdateAck.java index f880f51f..43c4bd9f 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgColorizerUpdateAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgColorizerUpdateAck.java @@ -1,18 +1,25 @@ package at.petrak.hexcasting.common.network; import at.petrak.hexcasting.api.misc.FrozenColorizer; +import at.petrak.hexcasting.api.player.HexPlayerDataHelper; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.resources.ResourceLocation; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to synchronize the status of the sentinel. */ -public record MsgColorizerUpdateAck(FrozenColorizer update) { +public record MsgColorizerUpdateAck(FrozenColorizer update) implements IMessage { + public static final ResourceLocation ID = modLoc("color"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } + public static MsgColorizerUpdateAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -21,16 +28,20 @@ public record MsgColorizerUpdateAck(FrozenColorizer update) { return new MsgColorizerUpdateAck(colorizer); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeNbt(this.update.serialize()); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::updateColorizer); + public static void handle(MsgColorizerUpdateAck self) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var player = Minecraft.getInstance().player; + if (player != null) { + HexPlayerDataHelper.setColorizer(player, self.update()); + } + } }); - ctx.get().setPacketHandled(true); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternAck.java index 2cff6d38..111b283c 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternAck.java @@ -1,20 +1,28 @@ package at.petrak.hexcasting.common.network; import at.petrak.hexcasting.api.spell.casting.ControllerInfo; +import at.petrak.hexcasting.client.gui.GuiSpellcasting; +import at.petrak.hexcasting.common.lib.HexSounds; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.resources.ResourceLocation; import java.util.ArrayList; -import java.util.function.Supplier; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client when the player finishes casting a spell. */ -public record MsgNewSpellPatternAck(ControllerInfo info) { +public record MsgNewSpellPatternAck(ControllerInfo info) implements IMessage { + public static final ResourceLocation ID = modLoc("patSC"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } public static MsgNewSpellPatternAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -34,9 +42,8 @@ public record MsgNewSpellPatternAck(ControllerInfo info) { ); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeBoolean(this.info.getWasSpellCast()); buf.writeBoolean(this.info.getHasCastingSound()); buf.writeBoolean(this.info.isStackClear()); @@ -47,12 +54,24 @@ public record MsgNewSpellPatternAck(ControllerInfo info) { } } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::newPattern); + public static void handle(MsgNewSpellPatternAck self) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var mc = Minecraft.getInstance(); + if (self.info().isStackClear()) { + // don't pay attention to the screen, so it also stops when we die + mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getId(), null); + } + var screen = Minecraft.getInstance().screen; + if (screen instanceof GuiSpellcasting spellGui) { + if (self.info().isStackClear()) { + mc.setScreen(null); + } else { + spellGui.recvServerUpdate(self.info()); + } + } + } }); - ctx.get().setPacketHandled(true); } - } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java index e9419c0f..b0275600 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgNewSpellPatternSyn.java @@ -1,30 +1,41 @@ package at.petrak.hexcasting.common.network; +import at.petrak.hexcasting.api.mod.HexItemTags; import at.petrak.hexcasting.api.player.HexPlayerDataHelper; import at.petrak.hexcasting.api.spell.casting.ControllerInfo; import at.petrak.hexcasting.api.spell.casting.ResolvedPattern; import at.petrak.hexcasting.api.spell.casting.ResolvedPatternValidity; import at.petrak.hexcasting.api.spell.math.HexCoord; import at.petrak.hexcasting.api.spell.math.HexPattern; -import at.petrak.hexcasting.api.mod.HexItemTags; import at.petrak.hexcasting.common.lib.HexSounds; import io.netty.buffer.ByteBuf; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; -import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.PacketDistributor; import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent client->server when the player finishes drawing a pattern. * Server will send back a MsgNewSpellPatternAck packet */ -public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern, List resolvedPatterns) { +public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern, + List resolvedPatterns) + implements IMessage { + public static final ResourceLocation ID = modLoc("patCS"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } + public static MsgNewSpellPatternSyn deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); var hand = buf.readEnum(InteractionHand.class); @@ -38,8 +49,8 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern return new MsgNewSpellPatternSyn(hand, pattern, resolvedPatterns); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + @Override + public void serialize(FriendlyByteBuf buf) { buf.writeEnum(handUsed); buf.writeNbt(this.pattern.serializeToNBT()); buf.writeInt(this.resolvedPatterns.size()); @@ -48,58 +59,56 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern } } - public void handle(Supplier networkCtx) { - networkCtx.get().enqueueWork(() -> { - ServerPlayer sender = networkCtx.get().getSender(); - if (sender != null) { - var held = sender.getItemInHand(this.handUsed); - if (held.is(HexItemTags.WANDS)) { - boolean autoFail = false; + public void handle(MinecraftServer server, ServerPlayer sender) { + var held = sender.getItemInHand(this.handUsed); + if (held.is(HexItemTags.WANDS)) { + boolean autoFail = false; - if (!resolvedPatterns.isEmpty()) { - var allPoints = new ArrayList(); - for (int i = 0; i < resolvedPatterns.size() - 1; i++) { - ResolvedPattern pat = resolvedPatterns.get(i); - allPoints.addAll(pat.getPattern().positions(pat.getOrigin())); - } - var currentResolvedPattern = resolvedPatterns.get(resolvedPatterns.size() - 1); - var currentSpellPoints = currentResolvedPattern.getPattern().positions(currentResolvedPattern.getOrigin()); - if (currentSpellPoints.stream().anyMatch(allPoints::contains)) - autoFail = true; - } - - var harness = HexPlayerDataHelper.getHarness(sender, this.handUsed); - - ControllerInfo clientInfo; - if (autoFail) { - clientInfo = new ControllerInfo(false, false, harness.getStack().isEmpty(), true, harness.generateDescs()); - } else { - clientInfo = harness.executeNewPattern(this.pattern, sender.getLevel()); - - if (clientInfo.getWasSpellCast() && clientInfo.getHasCastingSound()) { - sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(), - HexSounds.ACTUALLY_CAST.get(), SoundSource.PLAYERS, 1f, - 1f + ((float) Math.random() - 0.5f) * 0.2f); - } - } - - if (clientInfo.isStackClear()) { - HexPlayerDataHelper.setHarness(sender, null); - HexPlayerDataHelper.setPatterns(sender, List.of()); - } else { - HexPlayerDataHelper.setHarness(sender, harness); - if (!resolvedPatterns.isEmpty()) - resolvedPatterns.get(resolvedPatterns.size() - 1).setValid(clientInfo.getWasPrevPatternInvalid() ? - ResolvedPatternValidity.ERROR : ResolvedPatternValidity.OK); - HexPlayerDataHelper.setPatterns(sender, resolvedPatterns); - } - - HexMessages.getNetwork() - .send(PacketDistributor.PLAYER.with(() -> sender), new MsgNewSpellPatternAck(clientInfo)); + if (!resolvedPatterns.isEmpty()) { + var allPoints = new ArrayList(); + for (int i = 0; i < resolvedPatterns.size() - 1; i++) { + ResolvedPattern pat = resolvedPatterns.get(i); + allPoints.addAll(pat.getPattern().positions(pat.getOrigin())); + } + var currentResolvedPattern = resolvedPatterns.get(resolvedPatterns.size() - 1); + var currentSpellPoints = currentResolvedPattern.getPattern() + .positions(currentResolvedPattern.getOrigin()); + if (currentSpellPoints.stream().anyMatch(allPoints::contains)) { + autoFail = true; } } - }); - networkCtx.get().setPacketHandled(true); + + var harness = HexPlayerDataHelper.getHarness(sender, this.handUsed); + + ControllerInfo clientInfo; + if (autoFail) { + clientInfo = new ControllerInfo(false, false, harness.getStack().isEmpty(), true, + harness.generateDescs()); + } else { + clientInfo = harness.executeNewPattern(this.pattern, sender.getLevel()); + + if (clientInfo.getWasSpellCast() && clientInfo.getHasCastingSound()) { + sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(), + HexSounds.ACTUALLY_CAST.get(), SoundSource.PLAYERS, 1f, + 1f + ((float) Math.random() - 0.5f) * 0.2f); + } + } + + if (clientInfo.isStackClear()) { + HexPlayerDataHelper.setHarness(sender, null); + HexPlayerDataHelper.setPatterns(sender, List.of()); + } else { + HexPlayerDataHelper.setHarness(sender, harness); + if (!resolvedPatterns.isEmpty()) { + resolvedPatterns.get(resolvedPatterns.size() - 1).setValid(clientInfo.getWasPrevPatternInvalid() ? + ResolvedPatternValidity.ERROR : ResolvedPatternValidity.OK); + } + HexPlayerDataHelper.setPatterns(sender, resolvedPatterns); + } + + HexMessages.getNetwork() + .send(PacketDistributor.PLAYER.with(() -> sender), new MsgNewSpellPatternAck(clientInfo)); + } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgOpenSpellGuiAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgOpenSpellGuiAck.java index ea50d27e..5a036075 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgOpenSpellGuiAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgOpenSpellGuiAck.java @@ -1,22 +1,30 @@ package at.petrak.hexcasting.common.network; import at.petrak.hexcasting.api.spell.casting.ResolvedPattern; +import at.petrak.hexcasting.client.gui.GuiSpellcasting; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionHand; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; + +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client when the player opens the spell gui to request the server provide the current stack. */ -public record MsgOpenSpellGuiAck(InteractionHand hand, List patterns, List components) { +public record MsgOpenSpellGuiAck(InteractionHand hand, List patterns, List components) + implements IMessage { + public static final ResourceLocation ID = modLoc("cGui"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } public static MsgOpenSpellGuiAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -38,9 +46,7 @@ public record MsgOpenSpellGuiAck(InteractionHand hand, List pat return new MsgOpenSpellGuiAck(hand, patterns, desc); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - + public void serialize(FriendlyByteBuf buf) { buf.writeEnum(this.hand); buf.writeInt(this.patterns.size()); @@ -54,12 +60,13 @@ public record MsgOpenSpellGuiAck(InteractionHand hand, List pat } } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::openSpellGui); + public static void handle(MsgOpenSpellGuiAck msg) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var mc = Minecraft.getInstance(); + mc.setScreen(new GuiSpellcasting(msg.hand(), msg.patterns(), msg.components())); + } }); - ctx.get().setPacketHandled(true); } - } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgSentinelStatusUpdateAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgSentinelStatusUpdateAck.java index 8201d570..81cf11a8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgSentinelStatusUpdateAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgSentinelStatusUpdateAck.java @@ -1,21 +1,28 @@ package at.petrak.hexcasting.common.network; +import at.petrak.hexcasting.api.player.HexPlayerDataHelper; import at.petrak.hexcasting.api.player.Sentinel; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client to synchronize the status of the sentinel. */ -public record MsgSentinelStatusUpdateAck(Sentinel update) { +public record MsgSentinelStatusUpdateAck(Sentinel update) implements IMessage { + public static final ResourceLocation ID = modLoc("sntnl"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } + public static MsgSentinelStatusUpdateAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -28,8 +35,7 @@ public record MsgSentinelStatusUpdateAck(Sentinel update) { return new MsgSentinelStatusUpdateAck(sentinel); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + public void serialize(FriendlyByteBuf buf) { buf.writeBoolean(update.hasSentinel()); buf.writeBoolean(update.extendsRange()); buf.writeDouble(update.position().x); @@ -38,11 +44,15 @@ public record MsgSentinelStatusUpdateAck(Sentinel update) { buf.writeResourceLocation(update.dimension().location()); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::updateSentinel); + public static void handle(MsgSentinelStatusUpdateAck self) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + var player = Minecraft.getInstance().player; + if (player != null) { + HexPlayerDataHelper.setSentinel(player, self.update()); + } + } }); - ctx.get().setPacketHandled(true); } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java index 75715071..129a9c6e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgShiftScrollSyn.java @@ -11,19 +11,27 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.network.NetworkEvent; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent client->server when the client shift+scrolls with a shift-scrollable item * or scrolls in the spellcasting UI. */ -public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolean isCtrl) { +public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolean isCtrl) implements IMessage { + public static final ResourceLocation ID = modLoc("scroll"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } + public static MsgShiftScrollSyn deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); var hand = buf.readEnum(InteractionHand.class); @@ -32,27 +40,20 @@ public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolea return new MsgShiftScrollSyn(hand, scrollDelta, isCtrl); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); + public void serialize(FriendlyByteBuf buf) { buf.writeEnum(this.hand); buf.writeDouble(this.scrollDelta); buf.writeBoolean(this.isCtrl); } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ServerPlayer sender = ctx.get().getSender(); - if (sender != null) { - var stack = sender.getItemInHand(hand); + public void handle(MinecraftServer server, ServerPlayer sender) { + var stack = sender.getItemInHand(hand); - if (stack.getItem() == HexItems.SPELLBOOK.get()) { - spellbook(sender, stack); - } else if (stack.getItem() == HexItems.ABACUS.get()) { - abacus(sender, stack); - } - } - }); - ctx.get().setPacketHandled(true); + if (stack.getItem() == HexItems.SPELLBOOK.get()) { + spellbook(sender, stack); + } else if (stack.getItem() == HexItems.ABACUS.get()) { + abacus(sender, stack); + } } private void spellbook(ServerPlayer sender, ItemStack stack) { @@ -66,28 +67,32 @@ public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolea MutableComponent component; if (hand == InteractionHand.OFF_HAND && stack.hasCustomHoverName()) { - if (sealed) + if (sealed) { component = new TranslatableComponent("hexcasting.tooltip.spellbook.page_with_name.sealed", - new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), - new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE), - new TextComponent("").withStyle(stack.getRarity().color, ChatFormatting.ITALIC).append(stack.getHoverName()), + new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), + new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE), + new TextComponent("").withStyle(stack.getRarity().color, ChatFormatting.ITALIC) + .append(stack.getHoverName()), new TranslatableComponent("hexcasting.tooltip.spellbook.sealed").withStyle(ChatFormatting.GOLD)); - else + } else { component = new TranslatableComponent("hexcasting.tooltip.spellbook.page_with_name", new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE), - new TextComponent("").withStyle(stack.getRarity().color, ChatFormatting.ITALIC).append(stack.getHoverName())); + new TextComponent("").withStyle(stack.getRarity().color, ChatFormatting.ITALIC) + .append(stack.getHoverName())); + } } else { - if (sealed) + if (sealed) { component = new TranslatableComponent("hexcasting.tooltip.spellbook.page.sealed", new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE), new TranslatableComponent("hexcasting.tooltip.spellbook.sealed").withStyle(ChatFormatting.GOLD)); - else + } else { component = new TranslatableComponent("hexcasting.tooltip.spellbook.page", new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE), new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE)); + } } sender.displayClientMessage(component.withStyle(ChatFormatting.GRAY), true); @@ -122,7 +127,8 @@ public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolea var datumTag = HexItems.ABACUS.get().readDatumTag(stack); if (datumTag != null) { var popup = SpellDatum.DisplayFromTag(datumTag); - sender.displayClientMessage(new TranslatableComponent("hexcasting.tooltip.abacus", popup).withStyle(ChatFormatting.GREEN), true); + sender.displayClientMessage( + new TranslatableComponent("hexcasting.tooltip.abacus", popup).withStyle(ChatFormatting.GREEN), true); } } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgUpdateComparatorVisualsAck.java b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgUpdateComparatorVisualsAck.java index c0d58c0b..2d534b50 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/network/MsgUpdateComparatorVisualsAck.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/network/MsgUpdateComparatorVisualsAck.java @@ -1,18 +1,24 @@ package at.petrak.hexcasting.common.network; +import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry; import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkEvent; +import net.minecraft.resources.ResourceLocation; -import java.util.function.Supplier; +import static at.petrak.hexcasting.api.HexAPI.modLoc; /** * Sent server->client when a player is looking at a block through a lens whose comparator value is not the same as what they last saw. */ -public record MsgUpdateComparatorVisualsAck(BlockPos pos, int value) { +public record MsgUpdateComparatorVisualsAck(BlockPos pos, int value) implements IMessage { + public static final ResourceLocation ID = modLoc("cmp"); + + @Override + public ResourceLocation getFabricId() { + return ID; + } public static MsgUpdateComparatorVisualsAck deserialize(ByteBuf buffer) { var buf = new FriendlyByteBuf(buffer); @@ -23,21 +29,20 @@ public record MsgUpdateComparatorVisualsAck(BlockPos pos, int value) { return new MsgUpdateComparatorVisualsAck(pos, value); } - public void serialize(ByteBuf buffer) { - var buf = new FriendlyByteBuf(buffer); - + public void serialize(FriendlyByteBuf buf) { buf.writeInt(this.value); if (this.value != -1) { buf.writeBlockPos(this.pos); } } - public void handle(Supplier ctx) { - ctx.get().enqueueWork(() -> { - ClientPacketHandler handler = new ClientPacketHandler(this); - DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> handler::updateComparator); + public static void handle(MsgUpdateComparatorVisualsAck msg) { + Minecraft.getInstance().execute(new Runnable() { + @Override + public void run() { + ScryingLensOverlayRegistry.receiveComparatorValue(msg.pos(), msg.value()); + } }); - ctx.get().setPacketHandled(true); } } 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 38595500..976fe8ad 100644 --- a/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java +++ b/Common/src/main/java/at/petrak/hexcasting/xplat/IXplatAbstractions.java @@ -2,8 +2,11 @@ package at.petrak.hexcasting.xplat; import at.petrak.hexcasting.api.HexAPI; import at.petrak.hexcasting.common.command.PatternResLocArgument; +import at.petrak.hexcasting.common.network.IMessage; import net.minecraft.commands.synchronization.ArgumentTypes; import net.minecraft.commands.synchronization.EmptyArgumentSerializer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.LivingEntity; import java.util.ServiceLoader; import java.util.stream.Collectors; @@ -13,6 +16,14 @@ public interface IXplatAbstractions { boolean isPhysicalClient(); + void brainsweep(LivingEntity e); + + boolean isBrainswept(LivingEntity e); + + void sendPacketToPlayer(ServerPlayer target, IMessage packet); + + void sendPacketToServer(IMessage packet); + default void init() { HexAPI.LOGGER.info("Hello Hexcasting! This is {}!", this.platform()); diff --git a/Fabric/src/main/java/at/petrak/hexcasting/fabric/network/FabricPacketHandler.java b/Fabric/src/main/java/at/petrak/hexcasting/fabric/network/FabricPacketHandler.java new file mode 100644 index 00000000..bdd67151 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/network/FabricPacketHandler.java @@ -0,0 +1,4 @@ +package at.petrak.hexcasting.fabric.network; + +public class FabricPacketHandler { +} 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 new file mode 100644 index 00000000..58c427d6 --- /dev/null +++ b/Fabric/src/main/java/at/petrak/hexcasting/fabric/xplat/FabricListenersSetup.java @@ -0,0 +1,10 @@ +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/Forge/src/main/java/at/petrak/hexcasting/HexMod.kt b/Forge/src/main/java/at/petrak/hexcasting/HexMod.kt index 0d5cd005..7972f633 100644 --- a/Forge/src/main/java/at/petrak/hexcasting/HexMod.kt +++ b/Forge/src/main/java/at/petrak/hexcasting/HexMod.kt @@ -4,33 +4,12 @@ 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.api.mod.HexStatistics -import at.petrak.hexcasting.api.player.HexPlayerDataHelper -import at.petrak.hexcasting.client.* -import at.petrak.hexcasting.common.blocks.HexBlockEntities -import at.petrak.hexcasting.common.blocks.HexBlocks -import at.petrak.hexcasting.common.casting.RegisterPatterns -import at.petrak.hexcasting.common.casting.operators.spells.great.OpFlight -import at.petrak.hexcasting.common.command.HexCommands -import at.petrak.hexcasting.common.entities.HexEntities -import at.petrak.hexcasting.common.items.HexItems -import at.petrak.hexcasting.common.lib.HexCapabilityHandler -import at.petrak.hexcasting.common.lib.HexSounds -import at.petrak.hexcasting.common.misc.Brainsweeping -import at.petrak.hexcasting.common.network.HexMessages -import at.petrak.hexcasting.common.particles.HexParticles -import at.petrak.hexcasting.common.recipe.HexComposting -import at.petrak.hexcasting.common.recipe.HexCustomRecipes -import at.petrak.hexcasting.common.recipe.HexRecipeSerializers -import at.petrak.hexcasting.datagen.HexDataGenerators -import at.petrak.hexcasting.datagen.lootmods.HexLootModifiers import at.petrak.hexcasting.forge.ForgeHexConfig -import at.petrak.hexcasting.server.TickScheduler +import at.petrak.hexcasting.forge.network.ForgePacketHandler +import at.petrak.hexcasting.forge.xplat.ForgeListenersSetup import at.petrak.hexcasting.xplat.IXplatAbstractions -import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.common.ForgeConfigSpec import net.minecraftforge.eventbus.api.SubscribeEvent -import net.minecraftforge.fml.DistExecutor import net.minecraftforge.fml.ModLoadingContext import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.config.ModConfig @@ -56,6 +35,15 @@ object HexMod { HexConfig.setCommon(config.left) HexConfig.setClient(clientConfig.left) HexConfig.setServer(serverConfig.left) + ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, config.right) + ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, serverConfig.right) + ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, clientConfig.right) + + + ForgeListenersSetup.init() + ForgePacketHandler.init() + + /* // mod lifecycle val modBus = thedarkcolour.kotlinforforge.forge.MOD_BUS @@ -98,12 +86,7 @@ object HexMod { } } - // and then things that don't require busses - HexMessages.register() - - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, config.right) - ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, serverConfig.right) - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, clientConfig.right) + */ } @SubscribeEvent diff --git a/Forge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java b/Forge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java new file mode 100644 index 00000000..0ee5cb4b --- /dev/null +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/network/ForgePacketHandler.java @@ -0,0 +1,76 @@ +package at.petrak.hexcasting.forge.network; + +import at.petrak.hexcasting.HexMod; +import at.petrak.hexcasting.common.network.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.network.NetworkRegistry; +import net.minecraftforge.network.simple.SimpleChannel; +import org.apache.logging.log4j.util.TriConsumer; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class ForgePacketHandler { + private static final String PROTOCOL_VERSION = "1"; + private static final SimpleChannel NETWORK = NetworkRegistry.newSimpleChannel( + new ResourceLocation(HexMod.MOD_ID, "main"), + () -> PROTOCOL_VERSION, + PROTOCOL_VERSION::equals, + PROTOCOL_VERSION::equals + ); + + public static SimpleChannel getNetwork() { + return NETWORK; + } + + public static void init() { + int messageIdx = 0; + + // Client -> server + NETWORK.registerMessage(messageIdx++, MsgNewSpellPatternSyn.class, MsgNewSpellPatternSyn::serialize, + MsgNewSpellPatternSyn::deserialize, makeServerBoundHandler(MsgNewSpellPatternSyn::handle)); + NETWORK.registerMessage(messageIdx++, MsgShiftScrollSyn.class, MsgShiftScrollSyn::serialize, + MsgShiftScrollSyn::deserialize, makeServerBoundHandler(MsgShiftScrollSyn::handle)); + + // Server -> client + NETWORK.registerMessage(messageIdx++, MsgNewSpellPatternAck.class, MsgNewSpellPatternAck::serialize, + MsgNewSpellPatternAck::deserialize, makeClientBoundHandler(MsgNewSpellPatternAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgBlinkAck.class, MsgBlinkAck::serialize, + MsgBlinkAck::deserialize, makeClientBoundHandler(MsgBlinkAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgSentinelStatusUpdateAck.class, MsgSentinelStatusUpdateAck::serialize, + MsgSentinelStatusUpdateAck::deserialize, makeClientBoundHandler(MsgSentinelStatusUpdateAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgColorizerUpdateAck.class, MsgColorizerUpdateAck::serialize, + MsgColorizerUpdateAck::deserialize, makeClientBoundHandler(MsgColorizerUpdateAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgCastParticleAck.class, MsgCastParticleAck::serialize, + MsgCastParticleAck::deserialize, makeClientBoundHandler(MsgCastParticleAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgOpenSpellGuiAck.class, MsgOpenSpellGuiAck::serialize, + MsgOpenSpellGuiAck::deserialize, makeClientBoundHandler(MsgOpenSpellGuiAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgBeepAck.class, MsgBeepAck::serialize, + MsgBeepAck::deserialize, makeClientBoundHandler(MsgBeepAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgBrainsweepAck.class, MsgBrainsweepAck::serialize, + MsgBrainsweepAck::deserialize, makeClientBoundHandler(MsgBrainsweepAck::handle)); + NETWORK.registerMessage(messageIdx++, MsgUpdateComparatorVisualsAck.class, + MsgUpdateComparatorVisualsAck::serialize, + MsgUpdateComparatorVisualsAck::deserialize, + makeClientBoundHandler(MsgUpdateComparatorVisualsAck::handle)); + } + + private static BiConsumer> makeServerBoundHandler( + TriConsumer handler) { + return (m, ctx) -> { + handler.accept(m, ctx.get().getSender().getServer(), ctx.get().getSender()); + ctx.get().setPacketHandled(true); + }; + } + + private static BiConsumer> makeClientBoundHandler(Consumer consumer) { + return (m, ctx) -> { + consumer.accept(m); + ctx.get().setPacketHandled(true); + }; + } +} 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 new file mode 100644 index 00000000..2588fd96 --- /dev/null +++ b/Forge/src/main/java/at/petrak/hexcasting/forge/xplat/ForgeListenersSetup.java @@ -0,0 +1,20 @@ +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 11e52f9a..b019add6 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,9 +1,22 @@ package at.petrak.hexcasting.forge.xplat; +import at.petrak.hexcasting.common.lib.HexStringKeys; +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.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +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.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.network.PacketDistributor; public class ForgeXplatImpl implements IXplatAbstractions { @Override @@ -15,4 +28,43 @@ public class ForgeXplatImpl implements IXplatAbstractions { public boolean isPhysicalClient() { return FMLLoader.getDist() == Dist.CLIENT; } + + @Override + public void brainsweep(LivingEntity entity) { + if (entity instanceof VillagerDataHolder) { + entity.getPersistentData().putBoolean(HexStringKeys.BRAINSWEPT, true); + + if (entity instanceof Mob mob) { + mob.removeFreeWill(); + } + + if (entity instanceof Villager villager) { + Brain brain = villager.getBrain(); + if (entity.level instanceof ServerLevel slevel) { + brain.stopAll(slevel, villager); + } + ((AccessorLivingEntity) entity).hex$SetBrain(brain.copyWithoutBehaviors()); + } + + if (entity.level instanceof ServerLevel) { + ForgePacketHandler.getNetwork() + .send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), MsgBrainsweepAck.of(entity)); + } + } + } + + @Override + public boolean isBrainswept(LivingEntity e) { + return e instanceof VillagerDataHolder && e.getPersistentData().getBoolean(HexStringKeys.BRAINSWEPT); + } + + @Override + public void sendPacketToPlayer(ServerPlayer target, IMessage packet) { + ForgePacketHandler.getNetwork().send(PacketDistributor.PLAYER.with(() -> target), packet); + } + + @Override + public void sendPacketToServer(IMessage packet) { + ForgePacketHandler.getNetwork().sendToServer(packet); + } } \ No newline at end of file