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)));
});
}
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;
}
}
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);
});
}
});
}
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);
});
}
});
}
Aggregations