Skip to content

Add support for Npc Dialogues - #15

Open
TotallyNoCallum wants to merge 5 commits into
GeyserMC:masterfrom
TotallyNoCallum:master
Open

Add support for Npc Dialogues#15
TotallyNoCallum wants to merge 5 commits into
GeyserMC:masterfrom
TotallyNoCallum:master

Conversation

@TotallyNoCallum

@TotallyNoCallum TotallyNoCallum commented Sep 8, 2026

Copy link
Copy Markdown

This PR is my attempt at adding NPC Dialogues as NpcForms to Cumulus (Would close #4 )
This will also require changes in Geyser (GeyserMC/Geyser#6690), Floodgate works with this without any changes (besides bumping cumulus to 2.0.0 there)

image
Code for this ^ image

(armorStand is an ArmorStand in Paper's api)

FloodgateApi.getInstance().getPlayer(p.getUniqueId()).sendForm(
                                      NpcForm.builder()
                                              .title("Title")
                                              .content("Content")
                                              .entity(armorStand.getUniqueId())
                                              .button("button 1")
                                              .button("button 2")
                                              .button("button 3")
                                              .validResultHandler(response -> {
                                                  p.sendRichMessage("You clicked button " + (response.clickedButtonId() + 1));
                                                  //run on main thread
                                                  new BukkitRunnable() {
                                                      public void run() {
                                                          armorStand.remove();
                                                          cancel();
                                                      }
                                                  }.runTaskTimer(GeyserNpcDialogTest.getPlugin(GeyserNpcDialogTest.class), 1, 1);
                                              })
                                              .build()
                              );

Buttons are also entirely optional (which also means validResultHandler intentionally isn't usable in this case)
image

Code for this ^ image

(fish is a Silverfish in Paper's api)

FloodgateApi.getInstance().getPlayer(p.getUniqueId()).sendForm(
                                      NpcForm.builder()
                                              .title("Crazy?")
                                              .content("Crazy? I was crazy once, They locked me in a room, a rubber room, a rubber room of rats, and rats make me crazy")
                                              .entity(fish.getUniqueId())
                                              .entityOffset(-7, 0, 0)
                                              .closedOrInvalidResultHandler(response -> {
                                                  //run on main thread
                                                  new BukkitRunnable() {
                                                      public void run() {
                                                          fish.remove();
                                                          cancel();
                                                      }
                                                  }.runTaskTimer(GeyserNpcDialogTest.getPlugin(GeyserNpcDialogTest.class), 1, 1);
                                              })
                                              .build()
                              );

The limitations of this are that Npcforms can only have 6 buttons (from my testing, adding more causes all the buttons to vanish), and Player/Mannequin entities specifically dont show up in the entity portrait (I believe due to client limitations)

I decided on making a .button() method instead of .button1(), .button2(), .button3(), etc (like how ModalForm has it), as working with 6 button string would get messy imo. Speaking of, I made the buttons Strings instead of ButtonComponents since they cant have images, and also how the json is layed out in the dialogue packet in Geyser/actionJson. Calling .button() when theres already 6 buttons will be silently ignored

For the npc_data and actionJson variables in NpcFormImpl.java, I used rtm516/Geyser@95cb8a4 as a reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggestion: Add NPC Forms?

1 participant