too many things, kinda forgor to push/commit
This commit is contained in:
parent
897edf1d37
commit
bb514f8a63
69 changed files with 1691 additions and 1256 deletions
17
.forgejo/workflows/format.yaml
Normal file
17
.forgejo/workflows/format.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Format
|
||||||
|
|
||||||
|
run-name: ${{ github.actor }} is formatting
|
||||||
|
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
formatting:
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: axel-op/googlejavaformat-action@v3
|
||||||
|
with:
|
||||||
|
args: "--replace"
|
||||||
|
skip-commit: true
|
||||||
|
- name: Print diffs
|
||||||
|
run: git --no-pager diff --exit-code
|
|
@ -19,4 +19,6 @@ see [docs](https://git.unurled.me/SacredRealms/docs) for more information
|
||||||
|
|
||||||
- [Java 17](https://adoptium.net/temurin/releases/?version=17)
|
- [Java 17](https://adoptium.net/temurin/releases/?version=17)
|
||||||
- [PaperMC 1.20.6](https://papermc.io/downloads/paper) or any fork of it (purpur, etc)
|
- [PaperMC 1.20.6](https://papermc.io/downloads/paper) or any fork of it (purpur, etc)
|
||||||
- a build of the plugin
|
- a build of the plugin
|
||||||
|
|
||||||
|
spigot plugin development 90 replay plugin - 1:43:02
|
|
@ -2,7 +2,7 @@ import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
id("io.papermc.paperweight.userdev") version "1.7.2"
|
id("io.papermc.paperweight.userdev") version "1.7.3"
|
||||||
id("org.sonarqube") version "5.1.0.4882"
|
id("org.sonarqube") version "5.1.0.4882"
|
||||||
id("net.minecrell.plugin-yml.paper") version "0.6.0"
|
id("net.minecrell.plugin-yml.paper") version "0.6.0"
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,10 @@ repositories {
|
||||||
name = "unurled"
|
name = "unurled"
|
||||||
url = uri("https://repo.unurled.me/releases")
|
url = uri("https://repo.unurled.me/releases")
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
name = "cubbossa"
|
||||||
|
url = uri("https://nexus.leonardbausenwein.de/repository/maven-releases/")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -47,9 +51,9 @@ dependencies {
|
||||||
|
|
||||||
paperLibrary("redis.clients", "jedis", redisVersion)
|
paperLibrary("redis.clients", "jedis", redisVersion)
|
||||||
|
|
||||||
paperLibrary("com.github.retrooper", "packetevents-spigot", "2.4.0")
|
paperLibrary("com.github.retrooper", "packetevents-spigot", "2.5.0")
|
||||||
|
|
||||||
paperLibrary("me.unurled", "SR-Core", "0.1.0")
|
compileOnly("me.unurled:SR-Core:0.1.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
@ -106,7 +110,7 @@ paper {
|
||||||
"sr.resetadventure",
|
"sr.resetadventure",
|
||||||
"sr.treasure.manage",
|
"sr.treasure.manage",
|
||||||
"sr.difficulty.*",
|
"sr.difficulty.*",
|
||||||
"sr.cutscene"
|
"sr.cutscene.*"
|
||||||
)
|
)
|
||||||
description = "Gives access to all Sacred Realms permissions."
|
description = "Gives access to all Sacred Realms permissions."
|
||||||
}
|
}
|
||||||
|
@ -151,6 +155,10 @@ paper {
|
||||||
}
|
}
|
||||||
register("sr.cutscene") {
|
register("sr.cutscene") {
|
||||||
description = "Gives access to the cutscene command."
|
description = "Gives access to the cutscene command."
|
||||||
|
children = listOf(
|
||||||
|
"sr.cutscene.create",
|
||||||
|
"sr.cutscene.replay"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,9 @@ import java.util.List;
|
||||||
import me.unurled.sacredrealms.sr.components.block.BlockManager;
|
import me.unurled.sacredrealms.sr.components.block.BlockManager;
|
||||||
import me.unurled.sacredrealms.sr.components.clientbuild.ClientBuildManager;
|
import me.unurled.sacredrealms.sr.components.clientbuild.ClientBuildManager;
|
||||||
import me.unurled.sacredrealms.sr.components.combat.CombatManager;
|
import me.unurled.sacredrealms.sr.components.combat.CombatManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.ReplayManager;
|
||||||
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
||||||
import me.unurled.sacredrealms.sr.components.item.ItemManager;
|
import me.unurled.sacredrealms.sr.components.item.ItemManager;
|
||||||
import me.unurled.sacredrealms.sr.components.npc.NPCManager;
|
import me.unurled.sacredrealms.sr.components.npc.NPCManager;
|
||||||
|
@ -31,6 +34,7 @@ public final class SR extends JavaPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||||
|
PacketEvents.getAPI().getSettings().reEncodeByDefault(false).checkForUpdates(true);
|
||||||
// On Bukkit, calling this here is essential, hence the name "load"
|
// On Bukkit, calling this here is essential, hence the name "load"
|
||||||
PacketEvents.getAPI().load();
|
PacketEvents.getAPI().load();
|
||||||
}
|
}
|
||||||
|
@ -39,10 +43,10 @@ public final class SR extends JavaPlugin {
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
plugin = this;
|
plugin = this;
|
||||||
|
|
||||||
SRCore.getInstance().setPlugin(this);
|
|
||||||
|
|
||||||
PacketEvents.getAPI().init();
|
PacketEvents.getAPI().init();
|
||||||
|
|
||||||
|
SRCore.getInstance().setPlugin(this);
|
||||||
|
|
||||||
InvUI.getInstance().setPlugin(this);
|
InvUI.getInstance().setPlugin(this);
|
||||||
|
|
||||||
SRCore.getInstance()
|
SRCore.getInstance()
|
||||||
|
@ -61,7 +65,10 @@ public final class SR extends JavaPlugin {
|
||||||
ClientBuildManager.class,
|
ClientBuildManager.class,
|
||||||
TreasureManager.class,
|
TreasureManager.class,
|
||||||
BackgroundManager.class,
|
BackgroundManager.class,
|
||||||
ResourcePackManager.class));
|
ResourcePackManager.class,
|
||||||
|
CutsceneManager.class,
|
||||||
|
RecordingManager.class,
|
||||||
|
ReplayManager.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,6 +25,11 @@ public class SRLoader implements PluginLoader {
|
||||||
resolver.addRepository(
|
resolver.addRepository(
|
||||||
new RemoteRepository.Builder("invui", "default", "https://repo.xenondevs.xyz/releases/")
|
new RemoteRepository.Builder("invui", "default", "https://repo.xenondevs.xyz/releases/")
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
resolver.addDependency(new Dependency(new DefaultArtifact("me.unurled:SR-Core:0.1.1"), null));
|
||||||
|
resolver.addRepository(
|
||||||
|
new RemoteRepository.Builder("srcore", "default", "https://repo.unurled.me/releases")
|
||||||
|
.build());
|
||||||
classpathBuilder.addLibrary(resolver);
|
classpathBuilder.addLibrary(resolver);
|
||||||
|
|
||||||
PluginLibraries pluginLibraries = load();
|
PluginLibraries pluginLibraries = load();
|
||||||
|
|
|
@ -11,12 +11,14 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.AttributeCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.AttributeCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.ClientBuildCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.ClientBuildCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.CutsceneCommand;
|
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.EntityTypeCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.EntityTypeCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.ItemCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.ItemCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.LevelCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.LevelCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.SpawnEntityCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.SpawnEntityCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.admin.TreasureCommand;
|
import me.unurled.sacredrealms.sr.commands.admin.TreasureCommand;
|
||||||
|
import me.unurled.sacredrealms.sr.commands.admin.cutscene.CreateCutsceneCommand;
|
||||||
|
import me.unurled.sacredrealms.sr.commands.admin.cutscene.RecordCutsceneCommand;
|
||||||
|
import me.unurled.sacredrealms.sr.commands.admin.cutscene.StopRecordingCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.player.DifficultyCommand;
|
import me.unurled.sacredrealms.sr.commands.player.DifficultyCommand;
|
||||||
import me.unurled.sacredrealms.sr.commands.player.ResetAdventureCommand;
|
import me.unurled.sacredrealms.sr.commands.player.ResetAdventureCommand;
|
||||||
import me.unurled.srcore.api.Manager;
|
import me.unurled.srcore.api.Manager;
|
||||||
|
@ -51,7 +53,6 @@ public class CommandManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadCommands(BootstrapContext ctx) {
|
public static void loadCommands(BootstrapContext ctx) {
|
||||||
|
|
||||||
registerCommand("attributes", "Set the attributes of the player.", ctx, AttributeCommand.class);
|
registerCommand("attributes", "Set the attributes of the player.", ctx, AttributeCommand.class);
|
||||||
registerCommand(
|
registerCommand(
|
||||||
"clientbuild", "Set the client build of the player.", ctx, ClientBuildCommand.class);
|
"clientbuild", "Set the client build of the player.", ctx, ClientBuildCommand.class);
|
||||||
|
@ -66,6 +67,17 @@ public class CommandManager extends Manager {
|
||||||
registerCommand(
|
registerCommand(
|
||||||
"difficulty", "Set the difficulty of the player.", ctx, DifficultyCommand.class);
|
"difficulty", "Set the difficulty of the player.", ctx, DifficultyCommand.class);
|
||||||
|
|
||||||
registerCommand("cutscene", "Cutscene commands.", List.of("cs"), ctx, CutsceneCommand.class);
|
registerCommand("createcustcene", "Create a new Cutscene", ctx, CreateCutsceneCommand.class);
|
||||||
|
|
||||||
|
registerCommand(
|
||||||
|
"recordcutscene",
|
||||||
|
"Record a cutscene entity movement and everything",
|
||||||
|
ctx,
|
||||||
|
RecordCutsceneCommand.class);
|
||||||
|
registerCommand(
|
||||||
|
"stopcutscene",
|
||||||
|
"stop a record of a cutscene entity movement and everything",
|
||||||
|
ctx,
|
||||||
|
StopRecordingCommand.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
package me.unurled.sacredrealms.sr.commands.admin;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
package me.unurled.sacredrealms.sr.commands.admin;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.ERROR;
|
import static me.unurled.srcore.utils.Component.ERROR;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
|
||||||
import me.unurled.srcore.api.Manager;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class CutsceneCommand implements BasicCommand {
|
|
||||||
|
|
||||||
private CutsceneManager cutsceneManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the permission for the root command used in {@link #canUse(CommandSender)} by default.
|
|
||||||
*
|
|
||||||
* @return the permission for the root command used in {@link #canUse(CommandSender)}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public @Nullable String permission() {
|
|
||||||
return "cutscenes.admin";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the command with the given {@link CommandSourceStack} and arguments.
|
|
||||||
*
|
|
||||||
* @param sender the commandSourceStack of the command
|
|
||||||
* @param args the arguments of the command ignoring repeated spaces
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void execute(@NotNull CommandSourceStack sender, @NotNull String @NotNull [] args) {
|
|
||||||
if (cutsceneManager == null) {
|
|
||||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
|
||||||
}
|
|
||||||
// /cs stop, list, reload, play, create, remove
|
|
||||||
if (args.length == 1) {
|
|
||||||
if (args[0].equals("stop")) {
|
|
||||||
if (sender.getSender() instanceof Player p) {
|
|
||||||
cutsceneManager.stopCutscene(p);
|
|
||||||
} else {
|
|
||||||
sender
|
|
||||||
.getSender()
|
|
||||||
.sendMessage(
|
|
||||||
textComp("<red>You must be a player to stop a cutscene. Use /cs stop <player>"));
|
|
||||||
}
|
|
||||||
} else if (args[0].equals("list")) {
|
|
||||||
sender
|
|
||||||
.getSender()
|
|
||||||
.sendMessage(
|
|
||||||
textComp("<yellow>Cutscenes: " + cutsceneManager.getCutscenesId().toString()));
|
|
||||||
} else if (args[0].equals("reload")) {
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (args.length == 2) {
|
|
||||||
if (args[0].equals("play")) {
|
|
||||||
if (sender.getSender() instanceof Player p) {
|
|
||||||
Cutscene cutscene = cutsceneManager.getCutscene(args[1]);
|
|
||||||
cutsceneManager.playCutscene(cutscene, p);
|
|
||||||
} else {
|
|
||||||
sender
|
|
||||||
.getSender()
|
|
||||||
.sendMessage(
|
|
||||||
textComp(
|
|
||||||
"<red>You must be a player to play a cutscene. Use /cs play <cutscene_id> <player>"));
|
|
||||||
}
|
|
||||||
} else if (args[0].equals("stop")) {
|
|
||||||
Player p = Bukkit.getPlayer(args[1]);
|
|
||||||
if (p != null) {
|
|
||||||
cutsceneManager.stopCutscene(p);
|
|
||||||
}
|
|
||||||
} else if (args[0].equals("create")) {
|
|
||||||
String name = args[1];
|
|
||||||
cutsceneManager.createCutscene(name);
|
|
||||||
sender.getSender().sendMessage(textComp("<green>Created cutscene " + name));
|
|
||||||
} else if (args[0].equals("remove")) {
|
|
||||||
String name = args[1];
|
|
||||||
cutsceneManager.removeCutscene(name);
|
|
||||||
sender.getSender().sendMessage(textComp("<red>Removed cutscene " + name));
|
|
||||||
}
|
|
||||||
} else if (args.length == 3) {
|
|
||||||
if (args[0].equals("play")) {
|
|
||||||
Player p = Bukkit.getPlayer(args[2]);
|
|
||||||
if (p != null) {
|
|
||||||
Cutscene cutscene = cutsceneManager.getCutscene(args[1]);
|
|
||||||
cutsceneManager.playCutscene(cutscene, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender
|
|
||||||
.getSender()
|
|
||||||
.sendMessage(
|
|
||||||
textComp(
|
|
||||||
"<yellow>Usage: /cs <play|stop|reload|list> <cutscene_id|player (only play and stop)> <player (only possible if play with an id before)>"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Suggests possible completions for the given command {@link CommandSourceStack} and arguments.
|
|
||||||
*
|
|
||||||
* @param sender the commandSourceStack of the command
|
|
||||||
* @param args the arguments of the command including repeated spaces
|
|
||||||
* @return a collection of suggestions
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public @NotNull Collection<String> suggest(
|
|
||||||
@NotNull CommandSourceStack sender, @NotNull String[] args) {
|
|
||||||
if (cutsceneManager == null) {
|
|
||||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
|
||||||
}
|
|
||||||
List<String> complete = new ArrayList<>();
|
|
||||||
complete.add("stop");
|
|
||||||
if (sender.getSender().hasPermission("cutscenes.admin")) {
|
|
||||||
complete.add("play");
|
|
||||||
complete.add("list");
|
|
||||||
complete.add("reload");
|
|
||||||
complete.add("create");
|
|
||||||
complete.add("remove");
|
|
||||||
}
|
|
||||||
List<String> result = new ArrayList<>();
|
|
||||||
if (args.length == 1) {
|
|
||||||
for (String s : complete) {
|
|
||||||
if (s.toLowerCase().startsWith(args[0].toLowerCase())) {
|
|
||||||
result.add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else if (args.length == 2) {
|
|
||||||
if (sender.getSender().hasPermission("cutscenes.admin")) {
|
|
||||||
if (args[0].equalsIgnoreCase("stop")) {
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
|
||||||
if (p.getName().toLowerCase().startsWith(args[1].toLowerCase())) {
|
|
||||||
result.add(p.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (args[0].equalsIgnoreCase("play") || args[0].equalsIgnoreCase("remove")) {
|
|
||||||
for (String s : cutsceneManager.getCutscenesId()) {
|
|
||||||
if (s.toLowerCase().startsWith(args[1].toLowerCase())) {
|
|
||||||
result.add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else if (args.length == 3) {
|
|
||||||
if (sender.getSender().hasPermission("cutscenes.admin")) {
|
|
||||||
if (args[0].equalsIgnoreCase("play")) {
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
|
||||||
if (p.getName().toLowerCase().startsWith(args[2].toLowerCase())) {
|
|
||||||
result.add(p.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
package me.unurled.sacredrealms.sr.commands.admin;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.NOT_PLAYER;
|
import static me.unurled.srcore.utils.Component.NOT_PLAYER;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
package me.unurled.sacredrealms.sr.commands.admin;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
package me.unurled.sacredrealms.sr.commands.admin;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.NO_PERMISSION;
|
import static me.unurled.srcore.utils.Component.NO_PERMISSION;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.admin;
|
package me.unurled.sacredrealms.sr.commands.admin;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.NOT_PLAYER;
|
import static me.unurled.srcore.utils.Component.NOT_PLAYER;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package me.unurled.sacredrealms.sr.commands.admin.cutscene;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.NOT_PLAYER;
|
||||||
|
import static me.unurled.srcore.utils.Component.NO_PERMISSION;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class CreateCutsceneCommand implements BasicCommand {
|
||||||
|
|
||||||
|
private CutsceneManager cm;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(@NotNull CommandSourceStack sender, String[] args) {
|
||||||
|
if (!(sender.getSender() instanceof Player p)) {
|
||||||
|
sender.getSender().sendMessage(textComp(NOT_PLAYER));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!p.hasPermission("sr.cutscene.create")) {
|
||||||
|
p.sendMessage(textComp(NO_PERMISSION));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get the name
|
||||||
|
if (args.length < 1) {
|
||||||
|
p.sendMessage("Usage: /cs <name>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = args[0];
|
||||||
|
// create the cutscene
|
||||||
|
|
||||||
|
if (cm == null) {
|
||||||
|
cm = Manager.getInstance(CutsceneManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
cm.startCreatingCutscene(p, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> suggest(
|
||||||
|
CommandSourceStack commandSourceStack, String @NotNull [] args) {
|
||||||
|
if (args.length == 1) {
|
||||||
|
return List.of("name");
|
||||||
|
}
|
||||||
|
return BasicCommand.super.suggest(commandSourceStack, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package me.unurled.sacredrealms.sr.commands.admin.cutscene;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.NO_PERMISSION;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class RecordCutsceneCommand implements BasicCommand {
|
||||||
|
|
||||||
|
private RecordingManager rm;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(@NotNull CommandSourceStack stack, String[] args) {
|
||||||
|
if (!(stack.getSender() instanceof Player p)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p.hasPermission("sr.cutscene.create")) {
|
||||||
|
p.sendMessage(textComp(NO_PERMISSION));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rm == null) {
|
||||||
|
rm = Manager.getInstance(RecordingManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
Recording activeRecording = rm.getPlayerActiveRecording(p);
|
||||||
|
if (activeRecording != null) {
|
||||||
|
p.sendMessage("You are already recording a cutscene.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cutscene cutscene =
|
||||||
|
Manager.getInstance(CutsceneManager.class).getCutsceneBeingCreated(p.getUniqueId());
|
||||||
|
if (cutscene == null) {
|
||||||
|
p.sendMessage("You are not creating a cutscene.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
activeRecording = new Recording(cutscene, p);
|
||||||
|
|
||||||
|
// open menu for selection cutscene
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package me.unurled.sacredrealms.sr.commands.admin.cutscene;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.NOT_PLAYER;
|
||||||
|
import static me.unurled.srcore.utils.Component.NO_PERMISSION;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import java.util.Collection;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ReplayCommand implements BasicCommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(@NotNull CommandSourceStack stack, String[] args) {
|
||||||
|
if (!(stack.getSender() instanceof Player p)) {
|
||||||
|
stack.getSender().sendMessage(textComp(NOT_PLAYER));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p.hasPermission("sr.cutscene.replay")) {
|
||||||
|
p.sendMessage(textComp(NO_PERMISSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
// aaa
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> suggest(CommandSourceStack stack, String[] args) {
|
||||||
|
return BasicCommand.super.suggest(stack, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package me.unurled.sacredrealms.sr.commands.admin.cutscene;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.NOT_PLAYER;
|
||||||
|
import static me.unurled.srcore.utils.Component.NO_PERMISSION;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import java.util.Collection;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class StopRecordingCommand implements BasicCommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(@NotNull CommandSourceStack stack, String[] args) {
|
||||||
|
if (!(stack.getSender() instanceof Player p)) {
|
||||||
|
stack.getSender().sendMessage(textComp(NOT_PLAYER));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!p.hasPermission("sr.cutscene.create")) {
|
||||||
|
p.sendMessage(textComp(NO_PERMISSION));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager.getInstance(RecordingManager.class).stopRecording(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> suggest(CommandSourceStack commandSourceStack, String[] args) {
|
||||||
|
return BasicCommand.super.suggest(commandSourceStack, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.player;
|
package me.unurled.sacredrealms.sr.commands.player;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.NOT_PLAYER;
|
import static me.unurled.srcore.utils.Component.NOT_PLAYER;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.NO_PERMISSION;
|
import static me.unurled.srcore.utils.Component.NO_PERMISSION;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.PLAYER_NOT_FOUND;
|
import static me.unurled.srcore.utils.Component.PLAYER_NOT_FOUND;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.commands.player;
|
package me.unurled.sacredrealms.sr.commands.player;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.block;
|
package me.unurled.sacredrealms.sr.components.block;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.combat;
|
package me.unurled.sacredrealms.sr.components.combat;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.spawnIndicator;
|
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.spawnIndicator;
|
||||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.updateActionBar;
|
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.updateActionBar;
|
||||||
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
|
|
||||||
public enum Action {
|
|
||||||
IDLE(),
|
|
||||||
MOVE(Location.class),
|
|
||||||
TELEPORT(Location.class),
|
|
||||||
SPAWN(Location.class),
|
|
||||||
DESPAWN(),
|
|
||||||
HIT(Entity.class),
|
|
||||||
SNEAK(),
|
|
||||||
JUMP(),
|
|
||||||
PLACE(Location.class, BlockData.class),
|
|
||||||
INTERACT(Location.class, org.bukkit.event.block.Action.class),
|
|
||||||
BREAK(Location.class);
|
|
||||||
|
|
||||||
private final List<Class> types;
|
|
||||||
|
|
||||||
Action(Class... types) {
|
|
||||||
this.types = List.of(types);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
import static org.bukkit.Material.RED_WOOL;
|
||||||
|
|
||||||
|
import me.unurled.sacredrealms.sr.utils.Region;
|
||||||
|
import me.unurled.sacredrealms.sr.utils.RegionUtil;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class CreationListener implements Listener {
|
||||||
|
|
||||||
|
private CutsceneManager cm;
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(@NotNull InventoryClickEvent e) {
|
||||||
|
if (e.getWhoClicked() instanceof Player p) {
|
||||||
|
if (cm == null) {
|
||||||
|
cm = Manager.getInstance(CutsceneManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cutscene cutscene = cm.getCutsceneBeingCreated(p.getUniqueId());
|
||||||
|
if (cutscene == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onRightClick(@NotNull PlayerInteractEvent e) {
|
||||||
|
if (!e.getAction().isRightClick()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
if (cm == null) {
|
||||||
|
cm = Manager.getInstance(CutsceneManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cutscene cutscene = cm.getCutsceneBeingCreated(p.getUniqueId());
|
||||||
|
|
||||||
|
if (cutscene == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.setCancelled(true);
|
||||||
|
|
||||||
|
if (e.getItem() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (e.getItem().getType()) {
|
||||||
|
case BARRIER -> {
|
||||||
|
RegionUtil.killSelectorsWithTag(cutscene.name());
|
||||||
|
cm.cancelCreatingCutscene(p);
|
||||||
|
}
|
||||||
|
case EMERALD_BLOCK -> {
|
||||||
|
if (cutscene.pos1() == null) {
|
||||||
|
p.sendMessage(textComp("<red>Pos1 not set. Click on Red Wool."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cutscene.pos2() == null) {
|
||||||
|
p.sendMessage(textComp("<red>Pos2 not set. Click on Blue Wool."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cm.finishCreatingCutscene(p);
|
||||||
|
RegionUtil.killSelectorsWithTag(cutscene.name());
|
||||||
|
}
|
||||||
|
case RED_WOOL, BLUE_WOOL -> {
|
||||||
|
Location loc = null;
|
||||||
|
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && e.getClickedBlock() != null) {
|
||||||
|
loc = e.getClickedBlock().getLocation();
|
||||||
|
} else if (e.getAction() == Action.RIGHT_CLICK_AIR) {
|
||||||
|
loc = e.getPlayer().getLocation();
|
||||||
|
}
|
||||||
|
if (e.getItem().getType() == RED_WOOL) {
|
||||||
|
p.sendMessage(textComp("<green>Pos1 set."));
|
||||||
|
cutscene.setPos1(loc);
|
||||||
|
} else {
|
||||||
|
p.sendMessage(textComp("<green>Pos2 set."));
|
||||||
|
cutscene.setPos2(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cutscene.pos1() != null && cutscene.pos2() != null) {
|
||||||
|
Region region = new Region();
|
||||||
|
region.setCorner1(cutscene.pos1());
|
||||||
|
region.setCorner2(cutscene.pos2());
|
||||||
|
if (loc == null) return;
|
||||||
|
RegionUtil.killSelectorsWithTag(cutscene.name());
|
||||||
|
RegionUtil.drawSelector(region, loc.getWorld(), cutscene.name(), NamedTextColor.GREEN);
|
||||||
|
p.sendMessage(
|
||||||
|
textComp(
|
||||||
|
"<green>You have set both corners! Right click the Emerald block to finish."));
|
||||||
|
} else if (cutscene.pos1() != null && cutscene.pos2() == null) {
|
||||||
|
Region region = new Region();
|
||||||
|
region.setCorner1(cutscene.pos1());
|
||||||
|
region.setCorner2(cutscene.pos1());
|
||||||
|
if (loc == null) return;
|
||||||
|
RegionUtil.killSelectorsWithTag(cutscene.name());
|
||||||
|
RegionUtil.drawSelector(region, loc.getWorld(), cutscene.name(), NamedTextColor.YELLOW);
|
||||||
|
} else if (cutscene.pos1() == null && cutscene.pos2() != null) {
|
||||||
|
Region region = new Region();
|
||||||
|
region.setCorner1(cutscene.pos2());
|
||||||
|
region.setCorner2(cutscene.pos2());
|
||||||
|
if (loc == null) return;
|
||||||
|
RegionUtil.killSelectorsWithTag(cutscene.name());
|
||||||
|
RegionUtil.drawSelector(region, loc.getWorld(), cutscene.name(), NamedTextColor.YELLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,239 +1,80 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.CutsceneUtil.showBlackScreen;
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import me.unurled.sacredrealms.sr.SR;
|
|
||||||
import me.unurled.srcore.api.Manager;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
|
||||||
* Cutscene class
|
|
||||||
*
|
|
||||||
* <p>Represents a cutscene
|
|
||||||
*
|
|
||||||
* <pre>{@code
|
|
||||||
* {
|
|
||||||
* "id": "cutscene1",
|
|
||||||
* "name": "Cutscene 1",
|
|
||||||
* "markers": [1, 2, 3], // Marker IDs
|
|
||||||
* "start": {
|
|
||||||
* "world": "world",
|
|
||||||
* "x": 0,
|
|
||||||
* "y": 0,
|
|
||||||
* "z": 0,
|
|
||||||
* "yaw": 0,
|
|
||||||
* "pitch": 0
|
|
||||||
* },
|
|
||||||
* "end": {
|
|
||||||
* "world": "world",
|
|
||||||
* "x": 0,
|
|
||||||
* "y": 0,
|
|
||||||
* "z": 0,
|
|
||||||
* "yaw": 0,
|
|
||||||
* "pitch": 0
|
|
||||||
* }
|
|
||||||
* "blackBorders": true,
|
|
||||||
* "startFadeToBlack": true,
|
|
||||||
* "endFadeToBlack": true
|
|
||||||
* }
|
|
||||||
* }</pre>
|
|
||||||
*/
|
|
||||||
public class Cutscene {
|
public class Cutscene {
|
||||||
|
|
||||||
private final String id;
|
private UUID id = UUID.randomUUID();
|
||||||
private final String name;
|
private String name;
|
||||||
private final List<Marker> markers;
|
private Location pos1;
|
||||||
private final List<Integer> markerIds;
|
private Location pos2;
|
||||||
private CutsceneManager cutsceneManager;
|
|
||||||
private Location start;
|
|
||||||
private Location end;
|
|
||||||
private Map<UUID, BukkitTask> tasks;
|
|
||||||
private boolean blackBorders;
|
|
||||||
private boolean startFadeToBlack;
|
|
||||||
private boolean endFadeToBlack;
|
|
||||||
|
|
||||||
public Cutscene(String id, String name) {
|
public Cutscene() {}
|
||||||
|
|
||||||
|
public Cutscene(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cutscene(UUID id, String name, Location pos1, Location pos2) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.markers = new ArrayList<>();
|
this.pos1 = pos1;
|
||||||
this.markerIds = new ArrayList<>();
|
this.pos2 = pos2;
|
||||||
this.tasks = new HashMap<>();
|
|
||||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
|
||||||
if (cutsceneManager == null) {
|
|
||||||
error("CutsceneManager is null, could not create a Cutscene");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cutscene(@NotNull String id, String name, @NotNull ArrayList<Marker> markers) {
|
public boolean isInRegion(@NotNull Location location) {
|
||||||
this.id = id.toUpperCase();
|
double x1 = pos1.getX();
|
||||||
|
double x2 = pos2.getX();
|
||||||
|
double y1 = pos1.getY();
|
||||||
|
double y2 = pos2.getY();
|
||||||
|
double z1 = pos1.getZ();
|
||||||
|
double z2 = pos2.getZ();
|
||||||
|
double x = location.getX();
|
||||||
|
double y = location.getY();
|
||||||
|
double z = location.getZ();
|
||||||
|
return x >= Math.min(x1, x2)
|
||||||
|
&& x <= Math.max(x1, x2)
|
||||||
|
&& y >= Math.min(y1, y2)
|
||||||
|
&& y <= Math.max(y1, y2)
|
||||||
|
&& z >= Math.min(z1, z2)
|
||||||
|
&& z <= Math.max(z1, z2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID id() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cutscene setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cutscene setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.markers = markers;
|
return this;
|
||||||
markerIds = new ArrayList<>();
|
|
||||||
for (Marker marker : markers) {
|
|
||||||
markerIds.add(marker.getId());
|
|
||||||
}
|
|
||||||
if (markers.isEmpty()) return;
|
|
||||||
if (markers.getFirst().getFrames().isEmpty()) return;
|
|
||||||
start = markers.getFirst().getFrames().getFirst().getLocation();
|
|
||||||
end = markers.getLast().getFrames().getLast().getLocation();
|
|
||||||
this.tasks = new HashMap<>();
|
|
||||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
|
||||||
if (cutsceneManager == null) {
|
|
||||||
error("CutsceneManager is null, could not create a Cutscene");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMarkers() {
|
public Location pos1() {
|
||||||
for (Integer i : markerIds) {
|
return pos1;
|
||||||
markers.add(Marker.getMarker(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMarker(Marker marker) {
|
public Cutscene setPos1(Location pos1) {
|
||||||
this.markers.add(marker);
|
this.pos1 = pos1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public Location pos2() {
|
||||||
return this.id.toUpperCase();
|
return pos2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public Cutscene setPos2(Location pos2) {
|
||||||
return this.name;
|
this.pos2 = pos2;
|
||||||
}
|
return this;
|
||||||
|
|
||||||
public List<Marker> getMarkers() {
|
|
||||||
return this.markers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getStart() {
|
|
||||||
return this.start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStart(Location start) {
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getEnd() {
|
|
||||||
return this.end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnd(Location end) {
|
|
||||||
this.end = 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(@NotNull Player p) {
|
|
||||||
if (cutsceneManager.isPlayingCutscene(p)) {
|
|
||||||
p.sendMessage(textComp("You are already playing a cutscene!"));
|
|
||||||
}
|
|
||||||
cutsceneManager.addCurrentPlayingCutscene(this, p);
|
|
||||||
|
|
||||||
// hide toolbar and make it spectate entity
|
|
||||||
p.setGameMode(GameMode.SPECTATOR);
|
|
||||||
|
|
||||||
// set black borders
|
|
||||||
if (blackBorders) {
|
|
||||||
p.getInventory().setHelmet(new ItemStack(Material.PUMPKIN));
|
|
||||||
p.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startFadeToBlack) {
|
|
||||||
showBlackScreen(p, 2, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
BukkitTask task =
|
|
||||||
Bukkit.getScheduler()
|
|
||||||
.runTaskAsynchronously(
|
|
||||||
SR.getPlugin(),
|
|
||||||
() -> {
|
|
||||||
int finalI = 0;
|
|
||||||
for (Marker marker : markers) {
|
|
||||||
for (int i = 0; i < marker.getFrames().size(); i++) {
|
|
||||||
int finalI1 = i;
|
|
||||||
Bukkit.getScheduler()
|
|
||||||
.runTaskLater(
|
|
||||||
SR.getPlugin(),
|
|
||||||
() -> {
|
|
||||||
p.teleport(marker.getFrames().get(finalI1).getLocation());
|
|
||||||
marker.getFrames().get(finalI1).play();
|
|
||||||
},
|
|
||||||
(marker.getTimeBetweenFrames() * finalI) / 50);
|
|
||||||
finalI++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (endFadeToBlack) {
|
|
||||||
Bukkit.getScheduler()
|
|
||||||
.runTask(SR.getPlugin(), () -> showBlackScreen(p, 2, 1, 1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Bukkit.getScheduler()
|
|
||||||
.runTaskAsynchronously(
|
|
||||||
SR.getPlugin(),
|
|
||||||
() -> {
|
|
||||||
try {
|
|
||||||
Thread.sleep(time());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
error("Error while playing cutscene: " + e.getMessage());
|
|
||||||
}
|
|
||||||
Bukkit.getScheduler().runTask(SR.getPlugin(), () -> stop(p));
|
|
||||||
});
|
|
||||||
tasks.put(p.getUniqueId(), task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop(UUID player) {
|
|
||||||
Player p = Bukkit.getPlayer(player);
|
|
||||||
if (p == null) return;
|
|
||||||
stop(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop(@NotNull Player p) {
|
|
||||||
if (cutsceneManager.isPlayingCutscene(p)) {
|
|
||||||
if (cutsceneManager.getPlayingCutscene(p).equals(this.id)) {
|
|
||||||
cutsceneManager.removeCurrentPlayingCutscene(this, p);
|
|
||||||
tasks.get(p.getUniqueId()).cancel();
|
|
||||||
p.sendMessage(Component.text("You stopped playing the cutscene!"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p.sendMessage(Component.text("You are not playing a cutscene!"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void calculateMarkers() {
|
|
||||||
if (markers.isEmpty()) 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,168 +1,138 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.sacredrealms.sr.utils.Items.cancelItem;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import me.unurled.sacredrealms.sr.SR;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.tasks.TickTracker;
|
||||||
import me.unurled.srcore.api.Manager;
|
import me.unurled.srcore.api.Manager;
|
||||||
import org.bukkit.Bukkit;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class CutsceneManager extends Manager {
|
public class CutsceneManager extends Manager {
|
||||||
// TODO: spectator to hide toolbar (make it ride an invisible entity to prevent movement)
|
|
||||||
// TODO: save modifications if any
|
private static final TextComponent ALREADY_STARTED =
|
||||||
// TODO: do you set player back to original position ?
|
textComp("<red>You are already creating a cutscene.");
|
||||||
// TODO: make a system to easily create cutscenesw
|
|
||||||
|
|
||||||
private List<Cutscene> cutscenes;
|
private List<Cutscene> cutscenes;
|
||||||
|
private Map<UUID, Cutscene> cutsceneBeingCreated;
|
||||||
|
private Map<UUID, PlayerInventory> savedInventories;
|
||||||
|
|
||||||
// cutscene id, player uuid
|
|
||||||
private Map<String, UUID> currentPlayingCutscenes;
|
|
||||||
|
|
||||||
private Map<UUID, PlayerOrigin> playerOrigins;
|
|
||||||
|
|
||||||
private List<String> cutsceneIds;
|
|
||||||
|
|
||||||
/** Load the manager */
|
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
super.load();
|
super.load();
|
||||||
|
SR.getPlugin()
|
||||||
|
.getServer()
|
||||||
|
.getPluginManager()
|
||||||
|
.registerEvents(new CreationListener(), SR.getPlugin());
|
||||||
|
TickTracker.startTracking();
|
||||||
cutscenes = new ArrayList<>();
|
cutscenes = new ArrayList<>();
|
||||||
currentPlayingCutscenes = new HashMap<>();
|
cutsceneBeingCreated = new HashMap<>();
|
||||||
playerOrigins = new HashMap<>();
|
savedInventories = new HashMap<>();
|
||||||
cutsceneIds = new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Unload the manager */
|
|
||||||
@Override
|
@Override
|
||||||
public void unload() {
|
public void unload() {
|
||||||
super.unload();
|
super.unload();
|
||||||
cutscenes.clear();
|
cutscenes.clear();
|
||||||
currentPlayingCutscenes.clear();
|
cutsceneBeingCreated.clear();
|
||||||
playerOrigins.clear();
|
savedInventories.clear();
|
||||||
cutsceneIds.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createCutscene(String id) {
|
@Nullable
|
||||||
Cutscene cutscene = new Cutscene(id, id);
|
public Cutscene getCutsceneBeingCreated(@NotNull UUID uuid) {
|
||||||
addCutscene(cutscene);
|
return cutsceneBeingCreated.get(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeCutscene(String id) {
|
public void startCreatingCutscene(@NotNull Player p, String name) {
|
||||||
Cutscene cutscene = getCutscene(id);
|
if (cutsceneBeingCreated.containsKey(p.getUniqueId())) {
|
||||||
removeCutscene(cutscene);
|
p.sendMessage(ALREADY_STARTED);
|
||||||
}
|
|
||||||
|
|
||||||
public void addCutscene(Cutscene cutscene) {
|
|
||||||
cutscenes.add(cutscene);
|
|
||||||
cutsceneIds.add(cutscene.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeCutscene(Cutscene cutscene) {
|
|
||||||
cutscenes.remove(cutscene);
|
|
||||||
cutsceneIds.remove(cutscene.getId().toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addCurrentPlayingCutscene(@NotNull Cutscene cutscene, @NotNull Player p) {
|
|
||||||
currentPlayingCutscenes.put(cutscene.getId(), p.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeCurrentPlayingCutscene(@NotNull Cutscene cutscene, @NotNull Player p) {
|
|
||||||
currentPlayingCutscenes.remove(cutscene.getId(), p.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getCutscenesId() {
|
|
||||||
return cutsceneIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopCutscene(Player p) {
|
|
||||||
for (String string : currentPlayingCutscenes.keySet()) {
|
|
||||||
if (currentPlayingCutscenes.get(string).equals(p.getUniqueId())) {
|
|
||||||
currentPlayingCutscenes.remove(string, p.getUniqueId());
|
|
||||||
Cutscene cutscene = getCutscene(string);
|
|
||||||
if (cutscene != null) {
|
|
||||||
cutscene.stop(p);
|
|
||||||
PlayerOrigin.restore(playerOrigins.get(p.getUniqueId()), p);
|
|
||||||
playerOrigins.remove(p.getUniqueId());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopCutscenesForAllPlayers() {
|
|
||||||
for (String string : currentPlayingCutscenes.keySet()) {
|
|
||||||
Cutscene cutscene = getCutscene(string);
|
|
||||||
if (cutscene != null) {
|
|
||||||
UUID uuid = currentPlayingCutscenes.get(string);
|
|
||||||
cutscene.stop(uuid);
|
|
||||||
currentPlayingCutscenes.remove(cutscene.getId(), uuid);
|
|
||||||
Player player = Bukkit.getPlayer(uuid);
|
|
||||||
if (player == null) return;
|
|
||||||
PlayerOrigin.restore(playerOrigins.get(uuid), player);
|
|
||||||
playerOrigins.remove(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playCutscene(Cutscene cutscene, Player p) {
|
|
||||||
if (cutscene == null) {
|
|
||||||
p.sendMessage(textComp("<red>There was an error with the cutscene!"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cutscenes.contains(cutscene) && !currentPlayingCutscenes.containsValue(p.getUniqueId())) {
|
cutsceneBeingCreated.put(p.getUniqueId(), new Cutscene(name));
|
||||||
currentPlayingCutscenes.put(cutscene.getId(), p.getUniqueId());
|
|
||||||
setPlayerOrigins(p);
|
// process to create cutscene
|
||||||
cutscene.play(p);
|
savedInventories.put(p.getUniqueId(), p.getInventory());
|
||||||
|
p.getInventory().clear();
|
||||||
|
p.sendMessage(
|
||||||
|
textComp("<green>You are now creating a cutscene. Place the <gold>corner blocks</gold>."));
|
||||||
|
ItemStack cancel = cancelItem();
|
||||||
|
ItemStack finish = new ItemStack(Material.EMERALD_BLOCK);
|
||||||
|
ItemMeta meta = finish.getItemMeta();
|
||||||
|
meta.displayName(textComp("<b><green>Finish</green></b>"));
|
||||||
|
finish.setItemMeta(meta);
|
||||||
|
|
||||||
|
ItemStack pos1 = new ItemStack(Material.RED_WOOL);
|
||||||
|
meta = pos1.getItemMeta();
|
||||||
|
meta.displayName(textComp("<b><red>Pos1</red></b>"));
|
||||||
|
pos1.setItemMeta(meta);
|
||||||
|
|
||||||
|
ItemStack pos2 = new ItemStack(Material.BLUE_WOOL);
|
||||||
|
meta = pos2.getItemMeta();
|
||||||
|
meta.displayName(textComp("<b><blue>Pos2</blue></b>"));
|
||||||
|
pos2.setItemMeta(meta);
|
||||||
|
|
||||||
|
p.getInventory().setItem(8, cancel);
|
||||||
|
p.getInventory().setItem(0, finish);
|
||||||
|
p.getInventory().setItem(3, pos1);
|
||||||
|
p.getInventory().setItem(5, pos2);
|
||||||
|
|
||||||
|
p.updateInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishCreatingCutscene(@NotNull Player p) {
|
||||||
|
if (!cutsceneBeingCreated.containsKey(p.getUniqueId())) {
|
||||||
|
p.sendMessage(textComp("<red>You are not creating a cutscene."));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
Cutscene cutscene = cutsceneBeingCreated.get(p.getUniqueId());
|
||||||
|
|
||||||
|
cutscenes.add(cutscene);
|
||||||
|
p.getInventory().clear();
|
||||||
|
p.sendMessage(textComp("<green>Cutscene created."));
|
||||||
|
cutsceneBeingCreated.remove(p.getUniqueId());
|
||||||
|
PlayerInventory inv = savedInventories.get(p.getUniqueId());
|
||||||
|
for (int i = 0; i < inv.getSize(); i++) {
|
||||||
|
p.getInventory().setItem(i, inv.getItem(i));
|
||||||
|
}
|
||||||
|
p.updateInventory();
|
||||||
|
savedInventories.remove(p.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelCreatingCutscene(@NotNull Player p) {
|
||||||
|
if (!cutsceneBeingCreated.containsKey(p.getUniqueId())) {
|
||||||
|
p.sendMessage(textComp("<red>You are not creating a cutscene."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.getInventory().clear();
|
||||||
|
p.sendMessage(textComp("<green>Canceled creating cutscene."));
|
||||||
|
cutsceneBeingCreated.remove(p.getUniqueId());
|
||||||
|
PlayerInventory inv = savedInventories.get(p.getUniqueId());
|
||||||
|
for (int i = 0; i < inv.getSize(); i++) {
|
||||||
|
p.getInventory().setItem(i, inv.getItem(i));
|
||||||
|
}
|
||||||
|
p.updateInventory();
|
||||||
|
savedInventories.remove(p.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Cutscene> cutscenes() {
|
||||||
|
return cutscenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Cutscene getCutscene(Player p) {
|
public Cutscene findByUUID(UUID uuid) {
|
||||||
for (Entry<String, UUID> entry : currentPlayingCutscenes.entrySet()) {
|
return cutscenes.stream().filter(c -> c.id().equals(uuid)).findFirst().orElse(null);
|
||||||
if (entry.getValue().equals(p.getUniqueId())) return getCutscene(entry.getKey());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Cutscene getCutscene(@NotNull String id) {
|
|
||||||
if (!cutsceneIds.contains(id.toUpperCase())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (Cutscene cutscene : cutscenes) {
|
|
||||||
if (cutscene.getId().equalsIgnoreCase(id.toUpperCase())) return cutscene;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPlayingCutscene(@NotNull Player p) {
|
|
||||||
return currentPlayingCutscenes.containsValue(p.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getPlayingCutscene(@NotNull Player p) {
|
|
||||||
for (Entry<String, UUID> entry : currentPlayingCutscenes.entrySet()) {
|
|
||||||
if (entry.getValue().equals(p.getUniqueId())) return entry.getKey();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayerOrigins(@NotNull Player p) {
|
|
||||||
playerOrigins.put(
|
|
||||||
p.getUniqueId(),
|
|
||||||
new PlayerOrigin(
|
|
||||||
p.getLocation(),
|
|
||||||
p.getAllowFlight(),
|
|
||||||
p.isFlying(),
|
|
||||||
p.getWalkSpeed(),
|
|
||||||
p.getFlySpeed(),
|
|
||||||
p.getGameMode()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class EntityCinematicAction {
|
|
||||||
private Player p;
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import java.util.Map;
|
|
||||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frame class
|
|
||||||
*
|
|
||||||
* <p>example of serializable frame:
|
|
||||||
*
|
|
||||||
* <pre>{@code
|
|
||||||
* {
|
|
||||||
* "id": 1,
|
|
||||||
* "entities": "entities serializable",
|
|
||||||
* "blocks": "blocks serializable",
|
|
||||||
* "action": "action", // if type is entity
|
|
||||||
* "location": {
|
|
||||||
* "world": "world",
|
|
||||||
* "x": 0,
|
|
||||||
* "y": 0,
|
|
||||||
* "z": 0,
|
|
||||||
* "yaw": 0,
|
|
||||||
* "pitch": 0
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }</pre>
|
|
||||||
*/
|
|
||||||
public class Frame {
|
|
||||||
private static int idCounter = 0;
|
|
||||||
private final Location location;
|
|
||||||
private final int id;
|
|
||||||
@Nullable private Map<Location, BlockData> blocks;
|
|
||||||
|
|
||||||
public Frame(Location location) {
|
|
||||||
this.location = location;
|
|
||||||
id = idCounter;
|
|
||||||
idCounter++;
|
|
||||||
blocks = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Frame(Location location, int ID) {
|
|
||||||
this.location = location;
|
|
||||||
this.id = ID;
|
|
||||||
blocks = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract("_ -> new")
|
|
||||||
public static @NotNull Frame deserialize(@NotNull JsonElement jsonElement) {
|
|
||||||
int id = jsonElement.getAsJsonObject().get("id").getAsInt();
|
|
||||||
Location loc = null;
|
|
||||||
try {
|
|
||||||
LocationSerializer locationDeserializer = new LocationSerializer();
|
|
||||||
loc =
|
|
||||||
locationDeserializer.deserialize(
|
|
||||||
jsonElement.getAsJsonObject().get("location"), Location.class, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
error("Error deserializing location in Frame with ID: " + id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Frame frame = new Frame(loc, id);
|
|
||||||
|
|
||||||
try {
|
|
||||||
frame.setBlocks((Map<Location, BlockData>) jsonElement.getAsJsonObject().get("blocks"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
error("Error deserializing blocks in Frame with ID: " + id);
|
|
||||||
}
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Play the frame aka move stuff around :shrug: */
|
|
||||||
public void play() {}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable Map<Location, BlockData> getBlocks() {
|
|
||||||
return blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBlocks(@Nullable Map<Location, BlockData> blocks) {
|
|
||||||
this.blocks = blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonElement serialize() {
|
|
||||||
String s =
|
|
||||||
"{"
|
|
||||||
+ "\"id\":"
|
|
||||||
+ id
|
|
||||||
+ ","
|
|
||||||
+ ","
|
|
||||||
+ "\"blocks\":"
|
|
||||||
+ blocks
|
|
||||||
+ ","
|
|
||||||
+ "\"location\":"
|
|
||||||
+ location.serialize()
|
|
||||||
+ "}";
|
|
||||||
return new JsonPrimitive(s);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,146 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.CutsceneUtil.interpolateFrames;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marker class
|
|
||||||
*
|
|
||||||
* <pre>{@code
|
|
||||||
* {
|
|
||||||
* "id": 1,
|
|
||||||
* "frames": [ 1, 2, 3 ], // Frame IDs
|
|
||||||
* "timeBetweenFrames": 20,
|
|
||||||
* "overAllTime": 60,
|
|
||||||
* "start": {
|
|
||||||
* "world": "world",
|
|
||||||
* "x": 0,
|
|
||||||
* "y": 0,
|
|
||||||
* "z": 0,
|
|
||||||
* "yaw": 0,
|
|
||||||
* "pitch": 0
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }</pre>
|
|
||||||
*/
|
|
||||||
public class Marker {
|
|
||||||
|
|
||||||
private static int idCounter = 0;
|
|
||||||
private static List<Marker> markers = new ArrayList<>();
|
|
||||||
private final int id;
|
|
||||||
private List<Frame> frames;
|
|
||||||
private Long timeBetweenFrames;
|
|
||||||
private Long overAllTime;
|
|
||||||
private Location start;
|
|
||||||
|
|
||||||
public Marker(Integer id) {
|
|
||||||
frames = new ArrayList<>();
|
|
||||||
timeBetweenFrames = 0L;
|
|
||||||
overAllTime = 0L;
|
|
||||||
if (id == null) {
|
|
||||||
this.id = idCounter;
|
|
||||||
idCounter++;
|
|
||||||
} else {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Marker(@NotNull List<Frame> frames, long timeBetweenFrames, Location start) {
|
|
||||||
this.frames = frames;
|
|
||||||
this.timeBetweenFrames = timeBetweenFrames;
|
|
||||||
this.overAllTime = timeBetweenFrames * frames.size();
|
|
||||||
this.start = start;
|
|
||||||
id = idCounter;
|
|
||||||
idCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Marker> getMarkers() {
|
|
||||||
return markers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setMarkers(List<Marker> markers) {
|
|
||||||
Marker.markers = markers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @Nullable Marker getMarker(int ID) {
|
|
||||||
for (Marker marker : markers) {
|
|
||||||
if (marker.getId() == ID) {
|
|
||||||
return marker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Frame> getFrames() {
|
|
||||||
return frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFrames(List<Frame> frames) {
|
|
||||||
this.frames = frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getTimeBetweenFrames() {
|
|
||||||
return timeBetweenFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimeBetweenFrames(Long timeBetweenFrames) {
|
|
||||||
this.timeBetweenFrames = timeBetweenFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getOverAllTime() {
|
|
||||||
return overAllTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOverAllTime(Long overAllTime) {
|
|
||||||
this.overAllTime = overAllTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStart(Location start) {
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void calculateFrames(Marker endMarker) {
|
|
||||||
frames = interpolateFrames(this, endMarker, timeBetweenFrames);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFrame(Frame frame) {
|
|
||||||
frames.add(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeFrame(Frame frame) {
|
|
||||||
frames.remove(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeFrame(int index) {
|
|
||||||
frames.remove(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Marker{"
|
|
||||||
+ "ID="
|
|
||||||
+ id
|
|
||||||
+ ", frames="
|
|
||||||
+ frames
|
|
||||||
+ ", timeBetweenFrames="
|
|
||||||
+ timeBetweenFrames
|
|
||||||
+ ", overAllTime="
|
|
||||||
+ overAllTime
|
|
||||||
+ ", start="
|
|
||||||
+ start
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
|
||||||
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public record PlayerOrigin(
|
|
||||||
Location location,
|
|
||||||
boolean allowFlight,
|
|
||||||
boolean flying,
|
|
||||||
float walkSpeed,
|
|
||||||
float flySpeed,
|
|
||||||
GameMode gameMode) {
|
|
||||||
public static void restore(@NotNull PlayerOrigin origin, @NotNull Player p) {
|
|
||||||
p.teleport(origin.location());
|
|
||||||
p.setAllowFlight(origin.allowFlight());
|
|
||||||
p.setFlying(origin.flying());
|
|
||||||
p.setWalkSpeed(origin.walkSpeed());
|
|
||||||
p.setFlySpeed(origin.flySpeed());
|
|
||||||
p.setGameMode(origin.gameMode());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
|
||||||
import io.papermc.paper.event.player.PlayerArmSwingEvent;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.npc.ArmSwing;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.npc.EntityFrame;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.entity.Pose;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class PlayerRecording {
|
|
||||||
private final Player player;
|
|
||||||
private final EntityFrame entityFrame;
|
|
||||||
private ArmSwing swing;
|
|
||||||
|
|
||||||
public PlayerRecording(Player player, EntityFrame entityFrame) {
|
|
||||||
this.player = player;
|
|
||||||
this.entityFrame = entityFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static EntityPose toEntityPose(Pose pose) {
|
|
||||||
return pose == Pose.SNEAKING ? EntityPose.SITTING : EntityPose.valueOf(pose.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pose toBukkitPose(EntityPose pose) {
|
|
||||||
return pose == EntityPose.SITTING ? Pose.SNEAKING : Pose.valueOf(pose.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onArmSwing(@NotNull PlayerArmSwingEvent e) {
|
|
||||||
if (e.getPlayer().getUniqueId() != player.getUniqueId()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addSwing(
|
|
||||||
e.getHand() == EquipmentSlot.HAND
|
|
||||||
? ArmSwing.RIGHT
|
|
||||||
: (e.getHand() == EquipmentSlot.OFF_HAND ? ArmSwing.LEFT : ArmSwing.BOTH));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addSwing(ArmSwing swing) {
|
|
||||||
if (this.swing != null && this.swing != swing) {
|
|
||||||
this.swing = ArmSwing.BOTH;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.swing = swing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityFrame captureFrame() {
|
|
||||||
PlayerInventory inv = player.getInventory();
|
|
||||||
Pose pose = player.isInsideVehicle() ? Pose.SITTING : player.getPose();
|
|
||||||
EntityFrame data =
|
|
||||||
new EntityFrame(
|
|
||||||
player.getLocation(),
|
|
||||||
toEntityPose(pose),
|
|
||||||
swing,
|
|
||||||
inv.getItemInMainHand().isEmpty() ? null : inv.getItemInMainHand(),
|
|
||||||
inv.getItemInOffHand().isEmpty() ? null : inv.getItemInOffHand(),
|
|
||||||
inv.getHelmet(),
|
|
||||||
inv.getChestplate(),
|
|
||||||
inv.getLeggings(),
|
|
||||||
inv.getBoots());
|
|
||||||
swing = null;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyState(@NotNull EntityFrame value) {
|
|
||||||
player.teleport(value.location());
|
|
||||||
player.setPose(toBukkitPose(value.pose()));
|
|
||||||
PlayerInventory inv = player.getInventory();
|
|
||||||
inv.setItemInMainHand(value.mainHand());
|
|
||||||
inv.setItemInOffHand(value.offHand());
|
|
||||||
inv.setHelmet(value.helmet());
|
|
||||||
inv.setChestplate(value.chestplate());
|
|
||||||
inv.setLeggings(value.leggings());
|
|
||||||
inv.setBoots(value.boots());
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.tasks.TickTracker;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class RecordingManager extends Manager {
|
||||||
|
private List<Recording> recordings; // existing recordings
|
||||||
|
private List<Recording> activeRecordings; // currently recording
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load() {
|
||||||
|
super.load();
|
||||||
|
recordings = new ArrayList<>();
|
||||||
|
activeRecordings = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unload() {
|
||||||
|
super.unload();
|
||||||
|
recordings.clear();
|
||||||
|
activeRecordings.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Recording getPlayerActiveRecording(Player player) {
|
||||||
|
return activeRecordings.stream()
|
||||||
|
.filter(r -> r.recordingPlayer().equals(player))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startRecording(Cutscene cutscene, Player player) {
|
||||||
|
Recording recording = new Recording(cutscene, player);
|
||||||
|
player.sendMessage(textComp("<green>Recording started."));
|
||||||
|
activeRecordings.add(recording);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopRecording(Player player) {
|
||||||
|
Recording recording = getPlayerActiveRecording(player);
|
||||||
|
if (recording == null) {
|
||||||
|
player.sendMessage(textComp("<red>You are not recording a cutscene."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
activeRecordings.remove(recording);
|
||||||
|
recording.stopRecording();
|
||||||
|
recordings.add(recording);
|
||||||
|
player.sendMessage(textComp("<green>Recording stopped."));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRecordable(@NotNull Recording recording, @NotNull Recordable recordable) {
|
||||||
|
long tick = TickTracker.currentTick();
|
||||||
|
|
||||||
|
// normalize tick
|
||||||
|
tick = tick - recording.startTick();
|
||||||
|
|
||||||
|
recordable.setTick(tick);
|
||||||
|
|
||||||
|
if (recording.recordables().containsKey(tick)) {
|
||||||
|
recording.recordables().get(tick).add(recordable);
|
||||||
|
} else {
|
||||||
|
List<Recordable> recordables = new ArrayList<>();
|
||||||
|
recordables.add(recordable);
|
||||||
|
recording.recordables().put(tick, recordables);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||||
|
|
||||||
|
import me.unurled.sacredrealms.sr.SR;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.tasks.ReplayTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class Replay {
|
||||||
|
private final Player viewer;
|
||||||
|
private final Recording recording;
|
||||||
|
private final BukkitTask replayTask;
|
||||||
|
|
||||||
|
public Replay(Recording recording, @NotNull Player viewer) {
|
||||||
|
this.recording = recording;
|
||||||
|
this.viewer = viewer;
|
||||||
|
|
||||||
|
viewer.getInventory().clear();
|
||||||
|
// TODO: control cutscene replay
|
||||||
|
|
||||||
|
replayTask =
|
||||||
|
Bukkit.getScheduler()
|
||||||
|
.runTaskTimerAsynchronously(SR.getPlugin(), new ReplayTask(this), 0L, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player viewer() {
|
||||||
|
return viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recording recording() {
|
||||||
|
return recording;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitTask replayTask() {
|
||||||
|
return replayTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endReplay() {
|
||||||
|
if (replayTask != null) {
|
||||||
|
replayTask.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class ReplayManager extends Manager {
|
||||||
|
|
||||||
|
private Set<Replay> replays;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load() {
|
||||||
|
super.load();
|
||||||
|
replays = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unload() {
|
||||||
|
super.unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Replay getReplayForPlayer(Player player) {
|
||||||
|
return replays.stream()
|
||||||
|
.filter(replay -> replay.viewer().equals(player))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void replayRecording(Recording recording, Player player) {
|
||||||
|
if (getReplayForPlayer(player) != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Replay replay = new Replay(recording, player);
|
||||||
|
replays.add(replay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopReplay(@NotNull Replay replay) {
|
||||||
|
// stop replay taskk
|
||||||
|
replay.endReplay();
|
||||||
|
|
||||||
|
replays.remove(replay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Replay> replays() {
|
||||||
|
return replays;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene.gson;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.Action;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class ActionGson {
|
|
||||||
public class Deserializer implements JsonDeserializer<Action> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
|
||||||
* specified type.
|
|
||||||
*
|
|
||||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
|
||||||
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
|
||||||
* non-trivial field of the returned object. However, you should never invoke it on the same
|
|
||||||
* type passing {@code json} since that will cause an infinite loop (Gson will call your
|
|
||||||
* call-back method again).
|
|
||||||
*
|
|
||||||
* @param json The Json data being deserialized
|
|
||||||
* @param typeOfT The type of the Object to deserialize to
|
|
||||||
* @param context
|
|
||||||
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
|
||||||
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Action deserialize(
|
|
||||||
@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
|
||||||
throws JsonParseException {
|
|
||||||
return Action.valueOf(json.getAsString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Serializer implements JsonSerializer<Action> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gson invokes this call-back method during serialization when it encounters a field of the
|
|
||||||
* specified type.
|
|
||||||
*
|
|
||||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
|
||||||
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
|
||||||
* non-trivial field of the {@code src} object. However, you should never invoke it on the
|
|
||||||
* {@code src} object itself since that will cause an infinite loop (Gson will call your
|
|
||||||
* call-back method again).
|
|
||||||
*
|
|
||||||
* @param src the object that needs to be converted to Json.
|
|
||||||
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
|
||||||
* @param context
|
|
||||||
* @return a JsonElement corresponding to the specified object.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(Action src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
return new JsonPrimitive(src.name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene.gson;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Map;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.Action;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
|
|
||||||
public class EntityActionGson {
|
|
||||||
public class Deserializer implements JsonDeserializer<Map<Entity, Action>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
|
||||||
* specified type.
|
|
||||||
*
|
|
||||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
|
||||||
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
|
||||||
* non-trivial field of the returned object. However, you should never invoke it on the same
|
|
||||||
* type passing {@code json} since that will cause an infinite loop (Gson will call your
|
|
||||||
* call-back method again).
|
|
||||||
*
|
|
||||||
* @param json The Json data being deserialized
|
|
||||||
* @param typeOfT The type of the Object to deserialize to
|
|
||||||
* @param context
|
|
||||||
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
|
||||||
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<Entity, Action> deserialize(
|
|
||||||
JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
|
||||||
throws JsonParseException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Serializer implements JsonSerializer<Map<Entity, Action>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gson invokes this call-back method during serialization when it encounters a field of the
|
|
||||||
* specified type.
|
|
||||||
*
|
|
||||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
|
||||||
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
|
||||||
* non-trivial field of the {@code src} object. However, you should never invoke it on the
|
|
||||||
* {@code src} object itself since that will cause an infinite loop (Gson will call your
|
|
||||||
* call-back method again).
|
|
||||||
*
|
|
||||||
* @param src the object that needs to be converted to Json.
|
|
||||||
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
|
||||||
* @param context
|
|
||||||
* @return a JsonElement corresponding to the specified object.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(
|
|
||||||
Map<Entity, Action> src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene.npc;
|
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.components.packet.PacketManager.sendPacketTo;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation.EntityAnimationType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public enum ArmSwing {
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
BOTH;
|
|
||||||
|
|
||||||
public static void swingArm(@NotNull ArmSwing arm, Player p, int entityId) {
|
|
||||||
// Swing the arm
|
|
||||||
if (arm.isLeft()) {
|
|
||||||
sendPacketTo(
|
|
||||||
new WrapperPlayServerEntityAnimation(entityId, EntityAnimationType.SWING_OFF_HAND), p);
|
|
||||||
}
|
|
||||||
if (arm.isRight()) {
|
|
||||||
sendPacketTo(
|
|
||||||
new WrapperPlayServerEntityAnimation(entityId, EntityAnimationType.SWING_MAIN_ARM), p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
public @NotNull Boolean isLeft() {
|
|
||||||
return this == LEFT || this == BOTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract(pure = true)
|
|
||||||
public @NotNull Boolean isRight() {
|
|
||||||
return this == RIGHT || this == BOTH;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.components.cutscene.npc;
|
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import me.unurled.sacredrealms.sr.utils.Items;
|
|
||||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public record EntityFrame(
|
|
||||||
Location location,
|
|
||||||
EntityPose pose,
|
|
||||||
ArmSwing swing,
|
|
||||||
ItemStack mainHand,
|
|
||||||
ItemStack offHand,
|
|
||||||
ItemStack helmet,
|
|
||||||
ItemStack chestplate,
|
|
||||||
ItemStack leggings,
|
|
||||||
ItemStack boots) {
|
|
||||||
|
|
||||||
public static @NotNull EntityFrame deserialize(@NotNull JsonElement jsonElement) {
|
|
||||||
Location location =
|
|
||||||
new LocationSerializer()
|
|
||||||
.deserialize(jsonElement.getAsJsonObject().get("location"), Location.class, null);
|
|
||||||
EntityPose pose = EntityPose.valueOf(jsonElement.getAsJsonObject().get("pose").getAsString());
|
|
||||||
ArmSwing swing = ArmSwing.valueOf(jsonElement.getAsJsonObject().get("swing").getAsString());
|
|
||||||
ItemStack mainHand = Items.deserialize(jsonElement.getAsJsonObject().get("mainHand"));
|
|
||||||
ItemStack offHand = Items.deserialize(jsonElement.getAsJsonObject().get("offHand"));
|
|
||||||
ItemStack helmet = Items.deserialize(jsonElement.getAsJsonObject().get("helmet"));
|
|
||||||
ItemStack chestplate = Items.deserialize(jsonElement.getAsJsonObject().get("chestplate"));
|
|
||||||
ItemStack leggings = Items.deserialize(jsonElement.getAsJsonObject().get("leggings"));
|
|
||||||
ItemStack boots = Items.deserialize(jsonElement.getAsJsonObject().get("boots"));
|
|
||||||
return new EntityFrame(
|
|
||||||
location, pose, swing, mainHand, offHand, helmet, chestplate, leggings, boots);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull JsonElement serialize() {
|
|
||||||
String s =
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"location": %s,
|
|
||||||
"pose": %s,
|
|
||||||
"swing": %s,
|
|
||||||
"mainHand": %s,
|
|
||||||
"offHand": %s,
|
|
||||||
"helmet": %s,
|
|
||||||
"chestplate": %s,
|
|
||||||
"leggings": %s,
|
|
||||||
"boots": %s
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
.formatted(
|
|
||||||
location.serialize(),
|
|
||||||
pose.name(),
|
|
||||||
swing.name(),
|
|
||||||
mainHand.serialize(),
|
|
||||||
offHand.serialize(),
|
|
||||||
helmet.serialize(),
|
|
||||||
chestplate.serialize(),
|
|
||||||
leggings.serialize(),
|
|
||||||
boots.serialize());
|
|
||||||
return new JsonPrimitive(s);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.recording;
|
||||||
|
|
||||||
|
public abstract class Recordable {
|
||||||
|
private long tick;
|
||||||
|
|
||||||
|
public abstract void replay();
|
||||||
|
|
||||||
|
public long tick() {
|
||||||
|
return tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recordable setTick(long tick) {
|
||||||
|
this.tick = tick;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.recording;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import me.unurled.sacredrealms.sr.SR;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.tasks.ScanEntityTracker;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.tasks.TickTracker;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.tasks.TrackLocationTask;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
public class Recording {
|
||||||
|
// recordables
|
||||||
|
private final Map<Long, List<Recordable>> recordables = new HashMap<>();
|
||||||
|
private final Queue<UUID> recordableEntities = new ConcurrentLinkedQueue<>();
|
||||||
|
private final BukkitTask trackLocationTask;
|
||||||
|
private final BukkitTask scanEntitiesTask;
|
||||||
|
private Cutscene cutscene;
|
||||||
|
private Player recordingPlayer;
|
||||||
|
private long startTime;
|
||||||
|
private long endTime;
|
||||||
|
private long startTick;
|
||||||
|
private long endTick;
|
||||||
|
|
||||||
|
public Recording(Cutscene cutscene, Player recordingPlayer) {
|
||||||
|
this.cutscene = cutscene;
|
||||||
|
this.recordingPlayer = recordingPlayer;
|
||||||
|
|
||||||
|
this.startTime = System.currentTimeMillis();
|
||||||
|
this.startTick = 1; // TODO: get tick
|
||||||
|
this.endTick = 1; // TODO: get tick
|
||||||
|
|
||||||
|
this.scanEntitiesTask =
|
||||||
|
Bukkit.getScheduler().runTaskTimer(SR.getPlugin(), new ScanEntityTracker(this), 0L, 20L);
|
||||||
|
this.trackLocationTask =
|
||||||
|
Bukkit.getScheduler().runTaskTimer(SR.getPlugin(), new TrackLocationTask(this), 0L, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Long, List<Recordable>> recordables() {
|
||||||
|
return recordables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cutscene cutscene() {
|
||||||
|
return cutscene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Queue<UUID> recordableEntities() {
|
||||||
|
return recordableEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recording setCutscene(Cutscene cutscene) {
|
||||||
|
this.cutscene = cutscene;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player recordingPlayer() {
|
||||||
|
return recordingPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recording setRecordingPlayer(Player recordingPlayer) {
|
||||||
|
this.recordingPlayer = recordingPlayer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long startTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recording setStartTime(long startTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long endTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recording setEndTime(long endTime) {
|
||||||
|
this.endTime = endTime;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long startTick() {
|
||||||
|
return startTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Recording setStartTick(long startTick) {
|
||||||
|
this.startTick = startTick;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopRecording() {
|
||||||
|
this.endTime = System.currentTimeMillis();
|
||||||
|
this.endTick = TickTracker.currentTick();
|
||||||
|
scanEntitiesTask.cancel();
|
||||||
|
trackLocationTask.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long tickDuration() {
|
||||||
|
return endTick - startTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEntityBeingTracked(UUID uuid) {
|
||||||
|
synchronized (recordableEntities) {
|
||||||
|
return recordableEntities.contains(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addEntityIfNotBeingTracked(UUID uuid) {
|
||||||
|
synchronized (recordableEntities) {
|
||||||
|
if (recordableEntities.contains(uuid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
recordableEntities.add(uuid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.recording.recordables;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||||
|
|
||||||
|
public class DespawnEntityRecordable extends Recordable {
|
||||||
|
|
||||||
|
private UUID entityId;
|
||||||
|
|
||||||
|
public DespawnEntityRecordable() {}
|
||||||
|
|
||||||
|
public DespawnEntityRecordable(UUID entityId) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replay() {
|
||||||
|
// TODO: fake spawn entity
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID entityId() {
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DespawnEntityRecordable setEntityId(UUID entityId) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.recording.recordables;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
public class LocationChangeRecordable extends Recordable {
|
||||||
|
|
||||||
|
private UUID entityId;
|
||||||
|
private Location location;
|
||||||
|
|
||||||
|
public LocationChangeRecordable() {}
|
||||||
|
|
||||||
|
public LocationChangeRecordable(UUID entityId, Location location) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replay() {}
|
||||||
|
|
||||||
|
public UUID entityId() {
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationChangeRecordable setEntityId(UUID entityId) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location location() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationChangeRecordable setLocation(Location location) {
|
||||||
|
this.location = location;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.recording.recordables;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class SpawnEntityRecordable extends Recordable {
|
||||||
|
|
||||||
|
private EntityType entityType;
|
||||||
|
private Location location;
|
||||||
|
private UUID entityId;
|
||||||
|
private Component name;
|
||||||
|
|
||||||
|
public SpawnEntityRecordable() {}
|
||||||
|
|
||||||
|
public SpawnEntityRecordable(@NotNull Entity e) {
|
||||||
|
this.entityType = e.getType();
|
||||||
|
this.location = e.getLocation();
|
||||||
|
this.entityId = e.getUniqueId();
|
||||||
|
this.name = e.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpawnEntityRecordable(
|
||||||
|
EntityType entityType, Location location, UUID entityId, Component name) {
|
||||||
|
this.entityType = entityType;
|
||||||
|
this.location = location;
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replay() {
|
||||||
|
// TODO: fake spawn entity
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityType entityType() {
|
||||||
|
return entityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpawnEntityRecordable setEntityType(EntityType entityType) {
|
||||||
|
this.entityType = entityType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location location() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpawnEntityRecordable setLocation(Location location) {
|
||||||
|
this.location = location;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID entityId() {
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpawnEntityRecordable setEntityId(UUID entityId) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Component name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpawnEntityRecordable setName(Component name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.tasks;
|
||||||
|
|
||||||
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.ReplayManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recordable;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
|
||||||
|
public class ReplayTask implements Runnable {
|
||||||
|
|
||||||
|
private final Replay replay;
|
||||||
|
private final ReplayManager rm;
|
||||||
|
private long currentTick = 0;
|
||||||
|
|
||||||
|
public ReplayTask(Replay replay) {
|
||||||
|
this.replay = replay;
|
||||||
|
rm = Manager.getInstance(ReplayManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
if (currentTick >= replay.recording().tickDuration()) {
|
||||||
|
replay.viewer().sendMessage(textComp("<yellow>Replay has ended."));
|
||||||
|
rm.stopReplay(replay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get all recordables for current tick
|
||||||
|
var recordables = replay.recording().recordables().get(currentTick);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (recordables == null) {
|
||||||
|
currentTick++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Recordable r : recordables) {
|
||||||
|
// figure out how to replay a recordable
|
||||||
|
r.replay();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
error("Tick: " + currentTick);
|
||||||
|
error(e.getMessage());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
currentTick++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.tasks;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.recordables.SpawnEntityRecordable;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
public class ScanEntityTracker implements Runnable {
|
||||||
|
|
||||||
|
private final Recording recording;
|
||||||
|
|
||||||
|
public ScanEntityTracker(Recording recording) {
|
||||||
|
this.recording = recording;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Cutscene cutscene = recording.cutscene();
|
||||||
|
Location pos1 = cutscene.pos1();
|
||||||
|
Location pos2 = cutscene.pos2();
|
||||||
|
int chunkZ = pos1.getBlockZ() >> 4;
|
||||||
|
int chunkX = pos1.getBlockX() >> 4;
|
||||||
|
int chunkX2 = pos2.getBlockX() >> 4;
|
||||||
|
int chunkZ2 = pos2.getBlockZ() >> 4;
|
||||||
|
|
||||||
|
var loadedChunks = pos1.getWorld().getLoadedChunks();
|
||||||
|
List<Chunk> chunksInRegion = new ArrayList<>();
|
||||||
|
for (Chunk chunk : loadedChunks) {
|
||||||
|
if (chunk.getX() >= chunkX
|
||||||
|
&& chunk.getX() <= chunkX2
|
||||||
|
&& chunk.getZ() >= chunkZ
|
||||||
|
&& chunk.getZ() <= chunkZ2) {
|
||||||
|
chunksInRegion.add(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Chunk chunk : chunksInRegion) {
|
||||||
|
var entities = chunk.getEntities();
|
||||||
|
for (var entity : entities) {
|
||||||
|
if (!cutscene.isInRegion(entity.getLocation())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recording.addEntityIfNotBeingTracked(entity.getUniqueId())) {
|
||||||
|
// TODO: spawn entity
|
||||||
|
SpawnEntityRecordable recordable = new SpawnEntityRecordable(entity);
|
||||||
|
Manager.getInstance(RecordingManager.class).addRecordable(recording, recordable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.tasks;
|
||||||
|
|
||||||
|
import me.unurled.sacredrealms.sr.SR;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
public class TickTracker {
|
||||||
|
private static long currentTick = 0;
|
||||||
|
|
||||||
|
public static void startTracking() {
|
||||||
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(SR.getPlugin(), () -> currentTick++, 0L, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long currentTick() {
|
||||||
|
return currentTick;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.cutscene.tasks;
|
||||||
|
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.Recording;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.recordables.DespawnEntityRecordable;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.recording.recordables.LocationChangeRecordable;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
public class TrackLocationTask implements Runnable {
|
||||||
|
|
||||||
|
private final Recording recording;
|
||||||
|
|
||||||
|
public TrackLocationTask(Recording recording) {
|
||||||
|
this.recording = recording;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
var recordebaleEntities = recording.recordableEntities();
|
||||||
|
synchronized (recordebaleEntities) {
|
||||||
|
recordebaleEntities.forEach(
|
||||||
|
uuid -> {
|
||||||
|
Entity entity = Bukkit.getEntity(uuid);
|
||||||
|
if (entity == null) {
|
||||||
|
recording.recordableEntities().remove(uuid);
|
||||||
|
DespawnEntityRecordable recordable = new DespawnEntityRecordable(uuid);
|
||||||
|
Manager.getInstance(RecordingManager.class).addRecordable(recording, recordable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!recording.cutscene().isInRegion(entity.getLocation())) {
|
||||||
|
recording.recordableEntities().remove(uuid);
|
||||||
|
DespawnEntityRecordable recordable = new DespawnEntityRecordable(uuid);
|
||||||
|
Manager.getInstance(RecordingManager.class).addRecordable(recording, recordable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var recordable =
|
||||||
|
new LocationChangeRecordable(entity.getUniqueId(), entity.getLocation());
|
||||||
|
|
||||||
|
Manager.getInstance(RecordingManager.class).addRecordable(recording, recordable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.difficulty;
|
package me.unurled.sacredrealms.sr.components.difficulty;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.entity;
|
package me.unurled.sacredrealms.sr.components.entity;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.item;
|
package me.unurled.sacredrealms.sr.components.item;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Items.lore;
|
import static me.unurled.sacredrealms.sr.utils.Items.lore;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,9 @@ public class ResourcePackManager extends Manager {
|
||||||
super.saveData();
|
super.saveData();
|
||||||
DataManager dm = Manager.getInstance(DataManager.class);
|
DataManager dm = Manager.getInstance(DataManager.class);
|
||||||
DataHandler dh = dm.getDataHandler();
|
DataHandler dh = dm.getDataHandler();
|
||||||
|
if (hostingProvider.getMinecraftPackURL() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
dh.set("pack.url", hostingProvider.getMinecraftPackURL());
|
dh.set("pack.url", hostingProvider.getMinecraftPackURL());
|
||||||
dh.set("pack.uuid", hostingProvider.getPackUUID().toString());
|
dh.set("pack.uuid", hostingProvider.getPackUUID().toString());
|
||||||
dh.set("pack.sha1", hostingProvider.getPackUUID().toString());
|
dh.set("pack.sha1", hostingProvider.getPackUUID().toString());
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package me.unurled.sacredrealms.sr.components.player;
|
package me.unurled.sacredrealms.sr.components.player;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.updateActionBar;
|
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.updateActionBar;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
|
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
@ -167,7 +167,9 @@ public class PlayerManager extends Manager {
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
error("Failed to send resource pack to player. " + ex.getMessage());
|
error("Failed to send resource pack to player. " + ex.getMessage());
|
||||||
log(rpm.getHostingProvider().getOriginalSHA1());
|
log(rpm.getHostingProvider().getOriginalSHA1());
|
||||||
log(rpm.getHostingProvider().getPackUUID().toString());
|
if (rpm.getHostingProvider().getPackUUID() != null) {
|
||||||
|
log(rpm.getHostingProvider().getPackUUID().toString());
|
||||||
|
}
|
||||||
log(rpm.getHostingProvider().getMinecraftPackURL());
|
log(rpm.getHostingProvider().getMinecraftPackURL());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.treasure;
|
package me.unurled.sacredrealms.sr.components.treasure;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.components.treasure;
|
package me.unurled.sacredrealms.sr.components.treasure;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.events.player;
|
package me.unurled.sacredrealms.sr.events.player;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
|
|
||||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.gui.attributes;
|
package me.unurled.sacredrealms.sr.gui.attributes;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
||||||
|
|
||||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.gui.attributes;
|
package me.unurled.sacredrealms.sr.gui.attributes;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
|
|
||||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.gui.entitytype;
|
package me.unurled.sacredrealms.sr.gui.entitytype;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
|
|
||||||
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package me.unurled.sacredrealms.sr.gui.recordings;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import me.unurled.sacredrealms.sr.SR;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.xenondevs.invui.item.ItemProvider;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||||
|
|
||||||
|
public class CutsceneItem extends AbstractItem {
|
||||||
|
|
||||||
|
private static NamespacedKey ID = null;
|
||||||
|
private final String name;
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
public CutsceneItem(String name, UUID uuid) {
|
||||||
|
this.name = name;
|
||||||
|
this.uuid = uuid;
|
||||||
|
ID = new NamespacedKey(SR.getPlugin(), "cutscene_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemProvider getItemProvider() {
|
||||||
|
ItemStack itemStack = new ItemStack(Material.PAPER);
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
itemMeta.displayName(textComp(name));
|
||||||
|
itemMeta.getPersistentDataContainer().set(ID, PersistentDataType.STRING, uuid.toString());
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
|
||||||
|
return new ItemBuilder(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleClick(
|
||||||
|
@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||||
|
// get uuid
|
||||||
|
if (event.getCurrentItem() != null) {
|
||||||
|
String uuid =
|
||||||
|
event
|
||||||
|
.getCurrentItem()
|
||||||
|
.getItemMeta()
|
||||||
|
.getPersistentDataContainer()
|
||||||
|
.get(ID, PersistentDataType.STRING);
|
||||||
|
|
||||||
|
Cutscene cutscene =
|
||||||
|
Manager.getInstance(CutsceneManager.class).findByUUID(UUID.fromString(uuid));
|
||||||
|
|
||||||
|
if (cutscene == null) {
|
||||||
|
player.sendMessage(textComp("<red>Unexpected error."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (clickType.isLeftClick()) {
|
||||||
|
Manager.getInstance(RecordingManager.class).startRecording(cutscene, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package me.unurled.sacredrealms.sr.gui.recordings;
|
||||||
|
|
||||||
|
import static me.unurled.sacredrealms.sr.utils.Items.glassPane;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||||
|
import me.unurled.sacredrealms.sr.gui.BackItem;
|
||||||
|
import me.unurled.sacredrealms.sr.gui.ForwardItem;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.gui.PagedGui;
|
||||||
|
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||||
|
import xyz.xenondevs.invui.item.Item;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
|
||||||
|
public class StartRecordingGui {
|
||||||
|
private StartRecordingGui() {}
|
||||||
|
|
||||||
|
public static @NotNull Gui listGui() {
|
||||||
|
CutsceneManager cm = Manager.getInstance(CutsceneManager.class);
|
||||||
|
|
||||||
|
List<Item> items = new ArrayList<>();
|
||||||
|
for (Cutscene cs : cm.cutscenes()) {
|
||||||
|
CutsceneItem item = new CutsceneItem(cs.name(), cs.id());
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PagedGui.items()
|
||||||
|
.setStructure(
|
||||||
|
"# # # # # # # # #",
|
||||||
|
"# X X X X X X X #",
|
||||||
|
"# X X X X X X X #",
|
||||||
|
"# X X X X X X X #",
|
||||||
|
"# # # < # > # # #")
|
||||||
|
.addIngredient('#', new ItemBuilder(glassPane()))
|
||||||
|
.addIngredient('X', Markers.CONTENT_LIST_SLOT_HORIZONTAL)
|
||||||
|
.addIngredient('<', new BackItem())
|
||||||
|
.addIngredient('>', new ForwardItem())
|
||||||
|
.setContent(items)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package me.unurled.sacredrealms.sr.gui.replay;
|
||||||
|
|
||||||
|
import static me.unurled.sacredrealms.sr.utils.Items.glassPane;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Replay;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.ReplayManager;
|
||||||
|
import me.unurled.sacredrealms.sr.gui.BackItem;
|
||||||
|
import me.unurled.sacredrealms.sr.gui.ForwardItem;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.xenondevs.invui.gui.Gui;
|
||||||
|
import xyz.xenondevs.invui.gui.PagedGui;
|
||||||
|
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||||
|
import xyz.xenondevs.invui.item.Item;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
|
||||||
|
public class ReplayGui {
|
||||||
|
private ReplayGui() {}
|
||||||
|
|
||||||
|
public static @NotNull Gui listGui() {
|
||||||
|
ReplayManager rm = Manager.getInstance(ReplayManager.class);
|
||||||
|
|
||||||
|
List<Item> items = new ArrayList<>();
|
||||||
|
for (Replay r : rm.replays()) {}
|
||||||
|
|
||||||
|
return PagedGui.items()
|
||||||
|
.setStructure(
|
||||||
|
"# # # # # # # # #",
|
||||||
|
"# X X X X X X X #",
|
||||||
|
"# X X X X X X X #",
|
||||||
|
"# X X X X X X X #",
|
||||||
|
"# # # < # > # # #")
|
||||||
|
.addIngredient('#', new ItemBuilder(glassPane()))
|
||||||
|
.addIngredient('X', Markers.CONTENT_LIST_SLOT_HORIZONTAL)
|
||||||
|
.addIngredient('<', new BackItem())
|
||||||
|
.addIngredient('>', new ForwardItem())
|
||||||
|
.setContent(items)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package me.unurled.sacredrealms.sr.gui.replay;
|
||||||
|
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import me.unurled.sacredrealms.sr.SR;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||||
|
import me.unurled.sacredrealms.sr.components.cutscene.RecordingManager;
|
||||||
|
import me.unurled.srcore.api.Manager;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.xenondevs.invui.item.ItemProvider;
|
||||||
|
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||||
|
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||||
|
|
||||||
|
public class ReplayItem extends AbstractItem {
|
||||||
|
private static NamespacedKey ID = null;
|
||||||
|
private final String name;
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
public ReplayItem(String name, UUID uuid) {
|
||||||
|
ID = new NamespacedKey(SR.getPlugin(), "cutscene_id");
|
||||||
|
this.name = name;
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemProvider getItemProvider() {
|
||||||
|
ItemStack itemStack = new ItemStack(Material.PAPER);
|
||||||
|
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||||
|
itemMeta.displayName(textComp(name));
|
||||||
|
itemMeta.getPersistentDataContainer().set(ID, PersistentDataType.STRING, uuid.toString());
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
return new ItemBuilder(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleClick(
|
||||||
|
@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||||
|
if (event.getCurrentItem() != null) {
|
||||||
|
String uuid =
|
||||||
|
event
|
||||||
|
.getCurrentItem()
|
||||||
|
.getItemMeta()
|
||||||
|
.getPersistentDataContainer()
|
||||||
|
.get(ID, PersistentDataType.STRING);
|
||||||
|
|
||||||
|
if (uuid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cutscene cutscene =
|
||||||
|
Manager.getInstance(CutsceneManager.class).findByUUID(UUID.fromString(uuid));
|
||||||
|
|
||||||
|
if (cutscene == null) {
|
||||||
|
player.sendMessage(textComp("<red>Unexpected error."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (clickType.isLeftClick()) {
|
||||||
|
Manager.getInstance(RecordingManager.class).startRecording(cutscene, player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.gui.treasure;
|
package me.unurled.sacredrealms.sr.gui.treasure;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.gui.treasure;
|
package me.unurled.sacredrealms.sr.gui.treasure;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
||||||
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package me.unurled.sacredrealms.sr.utils;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class Component {
|
|
||||||
|
|
||||||
public static final String NOT_PLAYER = "<red>You must be a player to use this command.";
|
|
||||||
public static final String NO_PERMISSION = "<red>You do not have permission to use this command.";
|
|
||||||
public static final String ERROR =
|
|
||||||
"<red>An error occurred while executing this command. Please" + " contact an admin.";
|
|
||||||
public static final String PLAYER_NOT_FOUND = "<red>Player not found.";
|
|
||||||
|
|
||||||
private static MiniMessage miniMessage;
|
|
||||||
|
|
||||||
private Component() {}
|
|
||||||
|
|
||||||
public static net.kyori.adventure.text.@NotNull Component comp(String msg) {
|
|
||||||
if (miniMessage == null) {
|
|
||||||
miniMessage = MiniMessage.miniMessage();
|
|
||||||
}
|
|
||||||
return miniMessage.deserialize(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static net.kyori.adventure.text.@NotNull TextComponent textComp(String msg) {
|
|
||||||
if (miniMessage == null) {
|
|
||||||
miniMessage = MiniMessage.miniMessage();
|
|
||||||
}
|
|
||||||
return (TextComponent) miniMessage.deserialize(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<net.kyori.adventure.text.Component> fromStringList(
|
|
||||||
@NotNull List<String> list) {
|
|
||||||
return list.stream().map(Component::comp).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,10 @@
|
||||||
package me.unurled.sacredrealms.sr.utils;
|
package me.unurled.sacredrealms.sr.utils;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.Frame;
|
|
||||||
import me.unurled.sacredrealms.sr.components.cutscene.Marker;
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
||||||
import net.kyori.adventure.title.Title.Times;
|
import net.kyori.adventure.title.Title.Times;
|
||||||
|
@ -32,36 +30,4 @@ public class CutsceneUtil {
|
||||||
Duration.ofSeconds(fadeOut)));
|
Duration.ofSeconds(fadeOut)));
|
||||||
p.showTitle(title);
|
p.showTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull List<Frame> interpolateFrames(
|
|
||||||
@NotNull Marker startMarker, @NotNull Marker endMarker, long stepMillis) {
|
|
||||||
long duration = startMarker.getOverAllTime();
|
|
||||||
|
|
||||||
int numFrames = (int) (duration / stepMillis);
|
|
||||||
|
|
||||||
double xDiff = (endMarker.getStart().getX() - startMarker.getStart().getX()) / numFrames;
|
|
||||||
double yDiff = (endMarker.getStart().getY() - startMarker.getStart().getY()) / numFrames;
|
|
||||||
double zDiff = (endMarker.getStart().getZ() - startMarker.getStart().getZ()) / numFrames;
|
|
||||||
double yawDiff = (endMarker.getStart().getYaw() - startMarker.getStart().getYaw()) / numFrames;
|
|
||||||
double pitchDiff =
|
|
||||||
(endMarker.getStart().getPitch() - startMarker.getStart().getPitch()) / numFrames;
|
|
||||||
|
|
||||||
ArrayList<Frame> frames = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < numFrames; i++) {
|
|
||||||
|
|
||||||
double x = startMarker.getStart().getX() + xDiff * i;
|
|
||||||
double y = startMarker.getStart().getY() + yDiff * i;
|
|
||||||
double z = startMarker.getStart().getZ() + zDiff * i;
|
|
||||||
double yaw = startMarker.getStart().getYaw() + yawDiff * i;
|
|
||||||
double pitch = startMarker.getStart().getPitch() + pitchDiff * i;
|
|
||||||
|
|
||||||
Frame frame =
|
|
||||||
new Frame(
|
|
||||||
new Location(startMarker.getStart().getWorld(), x, y, z, (float) yaw, (float) pitch));
|
|
||||||
|
|
||||||
frames.add(frame);
|
|
||||||
}
|
|
||||||
return frames;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package me.unurled.sacredrealms.sr.utils;
|
package me.unurled.sacredrealms.sr.utils;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
||||||
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
|
import static me.unurled.srcore.utils.Component.textComp;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
145
src/main/java/me/unurled/sacredrealms/sr/utils/Region.java
Normal file
145
src/main/java/me/unurled/sacredrealms/sr/utils/Region.java
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
package me.unurled.sacredrealms.sr.utils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class Region {
|
||||||
|
private Location corner1;
|
||||||
|
private Location corner2;
|
||||||
|
|
||||||
|
public Region() {
|
||||||
|
this.corner1 = null;
|
||||||
|
this.corner2 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSet() {
|
||||||
|
return corner1 != null && corner2 != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public World getWorld() {
|
||||||
|
if (corner1 == null) return null;
|
||||||
|
return corner1.getWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIn(final @NotNull Location loc) {
|
||||||
|
if (corner1 == null || corner2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double xMin = Math.min(corner1.getX(), corner2.getX());
|
||||||
|
double xMax = Math.max(corner1.getX(), corner2.getX());
|
||||||
|
double yMin = Math.min(corner1.getY(), corner2.getY());
|
||||||
|
double yMax = Math.max(corner1.getY(), corner2.getY());
|
||||||
|
double zMin = Math.min(corner1.getZ(), corner2.getZ());
|
||||||
|
double zMax = Math.max(corner1.getZ(), corner2.getZ());
|
||||||
|
|
||||||
|
// if the location is within the region in the x, y, and z axis
|
||||||
|
return loc.getBlockX() >= xMin
|
||||||
|
&& loc.getBlockX() <= xMax
|
||||||
|
&& loc.getBlockY() >= yMin
|
||||||
|
&& loc.getBlockY() <= yMax
|
||||||
|
&& loc.getBlockZ() >= zMin
|
||||||
|
&& loc.getBlockZ() <= zMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalBlockSize() {
|
||||||
|
return (int) (this.getHeight() * this.getXWidth() * this.getZWidth());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getHeight() {
|
||||||
|
if (corner1 == null || corner2 == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
double yMin = Math.min(corner1.getY(), corner2.getY());
|
||||||
|
double yMax = Math.max(corner1.getY(), corner2.getY());
|
||||||
|
return yMax - yMin + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getXWidth() {
|
||||||
|
if (corner1 == null || corner2 == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
double xMin = Math.min(corner1.getX(), corner2.getX());
|
||||||
|
double xMax = Math.max(corner1.getX(), corner2.getX());
|
||||||
|
return xMax - xMin + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZWidth() {
|
||||||
|
if (corner1 == null || corner2 == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
double zMin = Math.min(corner1.getZ(), corner2.getZ());
|
||||||
|
double zMax = Math.max(corner1.getZ(), corner2.getZ());
|
||||||
|
return zMax - zMin + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<Block> blockList(World world) {
|
||||||
|
if (corner1 == null || corner2 == null) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
double xMin = Math.min(corner1.getX(), corner2.getX());
|
||||||
|
double xMax = Math.max(corner1.getX(), corner2.getX());
|
||||||
|
double yMin = Math.min(corner1.getY(), corner2.getY());
|
||||||
|
double yMax = Math.max(corner1.getY(), corner2.getY());
|
||||||
|
double zMin = Math.min(corner1.getZ(), corner2.getZ());
|
||||||
|
double zMax = Math.max(corner1.getZ(), corner2.getZ());
|
||||||
|
|
||||||
|
final ArrayList<Block> bL = new ArrayList<>(this.getTotalBlockSize());
|
||||||
|
for (double x = xMin; x <= xMax; ++x) {
|
||||||
|
for (double y = yMin; y <= yMax; ++y) {
|
||||||
|
for (double z = zMin; z <= zMax; ++z) {
|
||||||
|
final Block b = world.getBlockAt((int) x, (int) y, (int) z);
|
||||||
|
bL.add(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPlayerIn(@NotNull Player player) {
|
||||||
|
return this.isIn(player.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<Entity> getEntities() {
|
||||||
|
List<Entity> entities = new ArrayList<>();
|
||||||
|
if (corner1 == null || corner1.getWorld() == null) {
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
List<Block> blocks = blockList(corner1.getWorld());
|
||||||
|
if (blocks == null) {
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
for (Block block : blocks) {
|
||||||
|
entities.addAll(block.getWorld().getNearbyEntities(block.getLocation(), 1, 1, 1));
|
||||||
|
}
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location corner1() {
|
||||||
|
return corner1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location corner2() {
|
||||||
|
return corner2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region setCorner1(Location corner1) {
|
||||||
|
this.corner1 = corner1;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region setCorner2(Location corner2) {
|
||||||
|
this.corner2 = corner2;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
139
src/main/java/me/unurled/sacredrealms/sr/utils/RegionUtil.java
Normal file
139
src/main/java/me/unurled/sacredrealms/sr/utils/RegionUtil.java
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
package me.unurled.sacredrealms.sr.utils;
|
||||||
|
|
||||||
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
|
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||||
|
import static org.bukkit.Bukkit.getServer;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Slime;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||||
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
import org.bukkit.scoreboard.Team;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class RegionUtil {
|
||||||
|
|
||||||
|
private static final String REGIONSELECTOR = "srselector";
|
||||||
|
|
||||||
|
public static void killSelectorsWithTag(String inputTag) {
|
||||||
|
for (World world : getServer().getWorlds()) {
|
||||||
|
for (Entity entity : world.getEntities()) {
|
||||||
|
for (String tag : entity.getScoreboardTags()) {
|
||||||
|
if (tag.equals(REGIONSELECTOR + "-" + inputTag)) {
|
||||||
|
entity.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void killAllSelectors() {
|
||||||
|
for (World world : getServer().getWorlds()) {
|
||||||
|
for (Entity entity : world.getEntities()) {
|
||||||
|
for (String tag : entity.getScoreboardTags()) {
|
||||||
|
if (tag.startsWith(REGIONSELECTOR + "-")) {
|
||||||
|
entity.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawSelector(
|
||||||
|
@NotNull Region region, World world, String id, NamedTextColor glowColor) {
|
||||||
|
Location loc1 = region.corner1();
|
||||||
|
Location loc2 = region.corner2();
|
||||||
|
if (loc1.getWorld() == null || !loc1.getWorld().equals(loc2.getWorld())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int minx = Math.min(loc1.getBlockX(), loc2.getBlockX());
|
||||||
|
int miny = Math.min(loc1.getBlockY(), loc2.getBlockY());
|
||||||
|
int minz = Math.min(loc1.getBlockZ(), loc2.getBlockZ());
|
||||||
|
int maxx = Math.max(loc1.getBlockX(), loc2.getBlockX());
|
||||||
|
int maxy = Math.max(loc1.getBlockY(), loc2.getBlockY());
|
||||||
|
int maxz = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
|
||||||
|
|
||||||
|
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
|
||||||
|
|
||||||
|
int highestNumber = 0;
|
||||||
|
|
||||||
|
for (Team team : board.getTeams()) {
|
||||||
|
if (team.getName().startsWith(REGIONSELECTOR + "+")) {
|
||||||
|
String number = team.getName().substring(11);
|
||||||
|
try {
|
||||||
|
int tempNumber = Integer.parseInt(number);
|
||||||
|
if (tempNumber >= highestNumber) {
|
||||||
|
highestNumber = tempNumber;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log(REGIONSELECTOR + "+" + (highestNumber + 1));
|
||||||
|
|
||||||
|
Team selectorTeam = board.registerNewTeam(REGIONSELECTOR + "+" + (highestNumber + 1));
|
||||||
|
if (glowColor != null) {
|
||||||
|
selectorTeam.color(glowColor);
|
||||||
|
}
|
||||||
|
selectorTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
|
||||||
|
|
||||||
|
for (double x = minx; x <= maxx; x++) {
|
||||||
|
makeSlime(id, world, selectorTeam, x, miny, minz);
|
||||||
|
makeSlime(id, world, selectorTeam, x, maxy, minz);
|
||||||
|
makeSlime(id, world, selectorTeam, x, miny, maxz);
|
||||||
|
makeSlime(id, world, selectorTeam, x, maxy, maxz);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (double y = miny; y <= maxy; y++) {
|
||||||
|
makeSlime(id, world, selectorTeam, minx, y, minz);
|
||||||
|
makeSlime(id, world, selectorTeam, maxx, y, minz);
|
||||||
|
makeSlime(id, world, selectorTeam, minx, y, maxz);
|
||||||
|
makeSlime(id, world, selectorTeam, maxx, y, maxz);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (double z = minz; z <= maxz; z++) {
|
||||||
|
makeSlime(id, world, selectorTeam, minx, miny, z);
|
||||||
|
makeSlime(id, world, selectorTeam, maxx, miny, z);
|
||||||
|
makeSlime(id, world, selectorTeam, minx, maxy, z);
|
||||||
|
makeSlime(id, world, selectorTeam, maxx, maxy, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeSlime(
|
||||||
|
String id, @NotNull World world, @NotNull Team selectorTeam, double x, double y, double z) {
|
||||||
|
Slime slime =
|
||||||
|
(Slime)
|
||||||
|
world.spawnEntity(
|
||||||
|
new Location(world, x + 0.5, y, z + 0.5), EntityType.SLIME, SpawnReason.CUSTOM);
|
||||||
|
slime.setSize(2);
|
||||||
|
slime.setAI(false);
|
||||||
|
slime.setGravity(false);
|
||||||
|
slime.setCollidable(false);
|
||||||
|
slime.setSilent(true);
|
||||||
|
slime.setCanPickupItems(false);
|
||||||
|
slime.setGlowing(true);
|
||||||
|
slime.setInvulnerable(true);
|
||||||
|
slime.setInvisible(true);
|
||||||
|
slime.addScoreboardTag(REGIONSELECTOR + "-" + id);
|
||||||
|
slime.setPersistent(true);
|
||||||
|
selectorTeam.addEntry(String.valueOf(slime.getUniqueId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTempTeams() {
|
||||||
|
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
|
||||||
|
for (Team team : board.getTeams()) {
|
||||||
|
if (team.getName().startsWith(REGIONSELECTOR + "+")) {
|
||||||
|
team.unregister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package me.unurled.sacredrealms.sr.utils;
|
package me.unurled.sacredrealms.sr.utils;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.srcore.utils.Component.comp;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue