diff --git a/src/main/java/io/github/thebusybiscuit/electricspawners/ElectricSpawner.java b/src/main/java/io/github/thebusybiscuit/electricspawners/ElectricSpawner.java index 69f91ac..40f28e5 100644 --- a/src/main/java/io/github/thebusybiscuit/electricspawners/ElectricSpawner.java +++ b/src/main/java/io/github/thebusybiscuit/electricspawners/ElectricSpawner.java @@ -5,10 +5,11 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Mob; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; - +import org.bukkit.configuration.file.FileConfiguration; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; @@ -31,26 +32,27 @@ public class ElectricSpawner extends SimpleSlimefunItem implements EnergyNetComponent { private static final int ENERGY_CONSUMPTION = 240; - private static int lifetime = 0; - private final EntityType entity; + private final boolean forceDisableAI; + private final boolean defaultDisabledAI; - public ElectricSpawner(ItemGroup category, String mob, EntityType type, Research research) { - // @formatter:off + public ElectricSpawner(ItemGroup category, String mob, EntityType type, Research research, boolean forceDisableAI, boolean defaultDisabledAI) { super(category, new SlimefunItemStack("ELECTRIC_SPAWNER_" + mob, "db6bd9727abb55d5415265789d4f2984781a343c68dcaf57f554a5e9aa1cd", "&ePowered Spawner &7(" + ChatUtils.humanize(mob) + ")", "", - "&8\u21E8 &e\u26A1 &7Max Entity Cap: 6", - "&8\u21E8 &e\u26A1 &7512 J Buffer", - "&8\u21E8 &e\u26A1 &7240 J/Mob" + "&8⇨ &e⚡ &7Max Entity Cap: 6", + "&8⇨ &e⚡ &7512 J Buffer", + "&8⇨ &e⚡ &7240 J/Mob", + forceDisableAI ? "&8⇨ &c&lAI Forcefully Disabled" : "" ), RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { - null, SlimefunItems.PLUTONIUM, null, + null, SlimefunItems.PLUTONIUM, null, SlimefunItems.ELECTRIC_MOTOR, new CustomItemStack(Material.SPAWNER, "&bReinforced Spawner", "&7Type: &b" + ChatUtils.humanize(type.toString())), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.LARGE_CAPACITOR, SlimefunItems.BLISTERING_INGOT_3 }); - // @formatter:on this.entity = type; + this.forceDisableAI = forceDisableAI; + this.defaultDisabledAI = defaultDisabledAI; addItemHandler(onBlockPlace()); @@ -59,7 +61,7 @@ SlimefunItems.ELECTRIC_MOTOR, new CustomItemStack(Material.SPAWNER, "&bReinforce @Override public void init() { for (int i = 0; i < 9; i++) { - if (i != 4) { + if (i != 4 && (!forceDisableAI && i != 7)) { addItem(i, new CustomItemStack(Material.LIGHT_GRAY_STAINED_GLASS_PANE, " "), (p, slot, item, action) -> false); } } @@ -68,20 +70,39 @@ public void init() { @Override public void newInstance(BlockMenu menu, Block b) { if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "enabled") == null || BlockStorage.getLocationInfo(b.getLocation(), "enabled").equals("false")) { - menu.replaceExistingItem(4, new CustomItemStack(Material.GUNPOWDER, "&7Enabled: &4\u2718", "", "&e> Click to enable this Machine")); + menu.replaceExistingItem(4, new CustomItemStack(Material.GUNPOWDER, "&7Enabled: &4✘", "", "&e> Click to enable this Machine")); menu.addMenuClickHandler(4, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "enabled", "true"); newInstance(menu, b); return false; }); } else { - menu.replaceExistingItem(4, new CustomItemStack(Material.REDSTONE, "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine")); + menu.replaceExistingItem(4, new CustomItemStack(Material.REDSTONE, "&7Enabled: &2✔", "", "&e> Click to disable this Machine")); menu.addMenuClickHandler(4, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "enabled", "false"); newInstance(menu, b); return false; }); } + + if (!forceDisableAI) { + boolean disableAI = BlockStorage.getLocationInfo(b.getLocation(), "disable_ai") == null ? + defaultDisabledAI : + BlockStorage.getLocationInfo(b.getLocation(), "disable_ai").equals("true"); + + menu.replaceExistingItem(7, new CustomItemStack( + disableAI ? Material.ZOMBIE_HEAD : Material.PLAYER_HEAD, + "&7Mob AI: " + (disableAI ? "&4Disabled" : "&2Enabled"), + "", + "&e> Click to toggle Mob AI" + )); + + menu.addMenuClickHandler(7, (p, slot, item, action) -> { + BlockStorage.addBlockInfo(b, "disable_ai", String.valueOf(!disableAI)); + newInstance(menu, b); + return false; + }); + } } @Override @@ -100,13 +121,13 @@ public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) { private BlockPlaceHandler onBlockPlace() { return new BlockPlaceHandler(false) { - @Override public void onPlayerPlace(BlockPlaceEvent e) { Block b = e.getBlock(); Player p = e.getPlayer(); BlockStorage.addBlockInfo(b, "enabled", "false"); BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); + BlockStorage.addBlockInfo(b, "disable_ai", String.valueOf(forceDisableAI || defaultDisabledAI)); } }; } @@ -115,8 +136,16 @@ public int getEnergyConsumption() { return ENERGY_CONSUMPTION; } + protected void tick(Block b) { - if (lifetime % 3 != 0) { + FileConfiguration config = getAddon().getJavaPlugin().getConfig(); + int tickDelay = config.getInt("spawner-settings.tick-delay", 20); + + String storedTick = BlockStorage.getLocationInfo(b.getLocation(), "last_spawn_tick"); + long lastTick = storedTick != null ? Long.parseLong(storedTick) : 0L; + long currentTick = b.getWorld().getFullTime(); + + if (currentTick - lastTick < tickDelay) { return; } @@ -132,7 +161,6 @@ protected void tick(Block b) { for (Entity n : b.getWorld().getNearbyEntities(b.getLocation(), 4.0, 4.0, 4.0)) { if (n.getType().equals(this.entity)) { count++; - if (count > 6) { return; } @@ -140,13 +168,22 @@ protected void tick(Block b) { } removeCharge(b.getLocation(), getEnergyConsumption()); - b.getWorld().spawnEntity(new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + 1.5D, b.getZ() + 0.5D), this.entity); + Location spawnLoc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + 1.5D, b.getZ() + 0.5D); + Entity spawned = b.getWorld().spawnEntity(spawnLoc, this.entity); + + if (spawned instanceof Mob) { + Mob mob = (Mob) spawned; + boolean disableAI = forceDisableAI || + BlockStorage.getLocationInfo(b.getLocation(), "disable_ai").equals("true"); + mob.setAware(!disableAI); + } + + BlockStorage.addBlockInfo(b, "last_spawn_tick", String.valueOf(currentTick)); } @Override public BlockTicker getItemHandler() { return new BlockTicker() { - @Override public void tick(Block b, SlimefunItem sf, Config data) { ElectricSpawner.this.tick(b); @@ -154,14 +191,12 @@ public void tick(Block b, SlimefunItem sf, Config data) { @Override public void uniqueTick() { - lifetime++; } @Override public boolean isSynchronized() { return true; } - }; } @@ -174,5 +209,4 @@ public int getCapacity() { public EnergyNetComponentType getEnergyComponentType() { return EnergyNetComponentType.CONSUMER; } - -} +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0a32596..d167301 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,10 @@ options: auto-update: true +spawner-settings: + tick-delay: 80 # Delay in ticks per mob spawn task (20 ticks = 1 second) +mob-ai: + force-disable: false # If true, all spawned mobs will have AI disabled and players cannot toggle + default-disabled: false # Default state for new spawners if force-disable is false mobs: - BLAZE - CAVE_SPIDER