Skip to content

Commit

Permalink
Add per-dialogue custom screen layout
Browse files Browse the repository at this point in the history
  • Loading branch information
Pyrofab committed Oct 27, 2023
1 parent 29dac3d commit 6091e76
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* 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.impl.client;
package org.ladysnake.blabber.api.client;

import com.google.common.collect.ImmutableList;
import net.minecraft.client.MinecraftClient;
Expand All @@ -26,6 +26,7 @@
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.ladysnake.blabber.Blabber;
import org.ladysnake.blabber.impl.common.DialogueScreenHandler;
Expand All @@ -36,6 +37,7 @@
import java.util.List;
import java.util.stream.IntStream;

@ApiStatus.Experimental // half internal, expect some things to change
public class BlabberDialogueScreen extends HandledScreen<DialogueScreenHandler> {
public static final List<Identifier> DIALOGUE_ARROWS = IntStream.range(1, 6).mapToObj(i -> Blabber.id("container/dialogue/dialogue_arrow_" + i)).toList();
public static final List<Identifier> DIALOGUE_LOCKS = IntStream.range(1, 4).mapToObj(i -> Blabber.id("container/dialogue/dialogue_lock_" + i)).toList();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Blabber
* Copyright (C) 2022-2023 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.api.client;

import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.ApiStatus;
import org.ladysnake.blabber.impl.client.BlabberClient;
import org.ladysnake.blabber.impl.common.DialogueScreenHandler;

@ApiStatus.Experimental
public final class BlabberScreenRegistry {
/**
* Registers a custom screen provider for a {@link org.ladysnake.blabber.impl.common.model.DialogueLayout}.
*/
public static void register(
Identifier layoutId,
HandledScreens.Provider<DialogueScreenHandler, BlabberDialogueScreen> screenProvider
) {
BlabberClient.registerLayoutScreen(layoutId, screenProvider);
}
}
30 changes: 25 additions & 5 deletions src/main/java/org/ladysnake/blabber/impl/client/BlabberClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,29 @@
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.ladysnake.blabber.Blabber;
import org.ladysnake.blabber.api.client.BlabberDialogueScreen;
import org.ladysnake.blabber.api.client.BlabberScreenRegistry;
import org.ladysnake.blabber.impl.common.BlabberRegistrar;
import org.ladysnake.blabber.impl.common.DialogueScreenHandler;
import org.ladysnake.blabber.impl.common.model.DialogueLayout;
import org.ladysnake.blabber.impl.common.packets.ChoiceAvailabilityPacket;
import org.ladysnake.blabber.impl.common.packets.SelectedDialogueStatePacket;

import java.util.HashMap;
import java.util.Map;

import static io.netty.buffer.Unpooled.buffer;

public final class BlabberClient implements ClientModInitializer {
private static final boolean ENABLE_RPG_SCREEN = false;
private static final Map<Identifier, HandledScreens.Provider<DialogueScreenHandler, BlabberDialogueScreen>> screenRegistry = new HashMap<>();

@Override
public void onInitializeClient() {
HandledScreens.register(BlabberRegistrar.DIALOGUE_SCREEN_HANDLER, BlabberClient::getBlabberRpgDialogueScreen);
BlabberScreenRegistry.register(DialogueLayout.CLASSIC_LAYOUT_ID, BlabberDialogueScreen::new);
BlabberScreenRegistry.register(DialogueLayout.RPG_LAYOUT_ID, BlabberRpgDialogueScreen::new);
HandledScreens.register(BlabberRegistrar.DIALOGUE_SCREEN_HANDLER, BlabberClient::createDialogueScreen);
ClientPlayNetworking.registerGlobalReceiver(ChoiceAvailabilityPacket.TYPE, (packet, player, responseSender) -> {
if (player.currentScreenHandler instanceof DialogueScreenHandler dialogueScreenHandler) {
dialogueScreenHandler.handleAvailabilityUpdate(packet);
Expand All @@ -48,10 +58,20 @@ public void onInitializeClient() {
});
}

private static BlabberDialogueScreen getBlabberRpgDialogueScreen(DialogueScreenHandler handler, PlayerInventory inventory, Text title) {
if (ENABLE_RPG_SCREEN) {
return new BlabberRpgDialogueScreen(handler, inventory, title);
public static void registerLayoutScreen(
Identifier layoutId,
HandledScreens.Provider<DialogueScreenHandler, BlabberDialogueScreen> screenProvider
) {
screenRegistry.put(layoutId, screenProvider);
}

private static BlabberDialogueScreen createDialogueScreen(DialogueScreenHandler handler, PlayerInventory inventory, Text title) {
Identifier layoutType = handler.getLayout().type();
var provider = screenRegistry.get(layoutType);
if (provider != null) {
return provider.create(handler, inventory, title);
}
Blabber.LOGGER.error("(Blabber) No screen provider found for {}", layoutType);
return new BlabberDialogueScreen(handler, inventory, title);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.minecraft.text.Text;
import net.minecraft.util.math.ColorHelper;
import org.joml.Matrix4f;
import org.ladysnake.blabber.api.client.BlabberDialogueScreen;
import org.ladysnake.blabber.impl.common.DialogueScreenHandler;
import org.ladysnake.blabber.impl.common.machine.AvailableChoice;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.ladysnake.blabber.impl.common.machine.AvailableChoice;
import org.ladysnake.blabber.impl.common.machine.DialogueStateMachine;
import org.ladysnake.blabber.impl.common.model.ChoiceResult;
import org.ladysnake.blabber.impl.common.model.DialogueLayout;
import org.ladysnake.blabber.impl.common.packets.ChoiceAvailabilityPacket;

public class DialogueScreenHandler extends ScreenHandler {
Expand All @@ -46,6 +47,10 @@ public DialogueScreenHandler(@Nullable ScreenHandlerType<?> type, int syncId, Di
this.dialogue = dialogue;
}

public DialogueLayout getLayout() {
return this.dialogue.getLayout();
}

public boolean isUnskippable() {
return this.dialogue.isUnskippable();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.ladysnake.blabber.impl.common.InstancedDialogueAction;
import org.ladysnake.blabber.impl.common.model.ChoiceResult;
import org.ladysnake.blabber.impl.common.model.DialogueChoiceCondition;
import org.ladysnake.blabber.impl.common.model.DialogueLayout;
import org.ladysnake.blabber.impl.common.model.DialogueState;
import org.ladysnake.blabber.impl.common.model.DialogueTemplate;
import org.ladysnake.blabber.impl.common.model.UnavailableAction;
Expand All @@ -53,6 +54,7 @@ public final class DialogueStateMachine {

private final Map<String, DialogueState> states;
private final Identifier id;
private final DialogueLayout layout;
private final boolean unskippable;
private final Map<String, Int2BooleanMap> conditionalChoices;
private @Nullable String currentStateKey;
Expand All @@ -63,6 +65,7 @@ public DialogueStateMachine(DialogueTemplate template, Identifier id) {
}

private DialogueStateMachine(DialogueTemplate template, Identifier id, String start) {
this.layout = template.layout();
this.states = template.states();
this.id = id;
this.unskippable = template.unskippable();
Expand Down Expand Up @@ -107,6 +110,10 @@ public Identifier getId() {
return this.id;
}

public DialogueLayout getLayout() {
return this.layout;
}

public Text getCurrentText() {
return this.getCurrentState().text();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Blabber
* Copyright (C) 2022-2023 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.impl.common.model;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.Identifier;
import org.ladysnake.blabber.Blabber;

// TODO change to a polymorphic type + registry to allow passing arbitrary data to the screen
public record DialogueLayout(Identifier type) {
public static final Codec<DialogueLayout> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Identifier.CODEC.fieldOf("type").forGetter(DialogueLayout::type)
).apply(instance, DialogueLayout::new));
public static final Identifier CLASSIC_LAYOUT_ID = Blabber.id("classic");
public static final Identifier RPG_LAYOUT_ID = Blabber.id("rpg");
public static final DialogueLayout DEFAULT = new DialogueLayout(CLASSIC_LAYOUT_ID);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public final class DialogueTemplate {
public static final Codec<DialogueTemplate> CODEC = Codecs.validate(RecordCodecBuilder.create(instance -> instance.group(
Codec.STRING.fieldOf("start_at").forGetter(DialogueTemplate::start),
Codec.BOOL.optionalFieldOf("unskippable", false).forGetter(DialogueTemplate::unskippable),
Codec.unboundedMap(Codec.STRING, DialogueState.CODEC).fieldOf("states").forGetter(DialogueTemplate::states)
Codec.unboundedMap(Codec.STRING, DialogueState.CODEC).fieldOf("states").forGetter(DialogueTemplate::states),
DialogueLayout.CODEC.optionalFieldOf("layout", DialogueLayout.DEFAULT).forGetter(DialogueTemplate::layout)
).apply(instance, DialogueTemplate::new)), DialogueTemplate::validateStructure);

private static DataResult<DialogueTemplate> validateStructure(DialogueTemplate dialogue) {
Expand Down Expand Up @@ -109,11 +110,13 @@ private static DataResult<DialogueTemplate> validateStructure(DialogueTemplate d
private final String start;
private final boolean unskippable;
private final Map<String, DialogueState> states;
private final DialogueLayout layout;

private DialogueTemplate(String start, boolean unskippable, Map<String, DialogueState> states) {
private DialogueTemplate(String start, boolean unskippable, Map<String, DialogueState> states, DialogueLayout layout) {
this.start = start;
this.unskippable = unskippable;
this.states = Map.copyOf(states);
this.layout = layout;
}

public boolean unskippable() {
Expand All @@ -128,6 +131,10 @@ public Map<String, DialogueState> states() {
return states;
}

public DialogueLayout layout() {
return this.layout;
}

@Override
public String toString() {
return "DialogueTemplate[start=%s, states=%s%s]".formatted(start, states, unskippable ? " (unskippable)" : "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import me.shedaniel.rei.api.client.registry.screen.OverlayDecider;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ActionResult;
import org.ladysnake.blabber.impl.client.BlabberDialogueScreen;
import org.ladysnake.blabber.api.client.BlabberDialogueScreen;

public class BlabberOverlayDecider implements OverlayDecider {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import dev.emi.emi.screen.EmiScreenManager;
import net.minecraft.client.MinecraftClient;
import org.ladysnake.blabber.impl.client.BlabberDialogueScreen;
import org.ladysnake.blabber.api.client.BlabberDialogueScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
Expand Down

0 comments on commit 6091e76

Please sign in to comment.