Default, special, swarm and boss waves implemented.
This commit is contained in:
Binary file not shown.
@@ -36,6 +36,7 @@ import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
import com.garbagemule.MobArena.waves.BossWave;
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
import com.garbagemule.MobArena.waves.Wave.WaveBranch;
|
||||
|
||||
@@ -71,6 +72,7 @@ public class Arena
|
||||
//protected TreeSet<RecurrentWave> recurrentWaves;
|
||||
protected TreeSet<Wave> singleWaves;
|
||||
protected TreeSet<Wave> recurrentWaves;
|
||||
protected BossWave bossWave;
|
||||
//
|
||||
//
|
||||
// NEW IMPLEMENTATION
|
||||
@@ -248,9 +250,6 @@ public class Arena
|
||||
|
||||
public void forceEnd()
|
||||
{
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
Bukkit.getServer().getScheduler().cancelTask(spawnTaskId);
|
||||
|
||||
for (Player p : getAllPlayers())
|
||||
@@ -259,11 +258,14 @@ public class Arena
|
||||
for (Entity e : monsters)
|
||||
e.remove();
|
||||
|
||||
if (bossWave != null)
|
||||
bossWave.clear();
|
||||
|
||||
arenaPlayers.clear();
|
||||
lobbyPlayers.clear();
|
||||
readyPlayers.clear();
|
||||
|
||||
monsters.clear();
|
||||
cleanup();
|
||||
|
||||
spawnTaskId = -1;
|
||||
}
|
||||
@@ -295,7 +297,8 @@ public class Arena
|
||||
MAUtils.clearInventory(p);
|
||||
|
||||
restoreInvAndGiveRewards(p);
|
||||
if (log.players.get(p) != null) log.players.get(p).lastWave = spawnThread.getWave() - 1;
|
||||
if (log != null && log.players.get(p) != null)
|
||||
log.players.get(p).lastWave = spawnThread.getWave() - 1;
|
||||
movePlayerToEntry(p);
|
||||
finishWithPlayer(p);
|
||||
endArena();
|
||||
@@ -403,8 +406,7 @@ public class Arena
|
||||
|
||||
public void restoreInvAndGiveRewards(final Player p)
|
||||
{
|
||||
final List<ItemStack> rewards = log.players.get(p).rewards;
|
||||
//final List<ItemStack> rewards = rewardMap.get(p);
|
||||
final List<ItemStack> rewards = log != null ? log.players.get(p).rewards : new LinkedList<ItemStack>();
|
||||
final boolean hadRewards = rewardedPlayers.contains(p);
|
||||
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin,
|
||||
@@ -556,6 +558,8 @@ public class Arena
|
||||
|
||||
private void removeMonsters()
|
||||
{
|
||||
if (bossWave != null)
|
||||
bossWave.clear();
|
||||
for (LivingEntity e : monsters)
|
||||
e.remove();
|
||||
for (LivingEntity e : explodingSheep)
|
||||
@@ -865,11 +869,21 @@ public class Arena
|
||||
return name;
|
||||
}
|
||||
|
||||
public MobArena getPlugin()
|
||||
{
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setBossWave(BossWave bossWave)
|
||||
{
|
||||
this.bossWave = bossWave;
|
||||
}
|
||||
|
||||
public List<String> getClasses()
|
||||
{
|
||||
return classes;
|
||||
@@ -880,6 +894,24 @@ public class Arena
|
||||
return spawnpoints.values();
|
||||
}
|
||||
|
||||
public Location getBossSpawnpoint()
|
||||
{
|
||||
Location result = null;
|
||||
|
||||
for (Map.Entry<String,Location> entry : spawnpoints.entrySet())
|
||||
{
|
||||
if (!entry.getKey().matches("^*boss*$")) continue;
|
||||
|
||||
result = entry.getValue();
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
return spawnpoints.values().iterator().next();
|
||||
}
|
||||
|
||||
public int getPlayerCount()
|
||||
{
|
||||
return spawnThread.getPlayerCount();
|
||||
|
||||
@@ -504,7 +504,7 @@ public class MACommands implements CommandExecutor
|
||||
return true;
|
||||
}
|
||||
|
||||
if (arena.arenaPlayers.isEmpty())
|
||||
if (arena.getAllPlayers().isEmpty())
|
||||
{
|
||||
MAUtils.tellPlayer(sender, MAMessages.get(Msg.FORCE_END_EMPTY));
|
||||
return true;
|
||||
|
||||
@@ -341,6 +341,24 @@ public class MAListener implements ArenaListener
|
||||
if (!arena.monsterInfight)
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
// Boss
|
||||
if (arena.bossWave != null && damagee.equals(arena.bossWave.getEntity()))
|
||||
{
|
||||
// Subtract boss health, and reset actual entity health
|
||||
arena.bossWave.subtractHealth(event.getDamage());
|
||||
arena.bossWave.getEntity().setHealth(200);
|
||||
|
||||
// Set damage to 1 for knockback and feedback
|
||||
event.setDamage(1);
|
||||
|
||||
// If the boss is dead, remove the entity and create an explosion!
|
||||
if (arena.bossWave.getHealth() <= 0)
|
||||
{
|
||||
arena.bossWave.clear();
|
||||
arena.bossWave = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,7 +510,7 @@ public class MAListener implements ArenaListener
|
||||
{
|
||||
if (arena.inRegion(from))
|
||||
{
|
||||
if (to.equals(arena.arenaLoc) || to.equals(arena.lobbyLoc) || to.equals(arena.spectatorLoc) || to.equals(old))
|
||||
if (arena.inRegion(to) || to.equals(arena.arenaLoc) || to.equals(arena.lobbyLoc) || to.equals(arena.spectatorLoc) || to.equals(old))
|
||||
return;
|
||||
|
||||
MAUtils.tellPlayer(p, MAMessages.get(Msg.WARP_FROM_ARENA));
|
||||
|
||||
@@ -76,8 +76,6 @@ public class MobArena extends JavaPlugin
|
||||
|
||||
public void onDisable()
|
||||
{
|
||||
// TODO: Re-implement this!
|
||||
/*
|
||||
// Force all arenas to end.
|
||||
for (Arena arena : am.arenas)
|
||||
arena.forceEnd();
|
||||
@@ -90,7 +88,7 @@ public class MobArena extends JavaPlugin
|
||||
Methods = null;
|
||||
System.out.println("[MobArena] Payment method was disabled. No longer accepting payments.");
|
||||
}
|
||||
*/
|
||||
|
||||
System.out.println("[MobArena] disabled.");
|
||||
}
|
||||
|
||||
@@ -137,6 +135,7 @@ public class MobArena extends JavaPlugin
|
||||
pm.registerEvent(Event.Type.ENTITY_DEATH, entityListener, Priority.Lowest, this); // Lowest because of Tombstone
|
||||
pm.registerEvent(Event.Type.ENTITY_REGAIN_HEALTH, entityListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.Highest, this);
|
||||
pm.registerEvent(Event.Type.EXPLOSION_PRIME, entityListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.ENTITY_COMBUST, entityListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.ENTITY_TARGET, entityListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.CREATURE_SPAWN, entityListener, Priority.Highest, this);
|
||||
|
||||
@@ -137,28 +137,34 @@ public class WaveUtils
|
||||
return null;
|
||||
|
||||
// TODO: Generate waves properly. These are place-holders!
|
||||
Wave result;
|
||||
Wave result = null;
|
||||
if (branch == WaveBranch.RECURRENT)
|
||||
{
|
||||
int frequency = config.getInt(path + "frequency", 0);
|
||||
int priority = config.getInt(path + "priority", 0);
|
||||
int wave = config.getInt(path + "wave", frequency);
|
||||
|
||||
//if (type == WaveType.DEFAULT)
|
||||
if (type == WaveType.DEFAULT)
|
||||
result = new DefaultWave(arena, name, wave, frequency, priority, config, path);
|
||||
result.setGrowth(WaveGrowth.OLD);
|
||||
//else
|
||||
// result = new SpecialWave(arena, name, wave, frequency, priority, config, path);
|
||||
else if (type == WaveType.SPECIAL)
|
||||
result = new SpecialWave(arena, name, wave, frequency, priority, config, path);
|
||||
else if (type == WaveType.SWARM)
|
||||
result = new SwarmWave(arena, name, wave, frequency, priority, config, path);
|
||||
else if (type == WaveType.BOSS)
|
||||
result = new BossWave(arena, name, wave, frequency, priority, config, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
int wave = config.getInt(path + "wave", 0);
|
||||
|
||||
//if (type == WaveType.DEFAULT)
|
||||
if (type == WaveType.DEFAULT)
|
||||
result = new DefaultWave(arena, name, wave, config, path);
|
||||
result.setGrowth(WaveGrowth.OLD);
|
||||
//else
|
||||
// result = new SpecialWave(arena, name, wave, config, path);
|
||||
else if (type == WaveType.SPECIAL)
|
||||
result = new SpecialWave(arena, name, wave, config, path);
|
||||
else if (type == WaveType.SWARM)
|
||||
result = new SwarmWave(arena, name, wave, config, path);
|
||||
else if (type == WaveType.BOSS)
|
||||
result = new BossWave(arena, name, wave, config, path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -249,7 +255,6 @@ public class WaveUtils
|
||||
|
||||
for (String monster : monsters)
|
||||
{
|
||||
//if (getEnumFromString(CreatureType.class, monster) != null)
|
||||
if (getEnumFromString(MACreature.class, monster) != null)
|
||||
continue;
|
||||
|
||||
@@ -275,7 +280,7 @@ public class WaveUtils
|
||||
MAUtils.error("Missing monster type in '" + path);
|
||||
return false;
|
||||
}
|
||||
else if (getEnumFromString(CreatureType.class, monster) == null)
|
||||
else if (getEnumFromString(MACreature.class, monster) == null)
|
||||
{
|
||||
MAUtils.error("Invalid monster type '" + monster + "' in " + path);
|
||||
return false;
|
||||
@@ -304,7 +309,7 @@ public class WaveUtils
|
||||
MAUtils.error("Missing monster type in '" + path);
|
||||
return false;
|
||||
}
|
||||
else if (getEnumFromString(CreatureType.class, monster) == null)
|
||||
else if (getEnumFromString(MACreature.class, monster) == null)
|
||||
{
|
||||
MAUtils.error("Invalid monster type '" + monster + "' in " + path);
|
||||
return false;
|
||||
@@ -316,7 +321,7 @@ public class WaveUtils
|
||||
{
|
||||
for (String ability : abilities.split(","))
|
||||
{
|
||||
if (BossAbility.fromString(ability.trim().toUpperCase()) != null)
|
||||
if (BossAbility.fromString(ability.trim().replaceAll("-", "_").toUpperCase()) != null)
|
||||
continue;
|
||||
|
||||
MAUtils.error("Invalid boss ability '" + ability + "' in " + path);
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public abstract class AbstractWave implements Wave
|
||||
{
|
||||
@@ -66,6 +74,52 @@ public abstract class AbstractWave implements Wave
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn an MACreature in the given location. The actual LivingEntity
|
||||
* spawned is returned.
|
||||
* @param creature The MACreature to spawn
|
||||
* @param loc The location to spawn the MACreature in
|
||||
* @return The resulting LivingEntity
|
||||
*/
|
||||
public LivingEntity spawnMonster(MACreature creature, Location loc)
|
||||
{
|
||||
// Spawn and add to collection
|
||||
LivingEntity e = creature.spawn(getWorld(), loc);
|
||||
getArena().addMonster(e);
|
||||
|
||||
// Grab a random target.
|
||||
if (e instanceof Creature)
|
||||
{
|
||||
Creature c = (Creature) e;
|
||||
c.setTarget(WaveUtils.getClosestPlayer(getArena(), e));
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for spawning a bunch of monsters over a
|
||||
* collection of spawnpoints. Used by wave types DEFAULT,
|
||||
* SPECIAL and SWARM.
|
||||
* @param monsters A collection of monsters to spawn, and how many of each
|
||||
* @param spawnpoints The spawnpoints to spawn the monsters over
|
||||
*/
|
||||
public void spawnAll(Map<MACreature,Integer> monsters, List<Location> spawnpoints)
|
||||
{
|
||||
Random random = new Random();
|
||||
int spawnpointCount = spawnpoints.size();
|
||||
int index = random.nextInt(spawnpointCount);
|
||||
|
||||
for (Map.Entry<MACreature,Integer> entry : monsters.entrySet())
|
||||
{
|
||||
for (int i = 0; i < entry.getValue(); i++)
|
||||
{
|
||||
spawnMonster(entry.getKey(), spawnpoints.get(index % spawnpointCount));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GETTERS
|
||||
public Arena getArena()
|
||||
{
|
||||
@@ -134,6 +188,7 @@ public abstract class AbstractWave implements Wave
|
||||
return "[name=" + waveName +
|
||||
", wave=" + wave +
|
||||
", frequency=" + frequency +
|
||||
", priority=" + priority + "]";
|
||||
", priority=" + priority +
|
||||
", type=" + type + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,116 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.waves.Wave.BossAbility;
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.MAUtils;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public class BossWave // TODO: implement/extend something?
|
||||
public class BossWave extends AbstractWave// TODO: implement/extend something?
|
||||
{
|
||||
private Creature boss;
|
||||
private Set<BossAbility> abilities;
|
||||
private MACreature boss;
|
||||
private LivingEntity bossCreature;
|
||||
private List<BossAbility> abilities;
|
||||
private Set<Creature> adds;
|
||||
private int health;
|
||||
private BossHealth bossHealth;
|
||||
private int healthAmount;
|
||||
private List<Integer> taskList;
|
||||
|
||||
public BossWave(Creature boss)
|
||||
// Recurrent
|
||||
public BossWave(Arena arena, String name, int wave, int frequency, int priority, Configuration config, String path)
|
||||
{
|
||||
this.boss = boss;
|
||||
super(arena, name, wave, frequency, priority);
|
||||
load(config, path);
|
||||
}
|
||||
|
||||
// Single
|
||||
public BossWave(Arena arena, String name, int wave, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave);
|
||||
load(config, path);
|
||||
}
|
||||
|
||||
private void load(Configuration config, String path)
|
||||
{
|
||||
setType(WaveType.BOSS);
|
||||
taskList = new LinkedList<Integer>();
|
||||
abilities = new LinkedList<BossAbility>();
|
||||
|
||||
// Get monster and health
|
||||
boss = MACreature.fromString(config.getString(path + "monster"));
|
||||
bossHealth = WaveUtils.getEnumFromString(BossHealth.class, config.getString(path + "health"), BossHealth.MEDIUM);
|
||||
|
||||
// Get abilities
|
||||
String abilities = config.getString(path + "abilities");
|
||||
if (abilities != null)
|
||||
{
|
||||
for (String a : abilities.split(","))
|
||||
{
|
||||
String ability = a.trim().replaceAll("-", "_").toUpperCase();
|
||||
System.out.println(ability);
|
||||
addAbility(BossAbility.fromString(ability));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void spawn(int wave)
|
||||
{
|
||||
// Spawn the boss and set the arena
|
||||
bossCreature = boss.spawn(getWorld(), getArena().getBossSpawnpoint());
|
||||
if (bossCreature instanceof Creature)
|
||||
((Creature) bossCreature).setTarget(MAUtils.getClosestPlayer(bossCreature, getArena()));
|
||||
getArena().addMonster(bossCreature);
|
||||
getArena().setBossWave(this);
|
||||
|
||||
// Set the health stuff
|
||||
bossCreature.setHealth(200);
|
||||
healthAmount = bossHealth.getAmount(getArena().getPlayerCount());
|
||||
|
||||
startAbilityTasks();
|
||||
}
|
||||
|
||||
private void startAbilityTasks()
|
||||
{
|
||||
final int abilityCount = abilities.size();
|
||||
|
||||
int i = 1;
|
||||
for (final BossAbility ability : abilities)
|
||||
{
|
||||
// Schedule the task
|
||||
int abilityTask = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(getArena().getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
ability.activate(getArena(), bossCreature);
|
||||
}
|
||||
}, 50*i, 50*abilityCount);
|
||||
|
||||
// Add the task to the task list for cancelling later, and increment counter
|
||||
taskList.add(abilityTask);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelAbilityTasks()
|
||||
{
|
||||
for (Integer i : taskList)
|
||||
Bukkit.getServer().getScheduler().cancelTask(i);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
cancelAbilityTasks();
|
||||
getArena().setBossWave(null);
|
||||
getWorld().createExplosion(bossCreature.getLocation(), 1);
|
||||
bossCreature.damage(32768);
|
||||
}
|
||||
|
||||
public void addAbility(BossAbility ability)
|
||||
@@ -30,21 +123,23 @@ public class BossWave // TODO: implement/extend something?
|
||||
adds.add(creature);
|
||||
}
|
||||
|
||||
public void setHealth(int health)
|
||||
public int getHealth()
|
||||
{
|
||||
this.health = health;
|
||||
return healthAmount;
|
||||
}
|
||||
|
||||
public void spawn(int wave, Collection<Location> spawnpoints)
|
||||
public LivingEntity getEntity()
|
||||
{
|
||||
// Spawn boss and adds
|
||||
// Something like this, perhaps? Pseudo-code
|
||||
// LivingEntity b = spawnCreature(bossType, random location)
|
||||
// boss = (Creature) b;
|
||||
// boss.setHealth(health);
|
||||
// for (String a : ablts)
|
||||
// abilities.add(BossAbility.fromString(a));
|
||||
// for (int i = 0; i < addCount; i++)
|
||||
// adds.add(spawnCreature(addType, bossLocation);
|
||||
return bossCreature;
|
||||
}
|
||||
|
||||
public void setHealth(int healthAmount)
|
||||
{
|
||||
this.healthAmount = healthAmount;
|
||||
}
|
||||
|
||||
public void subtractHealth(int amount)
|
||||
{
|
||||
healthAmount -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +1,75 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public class DefaultWave extends AbstractWave
|
||||
public class DefaultWave extends NormalWave
|
||||
{
|
||||
private int totalProbability = 0;
|
||||
private Map<Integer,MACreature> probabilities = new TreeMap<Integer,MACreature>();
|
||||
|
||||
// Recurrent
|
||||
public DefaultWave(Arena arena, String name, int wave, int frequency, int priority, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave, frequency, priority);
|
||||
load(config, path);
|
||||
super(arena, name, wave, frequency, priority, config, path);
|
||||
load(config, path, WaveType.DEFAULT);
|
||||
}
|
||||
|
||||
// Single
|
||||
public DefaultWave(Arena arena, String name, int wave, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave);
|
||||
load(config, path);
|
||||
super(arena, name, wave, config, path);
|
||||
load(config, path, WaveType.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the wave for spawning by initializing the variables and
|
||||
* populating the collections needed.
|
||||
* @param config The config-file
|
||||
* @param path The absolute path of the wave
|
||||
* Default waves spawn an amount of random monsters, picked from a
|
||||
* map of probabilities. The amount to spawn depends on the wave
|
||||
* number and player count.
|
||||
*/
|
||||
public void load(Configuration config, String path)
|
||||
{
|
||||
// Extract the monster probabilities and calculate the sum
|
||||
totalProbability = 0;
|
||||
int prob;
|
||||
for (String m : config.getKeys(path + "monsters"))
|
||||
{
|
||||
prob = config.getInt(path + "monsters." + m, 1);
|
||||
totalProbability += prob;
|
||||
probabilities.put(totalProbability, MACreature.fromString(m));
|
||||
}
|
||||
}
|
||||
|
||||
public void spawn(int wave)
|
||||
{
|
||||
// Get the valid spawnpoints, and initialize counter
|
||||
List<Location> validSpawnpoints = WaveUtils.getValidSpawnpoints(getArena().getSpawnpoints(), getArena().getLivingPlayers());
|
||||
int noOfSpawnpoints = validSpawnpoints.size();
|
||||
|
||||
// Initialize the total amount of mobs to spawn
|
||||
int totalToSpawn = getGrowth().getAmount(wave, getArena().getPlayerCount());
|
||||
|
||||
// Allocate some variables
|
||||
// Spawn all the monsters
|
||||
spawnAll(getMonstersToSpawn(totalToSpawn), validSpawnpoints);
|
||||
System.out.println("WAVE SPAWN! Wave: " + wave + ", name: " + getName() + ", type: " + getType());
|
||||
}
|
||||
|
||||
private Map<MACreature,Integer> getMonstersToSpawn(int totalToSpawn)
|
||||
{
|
||||
Map<MACreature,Integer> result = new HashMap<MACreature,Integer>();
|
||||
Random random = new Random();
|
||||
int randomNumber;
|
||||
Location loc;
|
||||
MACreature creature;
|
||||
|
||||
// Spawn <totalToSpawn> monsters
|
||||
for (int i = 0; i < totalToSpawn; i++)
|
||||
{
|
||||
// Grab the next location.
|
||||
loc = validSpawnpoints.get(i % noOfSpawnpoints);
|
||||
randomNumber = random.nextInt(getTotalProbability());
|
||||
|
||||
// Grab a random number.
|
||||
randomNumber = random.nextInt(totalProbability);
|
||||
|
||||
// Find the monster that corresponds to the random number, and spawn it
|
||||
for (Map.Entry<Integer,MACreature> entry : probabilities.entrySet())
|
||||
// Find the monster that corresponds to the random number, and increment its value
|
||||
for (Map.Entry<Integer,MACreature> entry : getProbabilityMap().entrySet())
|
||||
{
|
||||
if (randomNumber > entry.getKey()) continue;
|
||||
|
||||
// Spawn and add to collection
|
||||
LivingEntity e = entry.getValue().spawn(getWorld(), loc);
|
||||
getArena().addMonster(e);
|
||||
|
||||
// Grab a random target.
|
||||
if (e instanceof Creature)
|
||||
{
|
||||
Creature c = (Creature) e;
|
||||
c.setTarget(WaveUtils.getClosestPlayer(getArena(), e));
|
||||
}
|
||||
|
||||
creature = entry.getValue();
|
||||
if (result.containsKey(entry.getValue()))
|
||||
result.put(creature, result.get(creature) + 1);
|
||||
else
|
||||
result.put(creature, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("WAVE SPAWN! Wave: " + wave + ", name: " + getName() + ", type: " + getType());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,20 +13,20 @@ import com.garbagemule.MobArena.util.WaveUtils;
|
||||
public enum MACreature
|
||||
{
|
||||
// Default creatures
|
||||
ZOMBIES(CreatureType.ZOMBIE),
|
||||
SKELETONS(CreatureType.SKELETON),
|
||||
SPIDERS(CreatureType.SPIDER),
|
||||
CREEPERS(CreatureType.CREEPER),
|
||||
WOLVES(CreatureType.WOLF),
|
||||
ZOMBIE(CreatureType.ZOMBIE), ZOMBIES(CreatureType.ZOMBIE),
|
||||
SKELETON(CreatureType.SKELETON), SKELETONS(CreatureType.SKELETON),
|
||||
SPIDER(CreatureType.SPIDER), SPIDERS(CreatureType.SPIDER),
|
||||
CREEPER(CreatureType.CREEPER), CREEPERS(CreatureType.CREEPER),
|
||||
WOLF(CreatureType.WOLF), WOLVES(CreatureType.WOLF),
|
||||
|
||||
// Special creatures
|
||||
ZOMBIE_PIGMEN(CreatureType.PIG_ZOMBIE),
|
||||
POWERED_CREEPERS(CreatureType.CREEPER),
|
||||
ANGRY_WOLVES(CreatureType.WOLF),
|
||||
HUMANS(CreatureType.MONSTER),
|
||||
SLIMES(CreatureType.SLIME),
|
||||
GIANTS(CreatureType.GIANT),
|
||||
GHASTS(CreatureType.GHAST);
|
||||
ZOMBIE_PIGMAN(CreatureType.PIG_ZOMBIE), ZOMBIE_PIGMEN(CreatureType.PIG_ZOMBIE),
|
||||
POWERED_CREEPER(CreatureType.CREEPER), POWERED_CREEPERS(CreatureType.CREEPER),
|
||||
ANGRY_WOLF(CreatureType.WOLF), ANGRY_WOLVES(CreatureType.WOLF),
|
||||
HUMAN(CreatureType.MONSTER), HUMANS(CreatureType.MONSTER),
|
||||
SLIME(CreatureType.SLIME), SLIMES(CreatureType.SLIME),
|
||||
GIANT(CreatureType.GIANT), GIANTS(CreatureType.GIANT),
|
||||
GHAST(CreatureType.GHAST), GHASTS(CreatureType.GHAST);
|
||||
|
||||
// Misc
|
||||
// EXPLODING_SHEEP(CreatureType.SHEEP), // Explode (power: 1) when close enough to players
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public abstract class NormalWave extends AbstractWave
|
||||
{
|
||||
private int totalProbability = 0;
|
||||
private Map<Integer,MACreature> probabilities = new TreeMap<Integer,MACreature>();
|
||||
|
||||
// Recurrent
|
||||
public NormalWave(Arena arena, String name, int wave, int frequency, int priority, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave, frequency, priority);
|
||||
}
|
||||
|
||||
// Single
|
||||
public NormalWave(Arena arena, String name, int wave, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the wave for spawning by initializing the variables and
|
||||
* populating the collections needed.
|
||||
* @param config The config-file
|
||||
* @param path The absolute path of the wave
|
||||
* @param type DEFAULT or SPECIAL
|
||||
*/
|
||||
public void load(Configuration config, String path, WaveType type)
|
||||
{
|
||||
// Set type and (for DEFAULT) growth.
|
||||
setType(type);
|
||||
if (type == WaveType.DEFAULT)
|
||||
setGrowth(WaveUtils.getEnumFromString(WaveGrowth.class, config.getString(path + "growth"), WaveGrowth.OLD));
|
||||
|
||||
// Load monsters
|
||||
int prob;
|
||||
List<String> monsters = config.getKeys(path + "monsters");
|
||||
if (monsters != null && !monsters.isEmpty())
|
||||
{
|
||||
for (String m : config.getKeys(path + "monsters"))
|
||||
{
|
||||
prob = config.getInt(path + "monsters." + m, 1);
|
||||
incTotalProbability(prob);
|
||||
getProbabilityMap().put(getTotalProbability(), MACreature.fromString(m));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == WaveType.DEFAULT)
|
||||
{
|
||||
getProbabilityMap().put(10, MACreature.ZOMBIES);
|
||||
getProbabilityMap().put(10, MACreature.SKELETONS);
|
||||
getProbabilityMap().put(10, MACreature.SPIDERS);
|
||||
getProbabilityMap().put(10, MACreature.CREEPERS);
|
||||
getProbabilityMap().put(10, MACreature.WOLVES);
|
||||
}
|
||||
else if (type == WaveType.SPECIAL)
|
||||
{
|
||||
getProbabilityMap().put(10, MACreature.POWERED_CREEPERS);
|
||||
getProbabilityMap().put(10, MACreature.ANGRY_WOLVES);
|
||||
getProbabilityMap().put(10, MACreature.ZOMBIE_PIGMEN);
|
||||
getProbabilityMap().put(10, MACreature.SLIMES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalProbability()
|
||||
{
|
||||
return totalProbability;
|
||||
}
|
||||
|
||||
public void incTotalProbability(int value)
|
||||
{
|
||||
totalProbability += value;
|
||||
}
|
||||
|
||||
public Map<Integer,MACreature> getProbabilityMap()
|
||||
{
|
||||
return probabilities;
|
||||
}
|
||||
|
||||
public abstract void spawn(int wave);
|
||||
}
|
||||
@@ -1,23 +1,69 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class SpecialWave extends AbstractWave
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public class SpecialWave extends NormalWave
|
||||
{
|
||||
// Recurrent
|
||||
public SpecialWave(Arena arena, String name, int wave, int frequency, int priority)
|
||||
public SpecialWave(Arena arena, String name, int wave, int frequency, int priority, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave, frequency, priority);
|
||||
super(arena, name, wave, frequency, priority, config, path);
|
||||
load(config, path, WaveType.SPECIAL);
|
||||
}
|
||||
|
||||
// Single
|
||||
public SpecialWave(Arena arena, String name, int wave)
|
||||
public SpecialWave(Arena arena, String name, int wave, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave);
|
||||
super(arena, name, wave, config, path);
|
||||
load(config, path, WaveType.SPECIAL);
|
||||
}
|
||||
|
||||
public void spawn(int wave)
|
||||
{
|
||||
// Get the valid spawnpoints, and initialize counter
|
||||
List<Location> validSpawnpoints = WaveUtils.getValidSpawnpoints(getArena().getSpawnpoints(), getArena().getLivingPlayers());
|
||||
|
||||
// Spawn all the monsters
|
||||
spawnAll(getMonstersToSpawn(getArena().getPlayerCount()), validSpawnpoints);
|
||||
System.out.println("WAVE SPAWN! Wave: " + wave + ", name: " + getName() + ", type: " + getType());
|
||||
}
|
||||
|
||||
private Map<MACreature,Integer> getMonstersToSpawn(int playerCount)
|
||||
{
|
||||
Map<MACreature,Integer> result = new HashMap<MACreature,Integer>();
|
||||
|
||||
Random random = new Random();
|
||||
int randomNumber = random.nextInt(getTotalProbability());
|
||||
for (Map.Entry<Integer,MACreature> entry : getProbabilityMap().entrySet())
|
||||
{
|
||||
if (randomNumber > entry.getKey()) continue;
|
||||
|
||||
int amount;
|
||||
switch (entry.getValue())
|
||||
{
|
||||
case POWERED_CREEPERS:
|
||||
case ZOMBIE_PIGMEN:
|
||||
case ANGRY_WOLVES: amount = playerCount * 2; break;
|
||||
case SLIMES: amount = playerCount * 4; break;
|
||||
case HUMANS: amount = playerCount + 2; break;
|
||||
case GIANTS:
|
||||
case GHASTS: amount = 2;
|
||||
default: amount = playerCount + 1; break;
|
||||
}
|
||||
|
||||
result.put(entry.getValue(), amount);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public class SwarmWave extends AbstractWave
|
||||
{
|
||||
private MACreature monster;
|
||||
private SwarmAmount amount;
|
||||
|
||||
// Recurrent
|
||||
public SwarmWave(Arena arena, String name, int wave, int frequency, int priority, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave, frequency, priority);
|
||||
load(config, path);
|
||||
}
|
||||
|
||||
// Single
|
||||
public SwarmWave(Arena arena, String name, int wave, Configuration config, String path)
|
||||
{
|
||||
super(arena, name, wave);
|
||||
load(config, path);
|
||||
}
|
||||
|
||||
private void load(Configuration config, String path)
|
||||
{
|
||||
// Get the monster type
|
||||
monster = MACreature.fromString(config.getString(path + "monster"));
|
||||
|
||||
// And the amount
|
||||
amount = WaveUtils.getEnumFromString(SwarmAmount.class, config.getString(path + "amount"), SwarmAmount.LOW);
|
||||
}
|
||||
|
||||
public void spawn(int wave)
|
||||
{
|
||||
// Get the valid spawnpoints, and initialize counter
|
||||
List<Location> validSpawnpoints = WaveUtils.getValidSpawnpoints(getArena().getSpawnpoints(), getArena().getLivingPlayers());
|
||||
|
||||
// Spawn the hellians!
|
||||
spawnAll(monster, amount.getAmount(getArena().getPlayerCount()), validSpawnpoints);
|
||||
}
|
||||
|
||||
public void spawnAll(MACreature monster, int amount, List<Location> spawnpoints)
|
||||
{
|
||||
int spawnpointCount = spawnpoints.size();
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
LivingEntity e = spawnMonster(monster, spawnpoints.get(i % spawnpointCount));
|
||||
e.setHealth(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,17 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public interface Wave
|
||||
@@ -48,17 +60,118 @@ public interface Wave
|
||||
|
||||
public enum BossAbility
|
||||
{
|
||||
ARROWS, FIREBALLS, RING_OF_FIRE;
|
||||
ARROWS, FIREBALLS, FIRE_AURA, THROW_TARGET, THROW_NEARBY, FETCH_TARGET, FETCH_DISTANT;
|
||||
|
||||
public static BossAbility fromString(String string)
|
||||
{
|
||||
return WaveUtils.getEnumFromString(BossAbility.class, string);
|
||||
}
|
||||
|
||||
public void activate(Arena arena, LivingEntity boss)
|
||||
{
|
||||
LivingEntity target = getTarget(boss);
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc;
|
||||
|
||||
switch (this)
|
||||
{
|
||||
// Fire an arrow in the direction the boss is facing.
|
||||
case ARROWS:
|
||||
System.out.println("Shooting arrow");
|
||||
boss.shootArrow();
|
||||
break;
|
||||
// Hurl a fireball in the direction the boss is facing.
|
||||
case FIREBALLS:
|
||||
System.out.println("Shooting fireball");
|
||||
loc = bLoc.add(bLoc.getDirection().normalize().multiply(2).toLocation(boss.getWorld(), bLoc.getYaw(), bLoc.getPitch()));
|
||||
Fireball fireball = boss.getWorld().spawn(loc, Fireball.class);
|
||||
fireball.setIsIncendiary(false);
|
||||
break;
|
||||
// Set fire to all players nearby.
|
||||
case FIRE_AURA:
|
||||
System.out.println("Fire aura");
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
p.setFireTicks(20);
|
||||
break;
|
||||
// Throw target back
|
||||
case THROW_TARGET:
|
||||
System.out.println("Throw target");
|
||||
if (target != null)
|
||||
{
|
||||
loc = target.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
target.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
break;
|
||||
// Throw nearby players back
|
||||
case THROW_NEARBY:
|
||||
System.out.println("Throw nearby");
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
{
|
||||
loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
break;
|
||||
// Warp target to boss
|
||||
case FETCH_TARGET:
|
||||
System.out.println("Fetch target");
|
||||
if (target != null) target.teleport(boss);
|
||||
break;
|
||||
// Warp nearby players to boss
|
||||
case FETCH_DISTANT:
|
||||
System.out.println("Fetch distant");
|
||||
for (Player p : getDistantPlayers(arena, boss, 8))
|
||||
p.teleport(boss);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private LivingEntity getTarget(LivingEntity entity)
|
||||
{
|
||||
if (entity instanceof Creature)
|
||||
{
|
||||
LivingEntity target = ((Creature) entity).getTarget();
|
||||
if (target instanceof Player)
|
||||
return target;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Player> getNearbyPlayers(Arena arena, Entity boss, int x)
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
for (Entity e : boss.getNearbyEntities(x, x, x))
|
||||
if (arena.getLivingPlayers().contains(e))
|
||||
result.add((Player) e);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Player> getDistantPlayers(Arena arena, Entity boss, int x)
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
for (Player p : arena.getLivingPlayers())
|
||||
if (p.getLocation().distanceSquared(boss.getLocation()) > x*x)
|
||||
result.add(p);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public enum BossHealth
|
||||
{
|
||||
LOW, MEDIUM, HIGH;
|
||||
LOW(5), MEDIUM(8), HIGH(12), PSYCHO(20);
|
||||
private int multiplier;
|
||||
|
||||
private BossHealth(int multiplier)
|
||||
{
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
public int getAmount(int playerCount)
|
||||
{
|
||||
return (playerCount + 1) * 20 * multiplier;
|
||||
}
|
||||
|
||||
public static BossHealth fromString(String string)
|
||||
{
|
||||
@@ -68,7 +181,18 @@ public interface Wave
|
||||
|
||||
public enum SwarmAmount
|
||||
{
|
||||
LOW, MEDIUM, HIGH, PSYCHO;
|
||||
LOW(10), MEDIUM(20), HIGH(30), PSYCHO(50);
|
||||
private int multiplier;
|
||||
|
||||
private SwarmAmount(int multiplier)
|
||||
{
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
public int getAmount(int playerCount)
|
||||
{
|
||||
return Math.max(1, playerCount / 2) * multiplier;
|
||||
}
|
||||
|
||||
public static SwarmAmount fromString(String string)
|
||||
{
|
||||
@@ -120,6 +244,12 @@ public interface Wave
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Get the arena of this wave.
|
||||
* @return The arena
|
||||
*/
|
||||
public Arena getArena();
|
||||
|
||||
/**
|
||||
* Set the wave's growth
|
||||
* @param growth How fast the wave will grow
|
||||
|
||||
Reference in New Issue
Block a user