From 15d66f5ac86f51f7d382b829b077094ba4d1fa36 Mon Sep 17 00:00:00 2001 From: xoiox Date: Tue, 22 Sep 2026 01:21:28 +0200 Subject: [PATCH] cleanup & bug fixes --- .../dev/hytalemodding/RitualSetupState.java | 7 + .../java/dev/hytalemodding/RitualSpawner.java | 185 ++++++++++++------ .../definitions/RitualDefinitions.java | 6 +- .../definitions/RitualSetup.java | 6 +- 4 files changed, 139 insertions(+), 65 deletions(-) create mode 100644 src/main/java/dev/hytalemodding/RitualSetupState.java diff --git a/src/main/java/dev/hytalemodding/RitualSetupState.java b/src/main/java/dev/hytalemodding/RitualSetupState.java new file mode 100644 index 0000000..2aab2ae --- /dev/null +++ b/src/main/java/dev/hytalemodding/RitualSetupState.java @@ -0,0 +1,7 @@ +package dev.hytalemodding; + +public enum RitualSetupState { + INCOMPLETE, + COMPLETE, + CHANGED +} diff --git a/src/main/java/dev/hytalemodding/RitualSpawner.java b/src/main/java/dev/hytalemodding/RitualSpawner.java index 23be401..12bb725 100644 --- a/src/main/java/dev/hytalemodding/RitualSpawner.java +++ b/src/main/java/dev/hytalemodding/RitualSpawner.java @@ -9,6 +9,7 @@ import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.npc.NPCPlugin; import dev.hytalemodding.definitions.RitualDefinitions; import dev.hytalemodding.definitions.RitualPattern; +import dev.hytalemodding.definitions.RitualSacrifice; import dev.hytalemodding.definitions.RitualTypes; import org.joml.Vector3d; import org.joml.Vector3i; @@ -29,8 +30,8 @@ public class RitualSpawner { RitualPlugin.LOGGER.atInfo().log( "a block got %s at the position: %d, %d, %d with the block id: %s", placedRemovedString, targetPosition.x, targetPosition.y, targetPosition.z, blockId); - // RitualTypes ritualType = checkPatterns(ritualDefinitions.containsCenterBlock(blockId), targetPosition, world); - RitualTypes ritualType = getRitualTypeFromBlock(blockId, targetPosition, world); + Vector3i ritualCenter = new Vector3i(targetPosition); + RitualTypes ritualType = getRitualTypeFromBlock(blockId, ritualCenter, world, true); if(!ritualType.equals(RitualTypes.NONE)) { RitualPlugin.LOGGER.atInfo().log( "a ritual pattern got completed" @@ -44,70 +45,45 @@ public class RitualSpawner { int soundIndex = SoundEvent.getAssetMap().getIndex(soundId); world.execute(() -> { // Play sound - SoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, blockToEntityPos(targetPosition), world.getEntityStore().getStore()); + SoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, blockToEntityPos(ritualCenter), world.getEntityStore().getStore()); }); } } public void sacrificeDropEvent(String itemId, Vector3d targetPosition, World world) { Vector3i blockPosition = entityToBlockPos(targetPosition); - RitualPlugin.LOGGER.atInfo().log( + /*RitualPlugin.LOGGER.atInfo().log( "an item got thrown at the position: %f, %f, %f with the item id: %s", + targetPosition.x, targetPosition.y, targetPosition.z, itemId);*/ + RitualPlugin.LOGGER.atInfo().log( + "an item got thrown at the position: %d, %d, %d with the item id: %s", blockPosition.x, blockPosition.y, blockPosition.z, itemId); - RitualTypes ritualType = getRitualTypeFromSacrifice(blockPosition, world); + RitualTypes ritualType = getRitualTypeFromSacrifice(itemId, blockPosition, world); if (!ritualType.equals(RitualTypes.NONE)) { if (ritualType.equals(RitualTypes.SKELETON)) { RitualPlugin.LOGGER.atInfo().log("Ritual complete"); world.execute(() -> { - NPCPlugin.get().spawnNPC(world.getEntityStore().getStore(), "Skeleton", null, targetPosition, new Rotation3f(0, 0, 0)); + NPCPlugin.get().spawnNPC(world.getEntityStore().getStore(), "Skeleton", null, blockToEntityPos(blockPosition), new Rotation3f(0, 0, 0)); }); } } } - RitualTypes getRitualTypeFromSacrifice(Vector3i centerPosition, World world) { - int radius = 1; + RitualTypes getRitualTypeFromSacrifice(String itemId, Vector3i centerPosition, World world) { + List possibleSetups = getFullRitualSetupRange(); + checkSacrificePalette(possibleSetups, itemId); + int radius = getMaxSacrificeRadius(possibleSetups); for (int ix = centerPosition.x - radius; ix <= centerPosition.x + radius; ix++) { for (int iy = centerPosition.y - radius; iy <= centerPosition.y + radius; iy++) { for (int iz = centerPosition.z - radius; iz <= centerPosition.z + radius; iz++) { Vector3i samplePosition = new Vector3i(ix, iy, iz); String blockId = getBlockId(samplePosition, world); - List possibleSetups = getFullRitualSetupRange(); - possibleSetups = checkCenterBlock(possibleSetups, blockId); - if (!possibleSetups.isEmpty()) { - possibleSetups = checkPatterns(possibleSetups, samplePosition, world, samplePosition, "Empty"); - if (!possibleSetups.isEmpty()) { - return ritualDefinitions.getRitualType(possibleSetups.getFirst()); - } - } - } - } - } - return RitualTypes.NONE; - } - - RitualTypes getRitualTypeFromBlock(String blockId, Vector3i blockPosition, World world) { - List fullSetupRange = getFullRitualSetupRange(); - List possibleSetups = checkCenterBlock(new ArrayList<>(fullSetupRange), blockId); - if (!possibleSetups.isEmpty()) { - possibleSetups = checkPatterns(possibleSetups, blockPosition, world, blockPosition, "Empty"); - if (!possibleSetups.isEmpty()) { - return ritualDefinitions.getRitualType(possibleSetups.getFirst()); - } - } - possibleSetups = checkPatternPalette(new ArrayList<>(fullSetupRange), blockId); - if (possibleSetups.size() <= 0) { - return RitualTypes.NONE; - } - int radius = getMaxRadius(possibleSetups); - for (int ix = blockPosition.x - radius; ix <= blockPosition.x + radius; ix++) { - for (int iy = blockPosition.y - radius; iy <= blockPosition.y + radius; iy++) { - for (int iz = blockPosition.z - radius; iz <= blockPosition.z + radius; iz++) { - Vector3i samplePosition = new Vector3i(ix, iy, iz); - List setupsAtPosition = checkCenterBlock(new ArrayList<>(possibleSetups), getBlockId(samplePosition, world)); + List setupsAtPosition = new ArrayList<>(possibleSetups); + checkCenterBlock(setupsAtPosition, blockId); if (!setupsAtPosition.isEmpty()) { - setupsAtPosition = checkPatterns(setupsAtPosition, samplePosition, world, blockPosition, blockId); + checkPatterns(setupsAtPosition, samplePosition, world, samplePosition, "Empty"); if (!setupsAtPosition.isEmpty()) { + centerPosition.set(samplePosition); return ritualDefinitions.getRitualType(setupsAtPosition.getFirst()); } } @@ -117,66 +93,136 @@ public class RitualSpawner { return RitualTypes.NONE; } - List checkCenterBlock(List ritualSetups, String blockId) { - ritualSetups.removeIf(ritualSetup -> !ritualDefinitions.getCenterBlockId(ritualSetup).equals(blockId)); - return ritualSetups; + RitualTypes getRitualTypeFromBlock(String blockId, Vector3i blockPosition, World world, boolean onlyShowChanges) { + List possibleSetups = getFullRitualSetupRange(); + checkCenterBlock(possibleSetups, blockId); + if (!possibleSetups.isEmpty()) { + checkPatterns(possibleSetups, blockPosition, world, blockPosition, blockId); + if (!possibleSetups.isEmpty()) { + return ritualDefinitions.getRitualType(possibleSetups.getFirst()); + } + } + possibleSetups = getFullRitualSetupRange(); + checkPatternPalette(possibleSetups, blockId); + if (possibleSetups.size() <= 0) { + return RitualTypes.NONE; + } + int radius = getMaxPatternRadius(possibleSetups); + for (int ix = blockPosition.x - radius; ix <= blockPosition.x + radius; ix++) { + for (int iy = blockPosition.y - radius; iy <= blockPosition.y + radius; iy++) { + for (int iz = blockPosition.z - radius; iz <= blockPosition.z + radius; iz++) { + Vector3i samplePosition = new Vector3i(ix, iy, iz); + List setupsAtPosition = new ArrayList<>(possibleSetups); + checkCenterBlock(setupsAtPosition, getBlockId(samplePosition, world)); + if (!setupsAtPosition.isEmpty()) { + boolean didChange = checkPatterns(setupsAtPosition, samplePosition, world, blockPosition, blockId); + // one setup needs to be valid and either a change happened or no changes are required + if (!setupsAtPosition.isEmpty() && (didChange || !onlyShowChanges)) { + blockPosition.set(samplePosition); + return ritualDefinitions.getRitualType(setupsAtPosition.getFirst()); + } + } + } + } + } + return RitualTypes.NONE; } - List checkPatternPalette(List ritualSetups, String blockId) { + void checkCenterBlock(List ritualSetups, String blockId) { + ritualSetups.removeIf(ritualSetup -> !ritualDefinitions.getCenterBlockId(ritualSetup).equals(blockId)); + } + + void checkPatternPalette(List ritualSetups, String blockId) { List possibleSetups = new ArrayList<>(ritualSetups); - for (Integer ritualSetup : ritualSetups) { + for (Integer possibleSetup : possibleSetups) { boolean isPossibleSetup = false; - List ritualPatterns = ritualDefinitions.getPatterns(ritualSetup); + List ritualPatterns = ritualDefinitions.getPatterns(possibleSetup); for (RitualPattern ritualPattern : ritualPatterns) { - if (ritualPattern.blockId().equals(blockId)){ + if (ritualPattern.blockId().equals(blockId)) { isPossibleSetup = true; break; } } if (!isPossibleSetup) { - possibleSetups.remove(ritualSetup); + ritualSetups.remove(possibleSetup); } } - return possibleSetups; } - List checkPatterns(List ritualSetups, Vector3i centerPosition, World world, Vector3i placedBlockPosition, String placedBlockId) { + void checkSacrificePalette(List ritualSetups, String itemId) { List possibleSetups = new ArrayList<>(ritualSetups); - for (Integer ritualSetup : ritualSetups) { - List ritualPatterns = ritualDefinitions.getPatterns(ritualSetup); - //RitualPlugin.LOGGER.atInfo().log("ritualPatterns size in checkPatterns() is %d", ritualPatterns.size()); - for (RitualPattern ritualPattern : ritualPatterns) { - if(!checkPattern(ritualPattern, centerPosition, world, placedBlockPosition, placedBlockId)) { - possibleSetups.remove(ritualSetup); + for (Integer possibleSetup : possibleSetups) { + boolean isPossibleSetup = false; + List ritualSacrifices = ritualDefinitions.getSacrifices(possibleSetup); + for (RitualSacrifice ritualSacrifice : ritualSacrifices) { + if (ritualSacrifice.itemId().equals(itemId)) { + isPossibleSetup = true; + break; } } + if (!isPossibleSetup) { + ritualSetups.remove(possibleSetup); + } } - return possibleSetups; } - boolean checkPattern(RitualPattern ritualPattern, Vector3i centerPosition, World world, Vector3i placedBlockPosition, String placedBlockId) { + boolean checkPatterns(List ritualSetups, Vector3i centerPosition, World world, Vector3i placedBlockPosition, String placedBlockId) { + List possibleSetups = new ArrayList<>(ritualSetups); + boolean didChange = false; + for (Integer possibleSetup : possibleSetups) { + List ritualPatterns = ritualDefinitions.getPatterns(possibleSetup); + boolean didChangeThisSetup = false; + for (RitualPattern ritualPattern : ritualPatterns) { + RitualSetupState state = checkPattern(ritualPattern, centerPosition, world, placedBlockPosition, placedBlockId); + if(state.equals(RitualSetupState.INCOMPLETE)) { + ritualSetups.remove(possibleSetup); + didChangeThisSetup = false; + break; + } else if (state.equals(RitualSetupState.CHANGED)) { + didChangeThisSetup = true; + } + } + didChange |= didChangeThisSetup; + } + return didChange; + } + + RitualSetupState checkPattern(RitualPattern ritualPattern, Vector3i centerPosition, World world, Vector3i placedBlockPosition, String placedBlockId) { int countMatches = 0; int radius = ritualPattern.radius(); + boolean validBlockChanged = false; for (int ix = centerPosition.x - radius; ix <= centerPosition.x + radius; ix++) { for (int iy = centerPosition.y - radius; iy <= centerPosition.y + radius; iy++) { for (int iz = centerPosition.z - radius; iz <= centerPosition.z + radius; iz++) { Vector3i samplePosition = new Vector3i(ix, iy, iz); String blockId; + boolean blockChanged; if (samplePosition.equals(placedBlockPosition)) { blockId = placedBlockId; + blockChanged = true; } else { blockId = getBlockId(samplePosition, world); + blockChanged = false; } if (blockId.equals(ritualPattern.blockId())) { countMatches++; + validBlockChanged |= blockChanged; } } } } - return countMatches >= ritualPattern.amount(); + // the pattern now just has enough or not enough matching blocks + if (countMatches == ritualPattern.amount() && validBlockChanged) { + return RitualSetupState.CHANGED; + // the pattern state stayed the same + } else if (countMatches >= ritualPattern.amount()) { + return RitualSetupState.COMPLETE; + } else { + return RitualSetupState.INCOMPLETE; + } } - int getMaxRadius(List ritualSetups) { + int getMaxPatternRadius(List ritualSetups) { int maxRadius = 0; for (Integer ritualSetup : ritualSetups) { List ritualPatterns = ritualDefinitions.getPatterns(ritualSetup); @@ -189,6 +235,19 @@ public class RitualSpawner { return maxRadius; } + int getMaxSacrificeRadius(List ritualSetups) { + int maxRadius = 0; + for (Integer ritualSetup : ritualSetups) { + List ritualSacrifices = ritualDefinitions.getSacrifices(ritualSetup); + for (RitualSacrifice ritualSacrifice : ritualSacrifices) { + if (maxRadius < ritualSacrifice.radius()) { + maxRadius = ritualSacrifice.radius(); + } + } + } + return maxRadius; + } + List getFullRitualSetupRange() { List possibleSetups = new ArrayList<>(); for (int i = 0; i < ritualDefinitions.getRitualSetupsCount(); i++) { @@ -211,6 +270,6 @@ public class RitualSpawner { } Vector3i entityToBlockPos(Vector3d entityPosition) { - return new Vector3i(entityPosition, 0); + return new Vector3i(entityPosition.sub(0.5, 1, 0.5), 3); } } diff --git a/src/main/java/dev/hytalemodding/definitions/RitualDefinitions.java b/src/main/java/dev/hytalemodding/definitions/RitualDefinitions.java index 16daa8d..1af5d34 100644 --- a/src/main/java/dev/hytalemodding/definitions/RitualDefinitions.java +++ b/src/main/java/dev/hytalemodding/definitions/RitualDefinitions.java @@ -9,7 +9,7 @@ public class RitualDefinitions { public RitualDefinitions() { // Crude skeleton ritual ritualSetups.add(new RitualSetup("Deco_Bone_Skulls", RitualTypes.SKELETON) - .addPatern("Furniture_Crude_Torch", 2, 4, false, true) + .addPattern("Furniture_Crude_Torch", 2, 4, false, true) .addSacrifice("Ingredient_Life_Essence", 1, 1, true)); } @@ -29,6 +29,10 @@ public class RitualDefinitions { return ritualSetups.get(setupIndex).getPatterns(); } + public List getSacrifices(int setupIndex) { + return ritualSetups.get(setupIndex).getSacrifices(); + } + public RitualSacrifice getSacrificeItemId(int setupIndex, int sacrificeIndex) { return ritualSetups.get(setupIndex).getSacrificeItemId(sacrificeIndex); } diff --git a/src/main/java/dev/hytalemodding/definitions/RitualSetup.java b/src/main/java/dev/hytalemodding/definitions/RitualSetup.java index aed2dde..f73707a 100644 --- a/src/main/java/dev/hytalemodding/definitions/RitualSetup.java +++ b/src/main/java/dev/hytalemodding/definitions/RitualSetup.java @@ -14,7 +14,7 @@ public class RitualSetup { this.centerBlockId = centerBlockId; } - public RitualSetup addPatern(String blockId, int radius, int amount, boolean shouldConsume, boolean shouldInteract) { + public RitualSetup addPattern(String blockId, int radius, int amount, boolean shouldConsume, boolean shouldInteract) { patterns.add(new RitualPattern(blockId, radius, amount, shouldConsume, shouldInteract)); return this; } @@ -40,6 +40,10 @@ public class RitualSetup { return patterns; } + public List getSacrifices() { + return sacrifices; + } + public RitualSacrifice getSacrificeItemId(int index) { return sacrifices.get(index); }