Search in sources :

Example 11 with SpawnerStackSettings

use of dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings in project RoseStacker by Rosewood-Development.

the class CommandManager method reload.

@Override
public void reload() {
    LocaleManager localeManager = this.rosePlugin.getManager(LocaleManager.class);
    ConversionManager conversionManager = this.rosePlugin.getManager(ConversionManager.class);
    StackSettingManager stackSettingManager = this.rosePlugin.getManager(StackSettingManager.class);
    // Load custom message strings
    Map<String, String> acfCoreMessages = localeManager.getAcfCoreMessages();
    Map<String, String> acfMinecraftMessages = localeManager.getAcfMinecraftMessages();
    for (Entry<String, String> entry : acfCoreMessages.entrySet()) this.commandManager.getLocales().addMessage(Locale.ENGLISH, MessageKey.of("acf-core." + entry.getKey()), HexUtils.colorify(localeManager.getLocaleMessage("prefix") + entry.getValue()));
    for (Entry<String, String> entry : acfMinecraftMessages.entrySet()) this.commandManager.getLocales().addMessage(Locale.ENGLISH, MessageKey.of("acf-minecraft." + entry.getKey()), HexUtils.colorify(localeManager.getLocaleMessage("prefix") + entry.getValue()));
    CommandCompletions<BukkitCommandCompletionContext> completions = this.commandManager.getCommandCompletions();
    completions.registerStaticCompletion("stackableBlockMaterial", () -> stackSettingManager.getStackableBlockTypes().stream().map(Enum::name).map(String::toLowerCase).collect(Collectors.toSet()));
    completions.registerStaticCompletion("spawnableSpawnerEntityType", () -> stackSettingManager.getStackableSpawnerTypes().stream().map(Enum::name).map(String::toLowerCase).collect(Collectors.toSet()));
    completions.registerStaticCompletion("spawnableEggEntityType", () -> stackSettingManager.getStackableEntityTypes().stream().filter(x -> {
        EntityStackSettings stackSettings = stackSettingManager.getEntityStackSettings(x);
        return stackSettings.getEntityTypeData().getSpawnEggMaterial() != null;
    }).map(Enum::name).map(String::toLowerCase).collect(Collectors.toSet()));
    completions.registerAsyncCompletion("blockStackAmounts", ctx -> {
        Material blockType = ctx.getContextValue(Material.class);
        if (blockType == null)
            return Collections.emptyList();
        BlockStackSettings blockStackSettings = stackSettingManager.getBlockStackSettings(blockType);
        int maxStackAmount = blockStackSettings.getMaxStackSize();
        return Arrays.asList(String.valueOf(maxStackAmount), String.valueOf(maxStackAmount / 2), String.valueOf(maxStackAmount / 4), "<amount>");
    });
    completions.registerAsyncCompletion("spawnerStackAmounts", ctx -> {
        EntityType entityType = ctx.getContextValue(EntityType.class);
        if (entityType == null)
            return Collections.emptySet();
        SpawnerStackSettings spawnerStackSettings = stackSettingManager.getSpawnerStackSettings(entityType);
        int maxStackAmount = spawnerStackSettings.getMaxStackSize();
        return Arrays.asList(String.valueOf(maxStackAmount), String.valueOf(maxStackAmount / 2), String.valueOf(maxStackAmount / 4), "<amount>");
    });
    completions.registerAsyncCompletion("entityStackAmounts", ctx -> {
        EntityType entityType = ctx.getContextValue(EntityType.class);
        if (entityType == null)
            return Collections.emptySet();
        EntityStackSettings entityStackSettings = stackSettingManager.getEntityStackSettings(entityType);
        int maxStackAmount = entityStackSettings.getMaxStackSize();
        return Arrays.asList(String.valueOf(maxStackAmount), String.valueOf(maxStackAmount / 2), String.valueOf(maxStackAmount / 4), "<amount>");
    });
    completions.registerStaticCompletion("giveAmounts", () -> IntStream.rangeClosed(1, 5).mapToObj(String::valueOf).collect(Collectors.toList()));
    completions.registerStaticCompletion("clearallType", () -> Stream.of(ClearallType.values()).map(Enum::name).map(String::toLowerCase).collect(Collectors.toSet()));
    completions.registerStaticCompletion("stackType", () -> Stream.of(StackType.values()).map(Enum::name).map(String::toLowerCase).collect(Collectors.toSet()));
    completions.registerAsyncCompletion("conversionType", ctx -> conversionManager.getEnabledConverters().stream().map(Enum::name).collect(Collectors.toSet()));
    completions.registerAsyncCompletion("conversionEnabledType", ctx -> conversionManager.getEnabledHandlers().stream().map(ConversionHandler::getRequiredDataStackType).map(Enum::name).map(String::toLowerCase).collect(Collectors.toSet()));
    completions.registerAsyncCompletion("translationLocales", ctx -> localeManager.getPossibleTranslationLocales());
    this.commandManager.getCommandConditions().addCondition(int.class, "limits", (c, exec, value) -> {
        if (value == null)
            return;
        if (c.hasConfig("min") && c.getConfigValue("min", 0) > value)
            throw new ConditionFailedException(MessageKeys.PLEASE_SPECIFY_AT_LEAST, "{min}", String.valueOf(c.getConfigValue("min", 0)));
        if (c.hasConfig("max") && c.getConfigValue("max", Integer.MAX_VALUE) < value)
            throw new ConditionFailedException(MessageKeys.PLEASE_SPECIFY_AT_MOST, "{max}", String.valueOf(c.getConfigValue("max", Integer.MAX_VALUE)));
    });
}
Also used : EntityStackSettings(dev.rosewood.rosestacker.stack.settings.EntityStackSettings) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) ConversionHandler(dev.rosewood.rosestacker.conversion.handler.ConversionHandler) Material(org.bukkit.Material) BlockStackSettings(dev.rosewood.rosestacker.stack.settings.BlockStackSettings) EntityType(org.bukkit.entity.EntityType) ConditionFailedException(co.aikar.commands.ConditionFailedException) BukkitCommandCompletionContext(co.aikar.commands.BukkitCommandCompletionContext)

