From b8ddfd38af82f1fdd217e2d48636ddce1f302844 Mon Sep 17 00:00:00 2001 From: JR1811 Date: Mon, 7 Oct 2024 07:38:45 +0200 Subject: [PATCH] mixin refactor, keybindings refactor and added CameraPullEntity networking --- .../fabricatedatelier/mayor/MayorClient.java | 4 +- .../mayor/entity/custom/CameraPullEntity.java | 67 +++++++-- .../mayor/init/MayorClientEvents.java | 41 +++--- .../mayor/init/MayorCommonEvents.java | 88 ++++++------ .../mayor/init/MayorKeyBind.java | 65 +++++++++ .../mayor/init/MayorKeyBindings.java | 45 ------ .../mayor/init/MayorNetworkPayloads.java | 1 + .../mayor/init/MayorRenderers.java | 1 - .../mayor/mixin/CarvedPumpkinBlockMixin.java | 12 +- .../mayor/mixin/DecoratedPotBlockMixin.java | 70 ++++++---- .../mayor/mixin/PlayerEntityMixin.java | 2 + .../mayor/mixin/RaidMixin.java | 78 ++++++----- .../mayor/mixin/StructureStartMixin.java | 129 +++++++++++------- .../mayor/mixin/VillagerEntityMixin.java | 20 ++- .../mayor/mixin/client/KeyBindingMixin.java | 15 +- .../mixin/client/MinecraftClientMixin.java | 6 +- .../mayor/network/CustomC2SNetworking.java | 1 + .../packet/CameraPullMovementPacket.java | 44 ++++++ .../mayor/screen/MayorScreen.java | 5 +- .../mayor/screen/MayorVillageScreen.java | 4 +- .../mayor/screen/VillageScreen.java | 4 +- .../mayor/util/KeyHelper.java | 37 +++-- .../fabricatedatelier/mayor/util/NbtKeys.java | 1 + 23 files changed, 460 insertions(+), 280 deletions(-) create mode 100644 src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBind.java delete mode 100644 src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBindings.java create mode 100644 src/main/java/io/fabricatedatelier/mayor/network/packet/CameraPullMovementPacket.java diff --git a/src/main/java/io/fabricatedatelier/mayor/MayorClient.java b/src/main/java/io/fabricatedatelier/mayor/MayorClient.java index 6a1537d..9e719f9 100644 --- a/src/main/java/io/fabricatedatelier/mayor/MayorClient.java +++ b/src/main/java/io/fabricatedatelier/mayor/MayorClient.java @@ -3,7 +3,7 @@ import io.fabricatedatelier.mayor.entity.custom.client.CameraPullEntityRenderer; import io.fabricatedatelier.mayor.init.MayorClientEvents; import io.fabricatedatelier.mayor.init.MayorEntities; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.init.MayorRenderers; import io.fabricatedatelier.mayor.network.CustomS2CNetworking; import net.fabricmc.api.ClientModInitializer; @@ -17,7 +17,7 @@ public class MayorClient implements ClientModInitializer { @Override public void onInitializeClient() { CustomS2CNetworking.initialize(); - MayorKeyBindings.initialize(); + MayorKeyBind.initialize(); MayorClientEvents.initialize(); MayorRenderers.initialize(); diff --git a/src/main/java/io/fabricatedatelier/mayor/entity/custom/CameraPullEntity.java b/src/main/java/io/fabricatedatelier/mayor/entity/custom/CameraPullEntity.java index 22f7b5c..5f8f08a 100644 --- a/src/main/java/io/fabricatedatelier/mayor/entity/custom/CameraPullEntity.java +++ b/src/main/java/io/fabricatedatelier/mayor/entity/custom/CameraPullEntity.java @@ -2,12 +2,8 @@ import io.fabricatedatelier.mayor.camera.CameraHandler; import io.fabricatedatelier.mayor.camera.mode.FreeFlyMode; -import io.fabricatedatelier.mayor.camera.util.CameraMode; import io.fabricatedatelier.mayor.camera.util.CameraTarget; -import io.fabricatedatelier.mayor.init.MayorEntities; import io.fabricatedatelier.mayor.util.NbtKeys; -import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup; -import net.fabricmc.fabric.api.networking.v1.PlayerLookup; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.data.DataTracker; @@ -20,13 +16,15 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.minecraft.world.entity.EntityLookup; import org.jetbrains.annotations.Nullable; import java.util.Optional; import java.util.UUID; public class CameraPullEntity extends Entity implements CameraTarget { + @Nullable + private DirectionInput movementInput = null; + private int tick = 0; private static final TrackedData> USER = DataTracker.registerData(CameraPullEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID); public CameraPullEntity(EntityType type, World world) { @@ -41,6 +39,14 @@ public void setUser(@Nullable UUID user) { this.dataTracker.set(USER, Optional.ofNullable(user)); } + public Optional getMovementInput() { + return Optional.ofNullable(movementInput); + } + + public void setMovementInput(@Nullable DirectionInput movementInput) { + this.movementInput = movementInput; + } + @Override protected void initDataTracker(DataTracker.Builder builder) { builder.add(USER, Optional.empty()); @@ -60,28 +66,59 @@ public ActionResult interact(PlayerEntity player, Hand hand) { return ActionResult.SUCCESS; } + @Override + public void tick() { + super.tick(); + tick++; + if (tick % 20 != 0) return; + double speed = 1.5; + Vec3d input = getMovementInput().map(DirectionInput::getDirection).orElse(new Vec3d(0, 0, 0)); + this.addVelocity(input.multiply(speed)); + } + @Override protected void readCustomDataFromNbt(NbtCompound nbt) { - if (nbt.contains(NbtKeys.USER_UUID)) { - setUser(nbt.getUuid(NbtKeys.USER_UUID)); - } else { - setUser(null); - } + if (nbt.contains(NbtKeys.USER_UUID)) setUser(nbt.getUuid(NbtKeys.USER_UUID)); + else setUser(null); + + if (nbt.contains(NbtKeys.DIRECTION_INPUT)) + setMovementInput(DirectionInput.valueOf(nbt.getString(NbtKeys.DIRECTION_INPUT))); + else setMovementInput(null); } @Override protected void writeCustomDataToNbt(NbtCompound nbt) { - getUser().ifPresentOrElse(userUUID -> { - nbt.putUuid(NbtKeys.USER_UUID, userUUID); - }, () -> nbt.remove(NbtKeys.USER_UUID)); + getUser().ifPresentOrElse(userUUID -> nbt.putUuid(NbtKeys.USER_UUID, userUUID), () -> nbt.remove(NbtKeys.USER_UUID)); + getMovementInput().ifPresentOrElse(directionInput -> nbt.putString(NbtKeys.DIRECTION_INPUT, directionInput.name()), () -> nbt.remove(NbtKeys.DIRECTION_INPUT)); } - public Optional getUserPlayer() { - return getUser().flatMap(uuid -> Optional.ofNullable(this.getWorld().getPlayerByUuid(uuid))); + public static boolean hasCorrectUUID(Entity entity, ServerPlayerEntity player) { + if (!(entity instanceof CameraPullEntity cameraPullEntity)) return false; + if (cameraPullEntity.getUser().isEmpty()) return false; + return cameraPullEntity.getUser().get().equals(player.getUuid()); } @Override public Vec3d mayor$getTargetPosition() { return this.getPos(); } + + public enum DirectionInput { + FORWARD(new Vec3d(0, 0, 1)), + BACKWARD(new Vec3d(0, 0, -1)), + LEFT(new Vec3d(1, 0, 0)), + RIGHT(new Vec3d(-1, 0, 0)), + UP(new Vec3d(0, 1, 0)), + DOWN(new Vec3d(0, -1, 0)); + + private final Vec3d direction; + + DirectionInput(Vec3d direction) { + this.direction = direction; + } + + public Vec3d getDirection() { + return direction; + } + } } diff --git a/src/main/java/io/fabricatedatelier/mayor/init/MayorClientEvents.java b/src/main/java/io/fabricatedatelier/mayor/init/MayorClientEvents.java index f0a4ee1..33c9d71 100644 --- a/src/main/java/io/fabricatedatelier/mayor/init/MayorClientEvents.java +++ b/src/main/java/io/fabricatedatelier/mayor/init/MayorClientEvents.java @@ -8,28 +8,35 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.render.RenderTickCounter; @Environment(EnvType.CLIENT) public class MayorClientEvents { - public static void initialize() { - ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> { - if (!client.isInSingleplayer()) { - MayorManager.mayorStructureMap.clear(); - } - }); + ClientPlayConnectionEvents.JOIN.register(MayorClientEvents::handleClientConnection); WorldRenderEvents.AFTER_ENTITIES.register(RenderUtil::renderVillageStructure); - HudRenderCallback.EVENT.register((drawContext, tickCounter) -> { - RenderUtil.renderMayorHud(drawContext); - CameraHandler camera = CameraHandler.getInstance(); - if (camera.getTarget().isEmpty()) return; - if (camera.getStartTransition().isRunning()) { - camera.getStartTransition().renderOverlay(drawContext); - } - if (camera.getEndTransition().isRunning()) { - camera.getEndTransition().renderOverlay(drawContext); - } - }); + HudRenderCallback.EVENT.register(MayorClientEvents::handleHudRendering); + } + + private static void handleClientConnection(ClientPlayNetworkHandler handler, PacketSender sender, MinecraftClient client) { + if (!client.isInSingleplayer()) { + MayorManager.mayorStructureMap.clear(); + } } + private static void handleHudRendering(DrawContext drawContext, RenderTickCounter tickCounter) { + RenderUtil.renderMayorHud(drawContext); + CameraHandler camera = CameraHandler.getInstance(); + if (camera.getTarget().isEmpty()) return; + if (camera.getStartTransition().isRunning()) { + camera.getStartTransition().renderOverlay(drawContext); + } + if (camera.getEndTransition().isRunning()) { + camera.getEndTransition().renderOverlay(drawContext); + } + } } diff --git a/src/main/java/io/fabricatedatelier/mayor/init/MayorCommonEvents.java b/src/main/java/io/fabricatedatelier/mayor/init/MayorCommonEvents.java index c35273c..d5b68f5 100644 --- a/src/main/java/io/fabricatedatelier/mayor/init/MayorCommonEvents.java +++ b/src/main/java/io/fabricatedatelier/mayor/init/MayorCommonEvents.java @@ -10,8 +10,11 @@ import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.minecraft.block.BlockState; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.passive.IronGolemEntity; import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.BlockRotation; import net.minecraft.util.Identifier; @@ -24,57 +27,58 @@ import java.util.Map; public class MayorCommonEvents { - public static void initialize() { - ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> { - if (entity instanceof IronGolemEntity) { - BlockPos villageCenterPos = MayorStateHelper.getVillageCenterPos((ServerWorld) entity.getWorld(), entity.getBlockPos()); - if (villageCenterPos != null) { - MayorStateHelper.updateVillageUuids((ServerWorld) entity.getWorld(), villageCenterPos, entity); - } - } - }); + ServerLivingEntityEvents.AFTER_DEATH.register(MayorCommonEvents::handleAfterDeath); + ServerLifecycleEvents.SERVER_STARTED.register(MayorCommonEvents::handleServerStarted); + } - ServerLifecycleEvents.SERVER_STARTED.register((server) -> { - MayorManager.mayorStructureMap.clear(); + private static void handleAfterDeath(LivingEntity entity, DamageSource damageSource) { + if (entity instanceof IronGolemEntity) { + BlockPos villageCenterPos = MayorStateHelper.getVillageCenterPos((ServerWorld) entity.getWorld(), entity.getBlockPos()); + if (villageCenterPos != null) { + MayorStateHelper.updateVillageUuids((ServerWorld) entity.getWorld(), villageCenterPos, entity); + } + } + } - Iterator iterator = server.getStructureTemplateManager().streamTemplates().iterator(); - while (iterator.hasNext()) { - Identifier identifier = iterator.next(); + private static void handleServerStarted(MinecraftServer server) { + MayorManager.mayorStructureMap.clear(); - if (StringUtil.shouldStoreStructureIdentifier(identifier)) { + Iterator iterator = server.getStructureTemplateManager().streamTemplates().iterator(); + while (iterator.hasNext()) { + Identifier identifier = iterator.next(); - Identifier mayorStructureIdentifier = StringUtil.getMayorStructureIdentifier(identifier); - int level = StringUtil.getStructureLevelByIdentifier(identifier); - List requiredItemStacks = StructureHelper.getStructureItemRequirements(server.getOverworld(), identifier); + if (StringUtil.shouldStoreStructureIdentifier(identifier)) { - int experience = 0; - int price = 0; - if (StructureDataLoader.structureDataMap.containsKey(StringUtil.getMayorStructureString(identifier))) { - experience = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(identifier)).get(0); - price = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(identifier)).get(1); - } else { - experience = StructureHelper.getStructureExperience(requiredItemStacks); - price = 8; - StructureDataLoader.structureDataMap.put(StringUtil.getMayorStructureString(identifier), List.of(experience, price)); - } - Map blockMap = StructureHelper.getBlockPosBlockStateMap(server.getOverworld(), identifier, BlockRotation.NONE, false); - MayorCategory.BiomeCategory biomeCategory = StructureHelper.getBiomeCategory(identifier); - MayorCategory.BuildingCategory buildingCategory = StructureHelper.getBuildingCategory(identifier); - Vec3i size = StructureHelper.getStructureSize(server.getOverworld(), identifier); + Identifier mayorStructureIdentifier = StringUtil.getMayorStructureIdentifier(identifier); + int level = StringUtil.getStructureLevelByIdentifier(identifier); + List requiredItemStacks = StructureHelper.getStructureItemRequirements(server.getOverworld(), identifier); - MayorStructure mayorStructure = new MayorStructure(mayorStructureIdentifier, level, experience, price, biomeCategory, buildingCategory, requiredItemStacks, blockMap, size); - if (MayorManager.mayorStructureMap.containsKey(biomeCategory)) { - MayorManager.mayorStructureMap.get(biomeCategory).add(mayorStructure); - } else { - List list = new ArrayList<>(); - list.add(mayorStructure); - MayorManager.mayorStructureMap.put(biomeCategory, list); - } + int experience; + int price; + if (StructureDataLoader.structureDataMap.containsKey(StringUtil.getMayorStructureString(identifier))) { + experience = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(identifier)).get(0); + price = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(identifier)).get(1); + } else { + experience = StructureHelper.getStructureExperience(requiredItemStacks); + price = 8; + StructureDataLoader.structureDataMap.put(StringUtil.getMayorStructureString(identifier), List.of(experience, price)); + } + Map blockMap = StructureHelper.getBlockPosBlockStateMap(server.getOverworld(), identifier, BlockRotation.NONE, false); + MayorCategory.BiomeCategory biomeCategory = StructureHelper.getBiomeCategory(identifier); + MayorCategory.BuildingCategory buildingCategory = StructureHelper.getBuildingCategory(identifier); + Vec3i size = StructureHelper.getStructureSize(server.getOverworld(), identifier); + MayorStructure mayorStructure = new MayorStructure(mayorStructureIdentifier, level, experience, price, biomeCategory, buildingCategory, requiredItemStacks, blockMap, size); + if (MayorManager.mayorStructureMap.containsKey(biomeCategory)) { + MayorManager.mayorStructureMap.get(biomeCategory).add(mayorStructure); + } else { + List list = new ArrayList<>(); + list.add(mayorStructure); + MayorManager.mayorStructureMap.put(biomeCategory, list); } + } - }); + } } - } diff --git a/src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBind.java b/src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBind.java new file mode 100644 index 0000000..bb4a59d --- /dev/null +++ b/src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBind.java @@ -0,0 +1,65 @@ +package io.fabricatedatelier.mayor.init; + +import io.fabricatedatelier.mayor.util.KeyHelper; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.minecraft.client.option.KeyBinding; +import org.lwjgl.glfw.GLFW; + +@Environment(EnvType.CLIENT) +public enum MayorKeyBind { + MAYOR_VIEW("mayor_view", GLFW.GLFW_KEY_Y, MayorKeyBindCategory.MAIN), + MAYOR_VIEW_SELECTION("mayor_view_selection", GLFW.GLFW_KEY_U, MayorKeyBindCategory.MAIN), + ROTATE_LEFT("structure_rotate_left", GLFW.GLFW_KEY_Q, MayorKeyBindCategory.MAIN), + ROTATE_RIGHT("structure_rotate_right", GLFW.GLFW_KEY_E, MayorKeyBindCategory.MAIN), + TARGET_TO_CENTER("structure_center", GLFW.GLFW_KEY_R, MayorKeyBindCategory.MAIN), + UPWARD("structure_upward", GLFW.GLFW_KEY_PAGE_UP, MayorKeyBindCategory.MAIN), + DOWNWARD("structure_downward", GLFW.GLFW_KEY_PAGE_DOWN, MayorKeyBindCategory.MAIN), + FREE_FLY_CAMERA_MODE("free_fly_camera_mode", GLFW.GLFW_KEY_SPACE, MayorKeyBindCategory.MAIN); + + private final String name; + + private final KeyBinding keyBinding; + + MayorKeyBind(String name, int key, MayorKeyBindCategory category) { + this.name = name; + this.keyBinding = register(name, key, category.getTranslation()); + } + + public String getTranslation() { + return "key.mayor." + this.name; + } + + public KeyBinding register(String name, int key, String category) { + return KeyBindingHelper.registerKeyBinding(new KeyBinding("key.mayor." + name, key, category)); + } + + public static void initialize() { + ClientTickEvents.END_CLIENT_TICK.register((client) -> { + KeyHelper.viewKey(client); + KeyHelper.centerKey(client); + KeyHelper.heightKey(client); + }); + ClientTickEvents.START_CLIENT_TICK.register(KeyHelper::useKey); + } + + public KeyBinding get() { + return keyBinding; + } + + private enum MayorKeyBindCategory { + MAIN("key.categories.mayor"); + + private final String translation; + + MayorKeyBindCategory(String translation) { + this.translation = translation; + } + + public String getTranslation() { + return translation; + } + } +} diff --git a/src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBindings.java b/src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBindings.java deleted file mode 100644 index 8e517a1..0000000 --- a/src/main/java/io/fabricatedatelier/mayor/init/MayorKeyBindings.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.fabricatedatelier.mayor.init; - -import io.fabricatedatelier.mayor.util.KeyHelper; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import org.lwjgl.glfw.GLFW; - -@Environment(EnvType.CLIENT) -public class MayorKeyBindings { - - private static final String MAYOR_CATEGORY = "key.categories.mayor"; - - public static final KeyBinding mayorView = new KeyBinding("key.mayor.mayor_view", GLFW.GLFW_KEY_Y, MAYOR_CATEGORY); - public static final KeyBinding mayorViewSelection = new KeyBinding("key.mayor.mayor_view_selection", GLFW.GLFW_KEY_U, MAYOR_CATEGORY); - - public static final KeyBinding rotateLeft = new KeyBinding("key.mayor.structure_rotate_left", GLFW.GLFW_KEY_Q, MAYOR_CATEGORY); - public static final KeyBinding rotateRight = new KeyBinding("key.mayor.structure_rotate_right", GLFW.GLFW_KEY_E, MAYOR_CATEGORY); - public static final KeyBinding targetToCenter = new KeyBinding("key.mayor.structure_center", GLFW.GLFW_KEY_R, MAYOR_CATEGORY); - public static final KeyBinding upward = new KeyBinding("key.mayor.structure_upward", GLFW.GLFW_KEY_PAGE_UP, MAYOR_CATEGORY); - public static final KeyBinding downward = new KeyBinding("key.mayor.structure_downward", GLFW.GLFW_KEY_PAGE_DOWN, MAYOR_CATEGORY); - - public static final KeyBinding freeFlyCameraMode = new KeyBinding("key.mayor.free_fly_camera_mode", GLFW.GLFW_KEY_SPACE, MAYOR_CATEGORY); - - public static void initialize() { - KeyBindingHelper.registerKeyBinding(mayorView); - KeyBindingHelper.registerKeyBinding(mayorViewSelection); - KeyBindingHelper.registerKeyBinding(rotateLeft); - KeyBindingHelper.registerKeyBinding(rotateRight); - KeyBindingHelper.registerKeyBinding(targetToCenter); - KeyBindingHelper.registerKeyBinding(upward); - KeyBindingHelper.registerKeyBinding(downward); - KeyBindingHelper.registerKeyBinding(freeFlyCameraMode); - - ClientTickEvents.END_CLIENT_TICK.register((client) -> { - KeyHelper.viewKey(client); - KeyHelper.centerKey(client); - KeyHelper.heightKey(client); - }); - ClientTickEvents.START_CLIENT_TICK.register(KeyHelper::useKey); - } - -} diff --git a/src/main/java/io/fabricatedatelier/mayor/init/MayorNetworkPayloads.java b/src/main/java/io/fabricatedatelier/mayor/init/MayorNetworkPayloads.java index 48e18c2..79b7cb3 100644 --- a/src/main/java/io/fabricatedatelier/mayor/init/MayorNetworkPayloads.java +++ b/src/main/java/io/fabricatedatelier/mayor/init/MayorNetworkPayloads.java @@ -16,6 +16,7 @@ public class MayorNetworkPayloads { registerC2S(MayorUpdatePacket.PACKET_ID, MayorUpdatePacket.PACKET_CODEC); registerC2S(ElectionPacket.PACKET_ID, ElectionPacket.PACKET_CODEC); registerC2S(BallotPaperC2SPacket.PACKET_ID, BallotPaperC2SPacket.PACKET_CODEC); + registerC2S(CameraPullMovementPacket.PACKET_ID, CameraPullMovementPacket.PACKET_CODEC); // S2C registerS2C(MayorViewPacket.PACKET_ID, MayorViewPacket.PACKET_CODEC); diff --git a/src/main/java/io/fabricatedatelier/mayor/init/MayorRenderers.java b/src/main/java/io/fabricatedatelier/mayor/init/MayorRenderers.java index 9795cb3..0eefc7b 100644 --- a/src/main/java/io/fabricatedatelier/mayor/init/MayorRenderers.java +++ b/src/main/java/io/fabricatedatelier/mayor/init/MayorRenderers.java @@ -12,7 +12,6 @@ public class MayorRenderers { public static void initialize() { BlockEntityRendererFactories.register(MayorBlockEntities.VILLAGE_STORAGE, context -> new LumberStorageBlockEntityRenderer<>()); - HandledScreens.register(MayorBlockEntities.BALLOT_URN_SCREEN_HANDLER, BallotUrnBlockScreen::new); } } diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/CarvedPumpkinBlockMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/CarvedPumpkinBlockMixin.java index 56911db..7609ba3 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/CarvedPumpkinBlockMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/CarvedPumpkinBlockMixin.java @@ -19,12 +19,10 @@ public class CarvedPumpkinBlockMixin { @Inject(method = "trySpawnEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/CarvedPumpkinBlock;spawnEntity(Lnet/minecraft/world/World;Lnet/minecraft/block/pattern/BlockPattern$Result;Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/BlockPos;)V", ordinal = 1), locals = LocalCapture.CAPTURE_FAILSOFT) private void trySpawnEntityMixin(World world, BlockPos pos, CallbackInfo info, BlockPattern.Result result, BlockPattern.Result result2, IronGolemEntity ironGolemEntity) { - if (world instanceof ServerWorld serverWorld) { - VillageData villageData = MayorStateHelper.getClosestVillage(serverWorld, pos); - if (villageData != null) { - villageData.getIronGolems().add(ironGolemEntity.getUuid()); - MayorStateHelper.getMayorVillageState(serverWorld).markDirty(); - } - } + if (!(world instanceof ServerWorld serverWorld)) return; + VillageData villageData = MayorStateHelper.getClosestVillage(serverWorld, pos); + if (villageData == null) return; + villageData.getIronGolems().add(ironGolemEntity.getUuid()); + MayorStateHelper.getMayorVillageState(serverWorld).markDirty(); } } diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/DecoratedPotBlockMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/DecoratedPotBlockMixin.java index 7916549..8012549 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/DecoratedPotBlockMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/DecoratedPotBlockMixin.java @@ -14,6 +14,7 @@ import net.minecraft.block.entity.DecoratedPotBlockEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.particle.ParticleTypes; import net.minecraft.server.world.ServerWorld; @@ -28,12 +29,15 @@ import net.minecraft.world.event.GameEvent; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.util.List; + @Mixin(DecoratedPotBlock.class) public abstract class DecoratedPotBlockMixin extends BlockWithEntity { @@ -42,38 +46,46 @@ public DecoratedPotBlockMixin(Settings settings) { } @Inject(method = "onUseWithItem", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/block/entity/DecoratedPotBlockEntity;getStack()Lnet/minecraft/item/ItemStack;"), cancellable = true) - private void onUseWithItemMixin(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable info) { + private void onUseWithItemMixin(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, + Hand hand, BlockHitResult hit, CallbackInfoReturnable info) { // already on server world cause of injection point - if (stack.isOf(MayorItems.BALLOT_PAPER) && world.getBlockEntity(pos) instanceof DecoratedPotBlockEntity decoratedPotBlockEntity && decoratedPotBlockEntity.getSherds().stream().stream().allMatch(item -> item.equals(MayorItems.BALLOT_POTTERY_SHERD)) && decoratedPotBlockEntity instanceof BallotUrnAccess ballotUrnAccess) { - if (ballotUrnAccess.validated() && !ballotUrnAccess.getVotedPlayerUuids().contains(player.getUuid())) { - ballotUrnAccess.addStack(stack); - ballotUrnAccess.addVotedPlayerUuid(player.getUuid()); - - world.playSound(null, pos, SoundEvents.BLOCK_DECORATED_POT_INSERT, SoundCategory.BLOCKS, 1.0F, 0.7F + 0.5F * world.getRandom().nextFloat()); - if (world instanceof ServerWorld serverWorld) { - serverWorld.spawnParticles(ParticleTypes.DUST_PLUME, (double) pos.getX() + 0.5, (double) pos.getY() + 1.2, (double) pos.getZ() + 0.5, 7, 0.0, 0.0, 0.0, 0.0); - } - - decoratedPotBlockEntity.markDirty(); - world.emitGameEvent(player, GameEvent.BLOCK_CHANGE, pos); - info.setReturnValue(ItemActionResult.SUCCESS); + if (!stack.isOf(MayorItems.BALLOT_PAPER)) return; + if (!(world.getBlockEntity(pos) instanceof DecoratedPotBlockEntity decoratedPotBlockEntity)) return; + if (isInvalidBallotPot(decoratedPotBlockEntity)) return; + if (!(decoratedPotBlockEntity instanceof BallotUrnAccess ballotUrnAccess)) return; + if (ballotUrnAccess.validated() && !ballotUrnAccess.getVotedPlayerUuids().contains(player.getUuid())) { + ballotUrnAccess.addStack(stack); + ballotUrnAccess.addVotedPlayerUuid(player.getUuid()); + world.playSound(null, pos, SoundEvents.BLOCK_DECORATED_POT_INSERT, SoundCategory.BLOCKS, + 1.0F, 0.7F + 0.5F * world.getRandom().nextFloat()); + if (world instanceof ServerWorld serverWorld) { + serverWorld.spawnParticles(ParticleTypes.DUST_PLUME, + (double) pos.getX() + 0.5, + (double) pos.getY() + 1.2, + (double) pos.getZ() + 0.5, + 7, 0.0, 0.0, 0.0, 0.0); } + decoratedPotBlockEntity.markDirty(); + world.emitGameEvent(player, GameEvent.BLOCK_CHANGE, pos); + info.setReturnValue(ItemActionResult.SUCCESS); } + } // Open vote screen @Inject(method = "onUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;emitGameEvent(Lnet/minecraft/entity/Entity;Lnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/util/math/BlockPos;)V"), cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT) - private void onUseMixin(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, CallbackInfoReturnable info, DecoratedPotBlockEntity decoratedPotBlockEntity) { - if (!world.isClient() && decoratedPotBlockEntity.getSherds().stream().stream().allMatch(item -> item.equals(MayorItems.BALLOT_POTTERY_SHERD))) { - VillageData villageData = MayorStateHelper.getClosestVillage((ServerWorld) world, pos); - if (villageData != null && (villageData.getBallotUrnPos() == null || villageData.getBallotUrnPos().equals(pos))) { - if (decoratedPotBlockEntity instanceof BallotUrnAccess ballotUrnAccess) { - ballotUrnAccess.setMayorPlayerTime(villageData.getMayorPlayerTime()); - } - player.openHandledScreen(state.createScreenHandlerFactory(world, pos)); - info.setReturnValue(ActionResult.SUCCESS); + private void onUseMixin(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit, + CallbackInfoReturnable info, DecoratedPotBlockEntity decoratedPotBlockEntity) { + if (world.isClient()) return; + if (isInvalidBallotPot(decoratedPotBlockEntity)) return; + VillageData villageData = MayorStateHelper.getClosestVillage((ServerWorld) world, pos); + if (villageData == null) return; + if (villageData.getBallotUrnPos() == null || villageData.getBallotUrnPos().equals(pos)) { + if (decoratedPotBlockEntity instanceof BallotUrnAccess ballotUrnAccess) { + ballotUrnAccess.setMayorPlayerTime(villageData.getMayorPlayerTime()); } - + player.openHandledScreen(state.createScreenHandlerFactory(world, pos)); + info.setReturnValue(ActionResult.SUCCESS); } } @@ -87,7 +99,9 @@ protected void onStateReplacedMixin(BlockState state, World world, BlockPos pos, @Override public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { super.onPlaced(world, pos, state, placer, itemStack); - if (!world.isClient() && world.getBlockEntity(pos) instanceof DecoratedPotBlockEntity decoratedPotBlockEntity && decoratedPotBlockEntity instanceof BallotUrnAccess ballotUrnAccess) { + if (world.isClient()) return; + if (!(world.getBlockEntity(pos) instanceof DecoratedPotBlockEntity decoratedPotBlockEntity)) return; + if (decoratedPotBlockEntity instanceof BallotUrnAccess ballotUrnAccess) { ballotUrnAccess.setValidated(false); decoratedPotBlockEntity.markDirty(); } @@ -98,4 +112,10 @@ public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable Livi public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { return validateTicker(type, BlockEntityType.DECORATED_POT, world.isClient() ? BallotUrnHelper::clientTick : BallotUrnHelper::serverTick); } + + @Unique + private static boolean isInvalidBallotPot(DecoratedPotBlockEntity blockEntity) { + List equippedSherds = blockEntity.getSherds().stream(); + return !equippedSherds.stream().allMatch(item -> item.equals(MayorItems.BALLOT_POTTERY_SHERD)); + } } diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/PlayerEntityMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/PlayerEntityMixin.java index d180a3a..ff07491 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/PlayerEntityMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/PlayerEntityMixin.java @@ -6,6 +6,7 @@ import io.fabricatedatelier.mayor.access.MayorManagerAccess; import io.fabricatedatelier.mayor.manager.MayorManager; import net.minecraft.entity.player.PlayerEntity; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -13,6 +14,7 @@ @Mixin(PlayerEntity.class) public class PlayerEntityMixin implements MayorManagerAccess { + @Unique private final MayorManager mayorManager = new MayorManager((PlayerEntity) (Object) this); @Override diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/RaidMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/RaidMixin.java index 6c98155..1977f1c 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/RaidMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/RaidMixin.java @@ -67,45 +67,51 @@ public void writeNbt(NbtCompound nbt, CallbackInfoReturnable info) @Inject(method = "tick", at = @At(value = "FIELD", target = "Lnet/minecraft/village/raid/Raid$Status;VICTORY:Lnet/minecraft/village/raid/Raid$Status;")) private void tickMixin(CallbackInfo info) { - if (this.centerPos != null) { - MayorVillageState mayorVillageState = MayorStateHelper.getMayorVillageState(this.world); - if (mayorVillageState != null && mayorVillageState.hasVillage(this.centerPos)) { - VillageData villageData = mayorVillageState.getVillageData(this.centerPos); - if (villageData.getMayorPlayerUuid() == null) { - int maxReputation = 0; - UUID mayorUuid = null; - String mayorName = ""; - for (UUID uUID : this.heroesOfTheVillage) { - if (this.world.getEntity(uUID) instanceof ServerPlayerEntity serverPlayerEntity) { - int reputation = 0; - for (UUID villager : villageData.getVillagers()) { - if (this.world.getEntity(villager) instanceof VillagerEntity villagerEntity) { - reputation += villagerEntity.getReputation(serverPlayerEntity); - } - } - if (reputation > maxReputation) { - maxReputation = reputation; - mayorUuid = uUID; - mayorName = serverPlayerEntity.getName().getString(); - } - } - } - if (mayorUuid != null) { - villageData.setMayorPlayerUuid(mayorUuid); - villageData.setMayorPlayerTime(this.world.getTime()); - mayorVillageState.markDirty(); + if (this.centerPos == null) return; + MayorVillageState mayorVillageState = MayorStateHelper.getMayorVillageState(this.world); + if (mayorVillageState == null || !mayorVillageState.hasVillage(this.centerPos)) return; + VillageData villageData = mayorVillageState.getVillageData(this.centerPos); + if (villageData.getMayorPlayerUuid() != null) return; + + int maxReputation = 0; + UUID mayorUuid = null; + String mayorName = ""; - for (ServerPlayerEntity serverPlayerEntity : this.world.getEntitiesByClass(ServerPlayerEntity.class, new Box(this.centerPos).expand(VillageHelper.VILLAGE_LEVEL_RADIUS.get(villageData.getLevel())), EntityPredicates.EXCEPT_SPECTATOR)) { - serverPlayerEntity.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("mayor.village.news", mayorVillageState.getVillageData(this.centerPos).getName()))); - if (serverPlayerEntity.getUuid().equals(mayorUuid)) { - serverPlayerEntity.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("mayor.village.mayor_elected_2"))); - } else { - serverPlayerEntity.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("mayor.village.mayor_elected", mayorName))); - } - } - } + for (UUID uUID : this.heroesOfTheVillage) { + if (!(this.world.getEntity(uUID) instanceof ServerPlayerEntity serverPlayerEntity)) continue; + int reputation = 0; + for (UUID villager : villageData.getVillagers()) { + if (this.world.getEntity(villager) instanceof VillagerEntity villagerEntity) { + reputation += villagerEntity.getReputation(serverPlayerEntity); } } + if (reputation > maxReputation) { + maxReputation = reputation; + mayorUuid = uUID; + mayorName = serverPlayerEntity.getName().getString(); + } + } + + if (mayorUuid != null) { + villageData.setMayorPlayerUuid(mayorUuid); + villageData.setMayorPlayerTime(this.world.getTime()); + mayorVillageState.markDirty(); + + broadcastVillageNews(this.world, villageData, mayorVillageState, this.centerPos, mayorUuid, mayorName); + } + } + + @Unique + private static void broadcastVillageNews(ServerWorld world, VillageData villageData, MayorVillageState villageState, + BlockPos centerPos, UUID mayorUuid, String mayorName) { + Box villageBoundingBox = new Box(centerPos).expand(VillageHelper.VILLAGE_LEVEL_RADIUS.get(villageData.getLevel())); + for (ServerPlayerEntity serverPlayerEntity : world.getEntitiesByClass(ServerPlayerEntity.class, villageBoundingBox, EntityPredicates.EXCEPT_SPECTATOR)) { + serverPlayerEntity.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("mayor.village.news", villageState.getVillageData(centerPos).getName()))); + if (serverPlayerEntity.getUuid().equals(mayorUuid)) { + serverPlayerEntity.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("mayor.village.mayor_elected_2"))); + } else { + serverPlayerEntity.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("mayor.village.mayor_elected", mayorName))); + } } } } diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/StructureStartMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/StructureStartMixin.java index 0051fea..946c007 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/StructureStartMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/StructureStartMixin.java @@ -48,63 +48,92 @@ public class StructureStartMixin { private BlockPos centerPos = BlockPos.ORIGIN; @Inject(method = "place", at = @At("HEAD")) - private void placeMixin(StructureWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, Random random, BlockBox chunkBox, ChunkPos chunkPos, CallbackInfo info) { - if (structure.getType().equals(StructureType.JIGSAW) && structure instanceof JigsawStructureAccess jigsawStructureAccess - && jigsawStructureAccess.getStartPool().isIn(MayorTags.StructurePools.VILLAGES)) { - MayorVillageState mayorVillageState = MayorStateHelper.getMayorVillageState(world.toServerWorld()); - BlockPos centerPos = ((StructureStart) (Object) this).getBoundingBox().getCenter(); - if (!mayorVillageState.hasVillage(centerPos)) { - VillageData villageData = mayorVillageState.createVillageData(centerPos); - if (villageData != null) { - this.centerPos = centerPos; - } - } + private void placeMixin(StructureWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, + Random random, BlockBox chunkBox, ChunkPos chunkPos, CallbackInfo info) { + if (!structure.getType().equals(StructureType.JIGSAW)) return; + if (!(structure instanceof JigsawStructureAccess jigsawStructureAccess)) return; + if (!jigsawStructureAccess.getStartPool().isIn(MayorTags.StructurePools.VILLAGES)) return; + + MayorVillageState mayorVillageState = MayorStateHelper.getMayorVillageState(world.toServerWorld()); + BlockPos centerPos = ((StructureStart) (Object) this).getBoundingBox().getCenter(); + if (mayorVillageState.hasVillage(centerPos)) return; + VillageData villageData = mayorVillageState.createVillageData(centerPos); + if (villageData != null) { + this.centerPos = centerPos; } } @SuppressWarnings("rawtypes") - @Inject(method = "place", at = @At(value = "INVOKE", target = "Lnet/minecraft/structure/StructurePiece;generate(Lnet/minecraft/world/StructureWorldAccess;Lnet/minecraft/world/gen/StructureAccessor;Lnet/minecraft/world/gen/chunk/ChunkGenerator;Lnet/minecraft/util/math/random/Random;Lnet/minecraft/util/math/BlockBox;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/util/math/BlockPos;)V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILSOFT) - private void placeMixin(StructureWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, Random random, BlockBox chunkBox, ChunkPos chunkPos, CallbackInfo info, - List list, BlockBox blockBox, BlockPos blockPos, BlockPos blockPos2, Iterator var11, StructurePiece structurePiece) { - if (!this.centerPos.equals(BlockPos.ORIGIN)) { - MayorVillageState mayorVillageState = MayorStateHelper.getMayorVillageState(world.toServerWorld()); - if (mayorVillageState.hasVillage(this.centerPos)) { - if (structurePiece instanceof PoolStructurePiece poolStructurePiece && poolStructurePiece.getPoolElement() instanceof SinglePoolElementAccess singlePoolElementAccess - && singlePoolElementAccess.getLocation().left().isPresent()) { - VillageData villageData = mayorVillageState.getVillageData(this.centerPos); - if (singlePoolElementAccess.getStructureTemplate() instanceof StructureTemplateAccess structureTemplateAccess && !structureTemplateAccess.getSpawnedEntities().isEmpty()) { - for (int i = 0; i < structureTemplateAccess.getSpawnedEntities().size(); i++) { - if (structureTemplateAccess.getSpawnedEntities().get(i) instanceof VillagerEntity villagerEntity) { - villageData.addVillager(villagerEntity.getUuid()); - } else if (structureTemplateAccess.getSpawnedEntities().get(i) instanceof IronGolemEntity ironGolemEntity) { - villageData.addIronGolem(ironGolemEntity.getUuid()); - } - } - structureTemplateAccess.clearSpawnedEntities(); - } - if (StringUtil.shouldStoreStructureIdentifier(singlePoolElementAccess.getLocation().left().get())) { - Identifier structureIdentifier = StringUtil.getMayorStructureIdentifier(singlePoolElementAccess.getLocation().left().get()); - int experience = 0; - int price = 8; - if (MayorConfig.CONFIG.instance().generatedStructureXp) { - if (StructureDataLoader.structureDataMap.containsKey(StringUtil.getMayorStructureString(structureIdentifier))) { - experience = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(structureIdentifier)).get(0); -// price = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(structureIdentifier)).get(1); - } else { - List requiredItemStacks = StructureHelper.getStructureItemRequirements(world.toServerWorld(), structureIdentifier); - experience = StructureHelper.getStructureExperience(requiredItemStacks); - StructureDataLoader.structureDataMap.put(StringUtil.getMayorStructureString(structureIdentifier), List.of(experience, price)); - } - } + @Inject(method = "place", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/structure/StructurePiece;generate(Lnet/minecraft/world/StructureWorldAccess;Lnet/minecraft/world/gen/StructureAccessor;Lnet/minecraft/world/gen/chunk/ChunkGenerator;Lnet/minecraft/util/math/random/Random;Lnet/minecraft/util/math/BlockBox;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/util/math/BlockPos;)V", + shift = At.Shift.AFTER), + locals = LocalCapture.CAPTURE_FAILSOFT + ) + private void placeMixin(StructureWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, + Random random, BlockBox chunkBox, ChunkPos chunkPos, CallbackInfo info, List list, + BlockBox blockBox, BlockPos blockPos, BlockPos blockPos2, Iterator var11, + StructurePiece structurePiece) { + if (this.centerPos.equals(BlockPos.ORIGIN)) return; + MayorVillageState mayorVillageState = MayorStateHelper.getMayorVillageState(world.toServerWorld()); + if (!mayorVillageState.hasVillage(this.centerPos)) return; + if (!(structurePiece instanceof PoolStructurePiece poolStructurePiece)) { + mayorVillageState.markDirty(); + return; + } + if (!(poolStructurePiece.getPoolElement() instanceof SinglePoolElementAccess singlePoolElementAccess)) { + mayorVillageState.markDirty(); + return; + } + + singlePoolElementAccess.getLocation().left().ifPresent(locationIdentifier -> { + VillageData villageData = mayorVillageState.getVillageData(this.centerPos); + if (singlePoolElementAccess instanceof StructureTemplateAccess structureTemplate) { + addEntitiesToVillageData(structureTemplate, villageData); + } + addStructureToVillageData(locationIdentifier, world, structurePiece, villageData); + }); + mayorVillageState.markDirty(); + } + - StructureData structureData = new StructureData(StructureHelper.getBottomCenterPos(structurePiece), structurePiece.getBoundingBox(), StructureHelper.getStructureRotation(structurePiece.getRotation()), - structureIdentifier, StringUtil.getStructureLevelByIdentifier(structureIdentifier), experience); - villageData.addStructure(structureData); - } - } - mayorVillageState.markDirty(); + @Unique + private static void addEntitiesToVillageData(StructureTemplateAccess structureTemplate, VillageData villageData) { + for (int i = 0; i < structureTemplate.getSpawnedEntities().size(); i++) { + if (structureTemplate.getSpawnedEntities().get(i) instanceof VillagerEntity villagerEntity) { + villageData.addVillager(villagerEntity.getUuid()); + } else if (structureTemplate.getSpawnedEntities().get(i) instanceof IronGolemEntity ironGolemEntity) { + villageData.addIronGolem(ironGolemEntity.getUuid()); + } + } + structureTemplate.clearSpawnedEntities(); + } + + @Unique + private static void addStructureToVillageData(Identifier locationIdentifier, StructureWorldAccess world, + StructurePiece structurePiece, VillageData villageData) { + if (!StringUtil.shouldStoreStructureIdentifier(locationIdentifier)) return; + Identifier structureIdentifier = StringUtil.getMayorStructureIdentifier(locationIdentifier); + int experience = 0; + int price = 8; + + if (!MayorConfig.CONFIG.instance().generatedStructureXp) { + if (StructureDataLoader.structureDataMap.containsKey(StringUtil.getMayorStructureString(structureIdentifier))) { + experience = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(structureIdentifier)).getFirst(); + // price = StructureDataLoader.structureDataMap.get(StringUtil.getMayorStructureString(structureIdentifier)).get(1); + } else { + List requiredItemStacks = StructureHelper.getStructureItemRequirements(world.toServerWorld(), structureIdentifier); + experience = StructureHelper.getStructureExperience(requiredItemStacks); + StructureDataLoader.structureDataMap.put(StringUtil.getMayorStructureString(structureIdentifier), List.of(experience, price)); } } + StructureData structureData = new StructureData( + StructureHelper.getBottomCenterPos(structurePiece), + structurePiece.getBoundingBox(), + StructureHelper.getStructureRotation(structurePiece.getRotation()), + structureIdentifier, StringUtil.getStructureLevelByIdentifier(structureIdentifier), experience); + + villageData.addStructure(structureData); } } diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/VillagerEntityMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/VillagerEntityMixin.java index e176ccc..e6a6953 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/VillagerEntityMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/VillagerEntityMixin.java @@ -2,7 +2,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.mojang.datafixers.util.Pair; @@ -15,11 +14,14 @@ import io.fabricatedatelier.mayor.util.VillageHelper; import net.minecraft.entity.EntityData; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.ai.brain.Activity; import net.minecraft.entity.ai.brain.Brain; import net.minecraft.entity.ai.brain.MemoryModuleState; import net.minecraft.entity.ai.brain.MemoryModuleType; +import net.minecraft.entity.ai.brain.sensor.Sensor; +import net.minecraft.entity.ai.brain.sensor.SensorType; import net.minecraft.entity.ai.brain.task.Task; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.data.DataTracker; @@ -56,6 +58,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -216,13 +219,26 @@ private void reinitializeBrainMixin(ServerWorld world, CallbackInfo info) { setTaskValue(0); } - @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;", ordinal = 0)) +/* @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;", ordinal = 0)) private static ImmutableList> initMixin(ImmutableList> original) { List> list = new ArrayList<>(original); list.add(MayorVillagerUtilities.BUSY); return ImmutableList.copyOf(list); + }*/ + @WrapOperation(method = "createBrainProfile", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/ai/brain/Brain;createProfile(Ljava/util/Collection;Ljava/util/Collection;)Lnet/minecraft/entity/ai/brain/Brain$Profile;") + ) + private Brain.Profile addMemoryModules(Collection> memoryModules, + Collection>> sensors, + Operation> original) { + List> memoryModuleTypes = new ArrayList<>(memoryModules); + memoryModuleTypes.add(MayorVillagerUtilities.BUSY); + return original.call(ImmutableList.copyOf(memoryModuleTypes), sensors); } + @Shadow public abstract VillagerData getVillagerData(); diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/client/KeyBindingMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/client/KeyBindingMixin.java index 324bcae..9922b48 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/client/KeyBindingMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/client/KeyBindingMixin.java @@ -1,15 +1,12 @@ package io.fabricatedatelier.mayor.mixin.client; -import io.fabricatedatelier.mayor.camera.CameraHandler; -import io.fabricatedatelier.mayor.camera.mode.FreeFlyMode; -import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import io.fabricatedatelier.mayor.access.MayorManagerAccess; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.manager.MayorManager; import io.fabricatedatelier.mayor.util.StructureHelper; import net.fabricmc.api.EnvType; @@ -27,7 +24,7 @@ private static void onKeyPressedMixin(InputUtil.Key key, CallbackInfo info) { MinecraftClient client = MinecraftClient.getInstance(); if (key.getCode() == 81 || key.getCode() == 69) { if (client.player != null && ((MayorManagerAccess) client.player).getMayorManager().isInMajorView()) { - if ((key.getCode() == 81 && MayorKeyBindings.rotateLeft.isDefault()) || (key.getCode() == 69 && MayorKeyBindings.rotateRight.isDefault())) { + if ((key.getCode() == 81 && MayorKeyBind.ROTATE_LEFT.get().isDefault()) || (key.getCode() == 69 && MayorKeyBind.ROTATE_RIGHT.get().isDefault())) { info.cancel(); } } @@ -46,11 +43,11 @@ private static void setKeyPressedMixin(InputUtil.Key key, boolean pressed, Callb if (key.getCode() == 81 || key.getCode() == 69) { MinecraftClient client = MinecraftClient.getInstance(); if (client.player != null && ((MayorManagerAccess) client.player).getMayorManager().isInMajorView()) { - if (key.getCode() == 81 && MayorKeyBindings.rotateLeft.isDefault()) { - MayorKeyBindings.rotateLeft.setPressed(pressed); + if (key.getCode() == 81 && MayorKeyBind.ROTATE_LEFT.get().isDefault()) { + MayorKeyBind.ROTATE_LEFT.get().setPressed(pressed); info.cancel(); - } else if (key.getCode() == 69 && MayorKeyBindings.rotateRight.isDefault()) { - MayorKeyBindings.rotateRight.setPressed(pressed); + } else if (key.getCode() == 69 && MayorKeyBind.ROTATE_RIGHT.get().isDefault()) { + MayorKeyBind.ROTATE_RIGHT.get().setPressed(pressed); info.cancel(); } } diff --git a/src/main/java/io/fabricatedatelier/mayor/mixin/client/MinecraftClientMixin.java b/src/main/java/io/fabricatedatelier/mayor/mixin/client/MinecraftClientMixin.java index 9764954..70c3907 100644 --- a/src/main/java/io/fabricatedatelier/mayor/mixin/client/MinecraftClientMixin.java +++ b/src/main/java/io/fabricatedatelier/mayor/mixin/client/MinecraftClientMixin.java @@ -1,7 +1,7 @@ package io.fabricatedatelier.mayor.mixin.client; import io.fabricatedatelier.mayor.access.MayorManagerAccess; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.util.KeyHelper; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -35,11 +35,11 @@ private void handleInputEventsMixin(CallbackInfo info) { if (this.majorKeyBindTicks > 0) { this.majorKeyBindTicks--; info.cancel(); - } else if (MayorKeyBindings.rotateLeft.isPressed()) { + } else if (MayorKeyBind.ROTATE_LEFT.get().isPressed()) { KeyHelper.rotateKey((MinecraftClient) (Object) this, true); this.majorKeyBindTicks = 5; info.cancel(); - } else if (MayorKeyBindings.rotateRight.isPressed()) { + } else if (MayorKeyBind.ROTATE_RIGHT.get().isPressed()) { KeyHelper.rotateKey((MinecraftClient) (Object) this, false); this.majorKeyBindTicks = 5; info.cancel(); diff --git a/src/main/java/io/fabricatedatelier/mayor/network/CustomC2SNetworking.java b/src/main/java/io/fabricatedatelier/mayor/network/CustomC2SNetworking.java index b00404e..17cb813 100644 --- a/src/main/java/io/fabricatedatelier/mayor/network/CustomC2SNetworking.java +++ b/src/main/java/io/fabricatedatelier/mayor/network/CustomC2SNetworking.java @@ -12,6 +12,7 @@ public class CustomC2SNetworking { ServerPlayNetworking.registerGlobalReceiver(MayorUpdatePacket.PACKET_ID, MayorUpdatePacket::handlePacket); ServerPlayNetworking.registerGlobalReceiver(ElectionPacket.PACKET_ID, ElectionPacket::handlePacket); ServerPlayNetworking.registerGlobalReceiver(BallotPaperC2SPacket.PACKET_ID, BallotPaperC2SPacket::handlePacket); + ServerPlayNetworking.registerGlobalReceiver(CameraPullMovementPacket.PACKET_ID, CameraPullMovementPacket::handlePacket); } public static void initialize() { diff --git a/src/main/java/io/fabricatedatelier/mayor/network/packet/CameraPullMovementPacket.java b/src/main/java/io/fabricatedatelier/mayor/network/packet/CameraPullMovementPacket.java new file mode 100644 index 0000000..467a2ad --- /dev/null +++ b/src/main/java/io/fabricatedatelier/mayor/network/packet/CameraPullMovementPacket.java @@ -0,0 +1,44 @@ +package io.fabricatedatelier.mayor.network.packet; + +import io.fabricatedatelier.mayor.Mayor; +import io.fabricatedatelier.mayor.entity.custom.CameraPullEntity; +import io.fabricatedatelier.mayor.init.MayorEntities; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.server.world.ServerWorld; + +import java.util.Optional; + +public record CameraPullMovementPacket(Optional movement) implements CustomPayload { + + public static final CustomPayload.Id PACKET_ID = + new CustomPayload.Id<>(Mayor.identifierOf("camera_pull_entity_movement")); + + public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( + PacketCodecs.optional(PacketCodecs.BYTE.xmap(index -> + CameraPullEntity.DirectionInput.values()[index], directionInput -> (byte) directionInput.ordinal())), + CameraPullMovementPacket::movement, + CameraPullMovementPacket::new + ); + + @Override + public CustomPayload.Id getId() { + return PACKET_ID; + } + + + public void sendPacket() { + ClientPlayNetworking.send(this); + } + + public void handlePacket(ServerPlayNetworking.Context context) { + ServerWorld world = (ServerWorld) context.player().getWorld(); + var entities = world.getEntitiesByType(MayorEntities.CAMERA_PULL, pullEntity -> CameraPullEntity.hasCorrectUUID(pullEntity, context.player())); + CameraPullEntity pullEntity = entities.getFirst(); + pullEntity.setMovementInput(this.movement.orElse(null)); + } +} diff --git a/src/main/java/io/fabricatedatelier/mayor/screen/MayorScreen.java b/src/main/java/io/fabricatedatelier/mayor/screen/MayorScreen.java index 8b52e06..ce604ed 100644 --- a/src/main/java/io/fabricatedatelier/mayor/screen/MayorScreen.java +++ b/src/main/java/io/fabricatedatelier/mayor/screen/MayorScreen.java @@ -1,11 +1,10 @@ package io.fabricatedatelier.mayor.screen; import io.fabricatedatelier.mayor.Mayor; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.manager.MayorCategory; import io.fabricatedatelier.mayor.manager.MayorManager; import io.fabricatedatelier.mayor.manager.MayorStructure; -import io.fabricatedatelier.mayor.network.packet.EntityListC2SPacket; import io.fabricatedatelier.mayor.network.packet.StructureBuildPacket; import io.fabricatedatelier.mayor.screen.widget.ItemScrollableWidget; import io.fabricatedatelier.mayor.screen.widget.ObjectScrollableWidget; @@ -292,7 +291,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (MayorKeyBindings.mayorViewSelection.matchesKey(keyCode, scanCode) || MayorKeyBindings.mayorView.matchesKey(keyCode, scanCode)) { + if (MayorKeyBind.MAYOR_VIEW_SELECTION.get().matchesKey(keyCode, scanCode) || MayorKeyBind.MAYOR_VIEW.get().matchesKey(keyCode, scanCode)) { this.close(); return true; } diff --git a/src/main/java/io/fabricatedatelier/mayor/screen/MayorVillageScreen.java b/src/main/java/io/fabricatedatelier/mayor/screen/MayorVillageScreen.java index a7b6caf..7c10f04 100644 --- a/src/main/java/io/fabricatedatelier/mayor/screen/MayorVillageScreen.java +++ b/src/main/java/io/fabricatedatelier/mayor/screen/MayorVillageScreen.java @@ -1,6 +1,6 @@ package io.fabricatedatelier.mayor.screen; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.manager.MayorCategory; import io.fabricatedatelier.mayor.manager.MayorManager; import io.fabricatedatelier.mayor.manager.MayorStructure; @@ -239,7 +239,7 @@ public void tick() { @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (MayorKeyBindings.mayorViewSelection.matchesKey(keyCode, scanCode) || MayorKeyBindings.mayorView.matchesKey(keyCode, scanCode) || this.client.options.inventoryKey.matchesKey(keyCode, scanCode)) { + if (MayorKeyBind.MAYOR_VIEW_SELECTION.get().matchesKey(keyCode, scanCode) || MayorKeyBind.MAYOR_VIEW.get().matchesKey(keyCode, scanCode) || this.client.options.inventoryKey.matchesKey(keyCode, scanCode)) { this.client.setScreen(new MayorScreen(this.mayorManager)); return true; } diff --git a/src/main/java/io/fabricatedatelier/mayor/screen/VillageScreen.java b/src/main/java/io/fabricatedatelier/mayor/screen/VillageScreen.java index 5c72019..dabbf11 100644 --- a/src/main/java/io/fabricatedatelier/mayor/screen/VillageScreen.java +++ b/src/main/java/io/fabricatedatelier/mayor/screen/VillageScreen.java @@ -1,6 +1,6 @@ package io.fabricatedatelier.mayor.screen; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.util.RenderUtil; import io.fabricatedatelier.mayor.util.StringUtil; import net.fabricmc.api.EnvType; @@ -79,7 +79,7 @@ public boolean shouldPause() { @Override public boolean keyReleased(int keyCode, int scanCode, int modifiers) { - if (!this.initiated && MayorKeyBindings.mayorView.matchesKey(keyCode, scanCode)) { + if (!this.initiated && MayorKeyBind.MAYOR_VIEW.get().matchesKey(keyCode, scanCode)) { this.close(); } this.initiated = false; diff --git a/src/main/java/io/fabricatedatelier/mayor/util/KeyHelper.java b/src/main/java/io/fabricatedatelier/mayor/util/KeyHelper.java index 6862b48..266b6f0 100644 --- a/src/main/java/io/fabricatedatelier/mayor/util/KeyHelper.java +++ b/src/main/java/io/fabricatedatelier/mayor/util/KeyHelper.java @@ -1,7 +1,7 @@ package io.fabricatedatelier.mayor.util; import io.fabricatedatelier.mayor.access.MayorManagerAccess; -import io.fabricatedatelier.mayor.init.MayorKeyBindings; +import io.fabricatedatelier.mayor.init.MayorKeyBind; import io.fabricatedatelier.mayor.manager.MayorManager; import io.fabricatedatelier.mayor.network.packet.MayorViewPacket; import io.fabricatedatelier.mayor.screen.MayorScreen; @@ -21,7 +21,7 @@ public static void rotateKey(MinecraftClient client, boolean rotateLeft) { } public static void centerKey(MinecraftClient client) { - if (MayorKeyBindings.targetToCenter.wasPressed()) { + if (MayorKeyBind.TARGET_TO_CENTER.get().wasPressed()) { if (client.player != null) { MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); if (client.player != null && mayorManager.isInMajorView()) { @@ -32,14 +32,14 @@ public static void centerKey(MinecraftClient client) { } public static void heightKey(MinecraftClient client) { - if (MayorKeyBindings.upward.wasPressed()) { + if (MayorKeyBind.UPWARD.get().wasPressed()) { if (client.player != null) { MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); if (client.player != null && mayorManager.isInMajorView() && mayorManager.getStructureOriginBlockPos() != null) { mayorManager.setStructureOriginBlockPos(mayorManager.getStructureOriginBlockPos().up()); } } - } else if (MayorKeyBindings.downward.wasPressed()) { + } else if (MayorKeyBind.DOWNWARD.get().wasPressed()) { if (client.player != null) { MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); if (client.player != null && mayorManager.isInMajorView() && mayorManager.getStructureOriginBlockPos() != null) { @@ -50,12 +50,12 @@ public static void heightKey(MinecraftClient client) { } public static void viewKey(MinecraftClient client) { - if (MayorKeyBindings.mayorView.wasPressed()) { + if (MayorKeyBind.MAYOR_VIEW.get().wasPressed()) { if (client.player != null) { MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); new MayorViewPacket(!mayorManager.isInMajorView()).sendClientPacket(); } - } else if (MayorKeyBindings.mayorViewSelection.wasPressed()) { + } else if (MayorKeyBind.MAYOR_VIEW_SELECTION.get().wasPressed()) { if (client.player != null) { MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); @@ -71,21 +71,20 @@ public static void viewKey(MinecraftClient client) { } public static void useKey(MinecraftClient client) { - if (client.options.useKey.wasPressed() && client.player != null) { - MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); - if (mayorManager.isInMajorView() && !(client.currentScreen instanceof MayorScreen)) { - if (mayorManager.getStructureOriginBlockPos() == null) { - Optional hitResult = Optional.ofNullable(StructureHelper.findCrosshairTarget(client.player)); - if (hitResult.isPresent()) { - Optional origin = hitResult.map(BlockHitResult::getBlockPos); - if (origin.isPresent()) { - mayorManager.setStructureOriginBlockPos(origin.get()); - } - } - } else { - mayorManager.setStructureOriginBlockPos(null); + if (client.player == null) return; + if (!client.options.useKey.wasPressed()) return; + MayorManager mayorManager = ((MayorManagerAccess) client.player).getMayorManager(); + if (mayorManager.isInMajorView() && !(client.currentScreen instanceof MayorScreen)) { + if (mayorManager.getStructureOriginBlockPos() == null) { + Optional hitResult = Optional.ofNullable(StructureHelper.findCrosshairTarget(client.player)); + if (hitResult.isPresent()) { + Optional origin = hitResult.map(BlockHitResult::getBlockPos); + origin.ifPresent(mayorManager::setStructureOriginBlockPos); } + } else { + mayorManager.setStructureOriginBlockPos(null); } } + } } diff --git a/src/main/java/io/fabricatedatelier/mayor/util/NbtKeys.java b/src/main/java/io/fabricatedatelier/mayor/util/NbtKeys.java index ddc2e3e..6d84dee 100644 --- a/src/main/java/io/fabricatedatelier/mayor/util/NbtKeys.java +++ b/src/main/java/io/fabricatedatelier/mayor/util/NbtKeys.java @@ -5,4 +5,5 @@ public class NbtKeys { public static String CONNECTED_BLOCKS = "connected_pos"; public static String USER_UUID = "user"; + public static String DIRECTION_INPUT = "direction_input"; }