Compare commits
5
Commits
5feb2b851f
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58bd7499ce | ||
|
|
15d66f5ac8 | ||
|
|
e0db794528 | ||
|
|
19dcbb3412 | ||
|
|
8521d309e0 |
No files matched your search
+1
-1
@@ -26,7 +26,7 @@ group = dev.hytalemodding
|
|||||||
manifest_group = HytaleModding
|
manifest_group = HytaleModding
|
||||||
|
|
||||||
# Human-readable mod name.
|
# Human-readable mod name.
|
||||||
mod_name = Replace Me
|
mod_name = Ritual Mod
|
||||||
|
|
||||||
# Fully-qualified plugin entry point class.
|
# Fully-qualified plugin entry point class.
|
||||||
main_class = dev.hytalemodding.RitualPlugin
|
main_class = dev.hytalemodding.RitualPlugin
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
|
|||||||
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
|
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
|
||||||
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
|
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
|
||||||
import com.hypixel.hytale.server.core.util.Config;
|
import com.hypixel.hytale.server.core.util.Config;
|
||||||
|
import dev.hytalemodding.config.RitualConfig;
|
||||||
import dev.hytalemodding.events.RitualBreakBlockEvent;
|
import dev.hytalemodding.events.RitualBreakBlockEvent;
|
||||||
|
import dev.hytalemodding.events.RitualDropItemEvent;
|
||||||
import dev.hytalemodding.events.RitualPlaceBlockEvent;
|
import dev.hytalemodding.events.RitualPlaceBlockEvent;
|
||||||
import dev.hytalemodding.commands.ExampleCommand;
|
import dev.hytalemodding.commands.ExampleCommand;
|
||||||
import dev.hytalemodding.config.ExampleConfig;
|
import dev.hytalemodding.config.ExampleConfig;
|
||||||
@@ -17,11 +19,11 @@ public class RitualPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||||
|
|
||||||
private static Config<ExampleConfig> config = null;
|
private static Config<RitualConfig> config = null;
|
||||||
|
|
||||||
public RitualPlugin(@Nonnull JavaPluginInit init) {
|
public RitualPlugin(@Nonnull JavaPluginInit init) {
|
||||||
super(init);
|
super(init);
|
||||||
config = this.withConfig("example_config", ExampleConfig.CODEC);
|
config = this.withConfig("ritual_config", RitualConfig.CODEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -32,12 +34,13 @@ public class RitualPlugin extends JavaPlugin {
|
|||||||
RitualSpawner ritualSpawner = new RitualSpawner();
|
RitualSpawner ritualSpawner = new RitualSpawner();
|
||||||
this.getEntityStoreRegistry().registerSystem(new RitualPlaceBlockEvent(ritualSpawner));
|
this.getEntityStoreRegistry().registerSystem(new RitualPlaceBlockEvent(ritualSpawner));
|
||||||
this.getEntityStoreRegistry().registerSystem(new RitualBreakBlockEvent(ritualSpawner));
|
this.getEntityStoreRegistry().registerSystem(new RitualBreakBlockEvent(ritualSpawner));
|
||||||
|
this.getEntityStoreRegistry().registerSystem(new RitualDropItemEvent(ritualSpawner));
|
||||||
|
|
||||||
// Example
|
// Example
|
||||||
this.getCommandRegistry().registerCommand(new ExampleCommand("example", "An example command"));
|
/*this.getCommandRegistry().registerCommand(new ExampleCommand("example", "An example command"));
|
||||||
if (getConfig().get().isEnabledWelcomeMessage()) {
|
if (getConfig().get().isEnabledWelcomeMessage()) {
|
||||||
this.getEventRegistry().registerGlobal(PlayerReadyEvent.class, ExampleEvent::onPlayerReady);
|
this.getEventRegistry().registerGlobal(PlayerReadyEvent.class, ExampleEvent::onPlayerReady);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,7 +51,7 @@ public class RitualPlugin extends JavaPlugin {
|
|||||||
protected void shutdown() {
|
protected void shutdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Config<ExampleConfig> getConfig() {
|
public static Config<RitualConfig> getConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.hytalemodding;
|
||||||
|
|
||||||
|
public enum RitualSetupState {
|
||||||
|
INCOMPLETE,
|
||||||
|
COMPLETE,
|
||||||
|
CHANGED
|
||||||
|
}
|
||||||
@@ -1,13 +1,324 @@
|
|||||||
package dev.hytalemodding;
|
package dev.hytalemodding;
|
||||||
|
|
||||||
|
import com.hypixel.hytale.component.Ref;
|
||||||
|
import com.hypixel.hytale.component.RemoveReason;
|
||||||
|
import com.hypixel.hytale.component.Store;
|
||||||
|
import com.hypixel.hytale.math.vector.Rotation3f;
|
||||||
|
import com.hypixel.hytale.protocol.SoundCategory;
|
||||||
|
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
|
||||||
|
import com.hypixel.hytale.server.core.asset.type.soundevent.config.SoundEvent;
|
||||||
|
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
|
||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
|
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||||
|
import com.hypixel.hytale.server.npc.NPCPlugin;
|
||||||
|
import dev.hytalemodding.definitions.*;
|
||||||
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class RitualSpawner {
|
public class RitualSpawner {
|
||||||
public void blockChangeEvent(String itemId, Vector3i targetPosition, World world) {
|
RitualDefinitions ritualDefinitions = new RitualDefinitions();
|
||||||
String blockId = world.getBlockType(targetPosition).getId();
|
|
||||||
|
public void blockChangeEvent(String blockId, Vector3i targetPosition, World world, boolean gotPlaced) {
|
||||||
|
String placedRemovedString;
|
||||||
|
if (gotPlaced) {
|
||||||
|
placedRemovedString = "placed";
|
||||||
|
} else {
|
||||||
|
placedRemovedString = "removed";
|
||||||
|
}
|
||||||
RitualPlugin.LOGGER.atInfo().log(
|
RitualPlugin.LOGGER.atInfo().log(
|
||||||
"a block got placed or removed at the position: %d - %d - %d with the block id: %s and with the item id in hand: %s",
|
"a block got %s at the position: %d, %d, %d with the block id: %s",
|
||||||
targetPosition.x, targetPosition.y, targetPosition.z, blockId, itemId);
|
placedRemovedString, targetPosition.x, targetPosition.y, targetPosition.z, blockId);
|
||||||
|
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"
|
||||||
|
);
|
||||||
|
String soundId;
|
||||||
|
if (gotPlaced) {
|
||||||
|
soundId = "SFX_Skeleton_Praetorian_Alerted";
|
||||||
|
} else {
|
||||||
|
soundId = "SFX_Torch_Off";
|
||||||
|
}
|
||||||
|
int soundIndex = SoundEvent.getAssetMap().getIndex(soundId);
|
||||||
|
world.execute(() -> {
|
||||||
|
// Play sound
|
||||||
|
SoundUtil.playSoundEvent3d(soundIndex, SoundCategory.SFX, blockToEntityPos(ritualCenter), world.getEntityStore().getStore());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sacrificeDropEvent(String itemId, Vector3d targetPosition, World world, Store<EntityStore> store, Ref<EntityStore> ref) {
|
||||||
|
Vector3i blockPosition = entityToBlockPos(targetPosition);
|
||||||
|
/*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);
|
||||||
|
AtomicInteger setupIndex = new AtomicInteger(-1);
|
||||||
|
RitualTypes ritualType = getRitualTypeFromSacrifice(itemId, blockPosition, world, setupIndex);
|
||||||
|
if (!ritualType.equals(RitualTypes.NONE)) {
|
||||||
|
RitualPlugin.LOGGER.atInfo().log("Ritual complete");
|
||||||
|
if (ritualType.equals(RitualTypes.SKELETON)) {
|
||||||
|
world.execute(() -> {
|
||||||
|
NPCPlugin.get().spawnNPC(world.getEntityStore().getStore(), "Skeleton", null, blockToEntityPos(blockPosition), new Rotation3f(0, 0, 0));
|
||||||
|
});
|
||||||
|
} else if (ritualType.equals(RitualTypes.YEDI)) {
|
||||||
|
world.execute(() -> {
|
||||||
|
NPCPlugin.get().spawnNPC(world.getEntityStore().getStore(), "Yeti", null, blockToEntityPos(blockPosition), new Rotation3f(0, 0, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (setupIndex.get() >= 0) {
|
||||||
|
removeUsedBlocks(setupIndex.get(), blockPosition, world);
|
||||||
|
}
|
||||||
|
if (ritualDefinitions.getSacrifices(setupIndex.get()).getFirst().shouldConsume() && ref.isValid()) {
|
||||||
|
store.removeEntity(ref, RemoveReason.REMOVE); // Only supports one sacrifice for now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RitualTypes getRitualTypeFromSacrifice(String itemId, Vector3i centerPosition, World world, AtomicInteger setupIndex) {
|
||||||
|
List<Integer> 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<Integer> setupsAtPosition = new ArrayList<>(possibleSetups);
|
||||||
|
checkCenterBlock(setupsAtPosition, blockId);
|
||||||
|
if (!setupsAtPosition.isEmpty()) {
|
||||||
|
checkPatterns(setupsAtPosition, samplePosition, world, samplePosition, "Empty");
|
||||||
|
if (!setupsAtPosition.isEmpty()) {
|
||||||
|
centerPosition.set(samplePosition);
|
||||||
|
setupIndex.set(setupsAtPosition.getFirst());
|
||||||
|
return ritualDefinitions.getRitualType(setupsAtPosition.getFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RitualTypes.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RitualTypes getRitualTypeFromBlock(String blockId, Vector3i blockPosition, World world, boolean onlyShowChanges) {
|
||||||
|
List<Integer> 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<Integer> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkCenterBlock(List<Integer> ritualSetups, String blockId) {
|
||||||
|
ritualSetups.removeIf(ritualSetup -> !ritualDefinitions.getCenterBlockId(ritualSetup).equals(blockId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkPatternPalette(List<Integer> ritualSetups, String blockId) {
|
||||||
|
List<Integer> possibleSetups = new ArrayList<>(ritualSetups);
|
||||||
|
for (Integer possibleSetup : possibleSetups) {
|
||||||
|
boolean isPossibleSetup = false;
|
||||||
|
List<RitualPattern> ritualPatterns = ritualDefinitions.getPatterns(possibleSetup);
|
||||||
|
for (RitualPattern ritualPattern : ritualPatterns) {
|
||||||
|
if (ritualPattern.blockId().equals(blockId)) {
|
||||||
|
isPossibleSetup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isPossibleSetup) {
|
||||||
|
ritualSetups.remove(possibleSetup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkSacrificePalette(List<Integer> ritualSetups, String itemId) {
|
||||||
|
List<Integer> possibleSetups = new ArrayList<>(ritualSetups);
|
||||||
|
for (Integer possibleSetup : possibleSetups) {
|
||||||
|
boolean isPossibleSetup = false;
|
||||||
|
List<RitualSacrifice> ritualSacrifices = ritualDefinitions.getSacrifices(possibleSetup);
|
||||||
|
for (RitualSacrifice ritualSacrifice : ritualSacrifices) {
|
||||||
|
if (ritualSacrifice.itemId().equals(itemId)) {
|
||||||
|
isPossibleSetup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isPossibleSetup) {
|
||||||
|
ritualSetups.remove(possibleSetup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkPatterns(List<Integer> ritualSetups, Vector3i centerPosition, World world, Vector3i placedBlockPosition, String placedBlockId) {
|
||||||
|
List<Integer> possibleSetups = new ArrayList<>(ritualSetups);
|
||||||
|
boolean didChange = false;
|
||||||
|
for (Integer possibleSetup : possibleSetups) {
|
||||||
|
List<RitualPattern> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeUsedBlocks(int index, Vector3i centerPosition, World world) {
|
||||||
|
if (ritualDefinitions.getShouldConsumeCenterBlock(index)) {
|
||||||
|
world.setBlock(centerPosition.x, centerPosition.y, centerPosition.z, "Empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RitualPattern> ritualPatterns = ritualDefinitions.getPatterns(index);
|
||||||
|
for (RitualPattern ritualPattern : ritualPatterns) {
|
||||||
|
int radius = ritualPattern.radius();
|
||||||
|
int amountRemaining = ritualPattern.amount();
|
||||||
|
int side = 2 * radius + 1;
|
||||||
|
int total = side * side * side;
|
||||||
|
|
||||||
|
if (ritualPattern.shouldConsume()) {
|
||||||
|
for (int i = 0; i < total; i++) {
|
||||||
|
int ix = centerPosition.x - radius + (i % side);
|
||||||
|
int iy = centerPosition.y - radius + ((i / side) % side);
|
||||||
|
int iz = centerPosition.z - radius + (i / (side * side));
|
||||||
|
|
||||||
|
Vector3i samplePosition = new Vector3i(ix, iy, iz);
|
||||||
|
if (getBlockId(samplePosition, world).equals(ritualPattern.blockId())) {
|
||||||
|
world.setBlock(samplePosition.x, samplePosition.y, samplePosition.z, "Empty");
|
||||||
|
amountRemaining--;
|
||||||
|
if (amountRemaining <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInteractionState() {
|
||||||
|
//world.setBlockInteractionState(, new BlockType("Empty"), "Empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
int getMaxPatternRadius(List<Integer> ritualSetups) {
|
||||||
|
int maxRadius = 0;
|
||||||
|
for (Integer ritualSetup : ritualSetups) {
|
||||||
|
List<RitualPattern> ritualPatterns = ritualDefinitions.getPatterns(ritualSetup);
|
||||||
|
for (RitualPattern ritualPattern : ritualPatterns) {
|
||||||
|
if (maxRadius < ritualPattern.radius()) {
|
||||||
|
maxRadius = ritualPattern.radius();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getMaxSacrificeRadius(List<Integer> ritualSetups) {
|
||||||
|
int maxRadius = 0;
|
||||||
|
for (Integer ritualSetup : ritualSetups) {
|
||||||
|
List<RitualSacrifice> ritualSacrifices = ritualDefinitions.getSacrifices(ritualSetup);
|
||||||
|
for (RitualSacrifice ritualSacrifice : ritualSacrifices) {
|
||||||
|
if (maxRadius < ritualSacrifice.radius()) {
|
||||||
|
maxRadius = ritualSacrifice.radius();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> getFullRitualSetupRange() {
|
||||||
|
List<Integer> possibleSetups = new ArrayList<>();
|
||||||
|
for (int i = 0; i < ritualDefinitions.getRitualSetupsCount(); i++) {
|
||||||
|
possibleSetups.add(i);
|
||||||
|
}
|
||||||
|
return possibleSetups;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getBlockId(Vector3i samplePosition, World world) {
|
||||||
|
BlockType blockType = world.getBlockType(samplePosition);
|
||||||
|
String blockId = "Empty";
|
||||||
|
if (blockType != null) {
|
||||||
|
blockId = blockType.getId();
|
||||||
|
}
|
||||||
|
return blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d blockToEntityPos(Vector3i blockPosition) {
|
||||||
|
return new Vector3d(blockPosition).add(new Vector3d(0.5, 1, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3i entityToBlockPos(Vector3d entityPosition) {
|
||||||
|
return new Vector3i(entityPosition.sub(0.5, 1, 0.5), 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.hytalemodding.config;
|
||||||
|
|
||||||
|
import com.hypixel.hytale.codec.Codec;
|
||||||
|
import com.hypixel.hytale.codec.KeyedCodec;
|
||||||
|
import com.hypixel.hytale.codec.builder.BuilderCodec;
|
||||||
|
|
||||||
|
public class RitualConfig {
|
||||||
|
public static final BuilderCodec<RitualConfig> CODEC = BuilderCodec.builder(RitualConfig.class, RitualConfig::new)
|
||||||
|
.append(
|
||||||
|
new KeyedCodec<>("EnableLogging", Codec.BOOLEAN),
|
||||||
|
(ritConfig, aBoolean, extraInfo) -> ritConfig.enableLogging = aBoolean,
|
||||||
|
(ritConfig, extraInfo) -> ritConfig.enableLogging)
|
||||||
|
.add()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private boolean enableLogging;
|
||||||
|
|
||||||
|
private RitualConfig() {}
|
||||||
|
|
||||||
|
public boolean isLoggingEnabled() {
|
||||||
|
return enableLogging;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package dev.hytalemodding.definitions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RitualDefinitions {
|
||||||
|
List<RitualSetup> ritualSetups = new ArrayList<>();
|
||||||
|
|
||||||
|
public RitualDefinitions() {
|
||||||
|
// Crude skeleton ritual
|
||||||
|
ritualSetups.add(new RitualSetup("Deco_Bone_Skulls", true, RitualTypes.SKELETON)
|
||||||
|
.addPattern("Furniture_Crude_Torch", 2, 4, false, true)
|
||||||
|
.addSacrifice("Ingredient_Life_Essence", 1, 1, true));
|
||||||
|
ritualSetups.add(new RitualSetup("Furniture_Temple_Light_Brazier", false, RitualTypes.YEDI)
|
||||||
|
.addPattern("Rock_Crystal_Cyan_Small", 3, 6, false, false)
|
||||||
|
.addPattern("Rubble_Ice", 3, 6, true, false)
|
||||||
|
.addSacrifice("Ingredient_Ice_Essence", 2, 1, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRitualSetupsCount() {
|
||||||
|
return ritualSetups.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualTypes getRitualType(int index) {
|
||||||
|
return ritualSetups.get(index).getRitualType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCenterBlockId(int index) {
|
||||||
|
return ritualSetups.get(index).getCenterBlockId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getShouldConsumeCenterBlock(int index) {
|
||||||
|
return ritualSetups.get(index).getShouldConsumeCenterBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RitualPattern> getPatterns(int setupIndex) {
|
||||||
|
return ritualSetups.get(setupIndex).getPatterns();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RitualSacrifice> getSacrifices(int setupIndex) {
|
||||||
|
return ritualSetups.get(setupIndex).getSacrifices();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualSacrifice getSacrificeItemId(int setupIndex, int sacrificeIndex) {
|
||||||
|
return ritualSetups.get(setupIndex).getSacrificeItemId(sacrificeIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package dev.hytalemodding.definitions;
|
||||||
|
|
||||||
|
public record RitualPattern(String blockId, int radius, int amount, boolean shouldConsume, boolean shouldInteract) { }
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package dev.hytalemodding.definitions;
|
||||||
|
|
||||||
|
public record RitualSacrifice(String itemId, int radius, int amount, boolean shouldConsume) { }
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package dev.hytalemodding.definitions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RitualSetup {
|
||||||
|
RitualTypes ritualType;
|
||||||
|
String centerBlockId;
|
||||||
|
boolean shouldConsumeCenterBlock;
|
||||||
|
List<RitualPattern> patterns = new ArrayList<>();
|
||||||
|
List<RitualSacrifice> sacrifices = new ArrayList<>();
|
||||||
|
|
||||||
|
public RitualSetup(String centerBlockId, boolean shouldConsumeCenterBlock, RitualTypes ritualType) {
|
||||||
|
this.centerBlockId = centerBlockId;
|
||||||
|
this.shouldConsumeCenterBlock = shouldConsumeCenterBlock;
|
||||||
|
this.ritualType = ritualType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualSetup addPattern(String blockId, int radius, int amount, boolean shouldConsume, boolean shouldInteract) {
|
||||||
|
patterns.add(new RitualPattern(blockId, radius, amount, shouldConsume, shouldInteract));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualSetup addSacrifice(String itemId, int radius, int amount, boolean shouldConsume) {
|
||||||
|
sacrifices.add(new RitualSacrifice(itemId, radius, amount, shouldConsume));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualTypes getRitualType() {
|
||||||
|
return ritualType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCenterBlockId() {
|
||||||
|
return centerBlockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getShouldConsumeCenterBlock() {
|
||||||
|
return shouldConsumeCenterBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualPattern getPattern(int index) {
|
||||||
|
return patterns.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RitualPattern> getPatterns() {
|
||||||
|
return patterns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RitualSacrifice> getSacrifices() {
|
||||||
|
return sacrifices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RitualSacrifice getSacrificeItemId(int index) {
|
||||||
|
return sacrifices.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.hytalemodding.definitions;
|
||||||
|
|
||||||
|
public enum RitualTypes {
|
||||||
|
NONE,
|
||||||
|
SKELETON,
|
||||||
|
YEDI
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import com.hypixel.hytale.component.CommandBuffer;
|
|||||||
import com.hypixel.hytale.component.Store;
|
import com.hypixel.hytale.component.Store;
|
||||||
import com.hypixel.hytale.component.query.Query;
|
import com.hypixel.hytale.component.query.Query;
|
||||||
import com.hypixel.hytale.component.system.EntityEventSystem;
|
import com.hypixel.hytale.component.system.EntityEventSystem;
|
||||||
|
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
|
||||||
import com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent;
|
import com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent;
|
||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||||
@@ -27,10 +28,14 @@ public class RitualBreakBlockEvent extends EntityEventSystem<EntityStore, BreakB
|
|||||||
@NonNullDecl Store<EntityStore> store,
|
@NonNullDecl Store<EntityStore> store,
|
||||||
@NonNullDecl CommandBuffer<EntityStore> commandBuffer,
|
@NonNullDecl CommandBuffer<EntityStore> commandBuffer,
|
||||||
@NonNullDecl BreakBlockEvent breakBlockEvent) {
|
@NonNullDecl BreakBlockEvent breakBlockEvent) {
|
||||||
String itemHolding = breakBlockEvent.getItemInHand().getItemId();
|
|
||||||
Vector3i blockPosition = breakBlockEvent.getTargetBlock();
|
|
||||||
World world = store.getExternalData().getWorld();
|
World world = store.getExternalData().getWorld();
|
||||||
ritualSpawner.blockChangeEvent(itemHolding, blockPosition, world);
|
Vector3i blockPosition = breakBlockEvent.getTargetBlock();
|
||||||
|
BlockType blockType = world.getBlockType(blockPosition);
|
||||||
|
String blockId = "Empty";
|
||||||
|
if(blockType != null) {
|
||||||
|
blockId = blockType.getId();
|
||||||
|
}
|
||||||
|
ritualSpawner.blockChangeEvent(blockId, blockPosition, world, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NullableDecl
|
@NullableDecl
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package dev.hytalemodding.events;
|
||||||
|
|
||||||
|
import com.hypixel.hytale.component.*;
|
||||||
|
import com.hypixel.hytale.component.query.Query;
|
||||||
|
import com.hypixel.hytale.component.system.EntityEventSystem;
|
||||||
|
import com.hypixel.hytale.server.core.event.events.ecs.DropItemEvent;
|
||||||
|
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
|
||||||
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
|
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||||
|
import dev.hytalemodding.RitualSpawner;
|
||||||
|
import org.checkerframework.checker.nullness.compatqual.NonNullDecl;
|
||||||
|
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
public class RitualDropItemEvent extends EntityEventSystem<EntityStore, DropItemEvent.Drop> {
|
||||||
|
private final RitualSpawner ritualSpawner;
|
||||||
|
public RitualDropItemEvent(RitualSpawner ritualSpawner) {
|
||||||
|
super(DropItemEvent.Drop.class);
|
||||||
|
this.ritualSpawner = ritualSpawner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(int index,
|
||||||
|
@NonNullDecl ArchetypeChunk<EntityStore> archetypeChunk,
|
||||||
|
@NonNullDecl Store<EntityStore> store,
|
||||||
|
@NonNullDecl CommandBuffer<EntityStore> commandBuffer,
|
||||||
|
@NonNullDecl DropItemEvent.Drop dropItemEvent) {
|
||||||
|
String itemId = dropItemEvent.getItemStack().getItemId();
|
||||||
|
Ref<EntityStore> ref = archetypeChunk.getReferenceTo(index);
|
||||||
|
TransformComponent transform = store.getComponent(ref, TransformComponent.getComponentType());
|
||||||
|
assert transform != null;
|
||||||
|
Vector3d targetPosition = transform.getPosition();
|
||||||
|
World world = store.getExternalData().getWorld();
|
||||||
|
ritualSpawner.sacrificeDropEvent(itemId, targetPosition, world, store, archetypeChunk.getReferenceTo(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NullableDecl
|
||||||
|
@Override
|
||||||
|
public Query<EntityStore> getQuery() {
|
||||||
|
return Archetype.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import com.hypixel.hytale.component.CommandBuffer;
|
|||||||
import com.hypixel.hytale.component.Store;
|
import com.hypixel.hytale.component.Store;
|
||||||
import com.hypixel.hytale.component.query.Query;
|
import com.hypixel.hytale.component.query.Query;
|
||||||
import com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent;
|
import com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent;
|
||||||
|
import com.hypixel.hytale.server.core.inventory.ItemStack;
|
||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
import dev.hytalemodding.RitualSpawner;
|
import dev.hytalemodding.RitualSpawner;
|
||||||
import com.hypixel.hytale.component.system.EntityEventSystem;
|
import com.hypixel.hytale.component.system.EntityEventSystem;
|
||||||
@@ -27,10 +28,14 @@ public class RitualPlaceBlockEvent extends EntityEventSystem<EntityStore, PlaceB
|
|||||||
@NonNullDecl Store<EntityStore> store,
|
@NonNullDecl Store<EntityStore> store,
|
||||||
@NonNullDecl CommandBuffer<EntityStore> commandBuffer,
|
@NonNullDecl CommandBuffer<EntityStore> commandBuffer,
|
||||||
@NonNullDecl PlaceBlockEvent placeBlockEvent) {
|
@NonNullDecl PlaceBlockEvent placeBlockEvent) {
|
||||||
String blockId = placeBlockEvent.getItemInHand().getItemId();
|
|
||||||
Vector3i targetPosition = placeBlockEvent.getTargetBlock();
|
|
||||||
World world = store.getExternalData().getWorld();
|
World world = store.getExternalData().getWorld();
|
||||||
ritualSpawner.blockChangeEvent(blockId, targetPosition, world);
|
Vector3i targetPosition = placeBlockEvent.getTargetBlock();
|
||||||
|
ItemStack itemHolding = placeBlockEvent.getItemInHand();
|
||||||
|
String blockId = "Empty";
|
||||||
|
if(itemHolding != null) {
|
||||||
|
blockId = itemHolding.getItemId();
|
||||||
|
}
|
||||||
|
ritualSpawner.blockChangeEvent(blockId, targetPosition, world, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NullableDecl
|
@NullableDecl
|
||||||
|
|||||||
Reference in new issue
Block a user