Example 12 with SpawnerStackSettings

use of dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings in project RoseStacker by Rosewood-Development.

the class StackSettingManager method reload.

@Override
public void reload() {
    // Settings files
    File blockSettingsFile = this.getBlockSettingsFile();
    File entitySettingsFile = this.getEntitySettingsFile();
    File itemSettingsFile = this.getItemSettingsFile();
    File spawnerSettingsFile = this.getSpawnerSettingsFile();
    // Flags for if we should save the files
    AtomicBoolean saveBlockSettingsFile = new AtomicBoolean(false);
    AtomicBoolean saveEntitySettingsFile = new AtomicBoolean(false);
    AtomicBoolean saveItemSettingsFile = new AtomicBoolean(false);
    AtomicBoolean saveSpawnerSettingsFile = new AtomicBoolean(false);
    // Load block settings
    CommentedFileConfiguration blockSettingsConfiguration = CommentedFileConfiguration.loadConfiguration(blockSettingsFile);
    StackerUtils.getPossibleStackableBlockMaterials().forEach(x -> {
        BlockStackSettings blockStackSettings = new BlockStackSettings(blockSettingsConfiguration, x);
        this.blockSettings.put(x, blockStackSettings);
        if (blockStackSettings.hasChanges())
            saveBlockSettingsFile.set(true);
    });
    // Load entity settings and data from entity_data.json
    CommentedFileConfiguration entitySettingsConfiguration = CommentedFileConfiguration.loadConfiguration(entitySettingsFile);
    try (InputStream entityDataStream = this.getClass().getResourceAsStream("/entity_data.json");
        Reader entityDataReader = new InputStreamReader(entityDataStream)) {
        JsonParser jsonParser = new JsonParser();
        JsonObject jsonObject = jsonParser.parse(entityDataReader).getAsJsonObject();
        List<Class<EntityStackSettings>> classes = ClassUtils.getClassesOf(this.rosePlugin, PACKAGE_PATH, EntityStackSettings.class);
        List<String> ignoredLoading = new ArrayList<>();
        for (Class<EntityStackSettings> clazz : classes) {
            try {
                EntityStackSettings entityStackSetting = clazz.getConstructor(CommentedFileConfiguration.class, JsonObject.class).newInstance(entitySettingsConfiguration, jsonObject);
                this.entitySettings.put(entityStackSetting.getEntityType(), entityStackSetting);
                if (entityStackSetting.hasChanges())
                    saveEntitySettingsFile.set(true);
            } catch (Exception e) {
                // Log entity settings that failed to load
                // This should only be caused by version incompatibilities
                String className = clazz.getSimpleName();
                ignoredLoading.add(className.substring(0, className.length() - 13));
            }
        }
        if (!ignoredLoading.isEmpty())
            this.rosePlugin.getLogger().warning("Ignored loading stack settings for entities: " + ignoredLoading);
    } catch (Exception e) {
        e.printStackTrace();
    }
    // Load item settings
    CommentedFileConfiguration itemSettingsConfiguration = CommentedFileConfiguration.loadConfiguration(itemSettingsFile);
    Stream.of(Material.values()).sorted(Comparator.comparing(Enum::name)).forEach(x -> {
        ItemStackSettings itemStackSettings = new ItemStackSettings(itemSettingsConfiguration, x);
        this.itemSettings.put(x, itemStackSettings);
        if (itemStackSettings.hasChanges())
            saveItemSettingsFile.set(true);
    });
    // Load spawner settings
    boolean addSpawnerHeaderComments = !spawnerSettingsFile.exists();
    CommentedFileConfiguration spawnerSettingsConfiguration = CommentedFileConfiguration.loadConfiguration(spawnerSettingsFile);
    if (addSpawnerHeaderComments) {
        saveSpawnerSettingsFile.set(true);
        Map<String, String> conditionTags = ConditionTags.getTagDescriptionMap();
        spawnerSettingsConfiguration.addComments("Available Spawn Requirements:", "");
        for (Entry<String, String> entry : conditionTags.entrySet()) {
            String tag = entry.getKey();
            String description = entry.getValue();
            spawnerSettingsConfiguration.addComments(tag + " - " + description);
        }
        spawnerSettingsConfiguration.addComments("", "Valid Blocks: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html", "Valid Biomes: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/Biome.html", "", "Want to remove all requirements? Set the value to the following:", "spawn-requirements: []");
    }
    StackerUtils.getAlphabeticalStackableEntityTypes().forEach(x -> {
        SpawnerStackSettings spawnerStackSettings = new SpawnerStackSettings(spawnerSettingsConfiguration, x);
        this.spawnerSettings.put(x, spawnerStackSettings);
        if (spawnerStackSettings.hasChanges())
            saveSpawnerSettingsFile.set(true);
    });
    // Save files if changes were made
    if (saveBlockSettingsFile.get())
        blockSettingsConfiguration.save(true);
    if (saveEntitySettingsFile.get())
        entitySettingsConfiguration.save(true);
    if (saveItemSettingsFile.get())
        itemSettingsConfiguration.save(true);
    if (saveSpawnerSettingsFile.get())
        spawnerSettingsConfiguration.save(true);
    // Register dynamic permissions on first load
    if (!this.registeredPermissions) {
        PluginManager pluginManager = Bukkit.getPluginManager();
        List<Permission> silktouch = new ArrayList<>();
        List<Permission> nosilk = new ArrayList<>();
        List<Permission> spawnerplace = new ArrayList<>();
        for (EntityType entityType : this.entitySettings.keySet()) {
            String type = entityType.name().toLowerCase();
            silktouch.add(new Permission("rosestacker.silktouch." + type));
            nosilk.add(new Permission("rosestacker.nosilk." + type));
            spawnerplace.add(new Permission("rosestacker.spawnerplace." + type));
        }
        // Register silktouch permissions
        silktouch.forEach(pluginManager::addPermission);
        pluginManager.addPermission(new Permission("rosestacker.silktouch.*", silktouch.stream().collect(Collectors.toMap(Permission::getName, x -> true))));
        // Register nosilk permissions
        nosilk.forEach(pluginManager::addPermission);
        pluginManager.addPermission(new Permission("rosestacker.nosilk.*", nosilk.stream().collect(Collectors.toMap(Permission::getName, x -> true))));
        // Register spawnerplace permissions
        spawnerplace.forEach(pluginManager::addPermission);
        pluginManager.addPermission(new Permission("rosestacker.spawnerplace.*", spawnerplace.stream().collect(Collectors.toMap(Permission::getName, x -> true))));
        this.registeredPermissions = true;
    }
}
Also used : JsonObject(com.google.gson.JsonObject) Manager(dev.rosewood.rosegarden.manager.Manager) Item(org.bukkit.entity.Item) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClassUtils(dev.rosewood.rosegarden.utils.ClassUtils) HashMap(java.util.HashMap) JsonParser(com.google.gson.JsonParser) ItemUtils(dev.rosewood.rosestacker.utils.ItemUtils) ArrayList(java.util.ArrayList) EntityStackSettings(dev.rosewood.rosestacker.stack.settings.EntityStackSettings) Block(org.bukkit.block.Block) Map(java.util.Map) CommentedFileConfiguration(dev.rosewood.rosegarden.config.CommentedFileConfiguration) ItemStackSettings(dev.rosewood.rosestacker.stack.settings.ItemStackSettings) Material(org.bukkit.Material) Bukkit(org.bukkit.Bukkit) CreatureSpawner(org.bukkit.block.CreatureSpawner) Set(java.util.Set) Reader(java.io.Reader) EntityType(org.bukkit.entity.EntityType) LivingEntity(org.bukkit.entity.LivingEntity) InputStreamReader(java.io.InputStreamReader) Collectors(java.util.stream.Collectors) RosePlugin(dev.rosewood.rosegarden.RosePlugin) ConditionTags(dev.rosewood.rosestacker.spawner.conditions.ConditionTags) File(java.io.File) BlockStackSettings(dev.rosewood.rosestacker.stack.settings.BlockStackSettings) Permission(org.bukkit.permissions.Permission) List(java.util.List) Stream(java.util.stream.Stream) Entry(java.util.Map.Entry) StackerUtils(dev.rosewood.rosestacker.utils.StackerUtils) Comparator(java.util.Comparator) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) InputStream(java.io.InputStream) PluginManager(org.bukkit.plugin.PluginManager) ArrayList(java.util.ArrayList) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) JsonObject(com.google.gson.JsonObject) BlockStackSettings(dev.rosewood.rosestacker.stack.settings.BlockStackSettings) ItemStackSettings(dev.rosewood.rosestacker.stack.settings.ItemStackSettings) PluginManager(org.bukkit.plugin.PluginManager) CommentedFileConfiguration(dev.rosewood.rosegarden.config.CommentedFileConfiguration) Permission(org.bukkit.permissions.Permission) JsonParser(com.google.gson.JsonParser) EntityStackSettings(dev.rosewood.rosestacker.stack.settings.EntityStackSettings) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) EntityType(org.bukkit.entity.EntityType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) File(java.io.File)

