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.
This commit is contained in:
garbagemule 2013-06-24 22:24:01 +02:00
parent adb8ee1668
commit 1320c34f67
7 changed files with 216 additions and 77 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<String,List<Upgrade>> 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<String,List<ItemStack>> 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<String,List<ItemStack>> getUpgradeMap(ConfigSection config) {
private static Map<String,List<Upgrade>> getUpgradeMap(ConfigSection config) {
Set<String> classes = config.getKeys("upgrades");
if (classes == null || classes.isEmpty()) {
return null;
}
Map<String,List<ItemStack>> upgrades = new HashMap<String,List<ItemStack>>();
Map<String,List<Upgrade>> upgrades = new HashMap<String,List<Upgrade>>();
String path = "upgrades.";
for (String className : classes) {
String itemList = config.getString(path + className);
List<ItemStack> stacks = ItemParser.parseItems(itemList);
upgrades.put(className.toLowerCase(), stacks);
// Legacy support
String itemList = config.getString(path + className, null);
if (itemList != null) {
List<ItemStack> stacks = ItemParser.parseItems(itemList);
List<Upgrade> list = new ArrayList<Upgrade>();
for (ItemStack stack : stacks) {
list.add(new GenericUpgrade(stack));
}
upgrades.put(className.toLowerCase(), list);
}
// New complex setup
else {
List<Upgrade> list = new ArrayList<Upgrade>();
// 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<String> 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;

View File

@ -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<String,List<ItemStack>> classMap;
private Map<String,List<Upgrade>> upgrades;
private boolean giveAll;
public UpgradeWave(Map<String,List<ItemStack>> classMap) {
this.classMap = classMap;
public UpgradeWave(Map<String,List<Upgrade>> upgrades) {
this.upgrades = upgrades;
this.setType(WaveType.UPGRADE);
}
@ -25,27 +25,143 @@ public class UpgradeWave extends AbstractWave
public Map<MACreature,Integer> getMonstersToSpawn(int wave, int playerCount, Arena arena) {
return new HashMap<MACreature,Integer>();
}
public void grantItems(Player p, String className) {
List<ItemStack> 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<Upgrade> 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);
}
}
}