use of dev.rosewood.rosestacker.stack.settings.EntityStackSettings in project RoseStacker by Rosewood-Development.
the class InteractListener method onInteract.
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onInteract(PlayerInteractEvent event) {
Block clickedBlock = event.getClickedBlock();
ItemStack item = event.getItem();
if (item == null || event.getAction() != Action.RIGHT_CLICK_BLOCK || clickedBlock == null)
return;
StackManager stackManager = this.rosePlugin.getManager(StackManager.class);
if (stackManager.isWorldDisabled(event.getPlayer().getWorld()))
return;
if (stackManager.isSpawnerStackingEnabled()) {
// Handle spawner conversion before we try to spawn entities
if (clickedBlock.getType() == Material.SPAWNER && ItemUtils.isSpawnEgg(item.getType()) && ItemUtils.getStackedItemStackAmount(item) == 1) {
StackedSpawner stackedSpawner = stackManager.getStackedSpawner(clickedBlock);
if (stackedSpawner == null)
stackedSpawner = stackManager.createSpawnerStack(clickedBlock, 1, false);
EntityStackSettings stackSettings = this.rosePlugin.getManager(StackSettingManager.class).getEntityStackSettings(item.getType());
if (stackSettings != null && stackSettings.getEntityType() == stackedSpawner.getSpawnerTile().getSpawnedType()) {
// Don't allow converting spawners if it's the exact same type... that just wastes spawn eggs
event.setCancelled(true);
return;
}
if (!event.getPlayer().hasPermission("rosestacker.spawnerconvert")) {
event.setCancelled(true);
return;
}
if (Setting.SPAWNER_CONVERT_REQUIRE_SAME_AMOUNT.getBoolean() && item.getAmount() < stackedSpawner.getStackSize() && event.getPlayer().getGameMode() != GameMode.CREATIVE) {
event.setCancelled(true);
this.rosePlugin.getManager(LocaleManager.class).sendMessage(event.getPlayer(), "spawner-convert-not-enough");
return;
}
StackedSpawner finalStackedSpawner = stackedSpawner;
Bukkit.getScheduler().runTask(this.rosePlugin, () -> {
// Make sure spawners convert and update their display properly
finalStackedSpawner.updateSpawnerProperties(false);
finalStackedSpawner.updateDisplay();
if (finalStackedSpawner.getStackSize() != 1 && event.getPlayer().getGameMode() != GameMode.CREATIVE)
item.setAmount(item.getAmount() - finalStackedSpawner.getStackSize() + 1);
});
return;
}
}
Location spawnLocation = clickedBlock.getRelative(event.getBlockFace()).getLocation();
// Center on block
spawnLocation.add(0.5, 0, 0.5);
if (this.spawnEntities(null, spawnLocation, item) && clickedBlock.getType() != Material.SPAWNER) {
ItemUtils.takeOneItem(event.getPlayer(), event.getHand());
event.setCancelled(true);
}
}
use of dev.rosewood.rosestacker.stack.settings.EntityStackSettings in project RoseStacker by Rosewood-Development.
the class StackingThread method tryStackEntity.
/**
* Tries to stack a StackedEntity with all other StackedEntities
*
* @param stackedEntity the StackedEntity to try to stack
*/
private void tryStackEntity(StackedEntity stackedEntity) {
EntityStackSettings stackSettings = stackedEntity.getStackSettings();
if (stackSettings == null)
return;
if (stackedEntity.checkNPC()) {
this.removeEntityStack(stackedEntity);
return;
}
LivingEntity entity = stackedEntity.getEntity();
if (this.isRemoved(entity))
return;
if (!WorldGuardHook.testLocation(entity.getLocation()))
return;
Collection<Entity> nearbyEntities;
Predicate<Entity> predicate = x -> x.getType() == entity.getType();
if (!Setting.ENTITY_MERGE_ENTIRE_CHUNK.getBoolean()) {
nearbyEntities = this.entityCacheManager.getNearbyEntities(entity.getLocation(), stackSettings.getMergeRadius(), predicate);
} else {
nearbyEntities = this.entityCacheManager.getEntitiesInChunk(entity.getLocation(), predicate);
}
Set<StackedEntity> targetEntities = new HashSet<>();
targetEntities.add(stackedEntity);
for (Entity otherEntity : nearbyEntities) {
if (entity == otherEntity || this.isRemoved(otherEntity))
continue;
StackedEntity other = this.stackedEntities.get(otherEntity.getUniqueId());
if (other == null)
continue;
if (stackSettings.testCanStackWith(stackedEntity, other, false) && (!Setting.ENTITY_REQUIRE_LINE_OF_SIGHT.getBoolean() || EntityUtils.hasLineOfSight(entity, otherEntity, 0.75, false)) && WorldGuardHook.testLocation(otherEntity.getLocation()))
targetEntities.add(other);
}
StackedEntity increased;
int totalSize;
List<StackedEntity> removable = new ArrayList<>(targetEntities.size());
if (!Setting.ENTITY_MIN_STACK_COUNT_ONLY_INDIVIDUALS.getBoolean()) {
increased = targetEntities.stream().max(StackedEntity::compareTo).orElse(stackedEntity);
targetEntities.remove(increased);
totalSize = increased.getStackSize();
for (StackedEntity target : targetEntities) {
if (totalSize + target.getStackSize() <= stackSettings.getMaxStackSize()) {
totalSize += target.getStackSize();
removable.add(target);
}
}
} else {
increased = stackedEntity;
targetEntities.remove(increased);
totalSize = 1;
int totalStackSize = increased.getStackSize();
for (StackedEntity target : targetEntities) {
if (totalStackSize + target.getStackSize() <= stackSettings.getMaxStackSize()) {
totalSize++;
totalStackSize += target.getStackSize();
removable.add(target);
}
}
}
if (removable.isEmpty() || totalSize < stackSettings.getMinStackSize())
return;
EntityStackEvent entityStackEvent = new EntityStackEvent(removable, increased);
Bukkit.getPluginManager().callEvent(entityStackEvent);
if (entityStackEvent.isCancelled())
return;
for (StackedEntity toStack : removable) {
stackSettings.applyStackProperties(toStack.getEntity(), increased.getEntity());
increased.increaseStackSize(toStack.getEntity());
increased.increaseStackSize(toStack.getStackedEntityNBT());
this.removeEntityStack(toStack);
}
Runnable removeTask = () -> removable.stream().map(StackedEntity::getEntity).forEach(Entity::remove);
if (Bukkit.isPrimaryThread()) {
removeTask.run();
} else {
Bukkit.getScheduler().runTask(this.rosePlugin, removeTask);
}
}
use of dev.rosewood.rosestacker.stack.settings.EntityStackSettings in project RoseStacker by Rosewood-Development.
the class MobSpawningMethod method spawnEntitiesIntoNearbyStacks.
private int spawnEntitiesIntoNearbyStacks(StackedSpawner stackedSpawner, int spawnAmount, Set<Location> locations, List<StackedEntity> nearbyEntities, StackManager stackManager) {
EntityStackSettings entityStackSettings = RoseStacker.getInstance().getManager(StackSettingManager.class).getEntityStackSettings(this.entityType);
List<StackedEntity> stackedEntities = new ArrayList<>(nearbyEntities);
List<Location> possibleLocations = new ArrayList<>(locations);
if (this.entityType.getEntityClass() == null)
return 0;
boolean ageable = Ageable.class.isAssignableFrom(this.entityType.getEntityClass());
int successfulSpawns = 0;
if (stackManager.isEntityStackingEnabled() && entityStackSettings.isStackingEnabled() && Setting.SPAWNER_SPAWN_INTO_NEARBY_STACKS.getBoolean()) {
List<StackedEntity> newStacks = new ArrayList<>();
NMSHandler nmsHandler = NMSAdapter.getHandler();
for (int i = 0; i < spawnAmount; i++) {
if (possibleLocations.isEmpty())
break;
Location location = possibleLocations.get(this.random.nextInt(possibleLocations.size()));
LivingEntity entity = nmsHandler.createNewEntityUnspawned(this.entityType, location, CreatureSpawnEvent.SpawnReason.SPAWNER);
SpawnerFlagPersistenceHook.flagSpawnerSpawned(entity);
if (ageable)
((Ageable) entity).setAdult();
if ((stackedSpawner.getStackSettings().isMobAIDisabled() && (!Setting.SPAWNER_DISABLE_MOB_AI_ONLY_PLAYER_PLACED.getBoolean() || stackedSpawner.isPlacedByPlayer())) || Setting.ENTITY_DISABLE_ALL_MOB_AI.getBoolean())
PersistentDataUtils.removeEntityAi(entity);
PersistentDataUtils.tagSpawnedFromSpawner(entity);
entityStackSettings.applySpawnerSpawnedProperties(entity);
StackedEntity newStack = new StackedEntity(entity);
Optional<StackedEntity> matchingEntity = stackedEntities.stream().filter(x -> WorldGuardHook.testLocation(x.getLocation()) && entityStackSettings.testCanStackWith(x, newStack, false, true)).findFirst();
if (matchingEntity.isPresent()) {
matchingEntity.get().increaseStackSize(entity);
} else {
stackedEntities.add(newStack);
newStacks.add(newStack);
possibleLocations.remove(location);
}
successfulSpawns++;
}
Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> {
stackManager.setEntityStackingTemporarilyDisabled(true);
for (StackedEntity stackedEntity : newStacks) {
LivingEntity entity = stackedEntity.getEntity();
SpawnerSpawnEvent spawnerSpawnEvent = new SpawnerSpawnEvent(entity, stackedSpawner.getSpawner());
Bukkit.getPluginManager().callEvent(spawnerSpawnEvent);
if (spawnerSpawnEvent.isCancelled())
continue;
nmsHandler.spawnExistingEntity(stackedEntity.getEntity(), CreatureSpawnEvent.SpawnReason.SPAWNER, Setting.SPAWNER_BYPASS_REGION_SPAWNING_RULES.getBoolean());
entity.setVelocity(Vector.getRandom().multiply(0.01));
stackManager.addEntityStack(stackedEntity);
}
stackManager.setEntityStackingTemporarilyDisabled(false);
// Spawn particles for new entities and update nametags
for (StackedEntity entity : newStacks) {
entity.updateDisplay();
World world = entity.getLocation().getWorld();
if (world != null)
world.spawnParticle(Particle.EXPLOSION_NORMAL, entity.getLocation().clone().add(0, 0.75, 0), 5, 0.25, 0.25, 0.25, 0.01);
}
});
} else {
successfulSpawns = Math.min(spawnAmount, possibleLocations.size());
Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> {
NMSHandler nmsHandler = NMSAdapter.getHandler();
for (int i = 0; i < spawnAmount; i++) {
if (possibleLocations.isEmpty())
break;
Location location = possibleLocations.remove(this.random.nextInt(possibleLocations.size()));
World world = location.getWorld();
if (world == null)
continue;
LivingEntity entity = nmsHandler.spawnEntityWithReason(this.entityType, location, CreatureSpawnEvent.SpawnReason.SPAWNER, Setting.SPAWNER_BYPASS_REGION_SPAWNING_RULES.getBoolean());
entityStackSettings.applySpawnerSpawnedProperties(entity);
SpawnerFlagPersistenceHook.flagSpawnerSpawned(entity);
SpawnerSpawnEvent spawnerSpawnEvent = new SpawnerSpawnEvent(entity, stackedSpawner.getSpawner());
Bukkit.getPluginManager().callEvent(spawnerSpawnEvent);
if (spawnerSpawnEvent.isCancelled()) {
entity.remove();
continue;
}
// Spawn Particles
if (entity.isValid())
entity.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, entity.getLocation().clone().add(0, 0.75, 0), 5, 0.25, 0.25, 0.25, 0.01);
}
});
}
return successfulSpawns;
}
use of dev.rosewood.rosestacker.stack.settings.EntityStackSettings in project RoseStacker by Rosewood-Development.
the class ItemUtils method getEntityAsStackedItemStack.
public static ItemStack getEntityAsStackedItemStack(EntityType entityType, int amount) {
EntityStackSettings stackSettings = RoseStacker.getInstance().getManager(StackSettingManager.class).getEntityStackSettings(entityType);
Material spawnEggMaterial = stackSettings.getEntityTypeData().getSpawnEggMaterial();
if (spawnEggMaterial == null)
return null;
ItemStack itemStack = new ItemStack(spawnEggMaterial);
if (amount == 1)
return itemStack;
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null)
return itemStack;
StringPlaceholders placeholders = StringPlaceholders.builder("amount", amount).addPlaceholder("name", stackSettings.getDisplayName()).build();
String displayString = RoseStacker.getInstance().getManager(LocaleManager.class).getLocaleMessage("entity-stack-display-spawn-egg", placeholders);
itemMeta.setDisplayName(displayString);
// Set the lore, if defined
List<String> lore = RoseStacker.getInstance().getManager(LocaleManager.class).getLocaleMessages("stack-item-lore-entity", placeholders);
if (!lore.isEmpty())
itemMeta.setLore(lore);
itemStack.setItemMeta(itemMeta);
// Set stack size
NMSHandler nmsHandler = NMSAdapter.getHandler();
itemStack = nmsHandler.setItemStackNBT(itemStack, "StackSize", amount);
return itemStack;
}
use of dev.rosewood.rosestacker.stack.settings.EntityStackSettings in project RoseStacker by Rosewood-Development.
the class BreedingListener method onBreed.
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBreed(PlayerInteractEntityEvent event) {
Entity entity = event.getRightClicked();
if (!Setting.ENTITY_CUMULATIVE_BREEDING.getBoolean() || !(entity instanceof Animals))
return;
Animals animal = (Animals) entity;
if (!animal.canBreed())
return;
StackManager stackManager = this.rosePlugin.getManager(StackManager.class);
if (!stackManager.isEntityStackingEnabled())
return;
StackedEntity stackedEntity = stackManager.getStackedEntity(animal);
if (stackedEntity == null)
return;
Player player = event.getPlayer();
EntityStackSettings stackSettings = stackedEntity.getStackSettings();
ItemStack breedingItem = player.getInventory().getItem(event.getHand());
if (!stackSettings.getEntityTypeData().isValidBreedingMaterial(breedingItem.getType()) || (player.getGameMode() != GameMode.CREATIVE && breedingItem.getAmount() < 2))
return;
if (PersistentDataUtils.isAiDisabled(animal) && Setting.SPAWNER_DISABLE_MOB_AI_OPTIONS_DISABLE_BREEDING.getBoolean()) {
event.setCancelled(true);
return;
}
int stackSize = stackedEntity.getStackSize();
if (stackSize < 2)
return;
Class<? extends Entity> entityClass = animal.getType().getEntityClass();
if (entityClass == null)
return;
event.setCancelled(true);
// Take the items for breeding
int totalChildren;
if (player.getGameMode() != GameMode.CREATIVE) {
int requiredFood = Math.min(stackSize, breedingItem.getAmount());
breedingItem.setAmount(breedingItem.getAmount() - requiredFood);
totalChildren = requiredFood / 2;
} else {
// Creative mode should allow the entire stack to breed half as many babies as the total size
totalChildren = stackSize / 2;
}
// Reset breeding timer and play the breeding effect
animal.setAge(6000);
animal.setBreedCause(player.getUniqueId());
animal.playEffect(EntityEffect.LOVE_HEARTS);
boolean disableAi = PersistentDataUtils.isAiDisabled(animal);
// Drop experience and spawn entities a few ticks later
int f_totalChildren = totalChildren;
Bukkit.getScheduler().runTaskLater(this.rosePlugin, () -> {
for (int i = 0; i < f_totalChildren; i++) animal.getWorld().spawn(animal.getLocation(), entityClass, x -> {
Ageable baby = (Ageable) x;
baby.setBaby();
if (disableAi)
PersistentDataUtils.removeEntityAi(baby);
});
StackerUtils.dropExperience(animal.getLocation(), totalChildren, 7 * totalChildren, totalChildren);
}, 30);
}
Aggregations