use of dev.rosewood.rosestacker.stack.StackedEntity in project RoseStacker by Rosewood-Development.
the class EntityListener method handleEntityTransformation.
private void handleEntityTransformation(EntityTransformEvent event) {
if (this.stackManager.isWorldDisabled(event.getEntity().getWorld()))
return;
if (!this.stackManager.isEntityStackingEnabled())
return;
if (event.getEntity() instanceof Slime) {
if (PersistentDataUtils.isAiDisabled((LivingEntity) event.getEntity()))
event.getTransformedEntities().stream().map(x -> (Slime) x).forEach(PersistentDataUtils::removeEntityAi);
return;
}
if (!(event.getEntity() instanceof LivingEntity) || !(event.getTransformedEntity() instanceof LivingEntity) || event.getEntity().getType() == event.getTransformedEntity().getType() || !this.stackManager.isEntityStacked((LivingEntity) event.getEntity()))
return;
StackedEntity stackedEntity = this.stackManager.getStackedEntity((LivingEntity) event.getEntity());
if (stackedEntity.getStackSize() == 1)
return;
LivingEntity transformedEntity = (LivingEntity) event.getTransformedEntity();
if (Setting.ENTITY_TRANSFORM_ENTIRE_STACK.getBoolean()) {
NMSHandler nmsHandler = NMSAdapter.getHandler();
StackedEntityDataEntry<?> serialized = nmsHandler.getEntityAsNBT(transformedEntity);
event.setCancelled(true);
// Handle mooshroom shearing
if (event.getEntityType() == EntityType.MUSHROOM_COW) {
MushroomCowStackSettings stackSettings = (MushroomCowStackSettings) stackedEntity.getStackSettings();
int mushroomsDropped = 5;
if (stackSettings.shouldDropAdditionalMushroomsPerCowInStack())
mushroomsDropped += (stackedEntity.getStackSize() - 1) * stackSettings.getExtraMushroomsPerCowInStack();
Material dropType = ((MushroomCow) event.getEntity()).getVariant() == Variant.BROWN ? Material.BROWN_MUSHROOM : Material.RED_MUSHROOM;
this.stackManager.preStackItems(GuiUtil.getMaterialAmountAsItemStacks(dropType, mushroomsDropped), event.getEntity().getLocation());
}
boolean aiDisabled = PersistentDataUtils.isAiDisabled((LivingEntity) event.getEntity());
event.getEntity().remove();
Bukkit.getScheduler().scheduleSyncDelayedTask(this.rosePlugin, () -> {
this.stackManager.setEntityStackingTemporarilyDisabled(true);
LivingEntity newEntity = nmsHandler.createEntityFromNBT(serialized, transformedEntity.getLocation(), true, transformedEntity.getType());
if (aiDisabled)
PersistentDataUtils.removeEntityAi(newEntity);
StackedEntity newStack = this.stackManager.createEntityStack(newEntity, false);
this.stackManager.setEntityStackingTemporarilyDisabled(false);
if (newStack == null)
return;
for (StackedEntityDataEntry<?> serializedEntity : stackedEntity.getStackedEntityNBT().getAll()) {
LivingEntity entity = nmsHandler.createEntityFromNBT(serializedEntity, transformedEntity.getLocation(), false, transformedEntity.getType());
if (aiDisabled)
PersistentDataUtils.removeEntityAi(entity);
newStack.increaseStackSize(entity);
}
});
} else {
// Make sure disabled AI gets transferred
if (PersistentDataUtils.isAiDisabled((LivingEntity) event.getEntity()))
PersistentDataUtils.removeEntityAi((LivingEntity) event.getTransformedEntity());
if (event.getTransformReason() == TransformReason.LIGHTNING) {
// Wait for lightning to disappear
Bukkit.getScheduler().scheduleSyncDelayedTask(this.rosePlugin, stackedEntity::decreaseStackSize, 20);
} else {
Bukkit.getScheduler().runTask(this.rosePlugin, stackedEntity::decreaseStackSize);
}
}
}
use of dev.rosewood.rosestacker.stack.StackedEntity in project RoseStacker by Rosewood-Development.
the class EntityListener method onEntityTeleport.
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityTeleport(EntityPortalEvent event) {
if (event.getTo() == null || event.getFrom().getWorld() == event.getTo().getWorld())
return;
if (this.stackManager.isWorldDisabled(event.getEntity().getWorld()))
return;
Entity entity = event.getEntity();
if (entity instanceof LivingEntity) {
if (!this.stackManager.isEntityStackingEnabled())
return;
LivingEntity livingEntity = (LivingEntity) entity;
StackedEntity stackedEntity = this.stackManager.getStackedEntity(livingEntity);
if (stackedEntity != null) {
Bukkit.getScheduler().runTask(this.rosePlugin, () -> {
this.stackManager.changeStackingThread(livingEntity.getUniqueId(), stackedEntity, event.getFrom().getWorld(), event.getTo().getWorld());
stackedEntity.updateDisplay();
});
}
} else if (entity instanceof Item) {
if (!this.stackManager.isItemStackingEnabled())
return;
Item item = (Item) entity;
StackedItem stackedItem = this.stackManager.getStackedItem(item);
if (stackedItem != null)
event.setCancelled(true);
}
}
use of dev.rosewood.rosestacker.stack.StackedEntity in project RoseStacker by Rosewood-Development.
the class EntityListener method onEntityDamage.
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof LivingEntity) || event.getEntity().getType() == EntityType.ARMOR_STAND || event.getEntity().getType() == EntityType.PLAYER)
return;
LivingEntity entity = (LivingEntity) event.getEntity();
if (this.stackManager.isWorldDisabled(entity.getWorld()))
return;
if (!this.stackManager.isEntityStackingEnabled())
return;
StackedEntity stackedEntity = this.stackManager.getStackedEntity(entity);
if (stackedEntity == null || stackedEntity.getStackSize() == 1)
return;
if (!Setting.ENTITY_SHARE_DAMAGE_CONDITIONS.getStringList().contains(event.getCause().name()))
return;
double damage = event.getFinalDamage();
List<LivingEntity> killedEntities = new ArrayList<>();
List<LivingEntity> internalEntities = StackerUtils.deconstructStackedEntities(stackedEntity);
for (LivingEntity internal : internalEntities) {
double health = internal.getHealth();
if (health - damage <= 0) {
killedEntities.add(internal);
} else {
internal.setHealth(health - damage);
}
}
// Only try dropping loot if something actually died
if (!killedEntities.isEmpty()) {
internalEntities.removeIf(killedEntities::contains);
// Pick a random amount of exp to drop based on the entity type
// This is only an incredibly rough estimate and isn't 1:1 with vanilla
int experience;
Class<? extends Entity> type = stackedEntity.getStackSettings().getEntityType().getEntityClass();
if (type == null || NPC.class.isAssignableFrom(type) || Golem.class.isAssignableFrom(type) || type == Bat.class) {
experience = 0;
} else if (Animals.class.isAssignableFrom(type)) {
experience = StackerUtils.randomInRange(1, 3);
} else if (type == Wither.class) {
experience = 50;
} else if (type == Blaze.class || Guardian.class.isAssignableFrom(type)) {
experience = 10;
} else {
experience = 5;
}
stackedEntity.dropPartialStackLoot(killedEntities, new ArrayList<>(), experience);
Player killer = entity.getKiller();
if (killer != null && killedEntities.size() - 1 > 0)
killer.incrementStatistic(Statistic.KILL_ENTITY, entity.getType(), killedEntities.size() - 1);
}
StackerUtils.reconstructStackedEntities(stackedEntity, internalEntities);
}
use of dev.rosewood.rosestacker.stack.StackedEntity in project RoseStacker by Rosewood-Development.
the class EntityListener method handleSheepShear.
public static boolean handleSheepShear(RosePlugin rosePlugin, ItemStack shears, Entity entity) {
if (entity.getType() != EntityType.SHEEP)
return false;
StackManager stackManager = rosePlugin.getManager(StackManager.class);
if (stackManager.isWorldDisabled(entity.getWorld()))
return false;
if (!stackManager.isEntityStackingEnabled())
return false;
Sheep sheepEntity = (Sheep) entity;
StackedEntity stackedEntity = stackManager.getStackedEntity(sheepEntity);
if (stackedEntity == null || stackedEntity.getStackSize() == 1)
return false;
SheepStackSettings sheepStackSettings = (SheepStackSettings) stackedEntity.getStackSettings();
if (!sheepStackSettings.shouldShearAllSheepInStack())
return false;
ItemUtils.damageTool(shears);
ItemStack baseSheepWool = new ItemStack(ItemUtils.getWoolMaterial(sheepEntity.getColor()), getWoolDropAmount());
sheepEntity.setSheared(true);
List<ItemStack> drops = new ArrayList<>(Collections.singletonList(baseSheepWool));
stackManager.setEntityUnstackingTemporarilyDisabled(true);
Bukkit.getScheduler().runTaskAsynchronously(RoseStacker.getInstance(), () -> {
try {
List<Sheep> sheepList = StackerUtils.deconstructStackedEntities(stackedEntity).stream().map(x -> (Sheep) x).collect(Collectors.toList());
for (Sheep sheep : sheepList) {
if (!sheep.isSheared()) {
ItemStack sheepWool = new ItemStack(ItemUtils.getWoolMaterial(sheep.getColor()), getWoolDropAmount());
sheep.setSheared(true);
drops.add(sheepWool);
}
}
StackerUtils.reconstructStackedEntities(stackedEntity, sheepList);
Bukkit.getScheduler().runTask(RoseStacker.getInstance(), () -> stackManager.preStackItems(drops, sheepEntity.getLocation()));
} finally {
stackManager.setEntityUnstackingTemporarilyDisabled(false);
}
});
return true;
}
use of dev.rosewood.rosestacker.stack.StackedEntity 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