package me.unurled.sacredrealms.cutscenes; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Objects; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitTask; /** * Cutscene class * Start by creating an instance of it. * You can play it then using {@link Cutscene#play(org.bukkit.entity.Player)} */ public class Cutscene { private static final NamespacedKey PLAYING = new NamespacedKey(Cutscenes.getInstance(), "cutscene_playing"); private final String ID; private final String name; private final ArrayList markers; private ArrayList markerIds; private Location start; private Location end; private HashMap tasks; public Cutscene(String ID, String name) { this.ID = ID.toUpperCase(); this.name = name; this.markers = new ArrayList<>(); this.markerIds = new ArrayList<>(); this.tasks = new HashMap<>(); } public Cutscene(String ID, String name, ArrayList markers) { this.ID = ID.toUpperCase(); this.name = name; this.markers = markers; markerIds = new ArrayList<>(); for (Marker marker : markers) { markerIds.add(marker.getID()); } if (markers.size() == 0) return; if (markers.get(0).getFrames().size() == 0) return; start = markers.get(0).getFrames().get(0).getLocation(); end = markers.get(markers.size() - 1).getFrames().get(markers.get(markers.size() - 1).getFrames().size() - 1).getLocation(); this.tasks = new HashMap<>(); } public void setMarkers() { for (Integer i : markerIds) { markers.add(Marker.getMarker(i)); } } public void addMarker(Marker marker) { this.markers.add(marker); } public void setStart(Location start) { this.start = start; } public void setEnd(Location end) { this.end = end; } public String getID() { return this.ID.toUpperCase(); } public String getName() { return this.name; } public ArrayList getMarkers() { return this.markers; } public Location getStart() { return this.start; } public Location getEnd() { return this.end; } public void addMarkerId(Integer id) { this.markerIds.add(id); } public long time() { long time = 0; for (Marker marker : this.markers) { if (marker.getOverAllTime() != null) time += marker.getOverAllTime(); } return time; } public void play(Player p) { PersistentDataContainer pdc = p.getPersistentDataContainer(); if (pdc.has(PLAYING)) { if (pdc.get(PLAYING, PersistentDataType.STRING) == null) { pdc.remove(PLAYING); return; } if (!Cutscenes.getInstance().getCutscenesId().contains(pdc.get(PLAYING, PersistentDataType.STRING))) { pdc.remove(PLAYING); return; } if (Objects.equals(pdc.get(PLAYING, PersistentDataType.STRING), this.ID.toUpperCase())) { p.sendMessage( Component.text("You are already playing this cutscene!") .appendNewline() .append(Component.text("Type /cutscene stop to stop playing it.")) ); return; } else { p.sendMessage( Component.text("You are already playing a cutscene!") .appendNewline() .append(Component.text("Type /cutscene stop to stop playing it.")) ); } } pdc.set(PLAYING, PersistentDataType.STRING, this.ID.toUpperCase()); Cutscenes.getInstance().setOriginalLocation(p, p.getLocation()); Cutscenes.getInstance().addCurrentPlayingCutscene(this, p); BukkitTask task = RScheduler.scheduleAsync(Cutscenes.getInstance(), () -> { int finalI = 0; for (int j = 0 ; j < markers.size() ; j++) { Marker marker = markers.get(j); for (int i = 0 ; i < marker.getFrames().size() ; i++) { int finalI1 = i; RScheduler.schedule(Cutscenes.getInstance(), () -> { p.teleport(marker.getFrames().get(finalI1).getLocation()); marker.getFrames().get(finalI1).play(); }, Util.miliToTicks(marker.getTimeBetweenFrames()) * finalI); finalI++; } } }); RScheduler.scheduleAsync(Cutscenes.getInstance(), () -> { try { Thread.sleep(time()); } catch (InterruptedException e) { e.printStackTrace(); } RScheduler.schedule(Cutscenes.getInstance(), () -> stop(p)); }); tasks.put(p, task); } public void stop(Player p) { PersistentDataContainer pdc = p.getPersistentDataContainer(); if (pdc.has(PLAYING)) { if (pdc.get(PLAYING, PersistentDataType.STRING) == null) { pdc.remove(PLAYING); return; } if (Objects.equals(pdc.get(PLAYING, PersistentDataType.STRING), this.ID.toUpperCase())) { Cutscenes.getInstance().removeCurrentPlayingCutscene(Cutscenes.getInstance() .getCutscene(pdc.get(PLAYING, PersistentDataType.STRING)), p); pdc.remove(PLAYING); if (tasks.get(p) != null) tasks.get(p).cancel(); // TODO: replace player to it's original location Location loc = Cutscenes.getInstance().getOriginalLocation(p); if (loc != null) { p.teleport(loc); } p.sendMessage( Component.text("You stopped playing the cutscene!") ); return; } else { p.sendMessage( Component.text("You are not playing this cutscene!") ); return; } } if (!Cutscenes.getInstance().getCurrentPlayingCutscenes().containsValue(p)) { p.sendMessage( Component.text("You are not playing a cutscene!") ); } } public void calculateMarkers() { if (markers.size() == 0) return; for (int i = 0 ; i < markers.size() ; i++) { if (i < markers.size() - 1) { markers.get(i).calculateFrames(markers.get(i+1)); } else { ArrayList frames = new ArrayList<>(); frames.add(new Frame(markers.get(i).getStart())); markers.get(i).setFrames(frames); } } } @Override public String toString() { return "Cutscene{" + "ID='" + ID + '\'' + ", name='" + name + '\'' + ", markers=" + markers + ", markerIds=" + markerIds + ", start=" + start + ", end=" + end + ", tasks=" + tasks + '}'; } }