package net.glowstone.util.loot; import net.glowstone.GlowServer; import net.glowstone.entity.GlowLivingEntity; import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Random; public class LootingManager { private static final Map<EntityType, EntityLootTable> entities = new HashMap<>(); public static void load() throws Exception { String baseDir = "builtin/loot/entities/"; register(EntityType.BAT, baseDir + "bat.json"); register(EntityType.BLAZE, baseDir + "blaze.json"); register(EntityType.CAVE_SPIDER, baseDir + "cave_spider.json"); register(EntityType.CHICKEN, baseDir + "chicken.json"); register(EntityType.COW, baseDir + "cow.json"); register(EntityType.CREEPER, baseDir + "creeper.json"); register(EntityType.DONKEY, baseDir + "horse.json"); register(EntityType.ELDER_GUARDIAN, baseDir + "elder_guardian.json"); register(EntityType.ENDER_DRAGON, baseDir + "ender_dragon.json"); register(EntityType.ENDERMAN, baseDir + "enderman.json"); register(EntityType.ENDERMITE, baseDir + "endermite.json"); register(EntityType.EVOKER, baseDir + "evocation_illager.json"); register(EntityType.GHAST, baseDir + "ghast.json"); register(EntityType.GUARDIAN, baseDir + "guardian.json"); register(EntityType.HORSE, baseDir + "horse.json"); register(EntityType.HUSK, baseDir + "zombie.json"); register(EntityType.IRON_GOLEM, baseDir + "iron_golem.json"); register(EntityType.MAGMA_CUBE, baseDir + "magma_cube.json"); register(EntityType.MULE, baseDir + "horse.json"); register(EntityType.MUSHROOM_COW, baseDir + "mushroom_cow.json"); register(EntityType.LLAMA, baseDir + "llama.json"); register(EntityType.OCELOT, baseDir + "ocelot.json"); register(EntityType.PIG, baseDir + "pig.json"); register(EntityType.PIG_ZOMBIE, baseDir + "pig_zombie.json"); register(EntityType.POLAR_BEAR, baseDir + "polar_bear.json"); register(EntityType.RABBIT, baseDir + "rabbit.json"); register(EntityType.SHEEP, baseDir + "sheep.json"); register(EntityType.SHULKER, baseDir + "shulker.json"); register(EntityType.SILVERFISH, baseDir + "silverfish.json"); register(EntityType.SKELETON, baseDir + "skeleton.json"); register(EntityType.SKELETON_HORSE, baseDir + "skeleton_horse.json"); register(EntityType.SLIME, baseDir + "slime.json"); register(EntityType.SNOWMAN, baseDir + "snowman.json"); register(EntityType.SPIDER, baseDir + "spider.json"); register(EntityType.STRAY, baseDir + "skeleton.json"); register(EntityType.SQUID, baseDir + "squid.json"); register(EntityType.VEX, baseDir + "vex.json"); register(EntityType.VILLAGER, baseDir + "villager.json"); register(EntityType.VINDICATOR, baseDir + "vindication_illager.json"); register(EntityType.WITCH, baseDir + "witch.json"); register(EntityType.WITHER, baseDir + "wither.json"); register(EntityType.WITHER_SKELETON, baseDir + "wither_skeleton.json"); register(EntityType.WOLF, baseDir + "wolf.json"); register(EntityType.ZOMBIE, baseDir + "zombie.json"); register(EntityType.ZOMBIE_HORSE, baseDir + "zombie_horse.json"); register(EntityType.ZOMBIE_VILLAGER, baseDir + "zombie.json"); } private static void register(EntityType type, String location) throws Exception { try { InputStream in = LootingManager.class.getClassLoader().getResourceAsStream(location); if (in == null) { GlowServer.logger.warning("Could not find default entity loot table '" + location + "' on classpath"); return; } JSONObject json = (JSONObject) new JSONParser().parse(new InputStreamReader(in)); entities.put(type, new EntityLootTable(json)); } catch (Exception e) { Exception ex = new Exception("Failed to load loot table '" + location + "': " + e.getClass().getName() + " (" + e.getMessage() + ")"); ex.setStackTrace(e.getStackTrace()); throw ex; } } public static LootData generate(GlowLivingEntity entity) { if (!entities.containsKey(entity.getType())) { return new LootData(new ItemStack[0], 0); } Random random = LootingUtil.random; EntityLootTable table = entities.get(entity.getType()); ArrayList<ItemStack> items = new ArrayList<>(); for (LootItem lootItem : table.getItems()) { DefaultLootItem defaultItem = lootItem.getDefaultItem(); int count = defaultItem.getCount().generate(random, entity); int data = 0; if (defaultItem.getData().isPresent()) { data = defaultItem.getData().get().generate(random); } else if (defaultItem.getReflectiveData().isPresent()) { data = ((Number) defaultItem.getReflectiveData().get().process(entity)).intValue(); } String name = defaultItem.getType().generate(random); if (name == null) { name = ""; } name = name.toUpperCase(); ConditionalLootItem[] conditions = lootItem.getConditionalItems(); for (ConditionalLootItem condition : conditions) { if (LootingUtil.conditionValue(entity, condition.getCondition())) { if (condition.getCount().isPresent()) { count = condition.getCount().get().generate(random, entity); } if (condition.getType().isPresent()) { name = condition.getType().get().generate(random); if (name == null) { name = ""; } name = name.toUpperCase(); } if (condition.getData().isPresent()) { data = condition.getData().get().generate(random); } else if (condition.getReflectiveData().isPresent()) { data = ((Number) condition.getReflectiveData().get().process(entity)).intValue(); } } } Material material = Material.getMaterial(name); if (material != null && count > 0) { items.add(new ItemStack(material, count, (byte) data)); } } int experience = table.getExperience().generate(random, entity); return new LootData(items.toArray(new ItemStack[items.size()]), experience); } }