New looting system

This commit is contained in:
ceze88 2023-01-16 21:32:17 +01:00
parent a69c8ad0c3
commit 1db481d1aa
9 changed files with 92 additions and 56 deletions

View File

@ -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>

View File

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

View File

@ -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());

View File

@ -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;
}

View File

@ -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() {

View File

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

View File

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

View File

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

View File

@ -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));