896 lines
36 KiB
Java
896 lines
36 KiB
Java
package fr.leomelki.loupgarou.classes;
|
|
|
|
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
|
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
|
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
import fr.leomelki.com.comphenix.packetwrapper.*;
|
|
import fr.leomelki.loupgarou.MainLg;
|
|
import fr.leomelki.loupgarou.classes.LGCustomItems.LGCustomItemsConstraints;
|
|
import fr.leomelki.loupgarou.classes.chat.LGChat;
|
|
import fr.leomelki.loupgarou.events.*;
|
|
import fr.leomelki.loupgarou.events.LGPlayerKilledEvent.Reason;
|
|
import fr.leomelki.loupgarou.roles.*;
|
|
import fr.leomelki.loupgarou.scoreboard.CustomScoreboard;
|
|
import fr.leomelki.loupgarou.utils.MultipleValueMap;
|
|
import fr.leomelki.loupgarou.utils.VariousUtils;
|
|
import lombok.Getter;
|
|
import lombok.Setter;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.GameMode;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.HandlerList;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.potion.PotionEffect;
|
|
import org.bukkit.potion.PotionEffectType;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
import java.security.SecureRandom;
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map.Entry;
|
|
|
|
public class LGGame implements Listener {
|
|
private static final boolean autoStart = false;
|
|
|
|
|
|
@Getter
|
|
private final SecureRandom random = new SecureRandom();
|
|
@Getter
|
|
private final int maxPlayers;
|
|
@Getter
|
|
private final ArrayList<LGPlayer> inGame = new ArrayList<>();
|
|
@Getter
|
|
private final ArrayList<Role> roles = new ArrayList<>();
|
|
@Getter
|
|
private final MainLg plugin;
|
|
@Getter
|
|
private final HashMap<Integer, LGPlayer> placements = new HashMap<>();
|
|
@Getter
|
|
private final LGChat spectatorChat = new LGChat((sender, message) -> "§7" + sender.getName() + " §6» §f" + message);
|
|
@Getter
|
|
private final LGChat dayChat = new LGChat((sender, message) -> "§e" + sender.getName() + " §6» §f" + message);
|
|
@Getter
|
|
private final MultipleValueMap<LGPlayerKilledEvent.Reason, LGPlayer> deaths = new MultipleValueMap<>();
|
|
@Getter
|
|
public long time = 0;
|
|
@Setter
|
|
boolean ended;
|
|
boolean isPeopleVote = false;
|
|
@Getter
|
|
private boolean started;
|
|
@Getter
|
|
private int night = 0;
|
|
private BukkitTask startingTask;
|
|
@Getter
|
|
@Setter
|
|
private int waitTicks;
|
|
@Getter
|
|
private boolean day;
|
|
private BukkitTask waitTask;
|
|
@Getter
|
|
private LGPlayer mayor;
|
|
@Getter
|
|
private LGVote vote;
|
|
|
|
public LGGame(MainLg mainLg, int maxPlayers) {
|
|
this.plugin = mainLg;
|
|
this.maxPlayers = maxPlayers;
|
|
Bukkit.getPluginManager().registerEvents(this, MainLg.getInstance());
|
|
}
|
|
|
|
public void sendActionBarMessage(String msg) {
|
|
WrapperPlayServerChat chat = new WrapperPlayServerChat();
|
|
chat.setPosition((byte) 2);
|
|
chat.setMessage(WrappedChatComponent.fromText(msg));
|
|
for (LGPlayer lgp : inGame)
|
|
chat.sendPacket(lgp.getPlayer());
|
|
}
|
|
|
|
public void broadcastMessage(String msg) {
|
|
for (LGPlayer lgp : inGame)
|
|
lgp.sendMessage(msg);
|
|
}
|
|
|
|
public void broadcastSpacer() {
|
|
for (LGPlayer lgp : inGame)
|
|
lgp.getPlayer().sendMessage("\n");
|
|
}
|
|
|
|
public void wait(int seconds, Runnable callback) {
|
|
wait(seconds, callback, null);
|
|
}
|
|
|
|
public void wait(int seconds, Runnable callback, TextGenerator generator) {
|
|
cancelWait();
|
|
waitTicks = seconds * 20;
|
|
waitTask = new BukkitRunnable() {
|
|
@Override
|
|
public void run() {
|
|
WrapperPlayServerExperience exp = new WrapperPlayServerExperience();
|
|
exp.setLevel((short) (Math.floorDiv(waitTicks, 20) + 1));
|
|
exp.setExperienceBar((float) waitTicks / (seconds * 20F));
|
|
for (LGPlayer player : getInGame()) {
|
|
exp.sendPacket(player.getPlayer());
|
|
if (generator != null)
|
|
player.sendActionBarMessage(generator.generate(player, Math.floorDiv(waitTicks, 20) + 1));
|
|
}
|
|
if (waitTicks == 0) {
|
|
for (LGPlayer player : getInGame())
|
|
player.sendActionBarMessage("");
|
|
waitTask = null;
|
|
cancel();
|
|
callback.run();
|
|
}
|
|
waitTicks--;
|
|
}
|
|
}.runTaskTimer(MainLg.getInstance(), 0, 1);
|
|
}
|
|
|
|
public void wait(int seconds, int initialSeconds, Runnable callback, TextGenerator generator) {
|
|
cancelWait();
|
|
waitTicks = seconds * 20;
|
|
waitTask = new BukkitRunnable() {
|
|
@Override
|
|
public void run() {
|
|
WrapperPlayServerExperience exp = new WrapperPlayServerExperience();
|
|
exp.setLevel((short) (Math.floorDiv(waitTicks, 20) + 1));
|
|
exp.setExperienceBar((float) waitTicks / (initialSeconds * 20F));
|
|
for (LGPlayer player : getInGame()) {
|
|
exp.sendPacket(player.getPlayer());
|
|
if (generator != null)
|
|
player.sendActionBarMessage(generator.generate(player, Math.floorDiv(waitTicks, 20) + 1));
|
|
}
|
|
if (waitTicks == 0) {
|
|
for (LGPlayer player : getInGame())
|
|
player.sendActionBarMessage("");
|
|
waitTask = null;
|
|
cancel();
|
|
callback.run();
|
|
}
|
|
waitTicks--;
|
|
}
|
|
}.runTaskTimer(MainLg.getInstance(), 0, 1);
|
|
}
|
|
|
|
public void cancelWait() {
|
|
if (waitTask != null) {
|
|
waitTask.cancel();
|
|
waitTask = null;
|
|
}
|
|
}
|
|
|
|
public void kill(LGPlayer player, Reason reason) {
|
|
if (!deaths.containsValue(player) && !player.isDead()) {
|
|
LGNightPlayerPreKilledEvent event = new LGNightPlayerPreKilledEvent(this, player, reason);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (!event.isCancelled())
|
|
deaths.put(event.getReason(), player);
|
|
}
|
|
}
|
|
|
|
public boolean tryToJoin(LGPlayer lgp) {
|
|
if (ended) return false;
|
|
if (!started && inGame.size() < maxPlayers) {//Si la partie n'a pas démarrée et qu'il reste de la place
|
|
lgp.getPlayer().removePotionEffect(PotionEffectType.INVISIBILITY);
|
|
VariousUtils.setWarning(lgp.getPlayer(), false);
|
|
if (lgp.isMuted())
|
|
lgp.resetMuted();
|
|
|
|
Player player = lgp.getPlayer();
|
|
|
|
// Clear votes
|
|
|
|
WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy();
|
|
destroy.setEntityIds(new int[]{Integer.MIN_VALUE + player.getEntityId()});
|
|
int[] ids = new int[getInGame().size() + 1];
|
|
for (int i = 0; i < getInGame().size(); i++) {
|
|
Player l = getInGame().get(i).getPlayer();
|
|
if (l == null)
|
|
continue;
|
|
ids[i] = Integer.MIN_VALUE + l.getEntityId();
|
|
destroy.sendPacket(l);
|
|
}
|
|
|
|
ids[ids.length - 1] = -player.getEntityId();// Clear voting
|
|
|
|
destroy = new WrapperPlayServerEntityDestroy();
|
|
destroy.setEntityIds(ids);
|
|
destroy.sendPacket(player);
|
|
|
|
// End clear votes/voting
|
|
|
|
player.getInventory().clear();
|
|
player.updateInventory();
|
|
player.closeInventory();
|
|
|
|
lgp.joinChat(dayChat);
|
|
|
|
lgp.setGame(this);
|
|
inGame.add(lgp);
|
|
|
|
lgp.setScoreboard(null);
|
|
|
|
for (LGPlayer other : getInGame()) {
|
|
other.updatePrefix();
|
|
if (lgp != other) {
|
|
player.hidePlayer(plugin, other.getPlayer());
|
|
player.showPlayer(plugin, other.getPlayer());
|
|
|
|
other.getPlayer().hidePlayer(plugin, player);
|
|
other.getPlayer().showPlayer(plugin, player);
|
|
}
|
|
}
|
|
|
|
player.setGameMode(GameMode.ADVENTURE);
|
|
broadcastMessage("§7Le joueur §8" + lgp.getName() + "§7 a rejoint la partie §9(§8" + inGame.size() + "§7/§8" + maxPlayers + "§9)");
|
|
|
|
//Reset scoreboard
|
|
WrapperPlayServerScoreboardObjective obj = new WrapperPlayServerScoreboardObjective();
|
|
obj.setName("lg_scoreboard");
|
|
obj.setMode(1);
|
|
obj.sendPacket(player);
|
|
|
|
Bukkit.getPluginManager().callEvent(new LGGameJoinEvent(this, lgp));
|
|
//AutoStart
|
|
if (autoStart)
|
|
updateStart();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void checkLeave() {
|
|
if (startingTask != null) {
|
|
startingTask.cancel();
|
|
startingTask = null;
|
|
broadcastMessage("§c§oUn joueur s'est déconnecté. Le décompte de lancement a donc été arrêté.");
|
|
}
|
|
}
|
|
|
|
public void updateStart() {
|
|
if (!isStarted())
|
|
if (inGame.size() == maxPlayers) {//Il faut que la partie soit totalement remplie pour qu'elle démarre car sinon, tous les rôles ne seraient pas distribués
|
|
for (LGPlayer lgp : getInGame()) {
|
|
CustomScoreboard scoreboard = new CustomScoreboard("§7"/*[§9Loup-Garou§7]*/, lgp);
|
|
scoreboard.getLine(0).setDisplayName("§6La partie va démarrer...");
|
|
lgp.setScoreboard(scoreboard);
|
|
}
|
|
if (startingTask == null) {
|
|
startingTask = new BukkitRunnable() {
|
|
int timeLeft = 5 + 1;
|
|
|
|
@Override
|
|
public void run() {
|
|
if (--timeLeft == 0)//start
|
|
start();
|
|
else
|
|
sendActionBarMessage("§6Démarrage dans §e" + timeLeft + "§6...");
|
|
}
|
|
}.runTaskTimer(MainLg.getInstance(), 20, 20);
|
|
}
|
|
} else if (startingTask != null) {
|
|
startingTask.cancel();
|
|
broadcastMessage("§c§oLe démarrage de la partie a été annulé car une personne l'a quittée !");
|
|
}
|
|
}
|
|
|
|
public void start() {
|
|
if (startingTask != null) {
|
|
startingTask.cancel();
|
|
startingTask = null;
|
|
}
|
|
MainLg.getInstance().loadConfig();
|
|
started = true;
|
|
MainLg main = MainLg.getInstance();
|
|
|
|
//Registering roles
|
|
List<?> original = MainLg.getInstance().getConfig().getList("spawns");
|
|
List<Object> list = new ArrayList<>(original);
|
|
for (LGPlayer lgp : getInGame()) {
|
|
List<Double> location = (List<Double>) list.remove(random.nextInt(list.size()));
|
|
Player p = lgp.getPlayer();
|
|
p.setWalkSpeed(0);
|
|
p.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 99999, 180, false, false));
|
|
lgp.setPlace(original.indexOf(location));
|
|
placements.put(lgp.getPlace(), lgp);
|
|
p.teleport(new Location(p.getWorld(), location.get(0) + 0.5, location.get(1), location.get(2) + 0.5, location.get(3).floatValue(), location.get(4).floatValue()));
|
|
WrapperPlayServerUpdateHealth update = new WrapperPlayServerUpdateHealth();
|
|
update.setFood(6);
|
|
update.setFoodSaturation(1);
|
|
update.setHealth(20);
|
|
update.sendPacket(p);
|
|
lgp.getScoreboard().getLine(0).setDisplayName("§6Attribution des rôles...");
|
|
}
|
|
|
|
try {
|
|
for (Entry<String, Constructor<? extends Role>> role : main.getRoles().entrySet())
|
|
if (main.getConfig().getInt("role." + role.getKey()) > 0)
|
|
roles.add(role.getValue().newInstance(this));
|
|
} catch (Exception err) {
|
|
Bukkit.broadcastMessage("§4§lUne erreur est survenue lors de la création des roles... Regardez la console !");
|
|
err.printStackTrace();
|
|
}
|
|
|
|
new BukkitRunnable() {
|
|
int timeLeft = 5 * 2;
|
|
int actualRole = getRoles().size();
|
|
|
|
@Override
|
|
public void run() {
|
|
if (--timeLeft == 0) {
|
|
cancel();
|
|
_start();
|
|
return;
|
|
}
|
|
if (timeLeft == 5 * 2 - 1) {
|
|
for (LGPlayer lgp : getInGame()) {
|
|
lgp.sendMessage("§8Plugin développé par : §e§lLeomelki§8.\n§8Projet organisé par : §e§lShytoos§8.\n");
|
|
lgp.sendTitle("", "§8§8Plugin LoupGarou par §e§lLeomelki§8 & §e§lShytoos", 40);
|
|
lgp.getPlayer().getInventory().clear();
|
|
lgp.getPlayer().updateInventory();
|
|
}
|
|
broadcastMessage("§2Attribution des rôles...");
|
|
}
|
|
|
|
if (--actualRole < 0)
|
|
actualRole = getRoles().size() - 1;
|
|
|
|
ItemStack stack = new ItemStack(LGCustomItems.getItem(getRoles().get(actualRole)));
|
|
for (LGPlayer lgp : getInGame()) {
|
|
lgp.getPlayer().getInventory().setItemInOffHand(stack);
|
|
lgp.getPlayer().updateInventory();
|
|
}
|
|
}
|
|
}.runTaskTimer(MainLg.getInstance(), 0, 4);
|
|
}
|
|
|
|
private void _start() {
|
|
broadcastMessage("§8§oDébut de la partie...");
|
|
//Give roles...
|
|
ArrayList<LGPlayer> toGive = (ArrayList<LGPlayer>) inGame.clone();
|
|
started = false;
|
|
for (Role role : getRoles())
|
|
while (role.getWaitedPlayers() > 0) {
|
|
int randomized = random.nextInt(toGive.size());
|
|
LGPlayer player = toGive.remove(randomized);
|
|
|
|
role.join(player);
|
|
WrapperPlayServerUpdateHealth update = new WrapperPlayServerUpdateHealth();
|
|
update.setFood(6);
|
|
update.setFoodSaturation(1);
|
|
update.setHealth(20);
|
|
update.sendPacket(player.getPlayer());
|
|
}
|
|
started = true;
|
|
|
|
updateRoleScoreboard();
|
|
|
|
//Classe les roles afin de les appeler dans le bon ordre
|
|
roles.sort(Comparator.comparingInt(Role::getTurnOrder));
|
|
|
|
//Start day one
|
|
nextNight(10);
|
|
}
|
|
|
|
public void updateRoleScoreboard() {
|
|
HashMap<Role, IndexedRole> roles_ = new HashMap<>();
|
|
for (LGPlayer lgp : getAlive())
|
|
if (roles_.containsKey(lgp.getRole()))
|
|
roles_.get(lgp.getRole()).increase();
|
|
else
|
|
roles_.put(lgp.getRole(), new IndexedRole(lgp.getRole()));
|
|
ArrayList<IndexedRole> roles = new ArrayList<>(roles_.values());
|
|
roles.sort((a, b) -> {
|
|
//TODO fix dégueu juste ici pour le chien loup lg à changer (2x)
|
|
return (b.getNumber() + (b.getRole().getType() != RoleType.LOUP_GAROU || b.getRole() instanceof RChienLoupLG || b.getRole() instanceof REnfantSauvageLG ? b.getRole().getType() == RoleType.NEUTRAL ? 0 : 999 : 200) - a.getNumber() - (a.getRole().getType() != RoleType.LOUP_GAROU || a.getRole() instanceof RChienLoupLG || a.getRole() instanceof REnfantSauvageLG ? a.getRole().getType() == RoleType.NEUTRAL ? 0 : 999 : 200));
|
|
});
|
|
for (int i = 0; i < roles.size(); i++) {
|
|
IndexedRole role = roles.get(i);
|
|
if (role.getNumber() == 0) {
|
|
for (LGPlayer lgp : getInGame())
|
|
lgp.getScoreboard().getLine(i).delete();
|
|
} else
|
|
for (LGPlayer lgp : getInGame())
|
|
lgp.getScoreboard().getLine(i).setDisplayName("§e" + role.getNumber() + " §6- §e" + role.getRole().getName().replace("§l", ""));
|
|
}
|
|
for (int i = 15; i >= roles.size(); i--)
|
|
for (LGPlayer lgp : getInGame())
|
|
lgp.getScoreboard().getLine(i).delete();
|
|
}
|
|
|
|
public List<LGPlayer> getAlive() {
|
|
ArrayList<LGPlayer> alive = new ArrayList<>();
|
|
for (LGPlayer lgp : getInGame())
|
|
if (!lgp.isDead())
|
|
alive.add(lgp);
|
|
return alive;
|
|
}
|
|
|
|
public void nextNight() {
|
|
nextNight(5);
|
|
}
|
|
|
|
public void nextNight(int timeout) {
|
|
if (ended) return;
|
|
LGNightStart event = new LGNightStart(this);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (event.isCancelled())
|
|
return;
|
|
|
|
if (mayorKilled()) {//mort du maire
|
|
broadcastMessage("§9Le §5§lCapitaine§9 est mort, il désigne un joueur en remplaçant.");
|
|
getMayor().sendMessage("§6Choisis un joueur qui deviendra §5§lCapitaine§6 à son tour.");
|
|
LGGame.this.wait(30, () -> {
|
|
mayor.stopChoosing();
|
|
setMayor(getAlive().get(random.nextInt(getAlive().size())));
|
|
broadcastMessage("§7§l" + mayor.getName() + "§9 devient le nouveau §5§lCapitaine§9.");
|
|
nextNight();
|
|
}, (player, secondsLeft) -> "§e" + mayor.getName() + "§6 choisit qui sera le nouveau §5§lCapitaine§6 (§e" + secondsLeft + " s§6)");
|
|
mayor.choose((choosen) -> {
|
|
if (choosen != null) {
|
|
mayor.stopChoosing();
|
|
cancelWait();
|
|
setMayor(choosen);
|
|
broadcastMessage("§7§l" + mayor.getName() + "§9 devient le nouveau §5§lCapitaine§9.");
|
|
nextNight();
|
|
}
|
|
}, mayor);
|
|
return;
|
|
}
|
|
|
|
new BukkitRunnable() {
|
|
int timeoutLeft = timeout * 20;
|
|
|
|
@Override
|
|
public void run() {
|
|
if (--timeoutLeft <= 20 + 20 * 2) {
|
|
if (timeoutLeft == 20)
|
|
cancel();
|
|
WrapperPlayServerUpdateTime time = new WrapperPlayServerUpdateTime();
|
|
time.setAgeOfTheWorld(0);
|
|
time.setTimeOfDay(LGGame.this.time = (long) (18000 - (timeoutLeft - 20D) / (20 * 2D) * 12000D));
|
|
for (LGPlayer lgp : getInGame())
|
|
time.sendPacket(lgp.getPlayer());
|
|
}
|
|
}
|
|
}.runTaskTimer(MainLg.getInstance(), 1, 1);
|
|
LGGame.this.wait(timeout, this::nextNight_, (player, secondsLeft) -> "§6La nuit va tomber dans §e" + secondsLeft + " seconde" + (secondsLeft > 1 ? "s" : ""));
|
|
}
|
|
|
|
private void nextNight_() {
|
|
if (ended) return;
|
|
night++;
|
|
broadcastSpacer();
|
|
broadcastMessage("§9----------- §lNuit n°" + night + "§9 -----------");
|
|
broadcastMessage("§8§oLa nuit tombe sur le village...");
|
|
for (LGPlayer player : getAlive())
|
|
player.leaveChat();
|
|
for (LGPlayer player : getInGame()) {
|
|
player.stopAudio(LGSound.AMBIANT_DAY);
|
|
player.playAudio(LGSound.START_NIGHT, 0.5);
|
|
player.playAudio(LGSound.AMBIANT_NIGHT, 0.07);
|
|
}
|
|
day = false;
|
|
Bukkit.getPluginManager().callEvent(new LGDayEndEvent(this));
|
|
for (LGPlayer player : getInGame())
|
|
player.hideView();
|
|
|
|
ArrayList<Role> roles = (ArrayList<Role>) getRoles().clone();
|
|
new Runnable() {
|
|
Role lastRole;
|
|
|
|
public void run() {
|
|
Runnable run = this;
|
|
new BukkitRunnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
if (roles.size() == 0) {
|
|
Bukkit.getPluginManager().callEvent(new LGRoleTurnEndEvent(LGGame.this, null, lastRole));
|
|
lastRole = null;
|
|
endNight();
|
|
return;
|
|
}
|
|
Role role = roles.remove(0);
|
|
Bukkit.getPluginManager().callEvent(new LGRoleTurnEndEvent(LGGame.this, role, lastRole));
|
|
lastRole = role;
|
|
if (role.getTurnOrder() == -1 || !role.hasPlayersLeft())
|
|
this.run();
|
|
else {
|
|
broadcastMessage("§9" + role.getBroadcastedTask());
|
|
role.onNightTurn(run);
|
|
}
|
|
}
|
|
}.runTaskLater(MainLg.getInstance(), 60);
|
|
}
|
|
}.run();
|
|
}
|
|
|
|
public boolean kill(LGPlayer killed, Reason reason, boolean endGame) {
|
|
if (killed.getPlayer() != null) {
|
|
killed.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 999999, 1, false, false));
|
|
killed.die();
|
|
|
|
for (LGPlayer lgp : getInGame())
|
|
if (lgp == killed) {
|
|
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
|
ArrayList<PlayerInfoData> infos = new ArrayList<>();
|
|
info.setAction(PlayerInfoAction.REMOVE_PLAYER);
|
|
infos.add(new PlayerInfoData(new WrappedGameProfile(lgp.getPlayer().getUniqueId(), lgp.getName()), 0, NativeGameMode.ADVENTURE, WrappedChatComponent.fromText(lgp.getName())));
|
|
info.setData(infos);
|
|
info.sendPacket(lgp.getPlayer());
|
|
} else
|
|
lgp.getPlayer().hidePlayer(plugin, killed.getPlayer());
|
|
|
|
if (vote != null)
|
|
vote.remove(killed);
|
|
|
|
broadcastMessage(String.format(reason.getMessage(), killed.getName()) + ", il était " + killed.getRole().getName() + (killed.getCache().getBoolean("infected") ? " §c§l(Infecté)" : "") + (killed.getCache().getBoolean("vampire") ? " §5§l(Vampire)" : "") + "§4.");
|
|
|
|
//Lightning effect
|
|
killed.getPlayer().getWorld().strikeLightningEffect(killed.getPlayer().getLocation());
|
|
|
|
for (Role role : getRoles())
|
|
role.getPlayers().remove(killed);
|
|
|
|
killed.setDead(true);
|
|
|
|
Bukkit.getPluginManager().callEvent(new LGPlayerGotKilledEvent(this, killed, reason, !checkEndGame(false) && endGame));
|
|
|
|
VariousUtils.setWarning(killed.getPlayer(), true);
|
|
|
|
killed.getPlayer().getInventory().setHelmet(new ItemStack(Material.CARVED_PUMPKIN));
|
|
|
|
LGCustomItems.updateItem(killed);
|
|
|
|
//killed.leaveChat();
|
|
killed.joinChat(spectatorChat);
|
|
killed.joinChat(dayChat, true);
|
|
}
|
|
|
|
//Update scoreboard
|
|
|
|
updateRoleScoreboard();
|
|
|
|
//End update scoreboard
|
|
|
|
if (!checkEndGame(false))
|
|
return false;
|
|
if (endGame)
|
|
checkEndGame();
|
|
return true;
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
public void onGameEnd(LGGameEndEvent e) {
|
|
if (e.getGame() == this && e.getWinType() == LGWinType.VILLAGEOIS)
|
|
for (LGPlayer lgp : getInGame())
|
|
if (lgp.getRoleType() == RoleType.VILLAGER)
|
|
e.getWinners().add(lgp);
|
|
}
|
|
|
|
public void endGame(LGWinType winType) {
|
|
if (ended) return;
|
|
|
|
ArrayList<LGPlayer> winners = new ArrayList<>();
|
|
LGGameEndEvent event = new LGGameEndEvent(this, winType, winners);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled())
|
|
return;
|
|
|
|
for (LGPlayer lgp : getInGame())//Avoid bugs
|
|
if (lgp.getPlayer() != null)
|
|
lgp.getPlayer().closeInventory();
|
|
|
|
cancelWait();//Also avoid bugs
|
|
|
|
ended = true;
|
|
//We unregister every role listener because they are unused after the game's end !
|
|
for (Role role : getRoles())
|
|
HandlerList.unregisterAll(role);
|
|
|
|
broadcastMessage(winType.getMessage());
|
|
for (LGPlayer lgp : getInGame()) {
|
|
lgp.leaveChat();
|
|
lgp.joinChat(spectatorChat);
|
|
|
|
lgp.setScoreboard(null);
|
|
|
|
lgp.sendTitle("§7§lÉgalité", "§8Personne n'a gagné...", 200);
|
|
|
|
if (winners.contains(lgp))
|
|
lgp.sendTitle("§a§lVictoire !", "§6Vous avez gagné la partie.", 200);
|
|
else if (winType == LGWinType.EQUAL || winType == LGWinType.NONE)
|
|
lgp.sendTitle("§7§lÉgalité", "§8Personne n'a gagné...", 200);
|
|
else
|
|
lgp.sendTitle("§c§lDéfaite...", "§4Vous avez perdu la partie.", 200);
|
|
|
|
|
|
Player p = lgp.getPlayer();
|
|
lgp.showView();
|
|
p.removePotionEffect(PotionEffectType.JUMP);
|
|
p.setWalkSpeed(0.2f);
|
|
}
|
|
|
|
for (LGPlayer lgp : getInGame())
|
|
if (lgp.getPlayer().isOnline()) {
|
|
LGPlayer.removePlayer(lgp.getPlayer());
|
|
WrapperPlayServerScoreboardTeam team = new WrapperPlayServerScoreboardTeam();
|
|
team.setMode(1);
|
|
team.setName("you_are");
|
|
team.sendPacket(lgp.getPlayer());
|
|
LGPlayer.thePlayer(plugin, lgp.getPlayer()).join(MainLg.getInstance().getCurrentGame());
|
|
}
|
|
//A remettre pour activer le démarrage automatique
|
|
/* wait(30, ()->{
|
|
for(LGPlayer lgp : getInGame())
|
|
if(lgp.getPlayer().isOnline()) {
|
|
WrapperPlayServerScoreboardTeam team = new WrapperPlayServerScoreboardTeam();
|
|
team.setMode(1);
|
|
team.setName("you_are");
|
|
team.sendPacket(lgp.getPlayer());
|
|
LGPlayer.thePlayer(lgp.getPlayer()).join(MainLg.getInstance().getCurrentGame());
|
|
}
|
|
}, (player, secondsLeft)->{
|
|
return "§6Démarrage d'une nouvelle partie dans §e"+secondsLeft+" seconde"+(secondsLeft > 1 ? "s" : "");
|
|
});*/
|
|
}
|
|
|
|
public boolean mayorKilled() {
|
|
return getMayor() != null && getMayor().isDead();
|
|
}
|
|
|
|
public void endNight() {
|
|
if (ended) return;
|
|
broadcastSpacer();
|
|
broadcastMessage("§9----------- §lJour n°" + night + "§9 -----------");
|
|
broadcastMessage("§8§oLe jour se lève sur le village...");
|
|
|
|
for (LGPlayer p : getInGame()) {
|
|
p.stopAudio(LGSound.AMBIANT_NIGHT);
|
|
p.playAudio(LGSound.START_DAY, 0.5);
|
|
p.playAudio(LGSound.AMBIANT_DAY, 0.07);
|
|
}
|
|
|
|
LGNightEndEvent eventNightEnd = new LGNightEndEvent(this);
|
|
Bukkit.getPluginManager().callEvent(eventNightEnd);
|
|
if (eventNightEnd.isCancelled())
|
|
return;
|
|
|
|
int died = 0;
|
|
boolean endGame = false;
|
|
|
|
|
|
for (Entry<Reason, LGPlayer> entry : deaths.entrySet()) {
|
|
if (entry.getKey() == Reason.DONT_DIE)
|
|
continue;
|
|
if (entry.getValue().isDead())//On ne fait pas mourir quelqu'un qui est déjà mort (résout le problème du dictateur tué par le chasseur)
|
|
continue;
|
|
if (entry.getValue().getPlayer() != null) {//S'il a deco bah au moins ça crash pas hehe
|
|
LGPlayerKilledEvent event = new LGPlayerKilledEvent(this, entry.getValue(), entry.getKey());
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (!event.isCancelled()) {
|
|
endGame |= kill(event.getKilled(), event.getReason(), false);
|
|
died++;
|
|
}
|
|
}
|
|
}
|
|
deaths.clear();
|
|
if (died == 0)
|
|
broadcastMessage("§9Étonnamment, personne n'est mort cette nuit.");
|
|
|
|
day = true;
|
|
for (LGPlayer player : getInGame())
|
|
player.showView();
|
|
|
|
|
|
new BukkitRunnable() {
|
|
int timeoutLeft = 20;
|
|
|
|
@Override
|
|
public void run() {
|
|
if (timeoutLeft++ > 20) {
|
|
if (timeoutLeft == 20 + (2 * 20))
|
|
cancel();
|
|
WrapperPlayServerUpdateTime time = new WrapperPlayServerUpdateTime();
|
|
time.setAgeOfTheWorld(0);
|
|
time.setTimeOfDay(LGGame.this.time = (long) (18000 - (timeoutLeft - 20D) / (20 * 2D) * 12000D));
|
|
for (LGPlayer lgp : getInGame())
|
|
time.sendPacket(lgp.getPlayer());
|
|
}
|
|
}
|
|
}.runTaskTimer(MainLg.getInstance(), 1, 1);
|
|
|
|
LGPreDayStartEvent dayStart = new LGPreDayStartEvent(this);
|
|
Bukkit.getPluginManager().callEvent(dayStart);
|
|
if (!dayStart.isCancelled()) {
|
|
if (endGame)
|
|
checkEndGame();
|
|
else
|
|
startDay();
|
|
}
|
|
}
|
|
|
|
public void startDay() {
|
|
for (LGPlayer player : getInGame())
|
|
player.joinChat(dayChat, player.isDead());
|
|
|
|
LGDayStartEvent dayStart = new LGDayStartEvent(this);
|
|
Bukkit.getPluginManager().callEvent(dayStart);
|
|
if (dayStart.isCancelled())
|
|
return;
|
|
if (mayorKilled()) {//mort du maire
|
|
broadcastMessage("§9Le §5§lCapitaine§9 est mort, il désigne un joueur en remplaçant.");
|
|
getMayor().sendMessage("§6Choisis un joueur qui deviendra §5§lCapitaine§6 à son tour.");
|
|
LGGame.this.wait(30, () -> {
|
|
mayor.stopChoosing();
|
|
setMayor(getAlive().get(random.nextInt(getAlive().size())));
|
|
broadcastMessage("§7§l" + mayor.getName() + "§9 devient le nouveau §5§lCapitaine§9.");
|
|
startDay();
|
|
}, (player, secondsLeft) -> "§e" + mayor.getName() + "§6 choisit qui sera le nouveau §5§lCapitaine§6 (§e" + secondsLeft + " s§6)");
|
|
mayor.choose((choosen) -> {
|
|
if (choosen != null) {
|
|
mayor.stopChoosing();
|
|
cancelWait();
|
|
setMayor(choosen);
|
|
broadcastMessage("§7§l" + mayor.getName() + "§9 devient le nouveau §5§lCapitaine§9.");
|
|
startDay();
|
|
}
|
|
}, mayor);
|
|
return;
|
|
}
|
|
new BukkitRunnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
if (getMayor() == null && getAlive().size() > 2)
|
|
mayorVote();
|
|
else
|
|
peopleVote();
|
|
}
|
|
}.runTaskLater(MainLg.getInstance(), 40);
|
|
|
|
}
|
|
|
|
public void setMayor(LGPlayer mayor) {
|
|
LGPlayer latestMayor = this.mayor;
|
|
this.mayor = mayor;
|
|
if (mayor != null && mayor.getPlayer().isOnline()) {
|
|
LGCustomItems.updateItem(mayor);
|
|
mayor.updateSkin();
|
|
mayor.updateOwnSkin();
|
|
}
|
|
if (latestMayor != null && latestMayor.getPlayer() != null && latestMayor.getPlayer().isOnline()) {
|
|
LGCustomItems.updateItem(latestMayor);
|
|
latestMayor.updateSkin();
|
|
latestMayor.updateOwnSkin();
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void onCustomItemChange(LGCustomItemChangeEvent e) {
|
|
if (e.getGame() == this) {
|
|
if (getMayor() == e.getPlayer())
|
|
e.getConstraints().add(LGCustomItemsConstraints.MAYOR.getName());
|
|
if (e.getPlayer().isDead())
|
|
e.getConstraints().add(LGCustomItemsConstraints.DEAD.getName());
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOWEST)
|
|
public void onSkinChange(LGSkinLoadEvent e) {
|
|
if (e.getGame() == this) {
|
|
e.getProfile().getProperties().removeAll("textures");
|
|
if (getMayor() == e.getPlayer())
|
|
e.getProfile().getProperties().put("textures", LGCustomSkin.MAYOR.getProperty());
|
|
else
|
|
e.getProfile().getProperties().put("textures", LGCustomSkin.VILLAGER.getProperty());
|
|
}
|
|
}
|
|
|
|
private void mayorVote() {
|
|
if (ended) return;
|
|
LGMayorVoteEvent event = new LGMayorVoteEvent(this);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (!event.isCancelled()) {
|
|
broadcastMessage("§9Il est temps de voter pour élire un §5§lCapitaine§9.");
|
|
vote = new LGVote(180, 20, this, true, true, (player, secondsLeft) -> player.getCache().has("vote") ? "§6Tu votes pour §7§l" + player.getCache().<LGPlayer>get("vote").getName() : "§6Il te reste §e" + secondsLeft + " seconde" + (secondsLeft > 1 ? "s" : "") + "§6 pour voter");
|
|
vote.start(getAlive(), getInGame(), () -> {
|
|
if (vote.getChoosen() == null)
|
|
setMayor(getAlive().get(random.nextInt(getAlive().size())));
|
|
else
|
|
setMayor(vote.getChoosen());
|
|
|
|
broadcastMessage("§7§l" + mayor.getName() + "§6 devient le §5§lCapitaine §6du village.");
|
|
peopleVote();
|
|
});
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void leaderChange(LGVoteLeaderChange e) {
|
|
if (isPeopleVote && vote != null && e.getGame() == this) {
|
|
for (LGPlayer player : e.getLatest())
|
|
if (!e.getNow().contains(player))
|
|
VariousUtils.setWarning(player.getPlayer(), false);
|
|
|
|
for (LGPlayer player : e.getNow())
|
|
if (!e.getLatest().contains(player))
|
|
VariousUtils.setWarning(player.getPlayer(), true);
|
|
}
|
|
}
|
|
|
|
private void peopleVote() {
|
|
if (ended) return;
|
|
LGVoteEvent event = new LGVoteEvent(this);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (!event.isCancelled()) {
|
|
broadcastMessage("§9La phase des votes a commencé.");
|
|
isPeopleVote = true;
|
|
vote = new LGVote(180, 20, this, false, false, (player, secondsLeft) -> player.getCache().has("vote") ? "§6Tu votes pour §7§l" + player.getCache().<LGPlayer>get("vote").getName() : "§6Il te reste §e" + secondsLeft + " seconde" + (secondsLeft > 1 ? "s" : "") + "§6 pour voter");
|
|
vote.start(getAlive(), getInGame(), () -> {
|
|
isPeopleVote = false;
|
|
if (vote.getChoosen() == null || (vote.isMayorVote() && getMayor() == null))
|
|
broadcastMessage(/*getMayor() != null ? "§9Le maire a décidé de gracier les accusés." : */"§9Personne n'est mort aujourd'hui.");
|
|
else {
|
|
LGPlayerKilledEvent killEvent = new LGPlayerKilledEvent(this, vote.getChoosen(), Reason.VOTE);
|
|
Bukkit.getPluginManager().callEvent(killEvent);
|
|
if (killEvent.isCancelled())//chassou ?
|
|
return;
|
|
if (kill(killEvent.getKilled(), killEvent.getReason(), true))
|
|
return;
|
|
}
|
|
nextNight();
|
|
}, mayor);
|
|
}//Sinon c'est à celui qui a cancel de s'en occuper
|
|
}
|
|
|
|
public boolean checkEndGame() {
|
|
return checkEndGame(true);
|
|
}
|
|
|
|
public boolean checkEndGame(boolean doEndGame) {
|
|
int goodGuy = 0, badGuy = 0, solo = 0, vampires = 0;
|
|
for (LGPlayer lgp : getAlive())
|
|
if (lgp.getRoleWinType() == RoleWinType.LOUP_GAROU)
|
|
badGuy++;
|
|
else if (lgp.getRoleWinType() == RoleWinType.VILLAGE)
|
|
goodGuy++;
|
|
else if (lgp.getRoleWinType() == RoleWinType.SEUL)
|
|
solo++;
|
|
else if (lgp.getRoleWinType() == RoleWinType.VAMPIRE)
|
|
vampires++;
|
|
LGEndCheckEvent event = new LGEndCheckEvent(this, goodGuy == 0 || badGuy == 0 ? (goodGuy + badGuy == 0 ? LGWinType.EQUAL : (goodGuy > 0 ? LGWinType.VILLAGEOIS : LGWinType.LOUPGAROU)) : LGWinType.NONE);
|
|
|
|
if ((badGuy + goodGuy > 0 && solo > 0) || solo > 1 || (badGuy + goodGuy > 0 && vampires > 0) || (solo > 0 && vampires > 0))
|
|
event.setWinType(LGWinType.NONE);
|
|
|
|
if (badGuy + goodGuy == 0 && solo == 1 && vampires == 0)
|
|
event.setWinType(LGWinType.SOLO);
|
|
|
|
if (badGuy + goodGuy == 0 && solo == 0 && vampires > 0)
|
|
event.setWinType(LGWinType.VAMPIRE);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (doEndGame && event.getWinType() != LGWinType.NONE)
|
|
endGame(event.getWinType());
|
|
return event.getWinType() != LGWinType.NONE;
|
|
}
|
|
|
|
public interface TextGenerator {
|
|
String generate(LGPlayer player, int secondsLeft);
|
|
}
|
|
}
|