diff --git a/MobArena.jar b/MobArena.jar index 02f7b7c..712f56a 100644 Binary files a/MobArena.jar and b/MobArena.jar differ diff --git a/bin/plugin.yml b/bin/plugin.yml index fb0bc4f..8702e4c 100644 --- a/bin/plugin.yml +++ b/bin/plugin.yml @@ -1,6 +1,6 @@ name: MobArena main: com.garbagemule.MobArena.MobArena -version: 0.88.3 +version: 0.89 commands: ma: description: Base command for MobArena diff --git a/src/com/garbagemule/MobArena/ArenaManager.java b/src/com/garbagemule/MobArena/ArenaManager.java index 76db173..4eb3cff 100644 --- a/src/com/garbagemule/MobArena/ArenaManager.java +++ b/src/com/garbagemule/MobArena/ArenaManager.java @@ -14,6 +14,7 @@ import org.bukkit.Material; import org.bukkit.Location; import org.bukkit.ChatColor; import org.bukkit.block.Block; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.entity.LivingEntity; import org.bukkit.inventory.ItemStack; @@ -46,6 +47,8 @@ public class ArenaManager // Spawn locations list and monster distribution fields. protected static List spawnpoints = new ArrayList(); protected static int dZombies, dSkeletons, dSpiders, dCreepers, dWolves; + protected static int dPoweredCreepers, dPigZombies, dSlimes, dMonsters, + dAngryWolves, dGiants, dGhasts; // Set and Maps for storing players, their locations, items, armor, etc. protected static Set playerSet = new HashSet(); @@ -63,9 +66,10 @@ public class ArenaManager protected static Map everyWaveMap = new HashMap(); protected static Map afterWaveMap = new HashMap(); - // Entities and blocks on MobArena floor. + // Entities, blocks and items on MobArena floor. protected static Set monsterSet = new HashSet(); protected static Set blockSet = new HashSet(); + protected static Set dropSet = new HashSet(); @@ -104,6 +108,14 @@ public class ArenaManager dSpiders = MAUtils.getDistribution("spiders"); dCreepers = MAUtils.getDistribution("creepers"); dWolves = MAUtils.getDistribution("wolves"); + + dPigZombies = MAUtils.getDistribution("poweredcreepers", "special"); + dPigZombies = MAUtils.getDistribution("zombiepigmen", "special"); + dSlimes = MAUtils.getDistribution("slimes", "special"); + dMonsters = MAUtils.getDistribution("humans", "special"); + dAngryWolves = MAUtils.getDistribution("angrywolves", "special"); + dGiants = MAUtils.getDistribution("giants", "special"); + dGhasts = MAUtils.getDistribution("ghasts", "special"); } // Convenience variables. @@ -164,6 +176,7 @@ public class ArenaManager server.getScheduler().cancelTasks(plugin); killMonsters(); clearBlocks(); + clearDrops(); giveRewards(); // TO-DO: Fix this, maybe add a Set dead @@ -234,10 +247,10 @@ public class ArenaManager MAUtils.clearInventory(p); } - if (readySet.contains(p)) + //if (readySet.contains(p)) readySet.remove(p); - if (classMap.keySet().contains(p)) + //if (classMap.keySet().contains(p)) classMap.remove(p); // This must occur after playerSet.remove(p) to avoid teleport block. @@ -276,10 +289,10 @@ public class ArenaManager p.setHealth(20); tellAll(p.getName() + " died!"); - if (playerSet.contains(p)) + //if (playerSet.contains(p)) playerSet.remove(p); - if (classMap.keySet().contains(p)) + //if (classMap.keySet().contains(p)) classMap.remove(p); if (isRunning && playerSet.isEmpty()) @@ -357,10 +370,10 @@ public class ArenaManager public static void killMonsters() { // Remove all monsters, then clear the Set. - for (LivingEntity entity : monsterSet) + for (LivingEntity e : monsterSet) { - if (!entity.isDead()) - entity.remove(); + if (!e.isDead()) + e.remove(); } monsterSet.clear(); } @@ -378,6 +391,20 @@ public class ArenaManager blockSet.clear(); } + /** + * Removes all items on the arena floor. + */ + public static void clearDrops() + { + // Remove all blocks, then clear the Set. + for (Item i : dropSet) + { + i.remove(); + } + + dropSet.clear(); + } + /* ///////////////////////////////////////////////////////////////////// // diff --git a/src/com/garbagemule/MobArena/MADamageListener.java b/src/com/garbagemule/MobArena/MADamageListener.java index d7fbd53..daf1a43 100644 --- a/src/com/garbagemule/MobArena/MADamageListener.java +++ b/src/com/garbagemule/MobArena/MADamageListener.java @@ -1,9 +1,11 @@ package com.garbagemule.MobArena; import org.bukkit.entity.Player; +import org.bukkit.entity.LivingEntity; import org.bukkit.event.entity.EntityListener; -import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; /** * This listener acts as a type of death-listener. @@ -45,22 +47,58 @@ public class MADamageListener extends EntityListener } /** - * Clears all player drops on death. + * Clears all player/monster drops on death. */ public void onEntityDeath(EntityDeathEvent event) - { - if (!ArenaManager.isRunning) + { + // If player, call player death and such. + if (event.getEntity() instanceof Player) + { + Player p = (Player) event.getEntity(); + + if (!ArenaManager.playerSet.contains(p)) + return; + + event.getDrops().clear(); + ArenaManager.playerDeath(p); + } + // If monster, remove from monster set + else if (event.getEntity() instanceof LivingEntity) + { + LivingEntity e = (LivingEntity) event.getEntity(); + + if (!ArenaManager.monsterSet.contains(e)) + return; + + event.getDrops().clear(); + ArenaManager.monsterSet.remove(e); + } + } + + /** + * Prevents monsters from spawning inside the arena unless + * it's running, and adds mini-slimes to the monsterSet. + */ + public void onCreatureSpawn(CreatureSpawnEvent event) + { + if (!MAUtils.inRegion(event.getLocation())) + return; + + if (!(event.getEntity() instanceof LivingEntity)) return; - if (!(event.getEntity() instanceof Player)) - return; + System.out.println("This is the spawn command"); - Player p = (Player) event.getEntity(); + LivingEntity e = (LivingEntity) event.getEntity(); - if (!ArenaManager.playerSet.contains(p)) - return; - - event.getDrops().clear(); - ArenaManager.playerDeath(p); + if (ArenaManager.isRunning) + { + if (!ArenaManager.monsterSet.contains(e)) + ArenaManager.monsterSet.add(e); + } + else + { + event.setCancelled(true); + } } } \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MADisabledCommands.java b/src/com/garbagemule/MobArena/MADisabledCommands.java new file mode 100644 index 0000000..461c6b0 --- /dev/null +++ b/src/com/garbagemule/MobArena/MADisabledCommands.java @@ -0,0 +1,33 @@ +package com.garbagemule.MobArena; + +import java.util.Arrays; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +/** + * Handles the disabled commands. + */ +public class MADisabledCommands extends PlayerListener +{ + private MobArena plugin; + + public MADisabledCommands(MobArena instance) + { + plugin = instance; + } + + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) + { + Player p = event.getPlayer(); + + if (!ArenaManager.playerSet.contains(p)) + return; + + if (!Arrays.asList(plugin.DISABLED_COMMANDS).contains(event.getMessage().substring(1))) + return; + + event.setCancelled(true); + ArenaManager.tellPlayer(p, "You can't use that command in the arena!"); + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MALobbyListener.java b/src/com/garbagemule/MobArena/MALobbyListener.java new file mode 100644 index 0000000..3b8e57c --- /dev/null +++ b/src/com/garbagemule/MobArena/MALobbyListener.java @@ -0,0 +1,104 @@ +package com.garbagemule.MobArena; + +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Result; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +/** + * This listener prevents players from sharing class-specific + * items (read: cheating) before the arena session starts. + */ +// TO-DO: Merge with MASignListener and MAReadyListener into MALobbyListener +public class MALobbyListener extends PlayerListener +{ + private MobArena plugin; + + public MALobbyListener(MobArena instance) + { + plugin = instance; + } + + /** + * Players can only drop items when the arena session has started. + */ + public void onPlayerDropItem(PlayerDropItemEvent event) + { + Player p = event.getPlayer(); + + if (!ArenaManager.playerSet.contains(p)) + return; + + if (ArenaManager.isRunning) + { + ArenaManager.dropSet.add(event.getItemDrop()); + return; + } + + ArenaManager.tellPlayer(p, "No sharing before the arena starts!"); + event.setCancelled(true); + } + + /** + * Checks if the player hits an iron block or a sign, or if the player + * is trying to use an item. + */ + public void onPlayerInteract(PlayerInteractEvent event) + { + // Only do these checks if the arena isn't running. + if (ArenaManager.isRunning) + return; + + Player p = event.getPlayer(); + + if (!ArenaManager.playerSet.contains(p)) + return; + + // Iron block + if (event.hasBlock() && event.getClickedBlock().getTypeId() == 42) + { + if (ArenaManager.classMap.containsKey(p)) + { + ArenaManager.tellPlayer(p, "You have been flagged as ready!"); + ArenaManager.playerReady(p); + } + else + { + ArenaManager.tellPlayer(p, "You must first pick a class!"); + } + return; + } + + // Sign + if (event.hasBlock() && event.getClickedBlock().getState() instanceof Sign) + { + // Cast the block to a sign to get the text on it. + Sign sign = (Sign) event.getClickedBlock().getState(); + + // Check if the first line of the sign is a class name. + String className = sign.getLine(0); + if (!ArenaManager.classes.contains(className)) + return; + + // Set the player's class. + ArenaManager.assignClass(p, className); + ArenaManager.tellPlayer(p, "You have chosen " + className + " as your class!"); + return; + } + + // Trying to use stuff + Action a = event.getAction(); + + // Check if player is trying to use an item. + if ((a == Action.RIGHT_CLICK_AIR) || (a == Action.RIGHT_CLICK_BLOCK)) + { + if (ArenaManager.playerSet.contains(p)) + event.setUseItemInHand(Result.DENY); + return; + } + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MASpawnThread.java b/src/com/garbagemule/MobArena/MASpawnThread.java index b001256..0e7b8f2 100644 --- a/src/com/garbagemule/MobArena/MASpawnThread.java +++ b/src/com/garbagemule/MobArena/MASpawnThread.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Random; import org.bukkit.Location; import org.bukkit.entity.Wolf; +import org.bukkit.entity.Ghast; import org.bukkit.entity.Slime; import org.bukkit.entity.Player; import org.bukkit.entity.Creature; @@ -27,8 +28,9 @@ import org.bukkit.inventory.PlayerInventory; // TO-DO: Allow additional "default" waves. public class MASpawnThread implements Runnable { - private int wave, noOfSpawnPoints, noOfPlayers; + private int wave, ran, noOfSpawnPoints, noOfPlayers; private int dZombies, dSkeletons, dSpiders, dCreepers, dWolves; + private int dPoweredCreepers, dPigZombies, dSlimes, dMonsters, dAngryWolves, dGiants, dGhasts; private Random random; private String reward, currentRewards; @@ -45,6 +47,14 @@ public class MASpawnThread implements Runnable dSpiders = dSkeletons + ArenaManager.dSpiders; dCreepers = dSpiders + ArenaManager.dCreepers; dWolves = dCreepers + ArenaManager.dWolves; + + dPoweredCreepers = ArenaManager.dPoweredCreepers; + dPigZombies = dPoweredCreepers + ArenaManager.dPigZombies; + dSlimes = dPigZombies + ArenaManager.dSlimes; + dMonsters = dSlimes + ArenaManager.dMonsters; + dAngryWolves = dMonsters + ArenaManager.dAngryWolves; + dGiants = dAngryWolves + ArenaManager.dGiants; + dGhasts = dGiants + ArenaManager.dGhasts; } public void run() @@ -100,7 +110,6 @@ public class MASpawnThread implements Runnable private void defaultWave() { Location loc; - int ran; for (int i = 0; i < wave + noOfPlayers; i++) { @@ -139,42 +148,59 @@ public class MASpawnThread implements Runnable { Location loc; CreatureType mob; + ran = random.nextInt(dGhasts); - int ran, count; + int count; boolean slime = false; boolean wolf = false; + boolean ghast = false; + + if (ran < dPoweredCreepers) mob = CreatureType.CREEPER; + else if (ran < dPigZombies) mob = CreatureType.PIG_ZOMBIE; + else if (ran < dSlimes) mob = CreatureType.SLIME; + else if (ran < dMonsters) mob = CreatureType.MONSTER; + else if (ran < dAngryWolves) mob = CreatureType.WOLF; + else if (ran < dGiants) mob = CreatureType.GIANT; + else if (ran < dGhasts) mob = CreatureType.GHAST; + else return; // 5 on purpose - Ghasts act weird in Overworld. - switch (random.nextInt(5)) + switch (mob) + //switch (random.nextInt(5)) { - case 0: - mob = CreatureType.CREEPER; + case CREEPER: + //mob = CreatureType.CREEPER; count = noOfPlayers * 3; break; - case 1: - mob = CreatureType.PIG_ZOMBIE; + case PIG_ZOMBIE: + //mob = CreatureType.PIG_ZOMBIE; count = noOfPlayers * 2; break; - case 2: - mob = CreatureType.SLIME; + case SLIME: + //mob = CreatureType.SLIME; count = noOfPlayers * 4; slime = true; break; - case 3: - mob = CreatureType.MONSTER; + case MONSTER: + //mob = CreatureType.MONSTER; count = noOfPlayers + 1; break; - case 4: - mob = CreatureType.WOLF; + case WOLF: + //mob = CreatureType.WOLF; count = noOfPlayers * 3; wolf = true; break; - case 5: - mob = CreatureType.GHAST; - count = Math.max(1, noOfPlayers - 2); + case GIANT: + //mob = CreatureType.GIANT; + count = 1; + break; + case GHAST: + //mob = CreatureType.GHAST; + count = 2; + ghast = true; break; default: - mob = CreatureType.CHICKEN; + //mob = CreatureType.CHICKEN; count = 50; break; } @@ -185,10 +211,14 @@ public class MASpawnThread implements Runnable loc = ArenaManager.spawnpoints.get(i % noOfSpawnPoints); LivingEntity e = ArenaManager.world.spawnCreature(loc,mob); - ArenaManager.monsterSet.add(e); + if (!ArenaManager.monsterSet.contains(e)) + ArenaManager.monsterSet.add(e); + else + System.out.println("MASpawnThread - monsterSet contains this entity"); if (slime) ((Slime)e).setSize(2); if (wolf) ((Wolf)e).setAngry(true); + if (ghast) ((Ghast)e).setHealth(Math.min(noOfPlayers*25, 200)); // Slimes can't have targets, apparently. if (!(e instanceof Creature)) diff --git a/src/com/garbagemule/MobArena/MATeleportListener.java b/src/com/garbagemule/MobArena/MATeleportListener.java index 52978ec..ee281b1 100644 --- a/src/com/garbagemule/MobArena/MATeleportListener.java +++ b/src/com/garbagemule/MobArena/MATeleportListener.java @@ -22,21 +22,19 @@ public class MATeleportListener extends PlayerListener public void onPlayerTeleport(PlayerTeleportEvent event) { Player p = event.getPlayer(); - if (ArenaManager.playerSet.contains(p)) + if (!ArenaManager.playerSet.contains(p)) + return; + + Location to = event.getTo(); + + if (ArenaManager.arenaLoc.equals(to) || + ArenaManager.lobbyLoc.equals(to) || + ArenaManager.spectatorLoc.equals(to)) { - Location to = event.getTo(); - - if (ArenaManager.arenaLoc.equals(to) || - ArenaManager.lobbyLoc.equals(to) || - ArenaManager.spectatorLoc.equals(to)) - { - return; - } - - ArenaManager.tellPlayer(p, "Can't warp in arena! To leave, type /marena leave"); - event.setCancelled(true); - return; } + + ArenaManager.tellPlayer(p, "Can't warp in arena! To leave, type /ma leave"); + event.setCancelled(true); } } \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MAUtils.java b/src/com/garbagemule/MobArena/MAUtils.java index 6124099..7693b8e 100644 --- a/src/com/garbagemule/MobArena/MAUtils.java +++ b/src/com/garbagemule/MobArena/MAUtils.java @@ -22,13 +22,18 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.util.config.Configuration; public class MAUtils -{ - public static final int[] SWORDS_ID = {267,268,272,276,283}; - public static final Material[] SWORDS_TYPE = {Material.WOOD_SWORD, - Material.STONE_SWORD, - Material.GOLD_SWORD, - Material.IRON_SWORD, - Material.DIAMOND_SWORD}; +{ + public static final List SWORDS_ID = new LinkedList(); + public static final List SWORDS_TYPE = new LinkedList(); + static + { + SWORDS_TYPE.add(Material.WOOD_SWORD); + SWORDS_TYPE.add(Material.STONE_SWORD); + SWORDS_TYPE.add(Material.GOLD_SWORD); + SWORDS_TYPE.add(Material.IRON_SWORD); + SWORDS_TYPE.add(Material.DIAMOND_SWORD); + } + /* ///////////////////////////////////////////////////////////////////// // @@ -105,14 +110,16 @@ public class MAUtils { id = Integer.parseInt(item[0]); stack = new ItemStack(id, amount); - if (!reward && Arrays.asList(SWORDS_ID).contains(id)) + //if (!reward && Arrays.asList(SWORDS_ID).contains(id)) + if (!reward && SWORDS_ID.contains(id)) stack.setDurability((short)-3276); } else { stack = makeItemStack(item[0], amount); if (stack == null) continue; - if (!reward && Arrays.asList(SWORDS_TYPE).contains(stack.getType())) + //if (!reward && Arrays.asList(SWORDS_TYPE).contains(stack.getType())) + if (!reward && SWORDS_ID.contains(stack.getTypeId())) stack.setDurability((short)-3276); } @@ -240,6 +247,25 @@ public class MAUtils return new Configuration(configFile); } + public static String[] getDisabledCommands() + { + Configuration c = ArenaManager.config; + c.load(); + + String commands = c.getString("disabledcommands", "kill"); + c.setProperty("disabledcommands", commands); + c.save(); + + String[] result = commands.split(","); + for (int i = 0; i < result.length; i++) + { + result[i] = result[i].trim(); + System.out.println(result[i]); + } + + return result; + } + /** * Grabs the world from the config-file, or the "default" world * from the list of worlds in the server object. @@ -387,21 +413,29 @@ public class MAUtils * no coefficients are found, defaults (10) are added. */ public static int getDistribution(String monster) + { + return getDistribution(monster, "default"); + } + + public static int getDistribution(String monster, String type) { Configuration c = ArenaManager.config; c.load(); - if (c.getInt("waves.default." + monster, -1) == -1) + if (c.getInt("waves." + type + "." + monster, -1) == -1) { - c.setProperty("waves.default." + monster, 10); + int dist = 10; + if (monster.equals("giants") || monster.equals("ghasts") || monster.equals("slimes")) + dist = 0; + + c.setProperty("waves." + type + "." + monster, dist); c.save(); } - return c.getInt("waves.default." + monster, -1); + return c.getInt("waves." + type + "." + monster, 0); } - /* ///////////////////////////////////////////////////////////////////// // REGION AND SETUP METHODS @@ -619,7 +653,7 @@ public class MAUtils // Get the hippie bounds. int x1 = (int)loc.getX() - radius; int x2 = (int)loc.getX() + radius; - int y1 = (int)loc.getY() - 8; + int y1 = (int)loc.getY() - 9; int y2 = (int)loc.getY() - 1; int z1 = (int)loc.getZ() - radius; int z2 = (int)loc.getZ() + radius; @@ -778,8 +812,7 @@ public class MAUtils { FileInputStream fis = new FileInputStream("plugins/MobArena/precious.tmp"); ObjectInputStream ois = new ObjectInputStream(fis); - Object o = ois.readObject(); - preciousPatch = (HashMap) ois.readObject(); + preciousPatch = (HashMap) ois.readObject(); ois.close(); } catch (Exception e) diff --git a/src/com/garbagemule/MobArena/MobArena.java b/src/com/garbagemule/MobArena/MobArena.java index 8a288d7..7daa208 100644 --- a/src/com/garbagemule/MobArena/MobArena.java +++ b/src/com/garbagemule/MobArena/MobArena.java @@ -23,6 +23,7 @@ public class MobArena extends JavaPlugin "ready", "notready", "enabled", "force", "config", "setwarp", "addspawn", "delspawn", "setregion", "expandregion", "protect", "undo", "dooooo", "reset"}; + public String[] DISABLED_COMMANDS; public MobArena() { @@ -31,10 +32,10 @@ public class MobArena extends JavaPlugin public void onEnable() { PluginDescriptionFile pdfFile = this.getDescription(); - System.out.println(pdfFile.getName() + " v" + pdfFile.getVersion() + " enabled." ); // Initialize convenience variables in ArenaManager. ArenaManager.init(this); + DISABLED_COMMANDS = MAUtils.getDisabledCommands(); // Bind the /ma and /marena commands to MACommands. getCommand("ma").setExecutor(new MACommands()); @@ -43,9 +44,8 @@ public class MobArena extends JavaPlugin // Create event listeners. PluginManager pm = getServer().getPluginManager(); - PlayerListener signListener = new MASignListener(this); - PlayerListener dropListener = new MADropListener(this); - PlayerListener readyListener = new MAReadyListener(this); + PlayerListener commandListener = new MADisabledCommands(this); + PlayerListener lobbyListener = new MALobbyListener(this); PlayerListener teleportListener = new MATeleportListener(this); PlayerListener discListener = new MADisconnectListener(this); BlockListener blockListener = new MABlockListener(this); @@ -54,9 +54,9 @@ public class MobArena extends JavaPlugin // TO-DO: PlayerListener to check for kills/deaths. // Register events. - pm.registerEvent(Event.Type.PLAYER_INTERACT, signListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_DROP_ITEM, dropListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_INTERACT, readyListener, Priority.Normal, this); + pm.registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, commandListener, Priority.Monitor, this); + pm.registerEvent(Event.Type.PLAYER_INTERACT, lobbyListener, Priority.Normal, this); + pm.registerEvent(Event.Type.PLAYER_DROP_ITEM, lobbyListener, Priority.Normal, this); pm.registerEvent(Event.Type.PLAYER_TELEPORT, teleportListener, Priority.Normal, this); pm.registerEvent(Event.Type.PLAYER_QUIT, discListener, Priority.Normal, this); pm.registerEvent(Event.Type.PLAYER_KICK, discListener, Priority.Normal, this); @@ -69,7 +69,7 @@ public class MobArena extends JavaPlugin pm.registerEvent(Event.Type.ENTITY_COMBUST, monsterListener, Priority.Normal, this); pm.registerEvent(Event.Type.ENTITY_TARGET, monsterListener, Priority.Normal, this); - System.out.println(pdfFile.getName() + " v" + pdfFile.getVersion() + " initialized." ); + System.out.println(pdfFile.getName() + " v" + pdfFile.getVersion() + " enabled." ); } public void onDisable()