Search in sources :

Example 6 with NMSHandler

use of dev.rosewood.rosestacker.nms.NMSHandler in project RoseStacker by Rosewood-Development.

the class ConversionHandler method createEntityStackNBT.

/**
 * Used to fill in the missing entity stack nbt data
 *
 * @param entityType The type of entity
 * @param amount The amount of nbt entries to create
 * @param location The location of the main entity
 * @return A list of nbt data
 */
protected StackedEntityDataStorage createEntityStackNBT(EntityType entityType, int amount, Location location) {
    NMSHandler nmsHandler = NMSAdapter.getHandler();
    StackedEntityDataStorage stackedEntityDataStorage = nmsHandler.createEntityDataStorage(nmsHandler.createNewEntityUnspawned(entityType, location, CreatureSpawnEvent.SpawnReason.CUSTOM));
    for (int i = 0; i < amount - 1; i++) stackedEntityDataStorage.addFirst(nmsHandler.createNewEntityUnspawned(entityType, location, CreatureSpawnEvent.SpawnReason.CUSTOM));
    return stackedEntityDataStorage;
}
Also used : StackedEntityDataStorage(dev.rosewood.rosestacker.nms.storage.StackedEntityDataStorage) NMSHandler(dev.rosewood.rosestacker.nms.NMSHandler)

Example 7 with NMSHandler

use of dev.rosewood.rosestacker.nms.NMSHandler in project RoseStacker by Rosewood-Development.

the class StackedEntity method dropPartialStackLoot.

/**
 * Drops loot for entities that are part of the stack.
 * Does not include loot for the current entity (except for nether stars for withers).
 *
 * @param internalEntities The entities which should be part of this stack
 * @param existingLoot The loot from this.entity, nullable
 * @param droppedExp The exp dropped from this.entity
 */
public void dropPartialStackLoot(List<LivingEntity> internalEntities, Collection<ItemStack> existingLoot, int droppedExp) {
    // Cache the current entity just in case it somehow changes while we are processing the loot
    LivingEntity thisEntity = this.entity;
    Collection<ItemStack> loot = new ArrayList<>();
    if (existingLoot != null)
        loot.addAll(existingLoot);
    // The stack loot can either be processed synchronously or asynchronously depending on a setting
    // It should always be processed async unless errors are caused by other plugins
    boolean async = Setting.ENTITY_DEATH_EVENT_RUN_ASYNC.getBoolean();
    boolean multiplyCustomLoot = Setting.ENTITY_MULTIPLY_CUSTOM_LOOT.getBoolean();
    Runnable mainTask = () -> {
        boolean callEvents = Setting.ENTITY_TRIGGER_DEATH_EVENT_FOR_ENTIRE_STACK_KILL.getBoolean();
        int totalExp = droppedExp;
        NMSHandler nmsHandler = NMSAdapter.getHandler();
        boolean isAnimal = thisEntity instanceof Animals;
        boolean isSlime = thisEntity instanceof Slime;
        boolean isAccurateSlime = isSlime && ((SlimeStackSettings) this.stackSettings).isAccurateDropsWithKillEntireStackOnDeath();
        for (LivingEntity entity : internalEntities) {
            // Propagate fire ticks and last damage cause
            entity.setFireTicks(thisEntity.getFireTicks());
            entity.setLastDamageCause(thisEntity.getLastDamageCause());
            nmsHandler.setLastHurtBy(entity, thisEntity.getKiller());
            int iterations = 1;
            if (isSlime) {
                Slime slime = (Slime) entity;
                if (isAccurateSlime) {
                    int totalSlimes = 1;
                    int size = slime.getSize();
                    while (size > 1) {
                        size /= 2;
                        int currentSlimes = totalSlimes;
                        totalSlimes = StackerUtils.randomInRange(currentSlimes * 2, currentSlimes * 4);
                    }
                    iterations = totalSlimes;
                }
                slime.setSize(1);
            }
            boolean isBaby = isAnimal && !((Animals) entity).isAdult();
            int desiredExp = isBaby ? 0 : droppedExp;
            for (int i = 0; i < iterations; i++) {
                Collection<ItemStack> entityLoot = isBaby ? Collections.emptyList() : EntityUtils.getEntityLoot(entity, thisEntity.getKiller(), thisEntity.getLocation());
                if (callEvents && !multiplyCustomLoot) {
                    EntityDeathEvent deathEvent = new AsyncEntityDeathEvent(entity, new ArrayList<>(entityLoot), desiredExp);
                    Bukkit.getPluginManager().callEvent(deathEvent);
                    totalExp += deathEvent.getDroppedExp();
                    loot.addAll(deathEvent.getDrops());
                } else {
                    loot.addAll(entityLoot);
                    totalExp += desiredExp;
                }
            }
        }
        if (multiplyCustomLoot) {
            EntityDeathEvent deathEvent = new EntityDeathEvent(thisEntity, new ArrayList<>(), 0);
            for (int i = 0, k = this.getStackSize() - 1; i < k; i++) loot.addAll(deathEvent.getDrops());
            totalExp += deathEvent.getDroppedExp() * (this.getStackSize() - 1);
        }
        int finalTotalExp = totalExp;
        Runnable finishTask = () -> {
            RoseStacker.getInstance().getManager(StackManager.class).preStackItems(loot, thisEntity.getLocation());
            if (Setting.ENTITY_DROP_ACCURATE_EXP.getBoolean() && finalTotalExp > 0)
                StackerUtils.dropExperience(thisEntity.getLocation(), finalTotalExp, finalTotalExp, finalTotalExp / 2);
        };
        // Withers always drop nether stars on death, however this isn't in the actual wither loot table for some reason
        if (this.entity.getType() == EntityType.WITHER)
            loot.addAll(GuiUtil.getMaterialAmountAsItemStacks(Material.NETHER_STAR, internalEntities.size()));
        if (async) {
            Bukkit.getScheduler().runTask(RoseStacker.getInstance(), finishTask);
        } else {
            finishTask.run();
        }
    };
    if (async) {
        Bukkit.getScheduler().runTaskAsynchronously(RoseStacker.getInstance(), mainTask);
    } else {
        mainTask.run();
    }
}
Also used : AsyncEntityDeathEvent(dev.rosewood.rosestacker.event.AsyncEntityDeathEvent) EntityDeathEvent(org.bukkit.event.entity.EntityDeathEvent) AsyncEntityDeathEvent(dev.rosewood.rosestacker.event.AsyncEntityDeathEvent) StackManager(dev.rosewood.rosestacker.manager.StackManager) ArrayList(java.util.ArrayList) Slime(org.bukkit.entity.Slime) NMSHandler(dev.rosewood.rosestacker.nms.NMSHandler) LivingEntity(org.bukkit.entity.LivingEntity) Animals(org.bukkit.entity.Animals) SlimeStackSettings(dev.rosewood.rosestacker.stack.settings.entity.SlimeStackSettings) Collection(java.util.Collection) ItemStack(org.bukkit.inventory.ItemStack)