Example 13 with SpawnerStackSettings

use of dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings in project RoseStacker by Rosewood-Development.

the class ItemSpawningMethod method spawn.

@Override
public void spawn(StackedSpawner stackedSpawner) {
    StackedSpawnerTile spawnerTile = stackedSpawner.getSpawnerTile();
    SpawnerStackSettings stackSettings = stackedSpawner.getStackSettings();
    // Mob spawning logic
    List<ConditionTag> spawnRequirements = new ArrayList<>();
    // Check general spawner conditions // TODO
    List<ConditionTag> perSpawnConditions = spawnRequirements.stream().filter(ConditionTag::isRequiredPerSpawn).collect(Collectors.toList());
    spawnRequirements.removeAll(perSpawnConditions);
    Set<ConditionTag> invalidSpawnConditions = spawnRequirements.stream().filter(x -> !x.check(stackedSpawner, stackedSpawner.getBlock())).collect(Collectors.toSet());
    if (Setting.SPAWNER_SPAWN_ONLY_PLAYER_PLACED.getBoolean() && !stackedSpawner.isPlacedByPlayer())
        invalidSpawnConditions.add(NotPlayerPlacedConditionTag.INSTANCE);
    boolean passedSpawnerChecks = invalidSpawnConditions.isEmpty();
    // Will be removed when they pass
    invalidSpawnConditions.addAll(perSpawnConditions);
    // Spawn the items
    int spawnAmount;
    if (Setting.SPAWNER_SPAWN_COUNT_STACK_SIZE_RANDOMIZED.getBoolean()) {
        if (stackSettings.getSpawnCountStackSizeMultiplier() != -1) {
            int spawnerSpawnCount = Math.max(spawnerTile.getSpawnCount(), 0);
            spawnAmount = StackerUtils.randomInRange(stackedSpawner.getStackSize(), spawnerSpawnCount);
        } else {
            spawnAmount = this.random.nextInt(spawnerTile.getSpawnCount()) + 1;
        }
    } else {
        spawnAmount = spawnerTile.getSpawnCount();
    }
    Bukkit.getScheduler().runTaskAsynchronously(RoseStacker.getInstance(), () -> {
        Set<Location> spawnLocations = new HashSet<>();
        int spawnRange = spawnerTile.getSpawnRange();
        for (int i = 0; i < spawnAmount; i++) {
            int attempts = 0;
            while (attempts < Setting.SPAWNER_MAX_FAILED_SPAWN_ATTEMPTS.getInt()) {
                int xOffset = this.random.nextInt(spawnRange * 2 + 1) - spawnRange;
                int yOffset = !Setting.SPAWNER_USE_VERTICAL_SPAWN_RANGE.getBoolean() ? this.random.nextInt(3) - 1 : this.random.nextInt(spawnRange * 2 + 1) - spawnRange;
                int zOffset = this.random.nextInt(spawnRange * 2 + 1) - spawnRange;
                Location spawnLocation = stackedSpawner.getLocation().clone().add(xOffset + 0.5, yOffset, zOffset + 0.5);
                Block target = stackedSpawner.getLocation().clone().add(xOffset, yOffset, zOffset).getBlock();
                boolean invalid = false;
                for (ConditionTag conditionTag : perSpawnConditions) {
                    if (!conditionTag.check(stackedSpawner, target)) {
                        invalid = true;
                    } else {
                        invalidSpawnConditions.remove(conditionTag);
                    }
                }
                if (invalid) {
                    attempts++;
                    continue;
                }
                if (!passedSpawnerChecks)
                    break;
                spawnLocations.add(spawnLocation);
                break;
            }
        }
        int successfulSpawns = spawnLocations.size() > 0 ? spawnAmount : 0;
        // Drop items
        Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> {
            // Assign each location a portion of the total items to drop
            int amountPerLocation = (int) Math.ceil((double) spawnAmount / spawnLocations.size());
            int amountLeft = spawnAmount;
            for (Location location : spawnLocations) {
                int amount = Math.min(amountPerLocation, amountLeft);
                amountLeft -= amount;
                for (ItemStack itemStack : GuiUtil.getMaterialAmountAsItemStacks(this.itemType, amount)) stackedSpawner.getWorld().dropItemNaturally(location.clone().add(0.5, 0.5, 0.5), itemStack);
                stackedSpawner.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, location.clone().add(0, 0.75, 0), 2, 0.25, 0.25, 0.25, 0.01);
            }
        });
        stackedSpawner.getLastInvalidConditions().clear();
        if (successfulSpawns <= 0) {
            if (invalidSpawnConditions.isEmpty()) {
                stackedSpawner.getLastInvalidConditions().add(NoneConditionTag.class);
            } else {
                List<Class<? extends ConditionTag>> invalidSpawnConditionClasses = new ArrayList<>();
                for (ConditionTag conditionTag : invalidSpawnConditions) invalidSpawnConditionClasses.add(conditionTag.getClass());
                stackedSpawner.getLastInvalidConditions().addAll(invalidSpawnConditionClasses);
            }
            // Spawn particles indicating the spawn did not occur
            stackedSpawner.getWorld().spawnParticle(Particle.SMOKE_NORMAL, stackedSpawner.getLocation().clone().add(0.5, 0.5, 0.5), 50, 0.5, 0.5, 0.5, 0);
        } else {
            // Spawn particles indicating the spawn occurred
            stackedSpawner.getWorld().spawnParticle(Particle.FLAME, stackedSpawner.getLocation().clone().add(0.5, 0.5, 0.5), 50, 0.5, 0.5, 0.5, 0);
            Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> {
                if (stackedSpawner.getBlock().getType() == Material.SPAWNER)
                    PersistentDataUtils.increaseSpawnCount(spawnerTile, successfulSpawns);
            });
        }
    });
}
Also used : Setting(dev.rosewood.rosestacker.manager.ConfigurationManager.Setting) ConditionTag(dev.rosewood.rosestacker.spawner.conditions.ConditionTag) RoseStacker(dev.rosewood.rosestacker.RoseStacker) NoneConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NoneConditionTag) Set(java.util.Set) Random(java.util.Random) StackedSpawner(dev.rosewood.rosestacker.stack.StackedSpawner) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) ItemStack(org.bukkit.inventory.ItemStack) HashSet(java.util.HashSet) Particle(org.bukkit.Particle) List(java.util.List) Block(org.bukkit.block.Block) GuiUtil(dev.rosewood.guiframework.framework.util.GuiUtil) Location(org.bukkit.Location) NotPlayerPlacedConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NotPlayerPlacedConditionTag) StackedSpawnerTile(dev.rosewood.rosestacker.nms.spawner.StackedSpawnerTile) PersistentDataUtils(dev.rosewood.rosestacker.utils.PersistentDataUtils) StackerUtils(dev.rosewood.rosestacker.utils.StackerUtils) Material(org.bukkit.Material) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) Bukkit(org.bukkit.Bukkit) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) ConditionTag(dev.rosewood.rosestacker.spawner.conditions.ConditionTag) NoneConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NoneConditionTag) NotPlayerPlacedConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NotPlayerPlacedConditionTag) ArrayList(java.util.ArrayList) StackedSpawnerTile(dev.rosewood.rosestacker.nms.spawner.StackedSpawnerTile) Block(org.bukkit.block.Block) ItemStack(org.bukkit.inventory.ItemStack) Location(org.bukkit.Location) HashSet(java.util.HashSet)

