From 1320c34f673bf2e06c68a50ae3603a8026c7027e Mon Sep 17 00:00:00 2001 From: garbagemule Date: Mon, 24 Jun 2013 22:24:01 +0200 Subject: [PATCH] Major revamp of Upgrade Waves. Using a node setup similar to that of the classes-section, it is now possible to make complex Upgrade Waves that update weapons and armor on-the-fly. This also means 'permissions' upgrades. --- src/com/garbagemule/MobArena/ArenaClass.java | 20 +-- src/com/garbagemule/MobArena/ArenaImpl.java | 11 ++ .../garbagemule/MobArena/ArenaListener.java | 8 +- .../garbagemule/MobArena/MASpawnThread.java | 32 +--- .../garbagemule/MobArena/framework/Arena.java | 2 + .../MobArena/waves/WaveParser.java | 66 +++++++- .../MobArena/waves/types/UpgradeWave.java | 154 +++++++++++++++--- 7 files changed, 216 insertions(+), 77 deletions(-) diff --git a/src/com/garbagemule/MobArena/ArenaClass.java b/src/com/garbagemule/MobArena/ArenaClass.java index 0febd52..0093a91 100644 --- a/src/com/garbagemule/MobArena/ArenaClass.java +++ b/src/com/garbagemule/MobArena/ArenaClass.java @@ -1,10 +1,6 @@ package com.garbagemule.MobArena; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; import org.bukkit.Material; @@ -251,7 +247,7 @@ public class ArenaClass /** * Used by isWeapon() to determine if an ItemStack is a weapon type. */ - private static int[] weaponTypes = new int[]{256,257,258,261,267,268,269,270,271,272,273,274,275,276,277,278,279,283,284,285,286,290,291,292,293,294}; + private static int[] weaponTypes = {256,257,258,259,261,267,268,269,270,271,272,273,274,275,276,277,278,279,283,284,285,286,290,291,292,293,294,346,398}; /** * Returns true, if the ItemStack appears to be a weapon, in which case @@ -260,15 +256,9 @@ public class ArenaClass * @param stack an ItemStack * @return true, if the item is a weapon */ - public boolean isWeapon(ItemStack stack) { - int id = stack.getTypeId(); - - for (int type : weaponTypes) { - if (id == type) { - return true; - } - } - return false; + public static boolean isWeapon(ItemStack stack) { + if (stack == null) return false; + return Arrays.binarySearch(weaponTypes, stack.getTypeId()) > -1; } /** diff --git a/src/com/garbagemule/MobArena/ArenaImpl.java b/src/com/garbagemule/MobArena/ArenaImpl.java index 1e8e598..700fd87 100644 --- a/src/com/garbagemule/MobArena/ArenaImpl.java +++ b/src/com/garbagemule/MobArena/ArenaImpl.java @@ -1061,6 +1061,17 @@ public class ArenaImpl implements Arena } p.recalculatePermissions(); } + + @Override + public void addPermission(Player p, String perm, boolean value) { + PermissionAttachment pa = attachments.get(p); + if (pa == null) { + pa = p.addAttachment(plugin); + attachments.put(p, pa); + } + pa.setPermission(perm, value); + p.recalculatePermissions(); + } private void cleanup() { removeMonsters(); diff --git a/src/com/garbagemule/MobArena/ArenaListener.java b/src/com/garbagemule/MobArena/ArenaListener.java index 1dd5894..6206da7 100644 --- a/src/com/garbagemule/MobArena/ArenaListener.java +++ b/src/com/garbagemule/MobArena/ArenaListener.java @@ -579,12 +579,6 @@ public class ArenaListener private void onPetDamage(EntityDamageEvent event, Wolf pet, Entity damager) { event.setCancelled(true); } - - // Array of weapon IDs (includes flint and steel, fishing pole) - private final int[] weapons = { - 256, 257, 258, 259, 261, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 283, 284, 285, 286, 290, 291, 292, 293, 294, 346, 398 - }; private void onMonsterDamage(EntityDamageEvent event, Entity monster, Entity damager) { if (damager instanceof Player) { @@ -596,7 +590,7 @@ public class ArenaListener // Dirty hack for invincible weapons ItemStack weapon = p.getInventory().getContents()[p.getInventory().getHeldItemSlot()]; - if (weapon != null && Arrays.binarySearch(weapons, weapon.getTypeId()) >= 0) { + if (ArenaClass.isWeapon(weapon)) { weapon.setDurability((short) 0); } diff --git a/src/com/garbagemule/MobArena/MASpawnThread.java b/src/com/garbagemule/MobArena/MASpawnThread.java index 0f526bd..e8a1b4a 100644 --- a/src/com/garbagemule/MobArena/MASpawnThread.java +++ b/src/com/garbagemule/MobArena/MASpawnThread.java @@ -208,8 +208,8 @@ public class MASpawnThread implements Runnable for (Player p : arena.getPlayersInArena()) { String className = arena.getArenaPlayer(p).getArenaClass().getLowercaseName(); - uw.grantItems(p, className); - uw.grantItems(p, "all"); + uw.grantItems(arena, p, className); + uw.grantItems(arena, p, "all"); } } @@ -217,7 +217,6 @@ public class MASpawnThread implements Runnable * Check if the wave is clear for new spawns. * If clear-boss-before-next: true, bosses must be dead. * If clear-wave-before-next: true, all monsters must be dead. - * @param wave the next wave number * @return true, if the wave is "clear" for new spawns. */ private boolean isWaveClear() { @@ -334,31 +333,4 @@ public class MASpawnThread implements Runnable } } } - - /** - * Update the targets of all monsters, if their targets aren't alive. - */ - public void updateTargets() { - Creature c; - Entity target; - for (Entity e : monsterManager.getMonsters()) { - if (!(e instanceof Creature)) - continue; - - // TODO: Remove the try-catch when Bukkit API is fixed. - c = (Creature) e; - try { - target = c.getTarget(); - } - catch (ClassCastException cce) { - continue; - } - - if (target instanceof Player && arena.getPlayersInArena().contains((Player) target)) { - continue; - } - - c.setTarget(MAUtils.getClosestPlayer(plugin, e, arena)); - } - } } \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/framework/Arena.java b/src/com/garbagemule/MobArena/framework/Arena.java index 7335ffb..20a59ad 100644 --- a/src/com/garbagemule/MobArena/framework/Arena.java +++ b/src/com/garbagemule/MobArena/framework/Arena.java @@ -183,6 +183,8 @@ public interface Arena public void assignClassPermissions(Player p); public void removeClassPermissions(Player p); + + public void addPermission(Player p, String perm, boolean value); diff --git a/src/com/garbagemule/MobArena/waves/WaveParser.java b/src/com/garbagemule/MobArena/waves/WaveParser.java index fb9c1b0..ee85cfd 100644 --- a/src/com/garbagemule/MobArena/waves/WaveParser.java +++ b/src/com/garbagemule/MobArena/waves/WaveParser.java @@ -2,6 +2,7 @@ package com.garbagemule.MobArena.waves; import java.util.*; +import com.garbagemule.MobArena.ArenaClass; import org.bukkit.Location; import org.bukkit.inventory.ItemStack; @@ -19,6 +20,7 @@ import com.garbagemule.MobArena.waves.types.SpecialWave; import com.garbagemule.MobArena.waves.types.SupplyWave; import com.garbagemule.MobArena.waves.types.SwarmWave; import com.garbagemule.MobArena.waves.types.UpgradeWave; +import com.garbagemule.MobArena.waves.types.UpgradeWave.*; public class WaveParser { @@ -206,6 +208,20 @@ public class WaveParser } private static Wave parseUpgradeWave(Arena arena, String name, ConfigSection config) { + Map> upgrades = getUpgradeMap(config); + if (upgrades == null || upgrades.isEmpty()) { + Messenger.warning(WaveError.UPGRADE_MAP_MISSING.format(name, arena.configName())); + return null; + } + + UpgradeWave result = new UpgradeWave(upgrades); + + // Determine if all items should be given + boolean giveAll = config.getBoolean("give-all-items", false); + result.setGiveAll(giveAll); + + return result; + /* Map> classMap = getUpgradeMap(config); if (classMap == null || classMap.isEmpty()) { Messenger.warning(WaveError.UPGRADE_MAP_MISSING.format(name, arena.configName())); @@ -219,6 +235,7 @@ public class WaveParser result.setGiveAll(giveAll); return result; + */ } private static Wave parseBossWave(Arena arena, String name, ConfigSection config) { @@ -360,20 +377,57 @@ public class WaveParser return result; } - private static Map> getUpgradeMap(ConfigSection config) { + private static Map> getUpgradeMap(ConfigSection config) { Set classes = config.getKeys("upgrades"); if (classes == null || classes.isEmpty()) { return null; } - Map> upgrades = new HashMap>(); + Map> upgrades = new HashMap>(); String path = "upgrades."; for (String className : classes) { - String itemList = config.getString(path + className); - List stacks = ItemParser.parseItems(itemList); - - upgrades.put(className.toLowerCase(), stacks); + // Legacy support + String itemList = config.getString(path + className, null); + if (itemList != null) { + List stacks = ItemParser.parseItems(itemList); + List list = new ArrayList(); + for (ItemStack stack : stacks) { + list.add(new GenericUpgrade(stack)); + } + upgrades.put(className.toLowerCase(), list); + } + // New complex setup + else { + List list = new ArrayList(); + + // Items (Generic + Weapons) + itemList = config.getString(path + className + ".items", null); + if (itemList != null) { + for (ItemStack stack : ItemParser.parseItems(itemList)) { + list.add(ArenaClass.isWeapon(stack) ? new WeaponUpgrade(stack) : new GenericUpgrade(stack)); + } + } + + // Armor + itemList = config.getString(path + className + ".armor", null); + if (itemList != null) { + for (ItemStack stack : ItemParser.parseItems(itemList)) { + list.add(new ArmorUpgrade(stack)); + } + } + + // Permissions + List perms = config.getStringList(path + className + ".permissions", Collections.EMPTY_LIST); + if (!perms.isEmpty()) { + for (String perm : perms) { + list.add(new PermissionUpgrade(perm)); + } + } + + // Put in the map + upgrades.put(className.toLowerCase(), list); + } } return upgrades; diff --git a/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java b/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java index 7fcca6c..c0a399e 100644 --- a/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java +++ b/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java @@ -4,8 +4,8 @@ import java.util.*; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; +import com.garbagemule.MobArena.ArenaClass.ArmorType; import com.garbagemule.MobArena.framework.Arena; import com.garbagemule.MobArena.waves.AbstractWave; import com.garbagemule.MobArena.waves.MACreature; @@ -13,11 +13,11 @@ import com.garbagemule.MobArena.waves.enums.WaveType; public class UpgradeWave extends AbstractWave { - private Map> classMap; + private Map> upgrades; private boolean giveAll; - - public UpgradeWave(Map> classMap) { - this.classMap = classMap; + + public UpgradeWave(Map> upgrades) { + this.upgrades = upgrades; this.setType(WaveType.UPGRADE); } @@ -25,27 +25,143 @@ public class UpgradeWave extends AbstractWave public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { return new HashMap(); } - - public void grantItems(Player p, String className) { - List stacks = classMap.get(className); - if (stacks == null || stacks.isEmpty()) return; - PlayerInventory inv = p.getInventory(); - - // Check if we need to add all of the items or just one. + public void grantItems(Arena arena, Player p, String className) { + List list = upgrades.get(className); + if (list == null) return; + if (giveAll) { - for (ItemStack stack : stacks) { - inv.addItem(stack); + for (Upgrade upgrade : list) { + upgrade.upgrade(arena, p); } - } - // Get a random item from the list. - else { - int index = new Random().nextInt(stacks.size()); - inv.addItem(stacks.get(index)); + } else { + int index = new Random().nextInt(list.size()); + list.get(index).upgrade(arena, p); } } public void setGiveAll(boolean giveAll) { this.giveAll = giveAll; } + + /** + * Represents an upgrade for an upgrade wave + */ + public static interface Upgrade { + public void upgrade(Arena arena, Player p); + } + + /** + * Armor upgrades + * Replace the item in the specific slot + */ + public static class ArmorUpgrade implements Upgrade { + private ItemStack item; + private ArmorType type; + + public ArmorUpgrade(ItemStack item) { + this.item = item; + this.type = ArmorType.getType(item); + } + + @Override + public void upgrade(Arena arena, Player p) { + if (item == null || type == null) return; + + switch (type) { + case HELMET: p.getInventory().setHelmet(item); break; + case CHESTPLATE: p.getInventory().setChestplate(item); break; + case LEGGINGS: p.getInventory().setLeggings(item); break; + case BOOTS: p.getInventory().setBoots(item); break; + } + } + } + + /** + * Weapon upgrades + * Replace the first item that matches the ID on the quickbar + */ + public static class WeaponUpgrade implements Upgrade { + private ItemStack item; + + public WeaponUpgrade(ItemStack item) { + this.item = item; + } + + @Override + public void upgrade(Arena arena, Player p) { + if (item == null) return; + + ItemStack[] items = p.getInventory().getContents(); + int firstEmpty = -1; + + // Find a matching ID and upgrade it + for (int i = 0; i < 9; i++) { + // Save the first null index + if (items[i] == null) { + if (firstEmpty < 0) firstEmpty = i; + continue; + } + // If we find an ID, upgrade and quit + if (items[i].getTypeId() == item.getTypeId()) { + items[i] = item; + p.getInventory().setContents(items); + return; + } + } + + // If nothing was found, just give them a new weapon + if (firstEmpty > 0) { + items[firstEmpty] = item; + p.getInventory().setContents(items); + } else { + p.getInventory().addItem(item); + } + } + } + + /** + * Generic upgrades + * Add the item to the player's inventory + */ + public static class GenericUpgrade implements Upgrade { + private ItemStack item; + + public GenericUpgrade(ItemStack item) { + this.item = item; + } + + @Override + public void upgrade(Arena arena, Player p) { + if (item == null) return; + + p.getInventory().addItem(item); + } + } + + /** + * Permission upgrades + * Set the given permission + */ + public static class PermissionUpgrade implements Upgrade { + private String perm; + private boolean value; + + public PermissionUpgrade(String perm) { + if (perm.startsWith("-") || perm.startsWith("^")) { + perm = perm.substring(1).trim(); + value = false; + } else { + value = true; + } + this.perm = perm; + } + + @Override + public void upgrade(Arena arena, Player p) { + if (perm == null) return; + + arena.addPermission(p, perm, value); + } + } }