mirror of
https://github.com/songoda/UltimateStacker.git
synced 2024-12-27 19:07:41 +01:00
New looting system
This commit is contained in:
parent
a69c8ad0c3
commit
1db481d1aa
2
pom.xml
2
pom.xml
@ -122,7 +122,7 @@
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>SongodaCore</artifactId>
|
||||
<version>2.6.17</version>
|
||||
<version>2.6.18-Dev</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -64,6 +64,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class UltimateStacker extends SongodaPlugin {
|
||||
@ -104,6 +105,8 @@ public class UltimateStacker extends SongodaPlugin {
|
||||
|
||||
@Override
|
||||
public void onPluginDisable() {
|
||||
this.stackingTask.cancel();
|
||||
this.stackingTask = null;
|
||||
this.dataManager.bulkUpdateSpawners(this.spawnerStackManager.getStacks());
|
||||
HologramManager.removeAllHolograms();
|
||||
Async.shutdown();
|
||||
@ -395,7 +398,9 @@ public class UltimateStacker extends SongodaPlugin {
|
||||
* @param location The location to spawn the item
|
||||
*/
|
||||
public static void spawnStackedItem(ItemStack item, int amount, Location location) {
|
||||
location.getWorld().dropItem(location, item, dropped -> {
|
||||
if (item.getType() == Material.AIR) return;
|
||||
Objects.requireNonNull(location.getWorld()).dropItem(location, item, dropped -> {
|
||||
if (dropped.getItemStack().getType() == Material.AIR) return;
|
||||
updateItemMeta(dropped, item, amount);
|
||||
});
|
||||
}
|
||||
|
@ -63,6 +63,9 @@ public class DeathListeners implements Listener {
|
||||
if (event.getEntityType() == EntityType.PLAYER
|
||||
|| event.getEntityType() == EntityType.ARMOR_STAND) return;
|
||||
|
||||
//Respect MythicMobs
|
||||
if (plugin.getCustomEntityManager().isCustomEntity(entity)) return;
|
||||
|
||||
boolean custom = Settings.CUSTOM_DROPS.getBoolean();
|
||||
List<Drop> drops = custom ? plugin.getLootablesManager().getDrops(event.getEntity())
|
||||
: event.getDrops().stream().map(Drop::new).collect(Collectors.toList());
|
||||
|
@ -11,6 +11,8 @@ import com.songoda.core.lootables.loot.LootManager;
|
||||
import com.songoda.core.lootables.loot.Lootable;
|
||||
import com.songoda.ultimatestacker.UltimateStacker;
|
||||
import com.songoda.ultimatestacker.settings.Settings;
|
||||
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity;
|
||||
import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntityManager;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.Creeper;
|
||||
@ -21,11 +23,13 @@ import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LootablesManager {
|
||||
|
||||
@ -98,35 +102,7 @@ public class LootablesManager {
|
||||
}
|
||||
|
||||
public List<Drop> getDrops(LivingEntity entity, int times) {
|
||||
List<Drop> toDrop = new ArrayList<>();
|
||||
if (entity instanceof Ageable && !((Ageable) entity).isAdult() && !(entity instanceof Zombie)
|
||||
|| !lootManager.getRegisteredLootables().containsKey(entity.getType().name())) return toDrop;
|
||||
|
||||
Lootable lootable = lootManager.getRegisteredLootables().get(entity.getType().name());
|
||||
int looting = entity.getKiller() != null
|
||||
&& entity.getKiller().getItemInHand().containsEnchantment(Enchantment.LOOT_BONUS_MOBS)
|
||||
? entity.getKiller().getItemInHand().getEnchantmentLevel(Enchantment.LOOT_BONUS_MOBS)
|
||||
: 0;
|
||||
|
||||
int rerollChance = Settings.REROLL.getBoolean() ? looting / (looting + 1) : 0;
|
||||
|
||||
Random random = new Random();
|
||||
for (Loot loot : lootable.getRegisteredLoot()) {
|
||||
List<Drop> drops = runLoot(entity, loot, rerollChance, looting);
|
||||
drops.forEach(drop -> {
|
||||
int max = 2 * (int)(times * 0.55); //this generates more than the original, we need to reduce it
|
||||
int amount = random.nextInt((max - times) + 1) + times;
|
||||
if (loot.getChance() > 0) {
|
||||
amount = (int)(amount * loot.getChance()/100);
|
||||
}
|
||||
drop.getItemStack().setAmount(amount);
|
||||
toDrop.add(drop);
|
||||
});
|
||||
}
|
||||
if (toDrop.isEmpty()) {
|
||||
return getDrops(entity, times);
|
||||
}
|
||||
return toDrop;
|
||||
return getDrops(entity, times, 3);
|
||||
}
|
||||
|
||||
public List<Drop> getDrops(LivingEntity entity, int times, int attempts) {
|
||||
@ -141,23 +117,56 @@ public class LootablesManager {
|
||||
? entity.getKiller().getItemInHand().getEnchantmentLevel(Enchantment.LOOT_BONUS_MOBS)
|
||||
: 0;
|
||||
|
||||
int rerollChance = Settings.REROLL.getBoolean() ? looting / (looting + 1) : 0;
|
||||
double extraChance = looting / (looting + 1.0);
|
||||
|
||||
Random random = new Random();
|
||||
for (Loot loot : lootable.getRegisteredLoot()) {
|
||||
List<Drop> drops = runLoot(entity, loot, rerollChance, looting);
|
||||
drops.forEach(drop -> {
|
||||
int max = 2 * (int)(times * 0.55); //this generates more than the original, we need to reduce it
|
||||
int amount = random.nextInt((max - times) + 1) + times;
|
||||
if (loot.getChance() > 0) {
|
||||
amount = (int)(amount * loot.getChance()/100);
|
||||
}
|
||||
drop.getItemStack().setAmount(amount);
|
||||
toDrop.add(drop);
|
||||
});
|
||||
boolean isCharged = entity instanceof Creeper && ((Creeper) entity).isPowered();
|
||||
|
||||
//Run main loot
|
||||
for (Loot loot : lootable.getRegisteredLoot().stream().filter(loot -> loot.getMaterial() != null).collect(Collectors.toList())) {
|
||||
if (loot.isRequireCharged() && !isCharged) continue;
|
||||
if (loot.getOnlyDropFor().size() != 0 && loot.getOnlyDropFor().stream().noneMatch(type -> entity.getKiller() != null && type == entity.getKiller().getType())) continue;
|
||||
int finalLooting = loot.isAllowLootingEnchant() ? looting : 0;
|
||||
|
||||
int max = (int) (((loot.getMax() + finalLooting) * times) * (loot.getChance()/100));
|
||||
int min = (int) ((loot.getMin()) * times * (loot.getChance()/100));
|
||||
|
||||
int amount = random.nextInt((max - min) + 1) + min;
|
||||
|
||||
if (amount > 0) {
|
||||
ItemStack item = entity.getFireTicks() > 0
|
||||
? loot.getBurnedMaterial() != null ? loot.getBurnedMaterial().getItem() : loot.getMaterial().getItem()
|
||||
: loot.getMaterial().getItem().clone();
|
||||
item.setAmount(amount);
|
||||
toDrop.add(new Drop(item));
|
||||
}
|
||||
}
|
||||
//Run child loot
|
||||
for (Loot loot : lootable.getRegisteredLoot().stream().filter(loot -> loot.getMaterial() == null).collect(Collectors.toList())) {
|
||||
for (Loot child : loot.getChildLoot()) {
|
||||
if (child.isRequireCharged() && !isCharged) continue;
|
||||
if (loot.getOnlyDropFor().size() != 0 && loot.getOnlyDropFor().stream().noneMatch(type -> entity.getKiller() != null && type == entity.getKiller().getType())) continue;
|
||||
|
||||
int finalLooting = child.isAllowLootingEnchant() ? looting : 0;
|
||||
|
||||
int max = (int) (((loot.getMax() + finalLooting) * times * (loot.getChance()/100)));
|
||||
int min = (int) ((loot.getMin()) * times * (loot.getChance()/100));
|
||||
min = (int) (min - min*0.90);
|
||||
|
||||
int amount = random.nextInt((max - min) + 1) + min;
|
||||
|
||||
if (amount > 0) {
|
||||
ItemStack item = entity.getFireTicks() > 0
|
||||
? child.getBurnedMaterial() != null ? child.getBurnedMaterial().getItem() : child.getMaterial().getItem()
|
||||
: child.getMaterial().getItem().clone();
|
||||
item.setAmount(amount);
|
||||
toDrop.add(new Drop(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (toDrop.isEmpty() && attempts > 0) {
|
||||
return getDrops(entity, times, 2);
|
||||
return getDrops(entity, times, attempts);
|
||||
}
|
||||
return toDrop;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import com.songoda.ultimatestacker.utils.Methods;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ExperienceOrb;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
@ -62,7 +63,7 @@ public class EntityStack extends ColdEntityStack {
|
||||
Async.run(() -> {
|
||||
if (createDuplicates != 0) {
|
||||
List<StackedEntity> stackedEntities = new ArrayList<>();
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0; i < createDuplicates; i++) {
|
||||
StackedEntity entity = addEntityToStackSilently(getStackedEntity(hostEntity, true));
|
||||
if (entity != null)
|
||||
@ -71,15 +72,20 @@ public class EntityStack extends ColdEntityStack {
|
||||
plugin.getDataManager().createStackedEntities(this, stackedEntities);
|
||||
|
||||
createDuplicates = 0;
|
||||
updateNametag();
|
||||
}
|
||||
if (!Settings.ENTITY_NAMETAGS.getBoolean()) return;
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(UltimateStacker.getInstance(), () -> {
|
||||
if (hostEntity == null) return;
|
||||
|
||||
hostEntity.setCustomNameVisible(!Settings.HOLOGRAMS_ON_LOOK_ENTITY.getBoolean());
|
||||
hostEntity.setCustomName(Methods.compileEntityName(hostEntity, getAmount()));
|
||||
}, hostEntity == null ? 1L : 0L);
|
||||
});
|
||||
updateNametag();
|
||||
}
|
||||
|
||||
public void updateNametag() {
|
||||
if (hostEntity == null) {
|
||||
//Delay with 1 tick to make sure the entity is loaded.
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(UltimateStacker.getInstance(), this::updateNametag, 1L);
|
||||
return;
|
||||
}
|
||||
hostEntity.setCustomNameVisible(!Settings.HOLOGRAMS_ON_LOOK_ENTITY.getBoolean());
|
||||
hostEntity.setCustomName(Methods.compileEntityName(hostEntity, getAmount()));
|
||||
}
|
||||
|
||||
public LivingEntity getHostEntity() {
|
||||
|
@ -24,4 +24,6 @@ public abstract class CustomEntity {
|
||||
public abstract String getNBTIdentifier(Entity entity);
|
||||
|
||||
public abstract LivingEntity spawnFromIdentifier(String string, Location location);
|
||||
|
||||
public abstract boolean isCustomEntity(Entity entity);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class CustomEntityManager {
|
||||
|
||||
public CustomEntity getCustomEntity(Entity entity) {
|
||||
for (CustomEntity customEntity : registeredCustomEntities) {
|
||||
if (customEntity.isMatchingType(entity)) {
|
||||
if (customEntity.isMatchingType(entity) && customEntity.isCustomEntity(entity)) {
|
||||
if (Settings.BLACKLISTED_CUSTOM_ENTITIES.getStringList()
|
||||
.contains((customEntity.getPluginName() + "_" + customEntity.getNBTIdentifier(entity)).toLowerCase()))
|
||||
continue;
|
||||
@ -42,4 +42,8 @@ public class CustomEntityManager {
|
||||
public List<CustomEntity> getRegisteredCustomEntities() {
|
||||
return Collections.unmodifiableList(registeredCustomEntities);
|
||||
}
|
||||
|
||||
public boolean isCustomEntity(Entity entity) {
|
||||
return getCustomEntity(entity) != null && getCustomEntity(entity).isCustomEntity(entity);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import io.lumine.mythic.core.mobs.ActiveMob;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public class MythicMobsCustomEntity extends CustomEntity {
|
||||
@ -37,7 +38,7 @@ public class MythicMobsCustomEntity extends CustomEntity {
|
||||
|
||||
@Override
|
||||
public boolean isSimilar(LivingEntity original, LivingEntity entity) {
|
||||
if (!isMatchingType(original) || !isMatchingType(entity)) return false;
|
||||
if (!isMatchingType(original) || !isMatchingType(entity) || getMob(entity) == null) return false;
|
||||
return getMob(original).getType().equals(getMob(entity).getType());
|
||||
}
|
||||
|
||||
@ -48,12 +49,17 @@ public class MythicMobsCustomEntity extends CustomEntity {
|
||||
|
||||
@Override
|
||||
public LivingEntity spawnFromIdentifier(String string, Location location) {
|
||||
if (!getMobManager().getMythicMob(string).isPresent()) {
|
||||
if (getMobManager().getMythicMob(string).isPresent()) {
|
||||
return null;
|
||||
}
|
||||
return (LivingEntity)getMobManager().getMythicMob(string).get().spawn(BukkitAdapter.adapt(location), 1).getEntity().getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomEntity(Entity entity) {
|
||||
return getMob(entity) != null;
|
||||
}
|
||||
|
||||
private ActiveMob getMob(Entity entity) {
|
||||
return MythicBukkit.inst().getMobManager().getMythicMobInstance(entity);
|
||||
}
|
||||
|
@ -118,8 +118,9 @@ public class Methods {
|
||||
String displayName = TextUtils.formatText(UltimateStacker.getInstance().getMobFile().getString("Mobs." + entity.getType().name() + ".Display Name"));
|
||||
|
||||
CustomEntity customEntity = UltimateStacker.getInstance().getCustomEntityManager().getCustomEntity(entity);
|
||||
if (customEntity != null)
|
||||
if (customEntity != null) {
|
||||
displayName = customEntity.getDisplayName(entity);
|
||||
}
|
||||
|
||||
nameFormat = nameFormat.replace("{TYPE}", displayName);
|
||||
nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount));
|
||||
|
Loading…
Reference in New Issue
Block a user