Example 8 with NMSHandler

use of dev.rosewood.rosestacker.nms.NMSHandler in project RoseStacker by Rosewood-Development.

the class StackedEntity method updateDisplay.

@Override
public void updateDisplay() {
    this.displayName = null;
    String displayName = this.getDisplayName();
    NMSHandler nmsHandler = NMSAdapter.getHandler();
    for (Player player : this.getPlayersInVisibleRange()) nmsHandler.updateEntityNameTagForPlayer(player, this.entity, displayName, this.displayNameVisible);
}
Also used : Player(org.bukkit.entity.Player) NMSHandler(dev.rosewood.rosestacker.nms.NMSHandler)

Example 9 with NMSHandler

use of dev.rosewood.rosestacker.nms.NMSHandler in project RoseStacker by Rosewood-Development.

the class StackedEntity method dropStackLoot.

/**
 * Drops all loot and experience for all internally-stacked entities.
 * Does not include loot for the current entity.
 *
 * @param existingLoot The loot from this.entity, nullable
 * @param droppedExp The exp dropped from this.entity
 */
public void dropStackLoot(Collection<ItemStack> existingLoot, int droppedExp) {
    // Cache the current entity just in case it somehow changes while we are processing the loot
    LivingEntity thisEntity = this.entity;
    Bukkit.getScheduler().runTaskAsynchronously(RoseStacker.getInstance(), () -> {
        List<LivingEntity> internalEntities = new ArrayList<>();
        NMSHandler nmsHandler = NMSAdapter.getHandler();
        for (StackedEntityDataEntry<?> entityNBT : this.serializedStackedEntities.getAll()) {
            LivingEntity entity = nmsHandler.createEntityFromNBT(entityNBT, thisEntity.getLocation(), false, thisEntity.getType());
            if (entity == null)
                continue;
            internalEntities.add(entity);
        }
        Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> this.dropPartialStackLoot(internalEntities, existingLoot, droppedExp));
    });
}
Also used : LivingEntity(org.bukkit.entity.LivingEntity) ArrayList(java.util.ArrayList) NMSHandler(dev.rosewood.rosestacker.nms.NMSHandler)

Example 10 with NMSHandler

use of dev.rosewood.rosestacker.nms.NMSHandler 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;
}
Also used : EntityStackSettings(dev.rosewood.rosestacker.stack.settings.EntityStackSettings) 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) StackedEntity(dev.rosewood.rosestacker.stack.StackedEntity) ArrayList(java.util.ArrayList) StackSettingManager(dev.rosewood.rosestacker.manager.StackSettingManager) SpawnerSpawnEvent(org.bukkit.event.entity.SpawnerSpawnEvent) World(org.bukkit.World) NMSHandler(dev.rosewood.rosestacker.nms.NMSHandler) LivingEntity(org.bukkit.entity.LivingEntity) Location(org.bukkit.Location)

Aggregations

NMSHandler (dev.rosewood.rosestacker.nms.NMSHandler)19 LivingEntity (org.bukkit.entity.LivingEntity)10 StackSettingManager (dev.rosewood.rosestacker.manager.StackSettingManager)6 ArrayList (java.util.ArrayList)6 ItemStack (org.bukkit.inventory.ItemStack)6 StackManager (dev.rosewood.rosestacker.manager.StackManager)4 StackedEntityDataEntry (dev.rosewood.rosestacker.nms.storage.StackedEntityDataEntry)4 StackedEntityDataStorage (dev.rosewood.rosestacker.nms.storage.StackedEntityDataStorage)4 EntityStackSettings (dev.rosewood.rosestacker.stack.settings.EntityStackSettings)4 Collection (java.util.Collection)4 Material (org.bukkit.Material)4 StringPlaceholders (dev.rosewood.rosegarden.utils.StringPlaceholders)3 WorldGuardHook (dev.rosewood.rosestacker.hook.WorldGuardHook)3 Setting (dev.rosewood.rosestacker.manager.ConfigurationManager.Setting)3 EntityCacheManager (dev.rosewood.rosestacker.manager.EntityCacheManager)3 LocaleManager (dev.rosewood.rosestacker.manager.LocaleManager)3 NMSAdapter (dev.rosewood.rosestacker.nms.NMSAdapter)3 StackedEntity (dev.rosewood.rosestacker.stack.StackedEntity)3 PersistentDataUtils (dev.rosewood.rosestacker.utils.PersistentDataUtils)3 StackerUtils (dev.rosewood.rosestacker.utils.StackerUtils)3