|
@@ -9,341 +9,263 @@ import std.typecons;
|
|
|
import std.algorithm;
|
|
|
import variables;
|
|
|
|
|
|
+// Dialog state variables
|
|
|
int currentPage = 0;
|
|
|
float textDisplayProgress = 0.0f;
|
|
|
bool textFullyDisplayed = false;
|
|
|
|
|
|
// Texture variables
|
|
|
-bool texturesLoaded = false;
|
|
|
float circleRotationAngle = 0.0f;
|
|
|
|
|
|
// Border sizes for 9-slice scaling
|
|
|
-const int DIALOG_BORDER = 32; // Border size that won't be stretched
|
|
|
-const int CHOICE_BORDER = 32; // Border size for choice window
|
|
|
+const int DIALOG_BORDER = 32; // Border that won't be stretched
|
|
|
+const int CHOICE_BORDER = 32; // Choice window border
|
|
|
|
|
|
+// Draws a texture with 9-slice scaling
|
|
|
void draw9SliceTexture(Texture2D tex, Rectangle dest, int borderSize, Color tint) {
|
|
|
- // Source rectangle is the whole texture
|
|
|
Rectangle src = Rectangle(0, 0, tex.width, tex.height);
|
|
|
|
|
|
- // Prevent division by zero
|
|
|
- if (borderSize <= 0) borderSize = 1;
|
|
|
- if (borderSize * 2 >= src.width) borderSize = cast(int)src.width / 3;
|
|
|
- if (borderSize * 2 >= src.height) borderSize = cast(int)src.height / 3;
|
|
|
+ // Prevent invalid border sizes
|
|
|
+ borderSize = max(1, min(borderSize, tex.width/3, tex.height/3));
|
|
|
|
|
|
- // Calculate inner source rectangle (without borders)
|
|
|
Rectangle innerSrc = Rectangle(
|
|
|
- borderSize,
|
|
|
- borderSize,
|
|
|
- src.width - borderSize * 2,
|
|
|
- src.height - borderSize * 2
|
|
|
+ borderSize, borderSize,
|
|
|
+ src.width - borderSize*2, src.height - borderSize*2
|
|
|
);
|
|
|
|
|
|
- // Calculate inner destination rectangle
|
|
|
Rectangle innerDest = Rectangle(
|
|
|
- dest.x + borderSize,
|
|
|
- dest.y + borderSize,
|
|
|
- dest.width - borderSize * 2,
|
|
|
- dest.height - borderSize * 2
|
|
|
+ dest.x + borderSize, dest.y + borderSize,
|
|
|
+ dest.width - borderSize*2, dest.height - borderSize*2
|
|
|
);
|
|
|
|
|
|
- // Draw 9 parts:
|
|
|
- // 1. Top-left corner
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x, src.y, borderSize, borderSize),
|
|
|
- Rectangle(dest.x, dest.y, borderSize, borderSize),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
-
|
|
|
- // 2. Top edge
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x + borderSize, src.y, innerSrc.width, borderSize),
|
|
|
- Rectangle(dest.x + borderSize, dest.y, innerDest.width, borderSize),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
-
|
|
|
- // 3. Top-right corner
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x + src.width - borderSize, src.y, borderSize, borderSize),
|
|
|
- Rectangle(dest.x + dest.width - borderSize, dest.y, borderSize, borderSize),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
-
|
|
|
- // 4. Left edge
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x, src.y + borderSize, borderSize, innerSrc.height),
|
|
|
- Rectangle(dest.x, dest.y + borderSize, borderSize, innerDest.height),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
-
|
|
|
- // 5. Center (stretched)
|
|
|
- DrawTexturePro(tex,
|
|
|
- innerSrc,
|
|
|
- innerDest,
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
-
|
|
|
- // 6. Right edge
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x + src.width - borderSize, src.y + borderSize, borderSize, innerSrc.height),
|
|
|
- Rectangle(dest.x + dest.width - borderSize, dest.y + borderSize, borderSize, innerDest.height),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
+ // Draw all 9 parts
|
|
|
+ void drawPart(Rectangle s, Rectangle d) {
|
|
|
+ DrawTexturePro(tex, s, d, Vector2(0, 0), 0, tint);
|
|
|
+ }
|
|
|
|
|
|
- // 7. Bottom-left corner
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x, src.y + src.height - borderSize, borderSize, borderSize),
|
|
|
- Rectangle(dest.x, dest.y + dest.height - borderSize, borderSize, borderSize),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
+ // Corners
|
|
|
+ drawPart(Rectangle(src.x, src.y, borderSize, borderSize),
|
|
|
+ Rectangle(dest.x, dest.y, borderSize, borderSize));
|
|
|
+ drawPart(Rectangle(src.x + src.width - borderSize, src.y, borderSize, borderSize),
|
|
|
+ Rectangle(dest.x + dest.width - borderSize, dest.y, borderSize, borderSize));
|
|
|
+ drawPart(Rectangle(src.x, src.y + src.height - borderSize, borderSize, borderSize),
|
|
|
+ Rectangle(dest.x, dest.y + dest.height - borderSize, borderSize, borderSize));
|
|
|
+ drawPart(Rectangle(src.x + src.width - borderSize, src.y + src.height - borderSize, borderSize, borderSize),
|
|
|
+ Rectangle(dest.x + dest.width - borderSize, dest.y + dest.height - borderSize, borderSize, borderSize));
|
|
|
|
|
|
- // 8. Bottom edge
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x + borderSize, src.y + src.height - borderSize, innerSrc.width, borderSize),
|
|
|
- Rectangle(dest.x + borderSize, dest.y + dest.height - borderSize, innerDest.width, borderSize),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
+ // Edges
|
|
|
+ drawPart(Rectangle(src.x + borderSize, src.y, innerSrc.width, borderSize),
|
|
|
+ Rectangle(dest.x + borderSize, dest.y, innerDest.width, borderSize));
|
|
|
+ drawPart(Rectangle(src.x, src.y + borderSize, borderSize, innerSrc.height),
|
|
|
+ Rectangle(dest.x, dest.y + borderSize, borderSize, innerDest.height));
|
|
|
+ drawPart(Rectangle(src.x + src.width - borderSize, src.y + borderSize, borderSize, innerSrc.height),
|
|
|
+ Rectangle(dest.x + dest.width - borderSize, dest.y + borderSize, borderSize, innerDest.height));
|
|
|
+ drawPart(Rectangle(src.x + borderSize, src.y + src.height - borderSize, innerSrc.width, borderSize),
|
|
|
+ Rectangle(dest.x + borderSize, dest.y + dest.height - borderSize, innerDest.width, borderSize));
|
|
|
|
|
|
- // 9. Bottom-right corner
|
|
|
- DrawTexturePro(tex,
|
|
|
- Rectangle(src.x + src.width - borderSize, src.y + src.height - borderSize, borderSize, borderSize),
|
|
|
- Rectangle(dest.x + dest.width - borderSize, dest.y + dest.height - borderSize, borderSize, borderSize),
|
|
|
- Vector2(0, 0), 0, tint);
|
|
|
+ // Center
|
|
|
+ drawPart(innerSrc, innerDest);
|
|
|
}
|
|
|
|
|
|
-void displayDialog(string[] pages, string[] choices, ref int selectedChoice, int choicePage, Font dialogFont,
|
|
|
-bool *showDialog, ref float textSpeed, Color dialogColor,
|
|
|
-Texture2D circle, Texture2D dialogBackgroundTex, Texture2D choiceWindowTex) {
|
|
|
-
|
|
|
- int pagesLength = cast(int)pages.length;
|
|
|
- int screenWidth = GetScreenWidth();
|
|
|
- int screenHeight = GetScreenHeight();
|
|
|
+// Main dialog display function
|
|
|
+void displayDialog(string[] pages, string[] choices, ref int selectedChoice,
|
|
|
+ int choicePage, Font dialogFont, bool* showDialog,
|
|
|
+ ref float textSpeed, Texture2D circle,
|
|
|
+ Texture2D dialogBackgroundTex, Texture2D choiceWindowTex) {
|
|
|
|
|
|
- const int screenPadding = 10;
|
|
|
+ const screenWidth = GetScreenWidth();
|
|
|
+ const screenHeight = GetScreenHeight();
|
|
|
+ const screenPadding = 10;
|
|
|
|
|
|
- // Dialog background rectangle с отступами
|
|
|
+ // Dialog background rectangle with padding
|
|
|
Rectangle dialogRect = Rectangle(
|
|
|
- screenPadding, // X с отступом
|
|
|
- screenHeight - screenHeight / 3 - screenPadding, // Y с отступом
|
|
|
- screenWidth - 2 * screenPadding, // Ширина с учетом отступов
|
|
|
- screenHeight / 3 // Высота (без изменения)
|
|
|
- );
|
|
|
-
|
|
|
- // Draw dialog background with 9-slice scaling
|
|
|
- draw9SliceTexture(
|
|
|
- dialogBackgroundTex,
|
|
|
- dialogRect,
|
|
|
- DIALOG_BORDER,
|
|
|
- Color(255, 255, 255, 220) // Slightly transparent
|
|
|
+ screenPadding,
|
|
|
+ screenHeight - screenHeight/3 - screenPadding,
|
|
|
+ screenWidth - 2*screenPadding,
|
|
|
+ screenHeight/3
|
|
|
);
|
|
|
+ // Draw dialog background
|
|
|
+ draw9SliceTexture(dialogBackgroundTex, dialogRect, DIALOG_BORDER, Colors.WHITE);
|
|
|
|
|
|
+ // Text layout parameters
|
|
|
const float textLeftMargin = 33.0f;
|
|
|
const float textTopMargin = 20.0f;
|
|
|
+ const float textRightMargin = 33.0f;
|
|
|
+ const float textWidth = dialogRect.width - textLeftMargin - textRightMargin;
|
|
|
+ const float fontSize = 40.0f;
|
|
|
+ const float spacing = 1.0f;
|
|
|
+ string name;
|
|
|
|
|
|
- float marginLeft = dialogRect.x + textLeftMargin; // Отступ от левого края фона
|
|
|
- float marginRight = screenWidth/6.5f;
|
|
|
- float marginTop = dialogRect.y + textTopMargin; // Отступ от верхнего края фона
|
|
|
- float textWidth = dialogRect.width - textLeftMargin - marginRight;
|
|
|
- float fontSize = 40.0f;
|
|
|
- float spacing = 1.0f;
|
|
|
-
|
|
|
+ // Text display logic
|
|
|
string currentText = pages[currentPage];
|
|
|
- int textLength = cast(int)currentText.length;
|
|
|
-
|
|
|
- if (IsKeyPressed(KeyboardKey.KEY_ENTER) && !textFullyDisplayed) {
|
|
|
- textDisplayProgress = textLength;
|
|
|
- textFullyDisplayed = true;
|
|
|
- }
|
|
|
- else if (IsKeyPressed(KeyboardKey.KEY_ENTER) && textFullyDisplayed) {
|
|
|
- currentPage += 1;
|
|
|
- textDisplayProgress = 0.0f;
|
|
|
- textFullyDisplayed = false;
|
|
|
+ string displayText = currentText;
|
|
|
+
|
|
|
+ if (currentText[0] == '[') {
|
|
|
+
|
|
|
+ size_t start = currentText.indexOf('[') + 1;
|
|
|
+ size_t end = currentText.lastIndexOf(']');
|
|
|
+ name = currentText[start..end];
|
|
|
+
|
|
|
+ size_t nameStart = currentText.indexOf('[');
|
|
|
+ size_t nameEnd = currentText.lastIndexOf(']') + 1;
|
|
|
+ displayText = currentText[0..nameStart] ~ currentText[nameEnd..$];
|
|
|
+ Rectangle nameRect = Rectangle(
|
|
|
+ screenPadding,
|
|
|
+ dialogRect.y - screenHeight/12,
|
|
|
+ screenWidth / 12 + MeasureTextEx(dialogFont, name.toStringz(), fontSize, spacing).x,
|
|
|
+ screenHeight / 12
|
|
|
+ );
|
|
|
+ draw9SliceTexture(choiceWindowTex, nameRect, DIALOG_BORDER, Colors.WHITE);
|
|
|
+ Vector2 nameSize = MeasureTextEx(dialogFont, name.toStringz(), fontSize, spacing);
|
|
|
+
|
|
|
+ Vector2 namePos = Vector2(
|
|
|
+ nameRect.x + (nameRect.width - nameSize.x) / 2,
|
|
|
+ nameRect.y + (nameRect.height - nameSize.y) / 2
|
|
|
+ );
|
|
|
+
|
|
|
+ DrawTextEx(dialogFont, name.toStringz(), namePos + Vector2(2, 2), fontSize, spacing, Colors.BLACK);
|
|
|
+ DrawTextEx(dialogFont, name.toStringz(), namePos, fontSize, spacing, Colors.WHITE);
|
|
|
}
|
|
|
- else if (!textFullyDisplayed) {
|
|
|
- textDisplayProgress += textSpeed;
|
|
|
- if (textDisplayProgress >= textLength) {
|
|
|
- textDisplayProgress = textLength;
|
|
|
+
|
|
|
+ if (IsKeyPressed(KeyboardKey.KEY_ENTER)) {
|
|
|
+ if (!textFullyDisplayed) {
|
|
|
+ textDisplayProgress = displayText.length;
|
|
|
textFullyDisplayed = true;
|
|
|
+ } else {
|
|
|
+ currentPage++;
|
|
|
+ textDisplayProgress = 0.0f;
|
|
|
+ textFullyDisplayed = false;
|
|
|
}
|
|
|
+ } else if (!textFullyDisplayed) {
|
|
|
+ textDisplayProgress = min(textDisplayProgress + textSpeed, cast(float)displayText.length);
|
|
|
+ textFullyDisplayed = textDisplayProgress >= displayText.length;
|
|
|
}
|
|
|
|
|
|
- int charsToShow = cast(int)textDisplayProgress;
|
|
|
- string displayedText = currentText[0 .. min(charsToShow, textLength)];
|
|
|
-
|
|
|
+ // Split text into lines that fit the dialog width
|
|
|
string[] lines;
|
|
|
- string remainingText = displayedText;
|
|
|
+ string remaining = displayText[0..min(cast(int)textDisplayProgress, displayText.length)];
|
|
|
|
|
|
- while (remainingText.length > 0) {
|
|
|
+ while (!remaining.empty) {
|
|
|
int fitChars = 0;
|
|
|
- float width = 0.0f;
|
|
|
+ float lineWidth = 0.0f;
|
|
|
|
|
|
- while (fitChars < remainingText.length) {
|
|
|
- int nextChar = fitChars;
|
|
|
- while (nextChar < remainingText.length && !isWhite(remainingText[nextChar])) {
|
|
|
- nextChar++;
|
|
|
- }
|
|
|
+ while (fitChars < remaining.length) {
|
|
|
+ int wordEnd = fitChars;
|
|
|
+ while (wordEnd < remaining.length && !remaining[wordEnd].isWhite) wordEnd++;
|
|
|
|
|
|
- string word = remainingText[fitChars..nextChar];
|
|
|
+ string word = remaining[fitChars..wordEnd];
|
|
|
float wordWidth = MeasureTextEx(dialogFont, word.toStringz(), fontSize, spacing).x;
|
|
|
|
|
|
- if (width + wordWidth > textWidth && width > 0) {
|
|
|
- break;
|
|
|
- }
|
|
|
+ if (lineWidth > 0 && lineWidth + wordWidth > textWidth) break;
|
|
|
|
|
|
- width += wordWidth;
|
|
|
- fitChars = nextChar;
|
|
|
+ lineWidth += wordWidth;
|
|
|
+ fitChars = wordEnd;
|
|
|
|
|
|
- while (fitChars < remainingText.length && isWhite(remainingText[fitChars])) {
|
|
|
- width += MeasureTextEx(dialogFont, " ".toStringz(), fontSize, spacing).x;
|
|
|
+ // Add whitespace
|
|
|
+ while (fitChars < remaining.length && remaining[fitChars].isWhite) {
|
|
|
+ lineWidth += MeasureTextEx(dialogFont, " ".toStringz(), fontSize, spacing).x;
|
|
|
fitChars++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (fitChars == 0) {
|
|
|
- fitChars = 1;
|
|
|
- }
|
|
|
-
|
|
|
- lines ~= remainingText[0..fitChars];
|
|
|
- remainingText = remainingText[fitChars..$];
|
|
|
+ if (fitChars == 0) fitChars = 1;
|
|
|
+ lines ~= remaining[0..fitChars];
|
|
|
+ remaining = remaining[fitChars..$];
|
|
|
}
|
|
|
|
|
|
- float lineHeight = MeasureTextEx(dialogFont, "A", fontSize, spacing).y * 1.4;
|
|
|
- for (int i = 0; i < lines.length; i++) {
|
|
|
- DrawTextEx(
|
|
|
- dialogFont,
|
|
|
- lines[i].toStringz(),
|
|
|
- Vector2(marginLeft+3, 3+(marginTop + i * lineHeight)),
|
|
|
- fontSize,
|
|
|
- spacing,
|
|
|
- Colors.BLACK
|
|
|
- );
|
|
|
- DrawTextEx(
|
|
|
- dialogFont,
|
|
|
- lines[i].toStringz(),
|
|
|
- Vector2(marginLeft, marginTop + i * lineHeight),
|
|
|
- fontSize,
|
|
|
- spacing,
|
|
|
- Colors.WHITE
|
|
|
- );
|
|
|
+ // Draw text lines with shadow effect
|
|
|
+ const float lineHeight = MeasureTextEx(dialogFont, "A", fontSize, spacing).y * 1.4;
|
|
|
+ foreach(i, line; lines) {
|
|
|
+ Vector2 pos = Vector2(dialogRect.x + textLeftMargin, dialogRect.y + textTopMargin + i*lineHeight);
|
|
|
+ DrawTextEx(dialogFont, line.toStringz(), pos + Vector2(3, 3), fontSize, spacing, Colors.BLACK);
|
|
|
+ DrawTextEx(dialogFont, line.toStringz(), pos, fontSize, spacing, Colors.WHITE);
|
|
|
}
|
|
|
|
|
|
- if (textFullyDisplayed && lines.length > 0) {
|
|
|
- // Обновляем угол вращения (например, 45 градусов в секунду)
|
|
|
- circleRotationAngle += 45.0f * GetFrameTime();
|
|
|
- if (circleRotationAngle >= 360.0f) {
|
|
|
- circleRotationAngle -= 360.0f;
|
|
|
- }
|
|
|
-
|
|
|
- // Получаем позицию и размер последней строки текста
|
|
|
- float lastLineWidth = 10 + MeasureTextEx(dialogFont, lines[$-1].toStringz(), fontSize, spacing).x;
|
|
|
- float lastLineY = marginTop + 20 + (lines.length - 1) * lineHeight;
|
|
|
-
|
|
|
- // Позиция круга справа от последней строки
|
|
|
- float circleX = marginLeft + lastLineWidth + 10; // 10 - отступ от текста
|
|
|
- float circleY = lastLineY;
|
|
|
+ // Draw continue indicator when text is fully displayed
|
|
|
+ if (textFullyDisplayed && !lines.empty) {
|
|
|
+ circleRotationAngle = (circleRotationAngle + 45*GetFrameTime()) % 360;
|
|
|
|
|
|
- // Размер круга (можете настроить)
|
|
|
- float circleSize = 30.0f;
|
|
|
+ float lastLineWidth = MeasureTextEx(dialogFont, lines[$-1].toStringz(), fontSize, spacing).x;
|
|
|
+ Vector2 circlePos = Vector2(
|
|
|
+ dialogRect.x + textLeftMargin + lastLineWidth + 20,
|
|
|
+ dialogRect.y + textTopMargin + (lines.length-1)*lineHeight
|
|
|
+ );
|
|
|
|
|
|
- Rectangle destRect = Rectangle(circleX, circleY, circleSize, circleSize);
|
|
|
- Rectangle sourceRect = Rectangle(0, 0, circle.width, circle.height);
|
|
|
- Vector2 origin = Vector2(circleSize/2, circleSize/2);
|
|
|
DrawTexturePro(
|
|
|
circle,
|
|
|
- sourceRect,
|
|
|
- destRect,
|
|
|
- origin,
|
|
|
+ Rectangle(0, 0, circle.width, circle.height),
|
|
|
+ Rectangle(circlePos.x, circlePos.y+20, 30, 30),
|
|
|
+ Vector2(15, 15),
|
|
|
circleRotationAngle,
|
|
|
Colors.WHITE
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- if (currentPage == choicePage) {
|
|
|
- int verticalPadding = 30;
|
|
|
- int choiceHeight = 50;
|
|
|
- int choiceSpacing = 10;
|
|
|
-
|
|
|
- int choiceWindowWidth = screenWidth / 2;
|
|
|
- int choiceWindowHeight = cast(int)(verticalPadding * 2 + choices.length * choiceHeight + (choices.length - 1) * choiceSpacing);
|
|
|
-
|
|
|
- int choiceWindowX = (screenWidth - choiceWindowWidth) / 2;
|
|
|
- int choiceWindowY = (screenHeight - choiceWindowHeight) / 2;
|
|
|
-
|
|
|
- // Draw choice window with 9-slice scaling
|
|
|
- draw9SliceTexture(
|
|
|
- choiceWindowTex,
|
|
|
- Rectangle(choiceWindowX, choiceWindowY, choiceWindowWidth, choiceWindowHeight),
|
|
|
- CHOICE_BORDER,
|
|
|
- Colors.WHITE
|
|
|
+ // Choice selection logic
|
|
|
+ if (currentPage == choicePage) {
|
|
|
+ const choiceHeight = 50;
|
|
|
+ const choiceSpacing = 10;
|
|
|
+ const verticalPadding = 30;
|
|
|
+
|
|
|
+ Rectangle choiceWindow = Rectangle(
|
|
|
+ (screenWidth - screenWidth/2)/2,
|
|
|
+ (screenHeight - (verticalPadding*2 + choices.length*(choiceHeight + choiceSpacing)))/2,
|
|
|
+ screenWidth/2,
|
|
|
+ verticalPadding*2 + choices.length*(choiceHeight + choiceSpacing)
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
+ draw9SliceTexture(choiceWindowTex, choiceWindow, CHOICE_BORDER, Colors.WHITE);
|
|
|
+
|
|
|
Vector2 mousePos = GetMousePosition();
|
|
|
bool mouseClicked = IsMouseButtonPressed(MouseButton.MOUSE_BUTTON_LEFT);
|
|
|
|
|
|
- for (int i = 0; i < choices.length; i++) {
|
|
|
+ foreach(i, choice; choices) {
|
|
|
Rectangle choiceRect = Rectangle(
|
|
|
- choiceWindowX + 40,
|
|
|
- choiceWindowY + verticalPadding + i * (choiceHeight + choiceSpacing),
|
|
|
- choiceWindowWidth - 80,
|
|
|
+ choiceWindow.x + 40,
|
|
|
+ choiceWindow.y + verticalPadding + i*(choiceHeight + choiceSpacing),
|
|
|
+ choiceWindow.width - 80,
|
|
|
choiceHeight
|
|
|
);
|
|
|
|
|
|
- bool isHovered = CheckCollisionPointRec(mousePos, choiceRect);
|
|
|
+ bool hovered = CheckCollisionPointRec(mousePos, choiceRect);
|
|
|
+ if (hovered) selectedChoice = cast(int)i;
|
|
|
|
|
|
- if (isHovered) {
|
|
|
- selectedChoice = i;
|
|
|
- if (mouseClicked) {
|
|
|
- currentPage += 1;
|
|
|
- textDisplayProgress = 0.0f;
|
|
|
- textFullyDisplayed = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Color color = (i == selectedChoice) ? Colors.YELLOW : (isHovered ? Colors.LIGHTGRAY : Colors.WHITE);
|
|
|
-
|
|
|
- if (isHovered || i == selectedChoice) {
|
|
|
+ if (hovered || i == selectedChoice) {
|
|
|
DrawRectangleRec(choiceRect, Color(60, 60, 60, 200));
|
|
|
}
|
|
|
|
|
|
- Vector2 textSize = MeasureTextEx(dialogFont, choices[i].toStringz(), 39, spacing);
|
|
|
+ Vector2 textSize = MeasureTextEx(dialogFont, choice.toStringz(), 39, spacing);
|
|
|
Vector2 textPos = Vector2(
|
|
|
- choiceRect.x + (choiceRect.width - textSize.x) / 2,
|
|
|
- choiceRect.y + (choiceRect.height - textSize.y) / 2
|
|
|
- );
|
|
|
- DrawTextEx(
|
|
|
- dialogFont,
|
|
|
- choices[i].toStringz(),
|
|
|
- Vector2(textPos.x+3, textPos.y+3),
|
|
|
- 39,
|
|
|
- spacing,
|
|
|
- Colors.BLACK
|
|
|
+ choiceRect.x + (choiceRect.width - textSize.x)/2,
|
|
|
+ choiceRect.y + (choiceRect.height - textSize.y)/2
|
|
|
);
|
|
|
|
|
|
- DrawTextEx(
|
|
|
- dialogFont,
|
|
|
- choices[i].toStringz(),
|
|
|
- textPos,
|
|
|
- 39,
|
|
|
- spacing,
|
|
|
- color
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- if (IsKeyPressed(KeyboardKey.KEY_DOWN)) {
|
|
|
- selectedChoice = cast(int)((selectedChoice + 1) % choices.length);
|
|
|
- }
|
|
|
- if (IsKeyPressed(KeyboardKey.KEY_UP)) {
|
|
|
- selectedChoice = cast(int)((selectedChoice - 1 + choices.length) % choices.length);
|
|
|
- }
|
|
|
- if (IsMouseButtonPressed(MouseButton.MOUSE_BUTTON_LEFT)) {
|
|
|
- currentPage += 1;
|
|
|
- textDisplayProgress = 0.0f;
|
|
|
- textFullyDisplayed = false;
|
|
|
+ DrawTextEx(dialogFont, choice.toStringz(), textPos + Vector2(3, 3), 39, spacing, Colors.BLACK);
|
|
|
+ DrawTextEx(dialogFont, choice.toStringz(), textPos, 39, spacing,
|
|
|
+ (i == selectedChoice) ? Colors.YELLOW : (hovered ? Colors.LIGHTGRAY : Colors.WHITE));
|
|
|
+
|
|
|
+ if (hovered && mouseClicked) {
|
|
|
+ currentPage++;
|
|
|
+ textDisplayProgress = 0.0f;
|
|
|
+ textFullyDisplayed = false;
|
|
|
+ }
|
|
|
}
|
|
|
+ // Keyboard navigation
|
|
|
+ if (IsKeyPressed(KeyboardKey.KEY_DOWN)) selectedChoice = cast(int)((selectedChoice + 1) % choices.length);
|
|
|
+ if (IsKeyPressed(KeyboardKey.KEY_UP)) selectedChoice = cast(int)((selectedChoice - 1 + choices.length) % choices.length);
|
|
|
}
|
|
|
|
|
|
+ // Fast-forward with Ctrl
|
|
|
if ((IsKeyDown(KeyboardKey.KEY_LEFT_CONTROL) || IsKeyDown(KeyboardKey.KEY_RIGHT_CONTROL))
|
|
|
- && currentPage != choicePage && currentPage < pages.length) {
|
|
|
- currentPage += 1;
|
|
|
+ && currentPage != choicePage && currentPage < pages.length) {
|
|
|
+ currentPage++;
|
|
|
}
|
|
|
- if (currentPage >= pagesLength) {
|
|
|
+
|
|
|
+ // Close dialog when all pages are shown
|
|
|
+ if (currentPage >= pages.length) {
|
|
|
currentPage = 0;
|
|
|
textDisplayProgress = 0.0f;
|
|
|
textFullyDisplayed = false;
|
|
|
- pages = [];
|
|
|
- textSpeed = 0.6f;
|
|
|
*showDialog = false;
|
|
|
- return;
|
|
|
}
|
|
|
}
|