Cutscenes/src/main/java/me/unurled/sacredrealms/cutscenes/Cutscene.java

226 lines
7.4 KiB
Java

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<Marker> markers;
private ArrayList<Integer> markerIds;
private Location start;
private Location end;
private HashMap<Player, BukkitTask> 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<Marker> 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<Marker> 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<Frame> 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 +
'}';
}
}