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