Originally Posted by
arham 4
Oh, I was unaware that he meant hardcoded in the sense of reloadability.
I see your point. I believe the problem you stated actually may have caused me some conflict at times. However, shouldn't dialogues not be so closely linked? Because then, what happens when dialogues wish to reference backwards? That's a problem I face in my system too. I was advised by somebody to instead use a hashmap and allow the helper methods to redirect the next dialogue to a previous (or another) key.
I appreciate the feedback.
Yeah I could definitely see how it would cause issues. I see no issue with linking them, and in the point above I showed just how it would be possible to link 2 chains together. It doesn't make much sense to use a Map when order is necessary. Instead, you could use a list and maintain the index of the current link in the chain, like in the example below. In this class you can traverse and go to the previous link, forward to the next link, you can obtain the current link, etcetera. It allows you to do quite a bit. Simply calling #start would allow you to reset back to the first link.
Code:
public class DialogueChain {
private final List<DialogueLink> links = new ArrayList<>();
private int indexOfLink;
public void start(Player player) {
indexOfLink = 0;
show(player);
}
public void next(Player player) {
DialogueLink link = links.get(indexOfLink);
if (link != null) {
link.getContinueListeners().forEach(listener -> listener.onContinue(player, link.getDialogue()));
}
indexOfLink++;
show(player);
}
public boolean isOnLastLink() {
return indexOfLink == links.size() - 1;
}
public void end(Player player) {
DialogueLink link = links.get(indexOfLink);
if (link != null) {
link.getCloseListeners().forEach(listener -> listener.onClose(player, link.getDialogue()));
}
indexOfLink = 0;
}
public void previous(Player player) {
indexOfLink--;
if (indexOfLink < 0) {
indexOfLink = 0;
}
show(player);
}
public void show(Player player) {
DialogueLink link = links.get(indexOfLink);
if (link == null) {
return;
}
link.execute(player);
}
public DialogueChain link(DialogueLink link) {
links.add(link);
return this;
}
public DialogueLink getCurrentLink() {
return links.get(indexOfLink);
}
public DialogueChain option(ClickOptionDialogueListener optionListener, String title, String... options) {
if (options == null || options.length < 2 || options.length > 5) {
throw new IllegalArgumentException("Length of options must be between 2 and 5 inclusive and cannot be null.");
}
if (optionListener == null) {
throw new IllegalArgumentException("Option listener cannot be null.");
}
links.add(new DialogueLink(new OptionDialogue(title, options)).addClickOptionListener(optionListener));
return this;
}
public DialogueChain player(FacialAnimation animation, String... message) {
if (animation == null) {
throw new IllegalArgumentException("Animation for players face cannot be null.");
}
if (message == null || message.length == 0) {
throw new IllegalArgumentException("Messages length cannot be null and must be greater than zero.");
}
links.add(new DialogueLink(new PlayerDialogue(animation, message)));
return this;
}
public DialogueChain npc(NpcDefinition definition, FacialAnimation animation, String... message) {
if (definition == null || definition.name == null) {
throw new IllegalArgumentException("Definition or definition name is null, not permitted.");
}
if (animation == null) {
throw new IllegalArgumentException("Animation for npc cannot be null.");
}
if (message == null || message.length < 1 || message.length > 4) {
throw new IllegalArgumentException("Amount of lines must be between 1 and 4 inclusive. ");
}
links.add(new DialogueLink(new NpcDialogue(definition, animation, message)));
return this;
}
public DialogueChain statement(String... messages) {
if (messages == null || messages.length == 0 || messages.length > 6) {
throw new IllegalArgumentException("Messages cannot be null and must contain between 1 and 5 elements.");
}
links.add(new DialogueLink(new StatementDialogue(messages)));
return this;
}