Skip to content

Commit

Permalink
Improve editor wizard
Browse files Browse the repository at this point in the history
Fixes a few bugs with users getting stuck in the wizard, or instructions being unclear.
  • Loading branch information
Redned235 committed Jul 18, 2024
1 parent 0c99564 commit cf62d75
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 101 deletions.
22 changes: 3 additions & 19 deletions plugin/src/main/java/org/battleplugins/arena/BattleArena.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.battleplugins.arena.competition.map.MapType;
import org.battleplugins.arena.config.ArenaConfigParser;
import org.battleplugins.arena.config.ParseException;
import org.battleplugins.arena.event.BattleArenaPostInitializeEvent;
import org.battleplugins.arena.event.BattleArenaPreInitializeEvent;
import org.battleplugins.arena.event.BattleArenaReloadEvent;
import org.battleplugins.arena.event.BattleArenaReloadedEvent;
Expand All @@ -34,9 +33,6 @@
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
Expand All @@ -63,7 +59,7 @@
/**
* The main class for BattleArena.
*/
public class BattleArena extends JavaPlugin implements Listener, LoggerHolder {
public class BattleArena extends JavaPlugin implements LoggerHolder {
private static final int PLUGIN_ID = 4597;

private static BattleArena instance;
Expand Down Expand Up @@ -111,7 +107,7 @@ public void onLoad() {

@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
Bukkit.getPluginManager().registerEvents(new BattleArenaListener(this), this);

// Register default arenas
this.registerArena(this, "Arena", Arena.class);
Expand Down Expand Up @@ -197,19 +193,7 @@ private void disable() {
this.teams = null;
}

@EventHandler
public void onServerLoad(ServerLoadEvent event) {
// There is logic called later, however by this point all plugins
// using the BattleArena API should have been loaded. As modules will
// listen for this event to register their behavior, we need to ensure
// they are fully initialized so any references to said modules in
// arena config files will be valid.
new BattleArenaPostInitializeEvent(this).callEvent();

this.postInitialize();
}

private void postInitialize() {
void postInitialize() {
// Load messages
MessageLoader.load(this.getDataFolder().toPath().resolve("messages.yml"));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.battleplugins.arena;

import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.battleplugins.arena.editor.ArenaEditorWizard;
import org.battleplugins.arena.event.BattleArenaPostInitializeEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent;

class BattleArenaListener implements Listener {
private final BattleArena plugin;

public BattleArenaListener(BattleArena plugin) {
this.plugin = plugin;
}

@EventHandler
public void onServerLoad(ServerLoadEvent event) {
// There is logic called later, however by this point all plugins
// using the BattleArena API should have been loaded. As modules will
// listen for this event to register their behavior, we need to ensure
// they are fully initialized so any references to said modules in
// arena config files will be valid.
new BattleArenaPostInitializeEvent(this.plugin).callEvent();

this.plugin.postInitialize();
}

@EventHandler(priority = EventPriority.LOWEST)
public void onChat(AsyncChatEvent event) {
String message = PlainTextComponentSerializer.plainText().serialize(event.originalMessage());
if (message.equalsIgnoreCase("cancel")) {
ArenaEditorWizard.wizardContext(event.getPlayer()).ifPresent(ctx -> {
event.setCancelled(true);

ctx.getWizard().onCancel(ctx);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
import org.battleplugins.arena.editor.type.EditorKey;
import org.battleplugins.arena.messages.Messages;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Optional;
import java.util.function.Consumer;

public class ArenaEditorWizard<E extends EditorContext<E>> {
private static final String EDITOR_META_KEY = "editor";

private final BattleArena plugin;
private final ContextFactory<E> contextFactory;
Expand All @@ -26,8 +26,6 @@ public class ArenaEditorWizard<E extends EditorContext<E>> {
private Consumer<E> onCreationComplete;
private Consumer<E> onCancel;

private final List<UUID> players = new ArrayList<>();

public ArenaEditorWizard(BattleArena plugin, ContextFactory<E> contextFactory) {
this.plugin = plugin;
this.contextFactory = contextFactory;
Expand All @@ -42,6 +40,10 @@ public ArenaEditorWizard<E> addStage(EditorKey key, WizardStage<E> stage) {
return this;
}

Map<String, WizardStage<E>> getStages() {
return this.stages;
}

public ArenaEditorWizard<E> onEditComplete(Consumer<E> onEditComplete) {
this.onEditComplete = onEditComplete;
return this;
Expand All @@ -62,7 +64,9 @@ public void onCancel(E context) {
this.onCancel.accept(context);
}

this.players.remove(context.getPlayer().getUniqueId());
context.cancel();
context.getPlayer().removeMetadata(EDITOR_META_KEY, this.plugin);

Messages.WIZARD_CLOSED.send(context.getPlayer());
}

Expand All @@ -71,7 +75,7 @@ public void openWizard(Player player, Arena arena) {
}

public void openWizard(Player player, Arena arena, @Nullable Consumer<E> contextConsumer) {
if (this.players.contains(player.getUniqueId())) {
if (player.hasMetadata(EDITOR_META_KEY)) {
Messages.ERROR_ALREADY_IN_EDITOR.send(player);
return;
}
Expand All @@ -97,7 +101,7 @@ public void openWizard(Player player, Arena arena, @Nullable Consumer<E> context
this.onCreationComplete.accept(context);
}

this.players.remove(player.getUniqueId());
player.removeMetadata(EDITOR_META_KEY, this.plugin);
} else {
WizardStage<E> stage = iterator.next().getValue();
stage.enter(context);
Expand All @@ -108,14 +112,16 @@ public void openWizard(Player player, Arena arena, @Nullable Consumer<E> context
contextConsumer.accept(context);
}

Messages.ENTERED_WIZARD.send(player);

WizardStage<E> initialStage = iterator.next().getValue();
initialStage.enter(context);

this.players.add(player.getUniqueId());
player.setMetadata(EDITOR_META_KEY, new FixedMetadataValue(this.plugin, context));
}

public void openSingleWizardStage(Player player, Arena arena, WizardStage<E> stage, Consumer<E> contextConsumer) {
if (this.players.contains(player.getUniqueId())) {
if (player.hasMetadata(EDITOR_META_KEY)) {
Messages.ERROR_ALREADY_IN_EDITOR.send(player);
return;
}
Expand All @@ -133,7 +139,7 @@ public void openSingleWizardStage(Player player, Arena arena, WizardStage<E> sta
this.onEditComplete.accept(context);
}

this.players.remove(player.getUniqueId());
player.removeMetadata(EDITOR_META_KEY, this.plugin);
});

stage.enter(context);
Expand All @@ -149,6 +155,19 @@ public WizardStage<E> getStage(EditorKey key) {
return this.stages.get(key.getKey());
}

public static boolean inWizard(Player player) {
return player.hasMetadata(EDITOR_META_KEY);
}

public static <E extends EditorContext<E>> Optional<E> wizardContext(Player player) {
return Optional.ofNullable(getWizardContext(player));
}

@SuppressWarnings("unchecked")
public static <E extends EditorContext<E>> E getWizardContext(Player player) {
return player.hasMetadata(EDITOR_META_KEY) ? (E) player.getMetadata(EDITOR_META_KEY).get(0).value() : null;
}

public interface ContextFactory<E extends EditorContext<E>> {

E create(ArenaEditorWizard<E> wizard, Arena arena, Player player);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package org.battleplugins.arena.editor;

import net.kyori.adventure.text.Component;
import org.battleplugins.arena.Arena;
import org.battleplugins.arena.BattleArena;
import org.battleplugins.arena.messages.Message;
import org.battleplugins.arena.messages.Messages;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;

import java.util.ArrayList;
import java.util.List;

public abstract class EditorContext<E extends EditorContext<E>> {

protected final ArenaEditorWizard<E> wizard;
protected final Arena arena;
protected final Player player;
private Runnable advanceListener;
private int position;

private final List<Listener> boundListeners = new ArrayList<>();

protected boolean reconstructed;

Expand Down Expand Up @@ -44,10 +55,36 @@ void setAdvanceListener(Runnable listener) {
}

public void advanceStage() {
this.position++;
if (this.advanceListener != null) {
this.advanceListener.run();
}
}

public void bind(Listener listener) {
this.boundListeners.add(listener);
}

public void unbind(Listener listener) {
this.boundListeners.remove(listener);
}

public void cancel() {
this.boundListeners.forEach(HandlerList::unregisterAll);
this.boundListeners.clear();
}

public void inform(Message message) {
if (this.reconstructed) {
message.send(this.player);
return;
}

Component positionMessage = Component.text("(" + (this.position + 1) + "/" + this.wizard.getStages().size() + ") ", Messages.SECONDARY_COLOR)
.append(message.toComponent());

this.player.sendMessage(positionMessage);
}

public abstract boolean isComplete();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public PositionInputStage(Message chatMessage, Function<E, Consumer<Location>> i
@Override
public void enter(E context) {
if (this.chatMessage != null) {
this.chatMessage.send(context.getPlayer());
context.inform(this.chatMessage);
}

new InteractionInputs.PositionInput(context.getPlayer()) {
Expand All @@ -34,6 +34,6 @@ public void onPositionInteract(Location position) {
inputConsumer.apply(context).accept(position);
context.advanceStage();
}
};
}.bind(context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,14 @@ public SpawnInputStage(Message chatMessage, String input, Function<E, Consumer<L
@Override
public void enter(E context) {
if (this.chatMessage != null) {
this.chatMessage.send(context.getPlayer());
context.inform(this.chatMessage);
}

// Player types in chat their location is used for the spawn
new InteractionInputs.ChatInput(context.getPlayer(), null) {

@Override
public void onChatInput(String input) {
if ("cancel".equalsIgnoreCase(input)) {
context.getWizard().onCancel(context);
return;
}

inputConsumer.apply(context).accept(context.getPlayer().getLocation());
context.advanceStage();
}
Expand All @@ -44,6 +39,6 @@ public void onChatInput(String input) {
public boolean isValidChatInput(String input) {
return !input.startsWith("/") && SpawnInputStage.this.input.equalsIgnoreCase(input);
}
};
}.bind(context);
}
}
Loading

0 comments on commit cf62d75

Please sign in to comment.