diff --git a/src/main/java/com/artillexstudios/axminions/api/events/EffectDispatchEvent.java b/src/main/java/com/artillexstudios/axminions/api/events/EffectDispatchEvent.java index 61c14c1..bff5e55 100644 --- a/src/main/java/com/artillexstudios/axminions/api/events/EffectDispatchEvent.java +++ b/src/main/java/com/artillexstudios/axminions/api/events/EffectDispatchEvent.java @@ -5,7 +5,7 @@ import com.artillexstudios.axminions.minions.actions.effects.Effect; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -public class EffectDispatchEvent extends MinionEvent { +public final class EffectDispatchEvent extends MinionEvent { private static final HandlerList HANDLER_LIST = new HandlerList(); private final Effect effect; private final Object argument; diff --git a/src/main/java/com/artillexstudios/axminions/api/events/MinionPlaceEvent.java b/src/main/java/com/artillexstudios/axminions/api/events/MinionPlaceEvent.java new file mode 100644 index 0000000..ebdfc13 --- /dev/null +++ b/src/main/java/com/artillexstudios/axminions/api/events/MinionPlaceEvent.java @@ -0,0 +1,4 @@ +package com.artillexstudios.axminions.api.events; + +public class MinionPlaceEvent { +} diff --git a/src/main/java/com/artillexstudios/axminions/api/events/PreMinionPlaceEvent.java b/src/main/java/com/artillexstudios/axminions/api/events/PreMinionPlaceEvent.java new file mode 100644 index 0000000..012aed4 --- /dev/null +++ b/src/main/java/com/artillexstudios/axminions/api/events/PreMinionPlaceEvent.java @@ -0,0 +1,49 @@ +package com.artillexstudios.axminions.api.events; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public final class PreMinionPlaceEvent extends Event implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private final Player player; + private final Location location; + private boolean cancelled = false; + + public PreMinionPlaceEvent(Player player, Location location) { + this.player = player; + this.location = location; + } + + public Location location() { + return location; + } + + public Player player() { + return player; + } + + @NotNull + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/src/main/java/com/artillexstudios/axminions/config/Config.java b/src/main/java/com/artillexstudios/axminions/config/Config.java index ef055df..f937698 100644 --- a/src/main/java/com/artillexstudios/axminions/config/Config.java +++ b/src/main/java/com/artillexstudios/axminions/config/Config.java @@ -27,6 +27,7 @@ public final class Config { public static int DATABASE_KEEPALIVE_TIME = 0; public static int DATABASE_CONNECTION_TIMEOUT = 5000; public static DatabaseType DATABASE_TYPE = DatabaseType.H2; + public static int TICK_FREQUENCY = 1; public static boolean SHOW_HAND_ANIMATION = true; public static boolean ASYNC_HAND_ANIMATION = false; public static int ASYNC_PROCESSOR_POOL_SIZE = 3; @@ -76,6 +77,7 @@ public final class Config { DATABASE_MAXIMUM_LIFETIME = config.getInt("database.pool.maximum-lifetime", DATABASE_MAXIMUM_LIFETIME); DATABASE_KEEPALIVE_TIME = config.getInt("database.pool.keepalive-time", DATABASE_KEEPALIVE_TIME); DATABASE_CONNECTION_TIMEOUT = config.getInt("database.pool.connection-timeout", DATABASE_CONNECTION_TIMEOUT); + TICK_FREQUENCY = config.getInt("tick-frequency", TICK_FREQUENCY); SHOW_HAND_ANIMATION = config.getBoolean("show-hand-animation", SHOW_HAND_ANIMATION); ASYNC_HAND_ANIMATION = config.getBoolean("async-hand-animation", ASYNC_HAND_ANIMATION); ASYNC_PROCESSOR_POOL_SIZE = config.getInt("async-processor-pool-size", ASYNC_PROCESSOR_POOL_SIZE); diff --git a/src/main/java/com/artillexstudios/axminions/listeners/MinionPlaceListener.java b/src/main/java/com/artillexstudios/axminions/listeners/MinionPlaceListener.java index 9a85bb5..217b1c8 100644 --- a/src/main/java/com/artillexstudios/axminions/listeners/MinionPlaceListener.java +++ b/src/main/java/com/artillexstudios/axminions/listeners/MinionPlaceListener.java @@ -3,9 +3,7 @@ package com.artillexstudios.axminions.listeners; import com.artillexstudios.axapi.items.WrappedItemStack; import com.artillexstudios.axapi.items.component.DataComponents; import com.artillexstudios.axapi.items.nbt.CompoundTag; -import com.artillexstudios.axminions.config.Minions; import com.artillexstudios.axminions.database.DataHandler; -import com.artillexstudios.axminions.minions.Level; import com.artillexstudios.axminions.minions.Minion; import com.artillexstudios.axminions.minions.MinionArea; import com.artillexstudios.axminions.minions.MinionData; @@ -16,7 +14,6 @@ import com.artillexstudios.axminions.utils.Direction; import com.artillexstudios.axminions.utils.LocationUtils; import com.artillexstudios.axminions.utils.LogUtils; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -62,6 +59,7 @@ public final class MinionPlaceListener implements Listener { return; } + event.setCancelled(true); String typeName = compoundTag.getString("axminions_minion_type"); if (typeName == null || typeName.isBlank()) { LogUtils.warn("ItemStack in {}'s hand is an invalid minion; the miniontype is empty!", event.getPlayer().getName()); @@ -77,14 +75,26 @@ public final class MinionPlaceListener implements Listener { // TODO: level itemStack.setAmount(itemStack.getAmount() - 1); Location location = LocationUtils.toBlockCenter(clickedBlock.getRelative(event.getBlockFace()).getLocation()); + + MinionArea area = MinionWorldCache.getArea(location.getWorld()); + if (area == null) { + LogUtils.warn("{} attempted to place minion, but area is null!", event.getPlayer().getName()); + return; + } + + Minion atLocation = area.getMinionAt(location); + if (atLocation != null) { + // TODO: Send message + return; + } + // TODO: Database queries, etc.. // TODO: ownerId MinionData data = new MinionData(0, minionType, Direction.NORTH, null, minionType.level(1), 0, null, null, new HashMap<>()); Minion minion = new Minion(location, data); - MinionArea area = MinionWorldCache.getArea(location.getWorld()); MinionWorldCache.add(minion); DataHandler.insertMinion(minion).thenRun(() -> { - LogUtils.debug("Inserted minion!"); + LogUtils.debug("Inserted minion!"); }); minion.spawn(); area.startTicking(location.getChunk()); diff --git a/src/main/java/com/artillexstudios/axminions/minions/Minion.java b/src/main/java/com/artillexstudios/axminions/minions/Minion.java index 042fb69..8a359ae 100644 --- a/src/main/java/com/artillexstudios/axminions/minions/Minion.java +++ b/src/main/java/com/artillexstudios/axminions/minions/Minion.java @@ -42,14 +42,14 @@ public final class Minion { } public void tick() { - this.tick++; + this.tick += Config.TICK_FREQUENCY; if (this.tick < this.minionData.level().actionTicks()) { if (Config.SHOW_HAND_ANIMATION) { AsyncUtils.run(() -> { if (this.armTick >= 20) return; ArmorStandMeta meta = (ArmorStandMeta) this.entity.meta(); meta.metadata().set(Accessors.RIGHT_ARM_ROTATION, new EulerAngle((-2 + ((double) this.armTick / 10)), 0, 0)); - this.armTick += 2; + this.armTick += (2 * Config.TICK_FREQUENCY); }, Config.ASYNC_HAND_ANIMATION); } return; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 3208b5d..7b24005 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -12,6 +12,11 @@ database: keepalive-time: 0 connection-timeout: 5000 +# How often should we tick minions? +# Increasing this might improve performance a bit. +# If this is increased, minion animations might look a bit choppy. +tick-frequency: 1 + # If the minions should show a hand animation # This has a minimal impact on performance show-hand-animation: true