485 lines
21 KiB
Java
485 lines
21 KiB
Java
package fr.leomelki.loupgarou.classes;
|
|
|
|
import com.comphenix.protocol.wrappers.EnumWrappers.ItemSlot;
|
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
|
import fr.leomelki.com.comphenix.packetwrapper.*;
|
|
import fr.leomelki.loupgarou.MainLg;
|
|
import fr.leomelki.loupgarou.classes.LGGame.TextGenerator;
|
|
import fr.leomelki.loupgarou.classes.LGPlayer.LGChooseCallback;
|
|
import fr.leomelki.loupgarou.events.LGVoteLeaderChange;
|
|
import fr.leomelki.loupgarou.utils.VariousUtils;
|
|
import lombok.Getter;
|
|
import net.minecraft.server.v1_15_R1.*;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
|
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.util.*;
|
|
import java.util.Map.Entry;
|
|
|
|
public class LGVote {
|
|
private static final EntityArmorStand eas = new EntityArmorStand(((CraftWorld) Bukkit.getWorlds().get(0)).getHandle(), 0, 0, 0);
|
|
private static DataWatcherObject<Optional<IChatBaseComponent>> az;
|
|
private static DataWatcherObject<Boolean> aA;
|
|
private static DataWatcherObject<Byte> T;
|
|
|
|
static {
|
|
try {
|
|
Field f = Entity.class.getDeclaredField("az");
|
|
f.setAccessible(true);
|
|
az = (DataWatcherObject<Optional<IChatBaseComponent>>) f.get(null);
|
|
f = Entity.class.getDeclaredField("aA");
|
|
f.setAccessible(true);
|
|
aA = (DataWatcherObject<Boolean>) f.get(null);
|
|
f = Entity.class.getDeclaredField("T");
|
|
f.setAccessible(true);
|
|
T = (DataWatcherObject<Byte>) f.get(null);
|
|
} catch (Exception err) {
|
|
err.printStackTrace();
|
|
}
|
|
}
|
|
|
|
final WrappedDataWatcherObject invisible = new WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class));
|
|
final WrappedDataWatcherObject noGravity = new WrappedDataWatcherObject(5, WrappedDataWatcher.Registry.get(Boolean.class));
|
|
private final int initialTimeout;
|
|
private final int littleTimeout;
|
|
private final LGGame game;
|
|
private final TextGenerator generator;
|
|
@Getter
|
|
private final HashMap<LGPlayer, List<LGPlayer>> votes = new HashMap<>();
|
|
private final boolean randomIfEqual;
|
|
@Getter
|
|
LGPlayer choosen;
|
|
WrappedDataWatcherObject customNameVisible = new WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class));
|
|
WrappedDataWatcherObject customName = new WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.get(IChatBaseComponent.class));
|
|
WrappedDataWatcherObject item = new WrappedDataWatcherObject(7, WrappedDataWatcher.Registry.get(net.minecraft.server.v1_15_R1.ItemStack.class));
|
|
private int timeout;
|
|
private Runnable callback;
|
|
@Getter
|
|
private List<LGPlayer> participants, viewers;
|
|
private int votesSize = 0;
|
|
private LGPlayer mayor;
|
|
private ArrayList<LGPlayer> latestTop = new ArrayList<>(), blacklisted = new ArrayList<>();
|
|
@Getter
|
|
private boolean mayorVote;
|
|
private boolean ended;
|
|
|
|
public LGVote(int timeout, int littleTimeout, LGGame game, boolean positiveVote, boolean randomIfEqual, TextGenerator generator) {
|
|
this.littleTimeout = littleTimeout;
|
|
this.initialTimeout = timeout;
|
|
this.timeout = timeout;
|
|
this.game = game;
|
|
this.generator = generator;
|
|
this.randomIfEqual = randomIfEqual;
|
|
}
|
|
|
|
public void start(List<LGPlayer> participants, List<LGPlayer> viewers, Runnable callback) {
|
|
this.callback = callback;
|
|
this.participants = participants;
|
|
this.viewers = viewers;
|
|
game.wait(timeout, this::end, generator);
|
|
for (LGPlayer player : participants)
|
|
player.choose(getChooseCallback(player));
|
|
}
|
|
|
|
public void start(List<LGPlayer> participants, List<LGPlayer> viewers, Runnable callback, ArrayList<LGPlayer> blacklisted) {
|
|
this.callback = callback;
|
|
this.participants = participants;
|
|
this.viewers = viewers;
|
|
game.wait(timeout, this::end, generator);
|
|
for (LGPlayer player : participants)
|
|
player.choose(getChooseCallback(player));
|
|
this.blacklisted = blacklisted;
|
|
}
|
|
|
|
public void start(List<LGPlayer> participants, List<LGPlayer> viewers, Runnable callback, LGPlayer mayor) {
|
|
this.callback = callback;
|
|
this.participants = participants;
|
|
this.viewers = viewers;
|
|
this.mayor = mayor;
|
|
game.wait(timeout, this::end, generator);
|
|
for (LGPlayer player : participants)
|
|
player.choose(getChooseCallback(player));
|
|
}
|
|
|
|
private void end() {
|
|
ended = true;
|
|
for (LGPlayer lgp : viewers)
|
|
showVoting(lgp, null);
|
|
for (LGPlayer lgp : votes.keySet())
|
|
updateVotes(lgp, true);
|
|
int max = 0;
|
|
boolean equal = false;
|
|
for (Entry<LGPlayer, List<LGPlayer>> entry : votes.entrySet())
|
|
if (entry.getValue().size() > max) {
|
|
equal = false;
|
|
max = entry.getValue().size();
|
|
choosen = entry.getKey();
|
|
} else if (entry.getValue().size() == max)
|
|
equal = true;
|
|
for (LGPlayer player : participants) {
|
|
player.getCache().remove("vote");
|
|
player.stopChoosing();
|
|
}
|
|
if (equal)
|
|
choosen = null;
|
|
if (equal && mayor == null && randomIfEqual) {
|
|
ArrayList<LGPlayer> choosable = new ArrayList<>();
|
|
for (Entry<LGPlayer, List<LGPlayer>> entry : votes.entrySet())
|
|
if (entry.getValue().size() == max)
|
|
choosable.add(entry.getKey());
|
|
choosen = choosable.get(game.getRandom().nextInt(choosable.size()));
|
|
}
|
|
|
|
if (equal && mayor != null && max != 0) {
|
|
for (LGPlayer player : viewers)
|
|
player.sendMessage("§9Égalité, le §5§lCapitaine§9 va départager les votes.");
|
|
mayor.sendMessage("§6Tu dois choisir qui va mourir.");
|
|
|
|
ArrayList<LGPlayer> choosable = new ArrayList<>();
|
|
for (Entry<LGPlayer, List<LGPlayer>> entry : votes.entrySet())
|
|
if (entry.getValue().size() == max)
|
|
choosable.add(entry.getKey());
|
|
|
|
for (int i = 0; i < choosable.size(); i++) {
|
|
LGPlayer lgp = choosable.get(i);
|
|
showArrow(mayor, lgp, -mayor.getPlayer().getEntityId() - i);
|
|
}
|
|
|
|
StringJoiner sj = new StringJoiner(", ");
|
|
for (int i = 0; i < choosable.size() - 1; i++)
|
|
sj.add(choosable.get(0).getName());
|
|
//mayor.sendTitle("§6C'est à vous de délibérer", "Faut-il tuer "+sj+" ou "+choosable.get(choosable.size()-1).getName()+" ?", 100);
|
|
ArrayList<LGPlayer> blackListed = new ArrayList<>();
|
|
for (LGPlayer player : participants)
|
|
if (!choosable.contains(player))
|
|
blackListed.add(player);
|
|
else {
|
|
VariousUtils.setWarning(player.getPlayer(), true);
|
|
//player.sendMessage("§4§lVous êtes un des principaux suspects ! Défendez vous !");
|
|
//player.sendTitle("§4§lDéfendez vous !", "§cVous êtes l'un des principaux suspects", 100);
|
|
}
|
|
mayorVote = true;
|
|
game.wait(30, () -> {
|
|
for (LGPlayer player : participants)
|
|
if (choosable.contains(player))
|
|
VariousUtils.setWarning(player.getPlayer(), false);
|
|
|
|
for (int i = 0; i < choosable.size(); i++) {
|
|
LGPlayer lgp = choosable.get(i);
|
|
showArrow(mayor, null, -mayor.getPlayer().getEntityId() - i);
|
|
}
|
|
//Choix au hasard d'un joueur si personne n'a été désigné
|
|
choosen = choosable.get(game.getRandom().nextInt(choosable.size()));
|
|
callback.run();
|
|
}, (player, secondsLeft) -> {
|
|
timeout = secondsLeft;
|
|
return mayor == player ? "§6Il te reste §e" + secondsLeft + " seconde" + (secondsLeft > 1 ? "s" : "") + "§6 pour délibérer" : "§6Le §5§lCapitaine§6 délibère (§e" + secondsLeft + " s§6)";
|
|
});
|
|
mayor.choose(choosen -> {
|
|
if (choosen != null) {
|
|
if (blackListed.contains(choosen))
|
|
mayor.sendMessage("§4§oCe joueur n'est pas concerné par le choix.");
|
|
else {
|
|
for (LGPlayer player : participants)
|
|
if (choosable.contains(player))
|
|
VariousUtils.setWarning(player.getPlayer(), false);
|
|
|
|
for (int i = 0; i < choosable.size(); i++) {
|
|
LGPlayer lgp = choosable.get(i);
|
|
showArrow(mayor, null, -mayor.getPlayer().getEntityId() - i);
|
|
}
|
|
game.cancelWait();
|
|
LGVote.this.choosen = choosen;
|
|
callback.run();
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
game.cancelWait();
|
|
callback.run();
|
|
}
|
|
|
|
}
|
|
|
|
public LGChooseCallback getChooseCallback(LGPlayer who) {
|
|
return choosen -> {
|
|
if (choosen != null)
|
|
vote(who, choosen);
|
|
};
|
|
}
|
|
|
|
public void vote(LGPlayer voter, LGPlayer voted) {
|
|
if (blacklisted.contains(voted)) {
|
|
voter.sendMessage("§cVous ne pouvez pas votre pour §7§l" + voted.getName() + "§c.");
|
|
return;
|
|
}
|
|
if (voted == voter.getCache().get("vote"))
|
|
voted = null;
|
|
|
|
if (voted != null && voter.getPlayer() != null)
|
|
votesSize++;
|
|
if (voter.getCache().has("vote"))
|
|
votesSize--;
|
|
|
|
if (votesSize == participants.size() && game.getWaitTicks() > littleTimeout * 20) {
|
|
votesSize = 999;
|
|
game.wait(littleTimeout, initialTimeout, this::end, generator);
|
|
}
|
|
String italic = game.isDay() ? "" : "§o";
|
|
boolean changeVote = false;
|
|
if (voter.getCache().has("vote")) {//On enlève l'ancien vote
|
|
LGPlayer devoted = voter.getCache().get("vote");
|
|
if (votes.containsKey(devoted)) {
|
|
List<LGPlayer> voters = votes.get(devoted);
|
|
if (voters != null) {
|
|
voters.remove(voter);
|
|
if (voters.size() == 0)
|
|
votes.remove(devoted);
|
|
}
|
|
}
|
|
voter.getCache().remove("vote");
|
|
updateVotes(devoted);
|
|
changeVote = true;
|
|
}
|
|
|
|
if (voted != null) {//Si il vient de voter, on ajoute le nouveau vote
|
|
//voter.sendTitle("", "§7Tu as voté pour §7§l"+voted.getName(), 40);
|
|
if (votes.containsKey(voted))
|
|
votes.get(voted).add(voter);
|
|
else
|
|
votes.put(voted, new ArrayList<>(Collections.singletonList(voter)));
|
|
voter.getCache().set("vote", voted);
|
|
updateVotes(voted);
|
|
}
|
|
|
|
if (voter.getPlayer() != null) {
|
|
showVoting(voter, voted);
|
|
String message;
|
|
if (voted != null) {
|
|
if (changeVote) {
|
|
message = "§7§l" + voter.getName() + "§6 a changé son vote pour §7§l" + voted.getName() + "§6.";
|
|
voter.sendMessage("§6Tu as changé de vote pour §7§l" + voted.getName() + "§6.");
|
|
} else {
|
|
message = "§7§l" + voter.getName() + "§6 a voté pour §7§l" + voted.getName() + "§6.";
|
|
voter.sendMessage("§6Tu as voté pour §7§l" + voted.getName() + "§6.");
|
|
}
|
|
} else {
|
|
message = "§7§l" + voter.getName() + "§6 a annulé son vote.";
|
|
voter.sendMessage("§6Tu as annulé ton vote.");
|
|
}
|
|
|
|
for (LGPlayer player : viewers)
|
|
if (player != voter)
|
|
player.sendMessage(message);
|
|
}
|
|
}
|
|
|
|
public List<LGPlayer> getVotes(LGPlayer voted) {
|
|
return votes.containsKey(voted) ? votes.get(voted) : new ArrayList<>(0);
|
|
}
|
|
|
|
private void updateVotes(LGPlayer voted) {
|
|
updateVotes(voted, false);
|
|
}
|
|
|
|
private void updateVotes(LGPlayer voted, boolean kill) {
|
|
int entityId = Integer.MIN_VALUE + voted.getPlayer().getEntityId();
|
|
WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy();
|
|
destroy.setEntityIds(new int[]{entityId});
|
|
for (LGPlayer lgp : viewers)
|
|
destroy.sendPacket(lgp.getPlayer());
|
|
|
|
if (!kill) {
|
|
int max = 0;
|
|
for (Entry<LGPlayer, List<LGPlayer>> entry : votes.entrySet())
|
|
if (entry.getValue().size() > max)
|
|
max = entry.getValue().size();
|
|
ArrayList<LGPlayer> last = latestTop;
|
|
latestTop = new ArrayList<>();
|
|
for (Entry<LGPlayer, List<LGPlayer>> entry : votes.entrySet())
|
|
if (entry.getValue().size() == max)
|
|
latestTop.add(entry.getKey());
|
|
Bukkit.getPluginManager().callEvent(new LGVoteLeaderChange(game, this, last, latestTop));
|
|
}
|
|
|
|
if (votes.containsKey(voted) && !kill) {
|
|
Location loc = voted.getPlayer().getLocation();
|
|
|
|
WrapperPlayServerSpawnEntityLiving spawn = new WrapperPlayServerSpawnEntityLiving();
|
|
spawn.setEntityID(entityId);
|
|
spawn.setType(EntityType.DROPPED_ITEM);
|
|
//spawn.setMetadata(new WrappedDataWatcher(Arrays.asList(new WrappedWatchableObject(0, (byte)0x20), new WrappedWatchableObject(5, true))));
|
|
spawn.setX(loc.getX());
|
|
spawn.setY(loc.getY() + 0.3);
|
|
spawn.setZ(loc.getZ());
|
|
|
|
int votesNbr = votes.get(voted).size();
|
|
final int numberOfParticipants = participants.size();
|
|
final double votePercentage = ((double) votesNbr / numberOfParticipants) * 100;
|
|
final String votePercentageFormated = String.format("%.0f%%", votePercentage);
|
|
final String voteContent = "§6§l" + votesNbr + " / " + numberOfParticipants + "§e vote" + (votesNbr > 1 ? "s" : "") + " (§6§l" + votePercentageFormated + "§e)";
|
|
|
|
/*WrapperPlayServerEntityMetadata meta = new WrapperPlayServerEntityMetadata();
|
|
meta.setEntityID(entityId);
|
|
meta.setMetadata(Arrays.asList(new WrappedWatchableObject(invisible, (byte)0x20), new WrappedWatchableObject(noGravity, true), new WrappedWatchableObject(customNameVisible, true), new WrappedWatchableObject(customName, IChatBaseComponent.ChatSerializer.b("§6§l"+votesNbr+"§e vote"+(votesNbr > 1 ? "s" : "")))));
|
|
*/
|
|
DataWatcher datawatcher = new DataWatcher(eas);
|
|
datawatcher.register(T, (byte) 0x20);
|
|
datawatcher.register(az, Optional.ofNullable(IChatBaseComponent.ChatSerializer.a("{\"text\":\"" + voteContent + "\"}")));
|
|
datawatcher.register(aA, true);
|
|
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entityId, datawatcher, true);
|
|
|
|
for (LGPlayer lgp : viewers) {
|
|
spawn.sendPacket(lgp.getPlayer());
|
|
((CraftPlayer) lgp.getPlayer()).getHandle().playerConnection.sendPacket(meta);
|
|
}
|
|
|
|
|
|
/* EntityArmorStand ea = new EntityArmorStand(((CraftWorld)loc.getWorld()).getHandle(), loc.getX(), loc.getY()+0.3, loc.getZ());
|
|
ea.setPosition(loc.getX(), loc.getY()+0.3, loc.getZ());
|
|
ea.setInvisible(true);
|
|
ea.setCustomNameVisible(true);
|
|
int votesNbr = votes.get(voted).size();
|
|
ea.setCustomName((IChatBaseComponent) WrappedChatComponent.fromText("§6§l"+votesNbr+"§e vote"+(votesNbr > 1 ? "s" : "")).getHandle());
|
|
|
|
PacketPlayOutSpawnEntityLiving spawn = new PacketPlayOutSpawnEntityLiving(ea);
|
|
try {
|
|
Field field = spawn.getClass().getDeclaredField("a");
|
|
field.setAccessible(true);
|
|
field.set(spawn, entityId);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}*/
|
|
/* WrapperPlayServerSpawnEntityLiving spawn = new WrapperPlayServerSpawnEntityLiving();
|
|
spawn.setEntityID(entityId);
|
|
spawn.setType(EntityType.ARMOR_STAND);
|
|
WrappedDataWatcher meta = new WrappedDataWatcher();
|
|
meta.setObject(0, (byte)0x20);
|
|
meta.setObject(2, "§6§l"+votes.get(voted)+"§e votes");
|
|
// meta.setObject(3, true);
|
|
spawn.setMetadata(meta);
|
|
Location loc = voted.getPlayer().getLocation();
|
|
spawn.setX(loc.getX());
|
|
spawn.setY(loc.getY()+0.3);
|
|
spawn.setZ(loc.getZ());*/
|
|
/* for(LGPlayer lgp : viewers)
|
|
((CraftPlayer)lgp.getPlayer()).getHandle().playerConnection.sendPacket(spawn);*/
|
|
// spawn.sendPacket(lgp.getPlayer());
|
|
}
|
|
}
|
|
|
|
private void showVoting(LGPlayer to, LGPlayer ofWho) {
|
|
int entityId = -to.getPlayer().getEntityId();
|
|
WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy();
|
|
destroy.setEntityIds(new int[]{entityId});
|
|
destroy.sendPacket(to.getPlayer());
|
|
if (ofWho != null) {
|
|
WrapperPlayServerSpawnEntityLiving spawn = new WrapperPlayServerSpawnEntityLiving();
|
|
spawn.setEntityID(entityId);
|
|
spawn.setType(EntityType.DROPPED_ITEM);
|
|
//spawn.setMetadata(new WrappedDataWatcher(Arrays.asList(new WrappedWatchableObject(0, (byte)0x20), new WrappedWatchableObject(5, true))));
|
|
Location loc = ofWho.getPlayer().getLocation();
|
|
spawn.setX(loc.getX());
|
|
spawn.setY(loc.getY() + 1.3);
|
|
spawn.setZ(loc.getZ());
|
|
spawn.setHeadPitch(0);
|
|
Location toLoc = to.getPlayer().getLocation();
|
|
double diffX = loc.getX() - toLoc.getX(),
|
|
diffZ = loc.getZ() - toLoc.getZ();
|
|
float yaw = 180 - ((float) Math.toDegrees(Math.atan2(diffX, diffZ)));
|
|
|
|
spawn.setYaw(yaw);
|
|
spawn.sendPacket(to.getPlayer());
|
|
|
|
WrapperPlayServerEntityMetadata meta = new WrapperPlayServerEntityMetadata();
|
|
meta.setEntityID(entityId);
|
|
meta.setMetadata(Arrays.asList(new WrappedWatchableObject(invisible, (byte) 0x20), new WrappedWatchableObject(noGravity, true)));
|
|
meta.sendPacket(to.getPlayer());
|
|
|
|
WrapperPlayServerEntityLook look = new WrapperPlayServerEntityLook();
|
|
look.setEntityID(entityId);
|
|
look.setPitch(0);
|
|
look.setYaw(yaw);
|
|
look.sendPacket(to.getPlayer());
|
|
|
|
new BukkitRunnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
WrapperPlayServerEntityEquipment equip = new WrapperPlayServerEntityEquipment();
|
|
equip.setEntityID(entityId);
|
|
equip.setSlot(ItemSlot.HEAD);
|
|
ItemStack skull = new ItemStack(Material.EMERALD);
|
|
equip.setItem(skull);
|
|
equip.sendPacket(to.getPlayer());
|
|
}
|
|
}.runTaskLater(MainLg.getInstance(), 2);
|
|
}
|
|
}
|
|
|
|
private void showArrow(LGPlayer to, LGPlayer ofWho, int entityId) {
|
|
WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy();
|
|
destroy.setEntityIds(new int[]{entityId});
|
|
destroy.sendPacket(to.getPlayer());
|
|
if (ofWho != null) {
|
|
WrapperPlayServerSpawnEntityLiving spawn = new WrapperPlayServerSpawnEntityLiving();
|
|
spawn.setEntityID(entityId);
|
|
spawn.setType(EntityType.DROPPED_ITEM);
|
|
//spawn.setMetadata(new WrappedDataWatcher());
|
|
Location loc = ofWho.getPlayer().getLocation();
|
|
spawn.setX(loc.getX());
|
|
spawn.setY(loc.getY() + 1.3);
|
|
spawn.setZ(loc.getZ());
|
|
spawn.setHeadPitch(0);
|
|
Location toLoc = to.getPlayer().getLocation();
|
|
double diffX = loc.getX() - toLoc.getX(),
|
|
diffZ = loc.getZ() - toLoc.getZ();
|
|
float yaw = 180 - ((float) Math.toDegrees(Math.atan2(diffX, diffZ)));
|
|
|
|
spawn.setYaw(yaw);
|
|
spawn.sendPacket(to.getPlayer());
|
|
|
|
WrapperPlayServerEntityMetadata meta = new WrapperPlayServerEntityMetadata();
|
|
meta.setEntityID(entityId);
|
|
meta.setMetadata(Arrays.asList(new WrappedWatchableObject(invisible, (byte) 0x20), new WrappedWatchableObject(noGravity, true)));
|
|
meta.sendPacket(to.getPlayer());
|
|
|
|
WrapperPlayServerEntityLook look = new WrapperPlayServerEntityLook();
|
|
look.setEntityID(entityId);
|
|
look.setPitch(0);
|
|
look.setYaw(yaw);
|
|
look.sendPacket(to.getPlayer());
|
|
|
|
new BukkitRunnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
WrapperPlayServerEntityEquipment equip = new WrapperPlayServerEntityEquipment();
|
|
equip.setEntityID(entityId);
|
|
equip.setSlot(ItemSlot.HEAD);
|
|
ItemStack skull = new ItemStack(Material.EMERALD);
|
|
equip.setItem(skull);
|
|
equip.sendPacket(to.getPlayer());
|
|
}
|
|
}.runTaskLater(MainLg.getInstance(), 2);
|
|
}
|
|
}
|
|
|
|
public void remove(LGPlayer killed) {
|
|
participants.remove(killed);
|
|
if (!ended) {
|
|
votes.remove(killed);
|
|
latestTop.remove(killed);
|
|
}
|
|
}
|
|
}
|