shared parties, disco floor exceptions, sets

This commit is contained in:
Charlie 2014-08-01 17:04:08 -04:00
parent 51fd46e031
commit f64a5f85b7
4 changed files with 128 additions and 39 deletions

View File

@ -30,6 +30,7 @@ public class DiscoCommands {
static final String PERMISSION_SPAWNGUESTS = "discosheep.party.spawnguests"; static final String PERMISSION_SPAWNGUESTS = "discosheep.party.spawnguests";
static final String PERMISSION_TOGGLEPARTYONJOIN = "discosheep.admin.toggleonjoin"; static final String PERMISSION_TOGGLEPARTYONJOIN = "discosheep.admin.toggleonjoin";
static final String PERMISSION_LIGHTNING = "discosheep.party.lightning"; static final String PERMISSION_LIGHTNING = "discosheep.party.lightning";
static final String PERMISSION_SHARED = "discosheep.party.shared";
static final String FLAGS = "n:t:p:r:lfg"; static final String FLAGS = "n:t:p:r:lfg";
@ -190,8 +191,7 @@ public class DiscoCommands {
flags = FLAGS flags = FLAGS
) )
@CommandPermissions(value = PERMISSION_PARTY) @CommandPermissions(value = PERMISSION_PARTY)
public static void partyCommand(final CommandContext args, CommandSender sender public static void partyCommand(final CommandContext args, CommandSender sender) {
) {
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage("You must be a player to have a party"); sender.sendMessage("You must be a player to have a party");
return; return;
@ -206,6 +206,32 @@ public class DiscoCommands {
} }
} }
@Command(
aliases = {"shared"},
desc = "Start your own shared DiscoParty (other players can see the party)",
usage = "[optional flags]",
min = 0,
max = -1,
flags = FLAGS
)
@CommandPermissions(value = PERMISSION_SHARED)
public static void partySharedCommand(final CommandContext args, CommandSender sender) {
if (!(sender instanceof Player)) {
sender.sendMessage("You must be a player to have a party");
return;
}
Player player = (Player) sender;
if (!plugin.hasParty(player.getName())) {
DiscoParty party = new DiscoParty();
party.setMainPlayer(player);
parsePartyFlags(party, args, sender);
party.getPlayers().addAll(plugin.getPlayersWithin(player, party.getRadius()));
party.startDisco();
} else {
player.sendMessage(ChatColor.RED + "You already have a party.");
}
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
// UUIDs not necessary since DiscoSheep only lasts for one session at most // UUIDs not necessary since DiscoSheep only lasts for one session at most
// and permissions will handle onJoin DiscoSheep // and permissions will handle onJoin DiscoSheep
@ -218,8 +244,7 @@ public class DiscoCommands {
flags = FLAGS flags = FLAGS
) )
@CommandPermissions(value = PERMISSION_OTHER) @CommandPermissions(value = PERMISSION_OTHER)
public static void partyOtherCommand(CommandContext args, CommandSender sender public static void partyOtherCommand(CommandContext args, CommandSender sender) {
) {
DiscoParty party = new DiscoParty(); DiscoParty party = new DiscoParty();
parsePartyFlags(party, args, sender); parsePartyFlags(party, args, sender);
String players[] = args.getParsedSlice(0); String players[] = args.getParsedSlice(0);

View File

@ -1,12 +1,15 @@
package ca.gibstick.discosheep; package ca.gibstick.discosheep;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Effect; import org.bukkit.Material;
import static org.bukkit.EntityEffect.*; import static org.bukkit.EntityEffect.*;
import org.bukkit.FireworkEffect; import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Builder; import org.bukkit.FireworkEffect.Builder;
@ -15,6 +18,7 @@ import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -41,6 +45,20 @@ public class DiscoParty {
static int maxPeriod = 40; // 2.0 seconds static int maxPeriod = 40; // 2.0 seconds
private static HashMap<String, Integer> defaultGuestNumbers = new HashMap<String, Integer>(); private static HashMap<String, Integer> defaultGuestNumbers = new HashMap<String, Integer>();
private static HashMap<String, Integer> maxGuestNumbers = new HashMap<String, Integer>(); private static HashMap<String, Integer> maxGuestNumbers = new HashMap<String, Integer>();
private static final EnumSet<Material> floorExceptions = EnumSet.of(
Material.STAINED_GLASS,
Material.FURNACE,
Material.CHEST,
Material.ENDER_CHEST,
Material.BURNING_FURNACE,
Material.ENDER_PORTAL,
Material.ENDER_PORTAL_FRAME,
Material.OBSIDIAN,
Material.BED,
Material.BED_BLOCK,
Material.SOIL
);
private static final DyeColor[] discoColours = { private static final DyeColor[] discoColours = {
DyeColor.RED, DyeColor.RED,
DyeColor.ORANGE, DyeColor.ORANGE,
@ -56,6 +74,7 @@ public class DiscoParty {
DyeColor.BLACK, DyeColor.BLACK,
DyeColor.WHITE DyeColor.WHITE
}; };
private static final float[] pentatonicNotes = { private static final float[] pentatonicNotes = {
1.0f, 1.0f,
1.125f, 1.125f,
@ -68,9 +87,12 @@ public class DiscoParty {
private Random r = new Random(); private Random r = new Random();
private PartyEvents partyEvents; private PartyEvents partyEvents;
private final DiscoSheep parent = DiscoSheep.getInstance(); private final DiscoSheep parent = DiscoSheep.getInstance();
private Player player; private ArrayList<Player> players = new ArrayList<Player>();
private Player mainPlayer;
private ArrayList<Sheep> sheepList = new ArrayList<Sheep>(); private ArrayList<Sheep> sheepList = new ArrayList<Sheep>();
private HashSet<Sheep> sheepSet = new HashSet<Sheep>();
private ArrayList<Entity> guestList = new ArrayList<Entity>(); private ArrayList<Entity> guestList = new ArrayList<Entity>();
private HashSet<Entity> guestSet = new HashSet<Entity>();
private ArrayList<BlockState> floorBlockCache = new ArrayList<BlockState>(); private ArrayList<BlockState> floorBlockCache = new ArrayList<BlockState>();
private ArrayList<Block> floorBlocks = new ArrayList<Block>(); private ArrayList<Block> floorBlocks = new ArrayList<Block>();
private HashMap<String, Integer> guestNumbers = new HashMap<String, Integer>(); private HashMap<String, Integer> guestNumbers = new HashMap<String, Integer>();
@ -83,7 +105,8 @@ public class DiscoParty {
public DiscoParty(Player player) { public DiscoParty(Player player) {
this(); this();
this.player = player; this.mainPlayer = player;
this.players.add(player);
} }
public DiscoParty() { public DiscoParty() {
@ -110,6 +133,14 @@ public class DiscoParty {
return newParty; return newParty;
} }
HashSet<Sheep> getSheepSet() {
return sheepSet;
}
HashSet<Entity> getGuestSet() {
return guestSet;
}
ArrayList<Sheep> getSheepList() { ArrayList<Sheep> getSheepList() {
return sheepList; return sheepList;
} }
@ -126,6 +157,10 @@ public class DiscoParty {
return this.floorBlocks; return this.floorBlocks;
} }
public int getRadius() {
return radius;
}
public static HashMap<String, Integer> getDefaultGuestNumbers() { public static HashMap<String, Integer> getDefaultGuestNumbers() {
return defaultGuestNumbers; return defaultGuestNumbers;
} }
@ -142,13 +177,13 @@ public class DiscoParty {
return this.sheep; return this.sheep;
} }
public DiscoParty setPlayer(Player player) { public DiscoParty setMainPlayer(Player player) {
if (player != null) { this.mainPlayer = player;
this.player = player;
return this; return this;
} else {
throw new NullPointerException();
} }
public ArrayList<Player> getPlayers() {
return players;
} }
public DiscoParty setDuration(int duration) throws IllegalArgumentException { public DiscoParty setDuration(int duration) throws IllegalArgumentException {
@ -243,11 +278,11 @@ public class DiscoParty {
double azimuth = r.nextDouble() * 2 * Math.PI; // radians double azimuth = r.nextDouble() * 2 * Math.PI; // radians
x += rand * Math.cos(azimuth); x += rand * Math.cos(azimuth);
z += rand * Math.sin(azimuth); z += rand * Math.sin(azimuth);
y = this.player.getLocation().getY(); y = this.mainPlayer.getLocation().getY();
loc = new Location(world, x, y, z); loc = new Location(world, x, y, z);
loc.setPitch(r.nextFloat() * 360 - 180); loc.setPitch(r.nextFloat() * 360 - 180);
loc.setYaw(0); loc.setYaw(r.nextFloat() * 360 - 180);
return loc; return loc;
} }
@ -255,10 +290,10 @@ public class DiscoParty {
// Spawn some number of guests next to given player // Spawn some number of guests next to given player
void spawnAll(int sheep, int spawnRadius) { void spawnAll(int sheep, int spawnRadius) {
Location loc; Location loc;
World world = player.getWorld(); World world = mainPlayer.getWorld();
double x = player.getLocation().getX(); double x = mainPlayer.getLocation().getX();
double z = player.getLocation().getZ(); double z = mainPlayer.getLocation().getZ();
for (int i = 0; i < sheep; i++) { for (int i = 0; i < sheep; i++) {
loc = getRandomSpawnLocation(x, z, world, spawnRadius); loc = getRandomSpawnLocation(x, z, world, spawnRadius);
spawnSheep(world, loc); spawnSheep(world, loc);
@ -275,7 +310,7 @@ public class DiscoParty {
} }
} }
loc = player.getLocation(); loc = mainPlayer.getLocation();
this.spawnFloor(world, new Location(world, loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ())); this.spawnFloor(world, new Location(world, loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ()));
} }
@ -284,8 +319,9 @@ public class DiscoParty {
//newSheep.setColor(discoColours[(r.nextInt(discoColours.length))]); //newSheep.setColor(discoColours[(r.nextInt(discoColours.length))]);
newSheep.setBreed(false); // this prevents breeding - no event listener required newSheep.setBreed(false); // this prevents breeding - no event listener required
newSheep.teleport(loc); // teleport is needed to set orientation newSheep.teleport(loc); // teleport is needed to set orientation
newSheep.setTarget(player); newSheep.setTarget(this.mainPlayer);
getSheepList().add(newSheep); getSheepList().add(newSheep);
getSheepSet().add(newSheep);
if (doLightning) { if (doLightning) {
world.strikeLightningEffect(loc); world.strikeLightningEffect(loc);
} }
@ -297,6 +333,7 @@ public class DiscoParty {
void spawnGuest(World world, Location loc, EntityType type) { void spawnGuest(World world, Location loc, EntityType type) {
Entity newGuest = loc.getWorld().spawnEntity(loc, type); Entity newGuest = loc.getWorld().spawnEntity(loc, type);
getGuestList().add(newGuest); getGuestList().add(newGuest);
getGuestSet().add(newGuest);
if (doLightning) { if (doLightning) {
world.strikeLightningEffect(loc); world.strikeLightningEffect(loc);
} }
@ -307,7 +344,9 @@ public class DiscoParty {
for (int x = loc.getBlockX() - Math.min(this.radius, DiscoParty.maxFloorSize); x < loc.getX() + Math.min(this.radius, DiscoParty.maxFloorSize); ++x) { for (int x = loc.getBlockX() - Math.min(this.radius, DiscoParty.maxFloorSize); x < loc.getX() + Math.min(this.radius, DiscoParty.maxFloorSize); ++x) {
for (int z = loc.getBlockZ() - Math.min(this.radius, DiscoParty.maxFloorSize); z < loc.getZ() + Math.min(this.radius, DiscoParty.maxFloorSize); ++z) { for (int z = loc.getBlockZ() - Math.min(this.radius, DiscoParty.maxFloorSize); z < loc.getZ() + Math.min(this.radius, DiscoParty.maxFloorSize); ++z) {
Block block = world.getBlockAt(x, loc.getBlockY(), z); Block block = world.getBlockAt(x, loc.getBlockY(), z);
if (block.getType() != Material.STAINED_GLASS) { if (!DiscoParty.floorExceptions.contains(block.getType())
&& block.getRelative(BlockFace.UP).getType() == Material.AIR
&& (block.getType().isSolid() || block.getType() == Material.AIR)) {
this.getFloorCache().add(block.getState()); this.getFloorCache().add(block.getState());
block.setType(Material.STAINED_GLASS); block.setType(Material.STAINED_GLASS);
this.getFloorBlocks().add(block); this.getFloorBlocks().add(block);
@ -324,11 +363,14 @@ public class DiscoParty {
for (Entity guest : getGuestList()) { for (Entity guest : getGuestList()) {
guest.remove(); guest.remove();
} }
for (BlockState block : this.floorBlockCache) { for (BlockState block : this.floorBlockCache) {
block.update(true); block.update(true);
} }
getSheepList().clear(); getSheepList().clear();
getGuestList().clear(); getGuestList().clear();
getSheepSet().clear();
getGuestSet().clear();
floorBlockCache.clear(); floorBlockCache.clear();
} }
@ -339,7 +381,6 @@ public class DiscoParty {
void randomizeFloor(Block block, int index) { void randomizeFloor(Block block, int index) {
int to_color = (index + state) % discoColours.length; int to_color = (index + state) % discoColours.length;
block.setData(discoColours[to_color].getData()); block.setData(discoColours[to_color].getData());
} }
@ -350,7 +391,6 @@ public class DiscoParty {
entity.setVelocity(newVel); entity.setVelocity(newVel);
} }
// WHY ISN'T THERE A Color.getValue() ?!?!?!?!
private Color getColor(int i) { private Color getColor(int i) {
Color c = null; Color c = null;
if (i == 1) { if (i == 1) {
@ -434,23 +474,26 @@ public class DiscoParty {
} }
} }
} }
for (int i = 0; i < this.floorBlocks.size(); i++) { for (int i = 0; i < this.floorBlocks.size(); i++) {
this.randomizeFloor(floorBlocks.get(i), i); this.randomizeFloor(floorBlocks.get(i), i);
} }
} }
private float getPentatonicNote() { float getPentatonicNote() {
return DiscoParty.pentatonicNotes[r.nextInt(pentatonicNotes.length)]; return DiscoParty.pentatonicNotes[r.nextInt(pentatonicNotes.length)];
} }
void playSounds() { void playSounds() {
player.playSound(player.getLocation(), Sound.NOTE_BASS_DRUM, 0.75f, 1.0f); for (Player p : players) {
p.playSound(p.getLocation(), Sound.NOTE_BASS_DRUM, 0.75f, 1.0f);
if (this.state % 2 == 0) { if (this.state % 2 == 0) {
player.playSound(player.getLocation(), Sound.NOTE_SNARE_DRUM, 0.8f, 1.0f); p.playSound(p.getLocation(), Sound.NOTE_SNARE_DRUM, 0.8f, 1.0f);
} }
if ((this.state + 1) % 8 == 0) { if ((this.state + 1) % 8 == 0) {
player.playSound(player.getLocation(), Sound.NOTE_STICKS, 1.0f, 1.0f); p.playSound(p.getLocation(), Sound.NOTE_STICKS, 1.0f, 1.0f);
}
} }
} }
@ -504,7 +547,7 @@ public class DiscoParty {
void startDisco() { void startDisco() {
this.spawnAll(sheep, radius); this.spawnAll(sheep, radius);
this.scheduleUpdate(); this.scheduleUpdate();
parent.getPartyMap().put(this.player.getName(), this); parent.getPartyMap().put(this.mainPlayer.getName(), this);
// start listening // start listening
this.partyEvents = new PartyEvents(this); this.partyEvents = new PartyEvents(this);
parent.getServer().getPluginManager().registerEvents(this.partyEvents, this.parent); parent.getServer().getPluginManager().registerEvents(this.partyEvents, this.parent);
@ -517,7 +560,7 @@ public class DiscoParty {
updater.cancel(); updater.cancel();
} }
updater = null; updater = null;
parent.getPartyMap().remove(this.player.getName()); parent.getPartyMap().remove(this.mainPlayer.getName());
// stop listening // stop listening
HandlerList.unregisterAll(this.partyEvents); HandlerList.unregisterAll(this.partyEvents);
} }

View File

@ -7,11 +7,15 @@ import com.sk89q.minecraft.util.commands.CommandsManager;
import com.sk89q.minecraft.util.commands.MissingNestedCommandException; import com.sk89q.minecraft.util.commands.MissingNestedCommandException;
import com.sk89q.minecraft.util.commands.WrappedCommandException; import com.sk89q.minecraft.util.commands.WrappedCommandException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandException; import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -107,6 +111,7 @@ public final class DiscoSheep extends JavaPlugin {
getConfig().addDefault("max.guests." + ent.toString(), 5); getConfig().addDefault("max.guests." + ent.toString(), 5);
} }
} }
loadConfigFromDisk(); loadConfigFromDisk();
} }
@ -184,6 +189,7 @@ public final class DiscoSheep extends JavaPlugin {
if (this.hasParty(name)) { if (this.hasParty(name)) {
this.getParty(name).stopDisco(); this.getParty(name).stopDisco();
} }
} }
public void stopAllParties() { public void stopAllParties() {
@ -230,4 +236,16 @@ public final class DiscoSheep extends JavaPlugin {
sender.sendMessage(ChatColor.RED + "You do not have the permission node " + ChatColor.GRAY + permission); sender.sendMessage(ChatColor.RED + "You do not have the permission node " + ChatColor.GRAY + permission);
return false; return false;
} }
// From user "desht" on bukkit forums
public List<Player> getPlayersWithin(Player player, int distance) {
List<Player> res = new ArrayList<Player>();
int d2 = distance * distance;
for (Player p : Bukkit.getServer().getOnlinePlayers()) {
if (p.getWorld() == player.getWorld() && p.getLocation().distanceSquared(player.getLocation()) <= d2) {
res.add(p);
}
}
return res;
}
} }

View File

@ -1,5 +1,7 @@
package ca.gibstick.discosheep; package ca.gibstick.discosheep;
import org.bukkit.Instrument;
import org.bukkit.Sound;
import org.bukkit.entity.Sheep; import org.bukkit.entity.Sheep;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -35,7 +37,7 @@ public class PartyEvents implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerShear(PlayerShearEntityEvent e) { public void onPlayerShear(PlayerShearEntityEvent e) {
if (e.getEntity() instanceof Sheep) { if (e.getEntity() instanceof Sheep) {
if (party.getSheepList().contains((Sheep) e.getEntity())) { if (party.getSheepSet().contains((Sheep) e.getEntity())) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@ -45,12 +47,12 @@ public class PartyEvents implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onLivingEntityDamageEvent(EntityDamageEvent e) { public void onLivingEntityDamageEvent(EntityDamageEvent e) {
if (e.getEntity() instanceof Sheep) { if (e.getEntity() instanceof Sheep) {
if (party.getSheepList().contains((Sheep) e.getEntity())) { if (party.getSheepSet().contains((Sheep) e.getEntity())) {
party.jump(e.getEntity()); // for kicks party.jump(e.getEntity()); // for kicks
e.setCancelled(true); e.setCancelled(true);
} }
} }
if (party.getGuestList().contains(e.getEntity())) { if (party.getGuestSet().contains(e.getEntity())) {
party.jump(e.getEntity()); party.jump(e.getEntity());
e.setCancelled(true); e.setCancelled(true);
} }
@ -59,7 +61,7 @@ public class PartyEvents implements Listener {
// prevent uninvited guests from targetting players // prevent uninvited guests from targetting players
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEntityTargetLivingEntityEvent(EntityTargetEvent e) { public void onEntityTargetLivingEntityEvent(EntityTargetEvent e) {
if (party.getGuestList().contains(e.getEntity())) { if (party.getGuestSet().contains(e.getEntity())) {
e.setCancelled(true); e.setCancelled(true);
} }
} }
@ -67,15 +69,16 @@ public class PartyEvents implements Listener {
// prevent egg breeding // prevent egg breeding
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent e) { public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent e) {
if (party.getSheepList().contains(e.getRightClicked()) || party.getGuestList().contains(e.getRightClicked())) { if (party.getSheepSet().contains(e.getRightClicked()) || party.getGuestSet().contains(e.getRightClicked())) {
e.setCancelled(true); e.setCancelled(true);
e.getPlayer().playSound(e.getRightClicked().getLocation(), Sound.NOTE_BASS_GUITAR, 1.0f, party.getPentatonicNote());
} }
} }
// prevent portal teleport // prevent portal teleport
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEntityPortalEvent(EntityPortalEvent e) { public void onEntityPortalEvent(EntityPortalEvent e) {
if (party.getSheepList().contains(e.getEntity()) || party.getGuestList().contains(e.getEntity())) { if (party.getSheepSet().contains(e.getEntity()) || party.getGuestSet().contains(e.getEntity())) {
e.setCancelled(true); e.setCancelled(true);
} }
} }