package jp.jias.bukkit.bossmonster; import java.util.HashMap; import java.util.Map; import org.bukkit.Location; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.Item; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; /** * ドロップアイテムの設定 * * @author i_shi_ba_shi ( jias.jp ) * */ public class DropItem implements ConfigurationSerializable{ /** ドロップアイテムのスタック数が多すぎる場合に、フリーズ防止のため最大ドロップスタック数を制限する */ static final private int MAX_STACK_AMOUNT=10; /** アイテム数最小 */ static final private String AMOUNT_MIN="amountMin"; /** アイテム数最大 */ static final private String AMOUNT_MAX="amountMax"; /** レアリティ */ static final private String RARITY="rarity"; /** アイテム */ static final private String ITEM="item"; /** アイテム数最小 */ private double amountMin; /** アイテム数最大 */ private double amountMax; /** レアリティ */ private double rarity; /** アイテム */ private ItemStack item; /** アイテム数最小を設定する */ public void setAmountMin(double amountMin){ this.amountMin=amountMin; } /** アイテム数最大を設定する */ public void setAmountMax(double amountMax){ this.amountMax=amountMax; } /** レアリティを設定する */ public void setRarity(double rarity){ this.rarity=rarity; } /** アイテムを設定する */ public void setItem(ItemStack item){ this.item=item; } /** * 情報をシリアライズする * * @return シリアライズされた情報 */ @Override public Map serialize(){ // マップを作る Map map=new HashMap(); // 情報を「キー」と「値」のペアにして書き出す map.put(AMOUNT_MIN,amountMin); map.put(AMOUNT_MAX,amountMax); map.put(RARITY,rarity); map.put(ITEM,item); // データを保存したマップを返す(このマップの中身がconfig.ymlなどに書かれる) return map; } /** * 情報をデシリアライズする * * @param map * シリアライズされた情報 * @return デシリアライズされた情報 */ public static DropItem deserialize(Map map){ // config.ymlから読み込まれたマップが引数に渡されるので、このデータを元に情報を作成(復元)する // オブジェクトを作る DropItem dropItem=new DropItem(); // 「キー」で「値」を取り出してオブジェクトにセット dropItem.amountMin=Double.parseDouble(map.get(AMOUNT_MIN).toString()); dropItem.amountMax=Double.parseDouble(map.get(AMOUNT_MAX).toString()); dropItem.rarity=Double.parseDouble(map.get(RARITY).toString()); dropItem.item=(ItemStack) map.get(ITEM); // オブジェクトを返す return dropItem; } /** * 指定された設定に沿ってアイテムをドロップする * * @param loc * ドロップ位置 */ public void fire(Location loc){ // 0~100のランダムな数字を用意し、レアリティの値を超える場合、ドロップしない if(BossMonster.getRandom().nextInt(101) > rarity){ return; } // アイテム数を計算する int amount=item.getAmount() * (int) (amountMin + (BossMonster.getRandom().nextDouble() * (amountMax + 1 - amountMin))); // アイテム数が1未満になった場合はドロップしない if(amount < 1){ return; } // アイテム数が極端に多い場合、ドロップ量を制限する if(amount > item.getMaxStackSize() * MAX_STACK_AMOUNT){ amount=item.getMaxStackSize() * MAX_STACK_AMOUNT; } // アイテム数が1スタック分の数を超える場合は複数スタックに分割する int stack=(int) Math.ceil(amount / (double) item.getMaxStackSize()); // アイテム数をスタック数で割った数と、割り切れない端数を計算 int basic=amount / stack; int fraction=amount % stack; // スタック数だけ繰り返す for(int i=0;i < stack;i++){ ItemStack unit=item.clone(); // アイテム数を設定する // 端数未満ではアイテム数を+1する unit.setAmount(basic + (i < fraction?1:0)); // アイテムを対象位置周辺に散らばす Item drop=loc.getWorld().dropItem(loc,unit); drop.setVelocity(Vector.getRandom().multiply(0.3f)); } } }