From cbb5f3e2ae79e5127e920f2650e3b2adf4086ff4 Mon Sep 17 00:00:00 2001 From: bigguy345 Date: Thu, 25 Dec 2025 01:35:27 +0200 Subject: [PATCH] Made method call underlines work multi lines --- .../script/interpreter/ScriptDocument.java | 4 + .../util/script/interpreter/ScriptLine.java | 97 ++++++++++++++++++- .../gui/util/script/interpreter/Token.java | 39 -------- 3 files changed, 98 insertions(+), 42 deletions(-) diff --git a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java index 6f9d63fdd..78209f711 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java @@ -2631,6 +2631,10 @@ public class ScriptDocument { return Collections.unmodifiableList(methods); } + public List getMethodCalls() { + return Collections.unmodifiableList(methodCalls); + } + public Map getGlobalFields() { return Collections.unmodifiableMap(globalFields); } diff --git a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptLine.java b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptLine.java index 26d8ec848..9274a998f 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptLine.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptLine.java @@ -221,9 +221,6 @@ public class ScriptLine { builder.append(gapText); currentX += ClientProxy.Font.width(gapText); } - - // Track underline position if token has one - t.drawUnderline(currentX, y + ClientProxy.Font.height() - 1); // Append the colored token @@ -244,6 +241,100 @@ public class ScriptLine { // Draw the text ClientProxy.Font.drawString(builder.toString(), x, y, defaultColor); + + // Draw underlines for method call arguments that intersect this line + drawMethodCallUnderlines(x, y + ClientProxy.Font.height() - 1); + } + + /** + * Draw underlines for all method call arguments that intersect this line. + * Uses the same token-walking logic as Token.drawUnderline but applies it + * to ALL method calls in the document, enabling multi-line underlines. + */ + private void drawMethodCallUnderlines(int lineStartX, int baselineY) { + if (parent == null) + return; + + ScriptDocument doc = parent; + String lineText = getText(); + int lineStart = getGlobalStart(); + int lineEnd = getGlobalEnd(); + + // Check all method calls in the document + for (MethodCallInfo call : doc.getMethodCalls()) { + // Skip method declarations that were erroneously recorded as calls. + boolean isDeclaration = false; + int methodStart = call.getMethodNameStart(); + for (MethodInfo mi : doc.getMethods()) { + //SKIP method declarations cause for some reason their underlines are drawn here + if (mi.getDeclarationOffset() <= methodStart && mi.getBodyStart() >= methodStart) { + isDeclaration = true; + break; + } + } + if (isDeclaration) + continue; + // Skip if this call doesn't intersect this line + if (call.getCloseParenOffset() < lineStart || call.getOpenParenOffset() > lineEnd) + continue; + + // Handle arg count errors (underline the method name) + if (call.hasArgCountError()) { + // Check if method name is on this line + if (methodStart >= lineStart && methodStart < lineEnd) { + int lineLocalStart = methodStart - lineStart; + if (lineLocalStart >= 0 && lineLocalStart < lineText.length()) { + String beforeMethod = lineText.substring(0, lineLocalStart); + int beforeWidth = ClientProxy.Font.width(beforeMethod); + int methodWidth = ClientProxy.Font.width(call.getMethodName()); + drawCurlyUnderline(lineStartX + beforeWidth, baselineY, methodWidth, 0xFF5555); + } + } + } + + // Handle arg type errors (underline specific arguments) + if (call.hasArgTypeError()) { + for (MethodCallInfo.ArgumentTypeError error : call.getArgumentTypeErrors()) { + MethodCallInfo.Argument arg = error.getArg(); + int argStart = arg.getStartOffset(); + int argEnd = arg.getEndOffset(); + + // Clip argument to this line's bounds + int clipStart = Math.max(argStart, lineStart); + int clipEnd = Math.min(argEnd, lineEnd); + + // Skip if argument doesn't intersect this line + if (clipStart >= clipEnd) + continue; + + // Convert to line-local coordinates + int lineLocalStart = clipStart - lineStart; + int lineLocalEnd = clipEnd - lineStart; + + // Bounds check + if (lineLocalStart < 0 || lineLocalStart >= lineText.length()) + continue; + + // Compute pixel position using same logic as Token.drawUnderline + String beforeArg = lineText.substring(0, lineLocalStart); + int beforeWidth = ClientProxy.Font.width(beforeArg); + + int argWidth; + if (lineLocalEnd > lineText.length()) { + // Argument extends past line end + argWidth = ClientProxy.Font.width(lineText.substring(lineLocalStart)); + } else { + // Argument is fully on this line (or clipped) + String argTextOnLine = lineText.substring(lineLocalStart, lineLocalEnd); + argWidth = ClientProxy.Font.width(argTextOnLine); + } + + if (argWidth > 0) { + drawCurlyUnderline(lineStartX + beforeWidth, baselineY, argWidth, 0xFF5555); + } + } + } + } } /** diff --git a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/Token.java b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/Token.java index 55c60fac1..43143c252 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/Token.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/Token.java @@ -129,45 +129,6 @@ public class Token { public int getUnderlineColor() { return underlineColor; } - - /** - * Draw underlines for this token's errors. - * @param x start pixel of this token - * @param y baseline pixel for underline - */ - public void drawUnderline(int x, int y) { - if (!isMethodCall() || methodCallInfo == null) - return; - - if (methodCallInfo.hasArgCountError()) { - int tokenWidth = ClientProxy.Font.width(text); - ScriptLine.drawCurlyUnderline(x + 1, y, tokenWidth + 1, getUnderlineColor()); - return; - } - - if (methodCallInfo.hasArgTypeError()) { - // For arg type errors, underline the specific argument span(s). - // Compute pixel X for each argument by walking tokens on the same line - ScriptLine parent = getParentLine(); - - if (parent == null) - return; - String line = parent.getText(); - - for (MethodCallInfo.ArgumentTypeError error : methodCallInfo.getArgumentTypeErrors()) { - MethodCallInfo.Argument arg = error.getArg(); - int lineArgStart = arg.getStartOffset() - parent.getGlobalStart(); - if (lineArgStart < 0 || lineArgStart >= line.length()) - continue; - - String beforeArg = line.substring(0, lineArgStart); - int beforeWidth = ClientProxy.Font.width(beforeArg); - int argWidth = ClientProxy.Font.width(arg.getText()); - ScriptLine.drawCurlyUnderline(x + beforeWidth, y, argWidth, getUnderlineColor()); - - } - } - } // ==================== SETTERS ==================== public void setType(TokenType type) { this.type = type; }