feat: Answer requirements

This commit is contained in:
2026-02-18 09:13:00 +01:00
parent a8ce7b8ed1
commit 8935349f92
4 changed files with 257 additions and 88 deletions

1
.idea/compiler.xml generated
View File

@@ -34,6 +34,7 @@
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.38/lombok-1.18.38.jar" /> <entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.38/lombok-1.18.38.jar" />
</processorPath> </processorPath>
<module name="game (1)" /> <module name="game (1)" />
<module name="game" />
</profile> </profile>
</annotationProcessing> </annotationProcessing>
</component> </component>

View File

@@ -7,6 +7,7 @@ import cz.jzitnik.client.annotations.EventHandler;
import cz.jzitnik.client.annotations.injectors.InjectDependency; import cz.jzitnik.client.annotations.injectors.InjectDependency;
import cz.jzitnik.client.annotations.injectors.InjectState; import cz.jzitnik.client.annotations.injectors.InjectState;
import cz.jzitnik.client.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.client.game.GameState;
import cz.jzitnik.client.game.dialog.Dialog; import cz.jzitnik.client.game.dialog.Dialog;
import cz.jzitnik.client.game.dialog.OnEnd; import cz.jzitnik.client.game.dialog.OnEnd;
import cz.jzitnik.client.states.DialogState; import cz.jzitnik.client.states.DialogState;
@@ -22,8 +23,8 @@ import cz.jzitnik.client.utils.events.EventManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.awt.*; import java.awt.*;
import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
@Slf4j @Slf4j
@EventHandler(Dialog.class) @EventHandler(Dialog.class)
@@ -38,6 +39,9 @@ public class DialogEventHandler extends AbstractEventHandler<Dialog> {
@InjectState @InjectState
private ScreenBuffer screenBuffer; private ScreenBuffer screenBuffer;
@InjectState
private GameState gameState;
@InjectDependency @InjectDependency
private EventManager eventManager; private EventManager eventManager;
@@ -56,32 +60,45 @@ public class DialogEventHandler extends AbstractEventHandler<Dialog> {
public static final int BUTTON_PADDING = 5; public static final int BUTTON_PADDING = 5;
private static final float FONT_SIZE = 15f; private static final float FONT_SIZE = 15f;
public static int calculateButtonHeight(Dialog dialog) { public static int calculateButtonHeight(Dialog dialog, GameState gameState) {
if (dialog.getOnEnd() instanceof OnEnd.AskQuestion(OnEnd.AskQuestion.Answer[] answers)) { if (dialog.getOnEnd() instanceof OnEnd.AskQuestion askQuestion) {
return answers.length * BUTTON_HEIGHT + (answers.length - 1) * BUTTON_PADDING; int count = askQuestion.answers(gameState).length;
} else { return count * BUTTON_HEIGHT + Math.max(0, count - 1) * BUTTON_PADDING;
return 0;
} }
return 0;
} }
public static int getYStartButtons(TextRenderer textRenderer, Dialog dialog) { public static int getYStartButtons(TextRenderer textRenderer, Dialog dialog) {
var textSize = textRenderer.measureText(dialog.getText(), WIDTH - PADDING * 2, FONT_SIZE); var textSize = textRenderer.measureText(
dialog.getText(),
WIDTH - PADDING * 2,
FONT_SIZE
);
return PADDING + textSize.height + BUTTON_PADDING; return PADDING + textSize.height + BUTTON_PADDING;
} }
public static TerminalSize getSize(TextRenderer textRenderer, Dialog dialog) { public static TerminalSize getSize(TextRenderer textRenderer, Dialog dialog, GameState gameState) {
var textSize = textRenderer.measureText(dialog.getText(), WIDTH - PADDING * 2, FONT_SIZE); var textSize = textRenderer.measureText(
dialog.getText(),
WIDTH - PADDING * 2,
FONT_SIZE
);
return new TerminalSize(300, PADDING + textSize.height + ( int buttonsHeight = 0;
dialog.getOnEnd() instanceof OnEnd.AskQuestion ? BUTTON_PADDING + calculateButtonHeight(dialog) : 0 if (dialog.getOnEnd() instanceof OnEnd.AskQuestion) {
) + PADDING); buttonsHeight = BUTTON_PADDING + calculateButtonHeight(dialog, gameState);
}
return new TerminalSize(
300,
PADDING + textSize.height + buttonsHeight + PADDING
);
} }
public static TerminalPosition getStart(TerminalSize terminalSize, TerminalSize size) { public static TerminalPosition getStart(TerminalSize terminalSize, TerminalSize size) {
int startY = terminalSize.getRows() * 2 - MARGIN_BOTTOM - size.getRows(); int startY = terminalSize.getRows() * 2 - MARGIN_BOTTOM - size.getRows();
int startX = (terminalSize.getColumns() / 2) - (size.getColumns() / 2); int startX = (terminalSize.getColumns() / 2) - (size.getColumns() / 2);
return new TerminalPosition(startX, startY); return new TerminalPosition(startX, startY);
} }
@@ -89,58 +106,114 @@ public class DialogEventHandler extends AbstractEventHandler<Dialog> {
public void handle(Dialog event) { public void handle(Dialog event) {
boolean onlyLast = dialogState.getCurrentDialog() == event; boolean onlyLast = dialogState.getCurrentDialog() == event;
dialogState.setCurrentDialog(event); dialogState.setCurrentDialog(event);
TerminalSize terminalSize = terminalState.getTerminalScreen().getTerminalSize(); TerminalSize terminalSize = terminalState.getTerminalScreen().getTerminalSize();
var overrideBuffer = screenBuffer.getGlobalOverrideBuffer(); var overrideBuffer = screenBuffer.getGlobalOverrideBuffer();
var size = getSize(textRenderer, event); var size = getSize(textRenderer, event, gameState);
var start = getStart(terminalSize, size); var start = getStart(terminalSize, size);
var animation = textRenderer.renderTypingAnimation(event.getText(), size.getColumns() - PADDING * 2, size.getRows() - PADDING * 2, Color.WHITE, FONT_SIZE); var animation = textRenderer.renderTypingAnimation(
var textSize = textRenderer.measureText(event.getText(), size.getColumns() - PADDING * 2, FONT_SIZE); event.getText(),
size.getColumns() - PADDING * 2,
size.getRows() - PADDING * 2,
Color.WHITE,
FONT_SIZE
);
var textSize = textRenderer.measureText(
event.getText(),
size.getColumns() - PADDING * 2,
FONT_SIZE
);
OnEnd onEnd = event.getOnEnd(); OnEnd onEnd = event.getOnEnd();
List<AlphaPixel[][]> answersBuf = new ArrayList<>(); List<AlphaPixel[][]> answersBuf = new ArrayList<>();
OnEnd.AskQuestion askQuestion = null;
if (onEnd instanceof OnEnd.AskQuestion( if (onEnd instanceof OnEnd.AskQuestion aq) {
OnEnd.AskQuestion.Answer[] answers askQuestion = aq;
)) { for (OnEnd.AskQuestion.Answer answer : aq.answers(gameState)) {
for (OnEnd.AskQuestion.Answer answer : answers) { answersBuf.add(
answersBuf.add(textRenderer.renderText(answer.answer(), size.getColumns() - PADDING * 2, BUTTON_HEIGHT, Color.BLACK, FONT_SIZE, false)); textRenderer.renderText(
answer.answer(),
size.getColumns() - PADDING * 2,
BUTTON_HEIGHT,
Color.BLACK,
FONT_SIZE,
false
)
);
} }
} }
dialogState.setRenderInProgress(true); dialogState.setRenderInProgress(true);
try { try {
for (int i = onlyLast ? animation.length : 0; i <= animation.length; i++) { for (int i = onlyLast ? animation.length : 0; i <= animation.length; i++) {
var buf = animation[Math.min(i, animation.length - 1)]; var buf = animation[Math.min(i, animation.length - 1)];
for (int y = 0; y < size.getRows(); y++) { for (int y = 0; y < size.getRows(); y++) {
for (int x = 0; x < size.getColumns(); x++) { for (int x = 0; x < size.getColumns(); x++) {
var textPixel = buf[Math.min(Math.max(0, y - PADDING), buf.length - 1)][Math.min(Math.max(0, x - PADDING), buf[0].length - 1)];
if (textPixel instanceof Empty || y < PADDING || x < PADDING || x >= size.getColumns() - PADDING || y >= size.getRows() - PADDING) { var textPixel = buf[
if (i == animation.length && y - 2 > textSize.height + QUESTION_ACTIONS_GAP && onEnd instanceof OnEnd.AskQuestion( Math.min(Math.max(0, y - PADDING), buf.length - 1)
OnEnd.AskQuestion.Answer[] answers ][
)) { Math.min(Math.max(0, x - PADDING), buf[0].length - 1)
];
if (textPixel instanceof Empty
|| y < PADDING
|| x < PADDING
|| x >= size.getColumns() - PADDING
|| y >= size.getRows() - PADDING) {
if (i == animation.length
&& askQuestion != null
&& y - 2 > textSize.height + QUESTION_ACTIONS_GAP) {
var answers = askQuestion.answers(gameState);
int buttonsY = y - textSize.height - QUESTION_ACTIONS_GAP - 2; int buttonsY = y - textSize.height - QUESTION_ACTIONS_GAP - 2;
int buttonIndex = buttonsY / (BUTTON_HEIGHT + BUTTON_PADDING); int buttonIndex = buttonsY / (BUTTON_HEIGHT + BUTTON_PADDING);
int rest = buttonsY % (BUTTON_HEIGHT + BUTTON_PADDING); int rest = buttonsY % (BUTTON_HEIGHT + BUTTON_PADDING);
if (buttonIndex < answers.length && rest < BUTTON_HEIGHT && x >= PADDING && x < size.getColumns() - PADDING) { if (buttonIndex < answers.length
&& rest < BUTTON_HEIGHT
&& x >= PADDING
&& x < size.getColumns() - PADDING) {
int localY = rest - BUTTON_TEXT_PADDING; int localY = rest - BUTTON_TEXT_PADDING;
int localX = x - PADDING - BUTTON_TEXT_PADDING; int localX = x - PADDING - BUTTON_TEXT_PADDING;
var buttonBuf = answersBuf.get(buttonIndex); var buttonBuf = answersBuf.get(buttonIndex);
var buttonTextPixel = buttonBuf[Math.min(Math.max(0, localY), buttonBuf.length - 1)][Math.min(Math.max(0, localX), buttonBuf[0].length - 1)]; var buttonTextPixel = buttonBuf[
Math.min(Math.max(0, localY), buttonBuf.length - 1)
][
Math.min(Math.max(0, localX), buttonBuf[0].length - 1)
];
if (buttonTextPixel instanceof Empty || localY < 0 || localX < 0 || localY >= buttonBuf.length || localX >= buttonBuf[0].length) { if (buttonTextPixel instanceof Empty
overrideBuffer[start.getRow() + y][start.getColumn() + x] = new ColoredPixel(new TextColor.RGB(255, 255, 255), dialogState.getHoveredButtonIndex() == buttonIndex ? 0.8f : 0.6f); || localY < 0
|| localX < 0
|| localY >= buttonBuf.length
|| localX >= buttonBuf[0].length) {
overrideBuffer[start.getRow() + y][start.getColumn() + x] =
new ColoredPixel(
new TextColor.RGB(255, 255, 255),
dialogState.getHoveredButtonIndex() == buttonIndex ? 0.8f : 0.6f
);
} else { } else {
overrideBuffer[start.getRow() + y][start.getColumn() + x] = buttonTextPixel; overrideBuffer[start.getRow() + y][start.getColumn() + x] =
buttonTextPixel;
} }
continue; continue;
} }
} }
overrideBuffer[start.getRow() + y][start.getColumn() + x] = new ColoredPixel(new TextColor.RGB(0, 0, 0), 0.6f); overrideBuffer[start.getRow() + y][start.getColumn() + x] =
new ColoredPixel(new TextColor.RGB(0, 0, 0), 0.6f);
continue; continue;
} }
@@ -152,7 +225,10 @@ public class DialogEventHandler extends AbstractEventHandler<Dialog> {
new RerenderScreen( new RerenderScreen(
new RerenderScreen.ScreenPart( new RerenderScreen.ScreenPart(
start, start,
new TerminalPosition(start.getColumn() + size.getColumns(), start.getRow() + size.getRows()) new TerminalPosition(
start.getColumn() + size.getColumns(),
start.getRow() + size.getRows()
)
) )
) )
); );
@@ -161,7 +237,6 @@ public class DialogEventHandler extends AbstractEventHandler<Dialog> {
} }
dialogState.setRenderInProgress(false); dialogState.setRenderInProgress(false);
next(onEnd, start, size); next(onEnd, start, size);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -171,34 +246,38 @@ public class DialogEventHandler extends AbstractEventHandler<Dialog> {
private void next(OnEnd onEnd, TerminalPosition start, TerminalSize size) throws InterruptedException { private void next(OnEnd onEnd, TerminalPosition start, TerminalSize size) throws InterruptedException {
Thread.sleep(1000); Thread.sleep(1000);
if (onEnd instanceof OnEnd.Continue(Dialog nextDialog)) {
for (int y = start.getRow(); y < start.getRow() + size.getRows(); y++) {
for (int x = start.getColumn(); x < start.getColumn() + size.getColumns(); x++) {
screenBuffer.getGlobalOverrideBuffer()[y][x] = new Empty();
}
}
if (onEnd instanceof OnEnd.Continue(Dialog nextDialog)) {
clear(start, size);
eventManager.emitEvent(nextDialog); eventManager.emitEvent(nextDialog);
} else if (onEnd instanceof OnEnd.RunCode(Runnable runnable, OnEnd end)) { } else if (onEnd instanceof OnEnd.RunCode(Runnable runnable, OnEnd end)) {
dependencyManager.inject(runnable); dependencyManager.inject(runnable);
runnable.run(); runnable.run();
next(end, start, size); next(end, start, size);
} else if (onEnd instanceof OnEnd.End) {
for (int y = start.getRow(); y < start.getRow() + size.getRows(); y++) {
for (int x = start.getColumn(); x < start.getColumn() + size.getColumns(); x++) {
screenBuffer.getGlobalOverrideBuffer()[y][x] = new Empty();
}
}
} else if (onEnd instanceof OnEnd.End) {
clear(start, size);
dialogState.setCurrentDialog(null); dialogState.setCurrentDialog(null);
eventManager.emitEvent( eventManager.emitEvent(
new RerenderScreen( new RerenderScreen(
new RerenderScreen.ScreenPart( new RerenderScreen.ScreenPart(
start, start,
new TerminalPosition(start.getColumn() + size.getColumns(), start.getRow() + size.getRows()) new TerminalPosition(
start.getColumn() + size.getColumns(),
start.getRow() + size.getRows()
)
) )
) )
); );
} }
} }
private void clear(TerminalPosition start, TerminalSize size) {
for (int y = start.getRow(); y < start.getRow() + size.getRows(); y++) {
for (int x = start.getColumn(); x < start.getColumn() + size.getColumns(); x++) {
screenBuffer.getGlobalOverrideBuffer()[y][x] = new Empty();
}
}
}
} }

View File

@@ -4,6 +4,11 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import cz.jzitnik.client.game.GameState;
import cz.jzitnik.client.game.Requirement;
import java.util.Arrays;
import java.util.Optional;
@JsonTypeInfo( @JsonTypeInfo(
use = JsonTypeInfo.Id.NAME, use = JsonTypeInfo.Id.NAME,
@@ -15,9 +20,11 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonSubTypes.Type(value = OnEnd.End.class, name = "end"), @JsonSubTypes.Type(value = OnEnd.End.class, name = "end"),
}) })
public interface OnEnd { public interface OnEnd {
record End() implements OnEnd {} record End() implements OnEnd {
}
record RunCode(Runnable runnable, OnEnd onEnd) implements OnEnd {} // TODO: Serialize record RunCode(Runnable runnable, OnEnd onEnd) implements OnEnd {
} // TODO: Serialize
record Continue(Dialog nextDialog) implements OnEnd { record Continue(Dialog nextDialog) implements OnEnd {
@JsonCreator @JsonCreator
@@ -32,15 +39,46 @@ public interface OnEnd {
this.answers = answers; this.answers = answers;
} }
public record Answer(String answer, Dialog dialog) { public record Answer(
String answer,
Dialog dialog,
Optional<Requirement> requirement
) {
@JsonCreator @JsonCreator
public Answer( public Answer(
@JsonProperty("answer") String answer, @JsonProperty("answer") String answer,
@JsonProperty("dialog") Dialog dialog @JsonProperty("dialog") Dialog dialog,
@JsonProperty("requirement") Requirement requirement
) { ) {
this.answer = answer; this(answer, dialog, Optional.ofNullable(requirement));
this.dialog = dialog; }
}
private boolean isValid(GameState gameState) {
if (requirement.isPresent()) {
Requirement requirement = requirement().get();
if (requirement.itemType() != null) {
if (Arrays.stream(gameState.getPlayer().getInventory()).noneMatch(item -> {
if (item == null) {
return false;
}
return item.getType().getItemType().getSimpleName().equals(requirement.itemType());
})) {
return false;
}
}
return true;
}
return true;
}
}
public Answer[] answers(GameState gameState) {
return Arrays.stream(answers)
.filter(answer -> answer.isValid(gameState))
.toArray(Answer[]::new);
} }
} }
} }

View File

@@ -11,6 +11,7 @@ import cz.jzitnik.client.annotations.ui.UI;
import cz.jzitnik.client.events.MouseAction; import cz.jzitnik.client.events.MouseAction;
import cz.jzitnik.client.events.RerenderScreen; import cz.jzitnik.client.events.RerenderScreen;
import cz.jzitnik.client.events.handlers.DialogEventHandler; import cz.jzitnik.client.events.handlers.DialogEventHandler;
import cz.jzitnik.client.game.GameState;
import cz.jzitnik.client.game.dialog.OnEnd; import cz.jzitnik.client.game.dialog.OnEnd;
import cz.jzitnik.client.states.DialogState; import cz.jzitnik.client.states.DialogState;
import cz.jzitnik.client.states.ScreenBuffer; import cz.jzitnik.client.states.ScreenBuffer;
@@ -27,42 +28,57 @@ import static cz.jzitnik.client.events.handlers.DialogEventHandler.*;
@UI @UI
@Dependency @Dependency
public class DialogUI { public class DialogUI {
@InjectState @InjectState
private DialogState dialogState; private DialogState dialogState;
@InjectState @InjectState
private TerminalState terminalState; private TerminalState terminalState;
@InjectState
private ScreenBuffer screenBuffer;
@InjectState
private GameState gameState;
@InjectDependency @InjectDependency
private TextRenderer textRenderer; private TextRenderer textRenderer;
@InjectDependency @InjectDependency
private EventManager eventManager; private EventManager eventManager;
@InjectState
private ScreenBuffer screenBuffer;
@MouseHandler(MouseHandlerType.CLICK) @MouseHandler(MouseHandlerType.CLICK)
public boolean handleClick(MouseAction mouseAction) { public boolean handleClick(MouseAction mouseAction) {
if (dialogState.getCurrentDialog() == null || dialogState.isRenderInProgress()) { if (dialogState.getCurrentDialog() == null || dialogState.isRenderInProgress()) {
return false; return false;
} }
TerminalSize size = DialogEventHandler.getSize(textRenderer, dialogState.getCurrentDialog()); var dialog = dialogState.getCurrentDialog();
TerminalPosition start = DialogEventHandler.getStart(terminalState.getTerminalScreen().getTerminalSize(), size); TerminalSize size = DialogEventHandler.getSize(textRenderer, dialog, gameState);
TerminalPosition start = DialogEventHandler.getStart(
terminalState.getTerminalScreen().getTerminalSize(),
size
);
if (!(dialogState.getCurrentDialog().getOnEnd() instanceof OnEnd.AskQuestion( if (!(dialog.getOnEnd() instanceof OnEnd.AskQuestion askQuestion)) {
OnEnd.AskQuestion.Answer[] answers
))) {
setHoveredButtonIndex(-1); setHoveredButtonIndex(-1);
return false; return false;
} }
var answers = askQuestion.answers(gameState);
TerminalPosition mouse = mouseAction.getPosition(); TerminalPosition mouse = mouseAction.getPosition();
TerminalPosition mouseNormalized = new TerminalPosition(mouse.getColumn(), mouse.getRow() * 2); TerminalPosition mouseNormalized = new TerminalPosition(
mouse.getColumn(),
mouse.getRow() * 2
);
RerenderScreen.ScreenPart part = new RerenderScreen.ScreenPart( RerenderScreen.ScreenPart part = new RerenderScreen.ScreenPart(
start, start,
new TerminalPosition(start.getColumn() + size.getColumns(), start.getRow() + size.getRows()) new TerminalPosition(
start.getColumn() + size.getColumns(),
start.getRow() + size.getRows()
)
); );
if (!part.isWithin(mouseNormalized)) { if (!part.isWithin(mouseNormalized)) {
@@ -70,9 +86,13 @@ public class DialogUI {
return false; return false;
} }
int buttonsStartY = DialogEventHandler.getYStartButtons(textRenderer, dialogState.getCurrentDialog()); int buttonsStartY = DialogEventHandler.getYStartButtons(textRenderer, dialog);
TerminalPosition localPosition = new TerminalPosition(mouseNormalized.getColumn() - start.getColumn(), mouseNormalized.getRow() - start.getRow() - buttonsStartY); TerminalPosition localPosition = new TerminalPosition(
int buttonsHeight = DialogEventHandler.calculateButtonHeight(dialogState.getCurrentDialog()); mouseNormalized.getColumn() - start.getColumn(),
mouseNormalized.getRow() - start.getRow() - buttonsStartY
);
int buttonsHeight = DialogEventHandler.calculateButtonHeight(dialog, gameState);
if (localPosition.getRow() < 0 || localPosition.getRow() >= buttonsHeight) { if (localPosition.getRow() < 0 || localPosition.getRow() >= buttonsHeight) {
setHoveredButtonIndex(-1); setHoveredButtonIndex(-1);
@@ -82,23 +102,27 @@ public class DialogUI {
int buttonIndex = localPosition.getRow() / (BUTTON_HEIGHT + BUTTON_PADDING); int buttonIndex = localPosition.getRow() / (BUTTON_HEIGHT + BUTTON_PADDING);
int rest = localPosition.getRow() % (BUTTON_HEIGHT + BUTTON_PADDING); int rest = localPosition.getRow() % (BUTTON_HEIGHT + BUTTON_PADDING);
if (buttonIndex < answers.length && rest < BUTTON_HEIGHT && localPosition.getColumn() >= PADDING && localPosition.getColumn() < size.getColumns() - PADDING) { if (buttonIndex < answers.length
for (int y = start.getRow(); y < start.getRow() + size.getRows(); y++) { && rest < BUTTON_HEIGHT
for (int x = start.getColumn(); x < start.getColumn() + size.getColumns(); x++) { && localPosition.getColumn() >= PADDING
screenBuffer.getGlobalOverrideBuffer()[y][x] = new Empty(); && localPosition.getColumn() < size.getColumns() - PADDING) {
}
} clearDialog(start, size);
eventManager.emitEvent( eventManager.emitEvent(
new Event[]{ new Event[]{
new RerenderScreen( new RerenderScreen(
new RerenderScreen.ScreenPart( new RerenderScreen.ScreenPart(
start, start,
new TerminalPosition(start.getColumn() + size.getColumns(), start.getRow() + size.getRows()) new TerminalPosition(
start.getColumn() + size.getColumns(),
start.getRow() + size.getRows()
)
) )
), ),
answers[buttonIndex].dialog(), answers[buttonIndex].dialog()
}); }
);
return true; return true;
} }
@@ -112,21 +136,32 @@ public class DialogUI {
return false; return false;
} }
TerminalSize size = DialogEventHandler.getSize(textRenderer, dialogState.getCurrentDialog()); var dialog = dialogState.getCurrentDialog();
TerminalPosition start = DialogEventHandler.getStart(terminalState.getTerminalScreen().getTerminalSize(), size); TerminalSize size = DialogEventHandler.getSize(textRenderer, dialog, gameState);
TerminalPosition start = DialogEventHandler.getStart(
terminalState.getTerminalScreen().getTerminalSize(),
size
);
if (!(dialogState.getCurrentDialog().getOnEnd() instanceof OnEnd.AskQuestion( if (!(dialog.getOnEnd() instanceof OnEnd.AskQuestion askQuestion)) {
OnEnd.AskQuestion.Answer[] answers
))) {
setHoveredButtonIndex(-1); setHoveredButtonIndex(-1);
return false; return false;
} }
var answers = askQuestion.answers(gameState);
TerminalPosition mouse = mouseAction.getPosition(); TerminalPosition mouse = mouseAction.getPosition();
TerminalPosition mouseNormalized = new TerminalPosition(mouse.getColumn(), mouse.getRow() * 2); TerminalPosition mouseNormalized = new TerminalPosition(
mouse.getColumn(),
mouse.getRow() * 2
);
RerenderScreen.ScreenPart part = new RerenderScreen.ScreenPart( RerenderScreen.ScreenPart part = new RerenderScreen.ScreenPart(
start, start,
new TerminalPosition(start.getColumn() + size.getColumns(), start.getRow() + size.getRows()) new TerminalPosition(
start.getColumn() + size.getColumns(),
start.getRow() + size.getRows()
)
); );
if (!part.isWithin(mouseNormalized)) { if (!part.isWithin(mouseNormalized)) {
@@ -134,9 +169,13 @@ public class DialogUI {
return false; return false;
} }
int buttonsStartY = DialogEventHandler.getYStartButtons(textRenderer, dialogState.getCurrentDialog()); int buttonsStartY = DialogEventHandler.getYStartButtons(textRenderer, dialog);
TerminalPosition localPosition = new TerminalPosition(mouseNormalized.getColumn() - start.getColumn(), mouseNormalized.getRow() - start.getRow() - buttonsStartY); TerminalPosition localPosition = new TerminalPosition(
int buttonsHeight = DialogEventHandler.calculateButtonHeight(dialogState.getCurrentDialog()); mouseNormalized.getColumn() - start.getColumn(),
mouseNormalized.getRow() - start.getRow() - buttonsStartY
);
int buttonsHeight = DialogEventHandler.calculateButtonHeight(dialog, gameState);
if (localPosition.getRow() < 0 || localPosition.getRow() >= buttonsHeight) { if (localPosition.getRow() < 0 || localPosition.getRow() >= buttonsHeight) {
setHoveredButtonIndex(-1); setHoveredButtonIndex(-1);
@@ -146,7 +185,11 @@ public class DialogUI {
int buttonIndex = localPosition.getRow() / (BUTTON_HEIGHT + BUTTON_PADDING); int buttonIndex = localPosition.getRow() / (BUTTON_HEIGHT + BUTTON_PADDING);
int rest = localPosition.getRow() % (BUTTON_HEIGHT + BUTTON_PADDING); int rest = localPosition.getRow() % (BUTTON_HEIGHT + BUTTON_PADDING);
if (buttonIndex < answers.length && rest < BUTTON_HEIGHT && localPosition.getColumn() >= PADDING && localPosition.getColumn() < size.getColumns() - PADDING) { if (buttonIndex < answers.length
&& rest < BUTTON_HEIGHT
&& localPosition.getColumn() >= PADDING
&& localPosition.getColumn() < size.getColumns() - PADDING) {
setHoveredButtonIndex(buttonIndex); setHoveredButtonIndex(buttonIndex);
return true; return true;
} }
@@ -161,4 +204,12 @@ public class DialogUI {
eventManager.emitEvent(dialogState.getCurrentDialog()); eventManager.emitEvent(dialogState.getCurrentDialog());
} }
} }
private void clearDialog(TerminalPosition start, TerminalSize size) {
for (int y = start.getRow(); y < start.getRow() + size.getRows(); y++) {
for (int x = start.getColumn(); x < start.getColumn() + size.getColumns(); x++) {
screenBuffer.getGlobalOverrideBuffer()[y][x] = new Empty();
}
}
}
} }