Example 14 with SpawnerStackSettings

use of dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings in project RoseStacker by Rosewood-Development.

the class MobSpawningMethod method spawn.

@Override
public void spawn(StackedSpawner stackedSpawner) {
    StackedSpawnerTile spawnerTile = stackedSpawner.getSpawnerTile();
    SpawnerStackSettings stackSettings = stackedSpawner.getStackSettings();
    // Mob spawning logic
    List<ConditionTag> spawnRequirements = new ArrayList<>(stackSettings.getSpawnRequirements());
    // Check general spawner conditions
    List<ConditionTag> perSpawnConditions = spawnRequirements.stream().filter(ConditionTag::isRequiredPerSpawn).collect(Collectors.toList());
    spawnRequirements.removeAll(perSpawnConditions);
    Set<ConditionTag> invalidSpawnConditions = spawnRequirements.stream().filter(x -> !x.check(stackedSpawner, stackedSpawner.getBlock())).collect(Collectors.toSet());
    if (Setting.SPAWNER_SPAWN_ONLY_PLAYER_PLACED.getBoolean() && !stackedSpawner.isPlacedByPlayer())
        invalidSpawnConditions.add(NotPlayerPlacedConditionTag.INSTANCE);
    boolean passedSpawnerChecks = invalidSpawnConditions.isEmpty();
    // Will be removed when they pass
    invalidSpawnConditions.addAll(perSpawnConditions);
    // Spawn the mobs
    int spawnAmount;
    if (Setting.SPAWNER_SPAWN_COUNT_STACK_SIZE_RANDOMIZED.getBoolean()) {
        if (stackSettings.getSpawnCountStackSizeMultiplier() != -1) {
            int spawnerSpawnCount = Math.max(spawnerTile.getSpawnCount(), 0);
            spawnAmount = StackerUtils.randomInRange(stackedSpawner.getStackSize(), spawnerSpawnCount);
        } else {
            spawnAmount = this.random.nextInt(spawnerTile.getSpawnCount()) + 1;
        }
    } else {
        spawnAmount = spawnerTile.getSpawnCount();
    }
    EntityCacheManager entityCacheManager = RoseStacker.getInstance().getManager(EntityCacheManager.class);
    StackManager stackManager = RoseStacker.getInstance().getManager(StackManager.class);
    Bukkit.getScheduler().runTaskAsynchronously(RoseStacker.getInstance(), () -> {
        Set<Location> spawnLocations = new HashSet<>();
        int spawnRange = spawnerTile.getSpawnRange();
        for (int i = 0; i < spawnAmount; i++) {
            int attempts = 0;
            while (attempts < Setting.SPAWNER_MAX_FAILED_SPAWN_ATTEMPTS.getInt()) {
                int xOffset = this.random.nextInt(spawnRange * 2 + 1) - spawnRange;
                int yOffset = !Setting.SPAWNER_USE_VERTICAL_SPAWN_RANGE.getBoolean() ? this.random.nextInt(3) - 1 : this.random.nextInt(spawnRange * 2 + 1) - spawnRange;
                int zOffset = this.random.nextInt(spawnRange * 2 + 1) - spawnRange;
                Location spawnLocation = stackedSpawner.getLocation().clone().add(xOffset + 0.5, yOffset, zOffset + 0.5);
                Block target = stackedSpawner.getLocation().clone().add(xOffset, yOffset, zOffset).getBlock();
                boolean invalid = false;
                for (ConditionTag conditionTag : perSpawnConditions) {
                    if (!conditionTag.check(stackedSpawner, target)) {
                        invalid = true;
                    } else {
                        invalidSpawnConditions.remove(conditionTag);
                    }
                }
                if (invalid) {
                    attempts++;
                    continue;
                }
                if (!passedSpawnerChecks)
                    break;
                spawnLocations.add(spawnLocation);
                break;
            }
        }
        EntityType entityType = stackedSpawner.getSpawnerTile().getSpawnedType();
        Predicate<Entity> predicate = entity -> entity.getType() == entityType;
        Collection<Entity> nearbyEntities = entityCacheManager.getNearbyEntities(stackedSpawner.getLocation(), stackSettings.getSpawnRange(), predicate);
        List<StackedEntity> nearbyStackedEntities = new ArrayList<>();
        for (Entity entity : nearbyEntities) {
            StackedEntity stackedEntity = stackManager.getStackedEntity((LivingEntity) entity);
            if (stackedEntity != null)
                nearbyStackedEntities.add(stackedEntity);
        }
        int successfulSpawns = this.spawnEntitiesIntoNearbyStacks(stackedSpawner, spawnAmount, spawnLocations, nearbyStackedEntities, stackManager);
        stackedSpawner.getLastInvalidConditions().clear();
        if (successfulSpawns <= 0) {
            if (invalidSpawnConditions.isEmpty()) {
                stackedSpawner.getLastInvalidConditions().add(NoneConditionTag.class);
            } else {
                List<Class<? extends ConditionTag>> invalidSpawnConditionClasses = new ArrayList<>();
                for (ConditionTag conditionTag : invalidSpawnConditions) invalidSpawnConditionClasses.add(conditionTag.getClass());
                stackedSpawner.getLastInvalidConditions().addAll(invalidSpawnConditionClasses);
            }
            // Spawn particles indicating the spawn did not occur
            stackedSpawner.getWorld().spawnParticle(Particle.SMOKE_NORMAL, stackedSpawner.getLocation().clone().add(0.5, 0.5, 0.5), 50, 0.5, 0.5, 0.5, 0);
        } else {
            // Spawn particles indicating the spawn occurred
            stackedSpawner.getWorld().spawnParticle(Particle.FLAME, stackedSpawner.getLocation().clone().add(0.5, 0.5, 0.5), 50, 0.5, 0.5, 0.5, 0);
            Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> {
                if (stackedSpawner.getBlock().getType() == Material.SPAWNER)
                    PersistentDataUtils.increaseSpawnCount(spawnerTile, successfulSpawns);
            });
        }
    });
}
Also used : RoseStacker(dev.rosewood.rosestacker.RoseStacker) WorldGuardHook(dev.rosewood.rosestacker.hook.WorldGuardHook) StackedEntity(dev.rosewood.rosestacker.stack.StackedEntity) NoneConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NoneConditionTag) Random(java.util.Random) SpawnerSpawnEvent(org.bukkit.event.entity.SpawnerSpawnEvent) StackedSpawner(dev.rosewood.rosestacker.stack.StackedSpawner) ArrayList(java.util.ArrayList) EntityStackSettings(dev.rosewood.rosestacker.stack.settings.EntityStackSettings) HashSet(java.util.HashSet) StackSettingManager(dev.rosewood.rosestacker.manager.StackSettingManager) Block(org.bukkit.block.Block) Location(org.bukkit.Location) NotPlayerPlacedConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NotPlayerPlacedConditionTag) World(org.bukkit.World) NMSHandler(dev.rosewood.rosestacker.nms.NMSHandler) StackedSpawnerTile(dev.rosewood.rosestacker.nms.spawner.StackedSpawnerTile) PersistentDataUtils(dev.rosewood.rosestacker.utils.PersistentDataUtils) Material(org.bukkit.Material) Ageable(org.bukkit.entity.Ageable) Bukkit(org.bukkit.Bukkit) Setting(dev.rosewood.rosestacker.manager.ConfigurationManager.Setting) ConditionTag(dev.rosewood.rosestacker.spawner.conditions.ConditionTag) Entity(org.bukkit.entity.Entity) Predicate(java.util.function.Predicate) CreatureSpawnEvent(org.bukkit.event.entity.CreatureSpawnEvent) Collection(java.util.Collection) Set(java.util.Set) EntityType(org.bukkit.entity.EntityType) LivingEntity(org.bukkit.entity.LivingEntity) EntityCacheManager(dev.rosewood.rosestacker.manager.EntityCacheManager) Collectors(java.util.stream.Collectors) Particle(org.bukkit.Particle) Vector(org.bukkit.util.Vector) StackManager(dev.rosewood.rosestacker.manager.StackManager) SpawnerFlagPersistenceHook(dev.rosewood.rosestacker.hook.SpawnerFlagPersistenceHook) List(java.util.List) Optional(java.util.Optional) StackerUtils(dev.rosewood.rosestacker.utils.StackerUtils) NMSAdapter(dev.rosewood.rosestacker.nms.NMSAdapter) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) SpawnerStackSettings(dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings) StackedEntity(dev.rosewood.rosestacker.stack.StackedEntity) Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) StackedEntity(dev.rosewood.rosestacker.stack.StackedEntity) NoneConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NoneConditionTag) NotPlayerPlacedConditionTag(dev.rosewood.rosestacker.spawner.conditions.tags.NotPlayerPlacedConditionTag) ConditionTag(dev.rosewood.rosestacker.spawner.conditions.ConditionTag) StackManager(dev.rosewood.rosestacker.manager.StackManager) ArrayList(java.util.ArrayList) EntityCacheManager(dev.rosewood.rosestacker.manager.EntityCacheManager) StackedSpawnerTile(dev.rosewood.rosestacker.nms.spawner.StackedSpawnerTile) EntityType(org.bukkit.entity.EntityType) Block(org.bukkit.block.Block) Location(org.bukkit.Location) HashSet(java.util.HashSet)

