-
Notifications
You must be signed in to change notification settings - Fork 5
/
Blabber.java
146 lines (136 loc) · 6.33 KB
/
Blabber.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Blabber
* Copyright (C) 2022-2024 Ladysnake
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; If not, see <https://www.gnu.org/licenses>.
*/
package org.ladysnake.blabber;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.serialization.Codec;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.Registry;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import org.ladysnake.blabber.api.DialogueActionV2;
import org.ladysnake.blabber.impl.common.BlabberCommand;
import org.ladysnake.blabber.impl.common.BlabberRegistrar;
import org.ladysnake.blabber.impl.common.CommandDialogueAction;
import org.ladysnake.blabber.impl.common.DialogueInitializationException;
import org.ladysnake.blabber.impl.common.PlayerDialogueTracker;
import org.ladysnake.blabber.impl.common.machine.DialogueStateMachine;
public final class Blabber implements ModInitializer {
public static final String MOD_ID = "blabber";
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
public static Identifier id(String path) {
return new Identifier(MOD_ID, path);
}
/**
* Starts a dialogue
*
* <p>This operation closes the player's {@linkplain PlayerEntity#currentScreenHandler current screen handler},
* if any, and opens a new dialogue screen instead.
*
* <p>A dialogue may fail to start if it contains malformed texts as per {@link net.minecraft.text.Texts#parse(ServerCommandSource, Text, Entity, int)}.
* In that case, this method will throw a {@link DialogueInitializationException}.
*
* @param player the player for whom to initiate a dialogue
* @param id the identifier for the dialogue
* @throws IllegalArgumentException if {@code id} is not a valid dialogue in this game instance
* @throws DialogueInitializationException if the dialogue failed to initialize
*/
public static void startDialogue(ServerPlayerEntity player, Identifier id) {
startDialogue(player, id, null);
}
/**
* Starts a dialogue
*
* <p>This operation closes the player's {@linkplain PlayerEntity#currentScreenHandler current screen handler},
* if any, and opens a new dialogue screen instead.
*
* <p>A dialogue may fail to start if it contains malformed texts as per {@link net.minecraft.text.Texts#parse(ServerCommandSource, Text, Entity, int)}.
* In that case, this method will throw a {@link DialogueInitializationException}.
*
* @param player the player for whom to initiate a dialogue
* @param id the identifier for the dialogue
* @param interlocutor the entity with which the player is conversing
* @throws IllegalArgumentException if {@code id} is not a valid dialogue in this game instance
* @throws DialogueInitializationException if the dialogue failed to initialize
*/
public static void startDialogue(ServerPlayerEntity player, Identifier id, @Nullable Entity interlocutor) {
try {
PlayerDialogueTracker.get(player).startDialogue(id, interlocutor);
} catch (CommandSyntaxException e) {
throw new DialogueInitializationException("Failed to parse texts in dialogue template " + id, e);
}
}
/**
* Ends the current dialogue if its id equals {@code expectedDialogue}.
*
* <p>If the identifiers match, the current dialogue will be ended no matter
* its state.
*
* @param player the player for whom to end the current dialogue
* @param expectedDialogue the identifier being compared to the current dialogue, or {@code null} to end any ongoing dialogue
*/
public static void endDialogue(ServerPlayerEntity player, @Nullable Identifier expectedDialogue) {
Identifier currentDialogueId = PlayerDialogueTracker.get(player).getCurrentDialogue().map(DialogueStateMachine::getId).orElse(null);
if (currentDialogueId != null && (expectedDialogue == null || expectedDialogue.equals(currentDialogueId))) {
PlayerDialogueTracker.get(player).endDialogue();
}
}
/**
* Register a basic {@link DialogueAction} to handle dialogue choices.
*
* @param actionId the identifier used to reference the action in dialogue definition files
* @param action the action to run when triggered by a player
* @see #registerAction(Identifier, Codec)
*/
public static void registerAction(Identifier actionId, DialogueAction action) {
registerAction(actionId, Codec.unit(action));
}
/**
* Register a basic {@link DialogueAction} to handle dialogue choices.
*
* @param actionId the identifier used to reference the action in dialogue definition files
* @param action the action to run when triggered by a player
* @see #registerAction(Identifier, Codec)
*/
public static void registerAction(Identifier actionId, DialogueActionV2 action) {
registerAction(actionId, Codec.unit(action));
}
/**
* Register a configurable {@link DialogueAction} to handle dialogue choices.
*
* @param actionId the identifier used to reference the action in dialogue definition files
* @param codec a codec for deserializing dialogue actions using the given value
* @see #registerAction(Identifier, DialogueAction)
*/
public static void registerAction(Identifier actionId, Codec<? extends DialogueActionV2> codec) {
Registry.register(BlabberRegistrar.ACTION_REGISTRY, actionId, codec);
}
@Override
public void onInitialize() {
BlabberRegistrar.init();
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> BlabberCommand.register(dispatcher));
registerAction(id("command"), CommandDialogueAction.CODEC);
}
}