feat: implemented interlocutors and NPCClickEvent
This commit is contained in:
parent
f082b3b9f6
commit
a6fc0924a7
@ -14,6 +14,7 @@ import ru.dragonestia.msb3.api.dialog.action.DialogDialogActionHandler;
|
|||||||
import ru.dragonestia.msb3.api.dialog.condition.AlwaysDialogConditionHandler;
|
import ru.dragonestia.msb3.api.dialog.condition.AlwaysDialogConditionHandler;
|
||||||
import ru.dragonestia.msb3.api.dialog.condition.NeverDialogConditionHandler;
|
import ru.dragonestia.msb3.api.dialog.condition.NeverDialogConditionHandler;
|
||||||
import ru.dragonestia.msb3.api.entity.PickableItem;
|
import ru.dragonestia.msb3.api.entity.PickableItem;
|
||||||
|
import ru.dragonestia.msb3.api.event.NPCClickEvent;
|
||||||
import ru.dragonestia.msb3.api.item.ItemUtil;
|
import ru.dragonestia.msb3.api.item.ItemUtil;
|
||||||
import ru.dragonestia.msb3.api.player.MsbPlayer;
|
import ru.dragonestia.msb3.api.player.MsbPlayer;
|
||||||
import ru.dragonestia.msb3.api.player.PlayerContextManager;
|
import ru.dragonestia.msb3.api.player.PlayerContextManager;
|
||||||
@ -96,6 +97,8 @@ public final class ServerBootstrap {
|
|||||||
initDefaultSkins();
|
initDefaultSkins();
|
||||||
|
|
||||||
initDefaultDialogActionsAndConditions();
|
initDefaultDialogActionsAndConditions();
|
||||||
|
|
||||||
|
NPCClickEvent.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDefaultModules() {
|
private void initDefaultModules() {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import lombok.Setter;
|
|||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import ru.dragonestia.msb3.api.dialog.interlocutor.Interlocutor;
|
||||||
import ru.dragonestia.msb3.api.player.PlayerContext;
|
import ru.dragonestia.msb3.api.player.PlayerContext;
|
||||||
import ru.dragonestia.msb3.api.player.defaults.TalksContext;
|
import ru.dragonestia.msb3.api.player.defaults.TalksContext;
|
||||||
import ru.dragonestia.msb3.api.resource.dialog.ButtonNumber;
|
import ru.dragonestia.msb3.api.resource.dialog.ButtonNumber;
|
||||||
@ -16,7 +17,6 @@ import ru.dragonestia.msb3.api.ui.dialogue.DialogueTheme;
|
|||||||
import ru.dragonestia.msb3.api.util.DebugMessage;
|
import ru.dragonestia.msb3.api.util.DebugMessage;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@ -32,7 +32,7 @@ public class Dialog {
|
|||||||
private String themeId;
|
private String themeId;
|
||||||
private List<DialogButton> buttons;
|
private List<DialogButton> buttons;
|
||||||
|
|
||||||
public void switchDialog(Player player, DialogueRenderer renderer) {
|
public void switchDialog(Player player, DialogueRenderer renderer, Interlocutor interlocutor) {
|
||||||
var ctx = PlayerContext.of(player, TalksContext.class);
|
var ctx = PlayerContext.of(player, TalksContext.class);
|
||||||
if (rememberId) {
|
if (rememberId) {
|
||||||
ctx.getOpenedDialogues().add(id.asString());
|
ctx.getOpenedDialogues().add(id.asString());
|
||||||
@ -49,7 +49,9 @@ public class Dialog {
|
|||||||
log.error("Unknown theme: {}", themeId);
|
log.error("Unknown theme: {}", themeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderer.setTheme(theme);
|
renderer.setTheme(theme.toBuilder()
|
||||||
|
.setAvatar(interlocutor.getDialogAvatar())
|
||||||
|
.build());
|
||||||
|
|
||||||
renderer.setText(text);
|
renderer.setText(text);
|
||||||
|
|
||||||
@ -60,16 +62,16 @@ public class Dialog {
|
|||||||
if (buttons.isEmpty()) break;
|
if (buttons.isEmpty()) break;
|
||||||
var button = buttons.removeFirst();
|
var button = buttons.removeFirst();
|
||||||
renderer.setButton(buttonNumber, button.getText(), buttonCtx -> {
|
renderer.setButton(buttonNumber, button.getText(), buttonCtx -> {
|
||||||
var click = new DialogButtonClick(buttonCtx.player(), this, button, buttonCtx.buttonNumber(), buttonCtx.renderer());
|
var click = new DialogButtonClick(buttonCtx.player(), interlocutor, this, button, buttonCtx.buttonNumber(), buttonCtx.renderer());
|
||||||
button.onClick(click);
|
button.onClick(click);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
renderer.rerender();
|
renderer.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void open(Player player) {
|
public synchronized void open(Player player, Interlocutor interlocutor) {
|
||||||
var renderer = DialogueRenderer.getRenderer(player).orElseGet(() -> new DialogueRenderer(player, DialogueTheme.builder().build()));
|
var renderer = DialogueRenderer.getRenderer(player).orElseGet(() -> new DialogueRenderer(player, DialogueTheme.builder().build()));
|
||||||
switchDialog(player, renderer);
|
switchDialog(player, renderer, interlocutor);
|
||||||
renderer.show();
|
renderer.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
package ru.dragonestia.msb3.api.dialog;
|
package ru.dragonestia.msb3.api.dialog;
|
||||||
|
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import ru.dragonestia.msb3.api.dialog.interlocutor.Interlocutor;
|
||||||
import ru.dragonestia.msb3.api.resource.dialog.ButtonNumber;
|
import ru.dragonestia.msb3.api.resource.dialog.ButtonNumber;
|
||||||
import ru.dragonestia.msb3.api.ui.dialogue.DialogueRenderer;
|
import ru.dragonestia.msb3.api.ui.dialogue.DialogueRenderer;
|
||||||
|
|
||||||
public record DialogButtonClick(
|
public record DialogButtonClick(
|
||||||
Player player,
|
Player player,
|
||||||
|
Interlocutor interlocutor,
|
||||||
Dialog dialog,
|
Dialog dialog,
|
||||||
DialogButton dialogButton,
|
DialogButton dialogButton,
|
||||||
ButtonNumber buttonNumber,
|
ButtonNumber buttonNumber,
|
||||||
|
|||||||
@ -27,6 +27,6 @@ public class DialogDialogActionHandler implements DialogActionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.get().switchDialog(player, click.renderer());
|
dialog.get().switchDialog(player, click.renderer(), click.interlocutor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
package ru.dragonestia.msb3.api.dialog.interlocutor;
|
||||||
|
|
||||||
|
import ru.dragonestia.msb3.api.resource.DialogueResources;
|
||||||
|
import ru.dragonestia.msb3.api.resource.MonologueResources;
|
||||||
|
|
||||||
|
public class AnonymousInterlocutor extends SimpleInterlocutor {
|
||||||
|
|
||||||
|
public AnonymousInterlocutor(String name) {
|
||||||
|
super(
|
||||||
|
name,
|
||||||
|
DialogueResources.getAvatar(DialogueResources.DEFAULT).orElseThrow(),
|
||||||
|
MonologueResources.getAvatar(MonologueResources.DEFAULT).orElseThrow()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
package ru.dragonestia.msb3.api.dialog.interlocutor;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import ru.dragonestia.msb3.api.dialog.Dialog;
|
||||||
|
import ru.dragonestia.msb3.api.ui.dialogue.DialogueRenderer;
|
||||||
|
import ru.dragonestia.msb3.api.ui.monologue.Monologue;
|
||||||
|
import ru.dragonestia.msb3.api.ui.monologue.MonologueTheme;
|
||||||
|
import ru.dragonestia.msb3.resource.glyph.GlyphImage;
|
||||||
|
|
||||||
|
public interface Interlocutor {
|
||||||
|
|
||||||
|
String getInterlocutorName();
|
||||||
|
|
||||||
|
GlyphImage getDialogAvatar();
|
||||||
|
|
||||||
|
GlyphImage getMonologAvatar();
|
||||||
|
|
||||||
|
default MonologueTheme getMonologueTheme() {
|
||||||
|
return MonologueTheme.builder().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
default void sendMonolog(Player receiver, String message) {
|
||||||
|
sendMonolog(receiver, message, getMonologueTheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
default void sendMonolog(Player receiver, String message, MonologueTheme theme) {
|
||||||
|
Monologue.create(receiver, getInterlocutorName(), message).show(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void sendDialog(Player receiver, Dialog dialog) {
|
||||||
|
sendDialog(receiver, dialog, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void sendDialog(Player receiver, Dialog dialog, boolean inDialogueWindowNow) {
|
||||||
|
if (inDialogueWindowNow) {
|
||||||
|
var renderer = DialogueRenderer.getRenderer(receiver).orElseThrow();
|
||||||
|
dialog.switchDialog(receiver, renderer, this);
|
||||||
|
renderer.rerender();
|
||||||
|
} else {
|
||||||
|
dialog.open(receiver, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package ru.dragonestia.msb3.api.dialog.interlocutor;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import ru.dragonestia.msb3.resource.glyph.GlyphImage;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SimpleInterlocutor implements Interlocutor {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private GlyphImage dialogAvatar;
|
||||||
|
private GlyphImage monologAvatar;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInterlocutorName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GlyphImage getDialogAvatar() {
|
||||||
|
return dialogAvatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GlyphImage getMonologAvatar() {
|
||||||
|
return monologAvatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
api/src/main/java/ru/dragonestia/msb3/api/entity/NPC.java
Normal file
13
api/src/main/java/ru/dragonestia/msb3/api/entity/NPC.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package ru.dragonestia.msb3.api.entity;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import ru.dragonestia.msb3.api.event.NPCClickEvent;
|
||||||
|
|
||||||
|
public interface NPC {
|
||||||
|
|
||||||
|
default boolean supportedClickType(NPCClickEvent.ClickType clickType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onClickByPlayer(Player player, NPCClickEvent.ClickType clickType);
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package ru.dragonestia.msb3.api.event;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.entity.PlayerHand;
|
||||||
|
import net.minestom.server.event.entity.EntityAttackEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerEntityInteractEvent;
|
||||||
|
import net.minestom.server.event.trait.EntityEvent;
|
||||||
|
import net.minestom.server.event.trait.InstanceEvent;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import ru.dragonestia.msb3.api.entity.NPC;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class NPCClickEvent implements EntityEvent, InstanceEvent {
|
||||||
|
|
||||||
|
@Getter private final Player player;
|
||||||
|
private final NPC npcEntity;
|
||||||
|
private final ClickType clickType;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Entity getEntity() {
|
||||||
|
return (Entity) npcEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Instance getInstance() {
|
||||||
|
return Objects.requireNonNull(player.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ClickType {
|
||||||
|
ATTACK,
|
||||||
|
INTERACT
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
MinecraftServer.getGlobalEventHandler().addListener(PlayerEntityInteractEvent.class, event -> {
|
||||||
|
if (event.getHand() != PlayerHand.MAIN) return;
|
||||||
|
if (event.getEntity() instanceof NPC npc) {
|
||||||
|
if (!npc.supportedClickType(ClickType.INTERACT)) return;
|
||||||
|
MinecraftServer.getGlobalEventHandler().call(new NPCClickEvent(event.getPlayer(), npc, ClickType.INTERACT));
|
||||||
|
}
|
||||||
|
}).addListener(EntityAttackEvent.class, event -> {
|
||||||
|
if (event.getTarget() instanceof NPC npc && event.getEntity() instanceof Player player) {
|
||||||
|
if (!npc.supportedClickType(ClickType.ATTACK)) return;
|
||||||
|
MinecraftServer.getGlobalEventHandler().call(new NPCClickEvent(player, npc, ClickType.ATTACK));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user