Aggregations

SpawnerStackSettings (dev.rosewood.rosestacker.stack.settings.SpawnerStackSettings)14 EntityType (org.bukkit.entity.EntityType)10 MobSpawningMethod (dev.rosewood.rosestacker.spawner.spawning.MobSpawningMethod)5 ArrayList (java.util.ArrayList)5 Material (org.bukkit.Material)5 NamespacedKey (org.bukkit.NamespacedKey)5 Block (org.bukkit.block.Block)5 StackManager (dev.rosewood.rosestacker.manager.StackManager)4 StackedSpawner (dev.rosewood.rosestacker.stack.StackedSpawner)4 List (java.util.List)4 LivingEntity (org.bukkit.entity.LivingEntity)4 StackSettingManager (dev.rosewood.rosestacker.manager.StackSettingManager)3 StackedSpawnerTile (dev.rosewood.rosestacker.nms.spawner.StackedSpawnerTile)3 ConditionTag (dev.rosewood.rosestacker.spawner.conditions.ConditionTag)3 BlockStackSettings (dev.rosewood.rosestacker.stack.settings.BlockStackSettings)3 EntityStackSettings (dev.rosewood.rosestacker.stack.settings.EntityStackSettings)3 StackerUtils (dev.rosewood.rosestacker.utils.StackerUtils)3 Set (java.util.Set)3 Collectors (java.util.stream.Collectors)3 ResourceLocation (net.minecraft.resources.ResourceLocation)3