Implemented auto splitting of excessively long dialogue lines
Many new farming-related player messages added, and some existing messages updated Raking animation updated Herb picking animation updated Digging up farming patch animation updated Plant cure animation updated A scarecrow can be retrieved from a flower patch by digging it up with a spade Picking fruit/berries stops when running out of inventory space The player can no longer dig up a tree they have planted before chopping it down
This commit is contained in:
@@ -767,10 +767,15 @@ fun emote(entity: Entity, emote: Emotes) {
|
||||
|
||||
/**
|
||||
* Sends a message to the given player.
|
||||
*
|
||||
* The message will be split on word boundaries into multiple lines so
|
||||
* that none of the lines will overflow the player's message box.
|
||||
*
|
||||
* @param player the player to send the message to.
|
||||
* @param message the message to send.
|
||||
*/
|
||||
fun sendMessage(player: Player, message: String) {
|
||||
player.sendMessage(message)
|
||||
player.sendMessages(*splitLines(message, 86))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,12 +2,20 @@ package core.api
|
||||
import java.util.*
|
||||
import kotlin.math.ceil
|
||||
|
||||
object DialUtils {
|
||||
val tagRegex = "<([A-Za-z0-9=/]+)>".toRegex()
|
||||
|
||||
fun removeMatches(message: String, regex: Regex): String {
|
||||
return regex.replace(message, "")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically split a single continuous string into multiple comma-separated lines.
|
||||
* Should this not work out for any reason, you should fallback to standard npc and player methods for dialogue.
|
||||
*/
|
||||
fun splitLines(message: String, perLineLimit: Int = 54) : Array<String> {
|
||||
var lines = Array(ceil(message.length / perLineLimit.toFloat()).toInt()) {""}
|
||||
fun splitLines(message: String, perLineLimit: Int = 54): Array<String> {
|
||||
var lines = Array(ceil(DialUtils.removeMatches(message, DialUtils.tagRegex).length / perLineLimit.toFloat()).toInt()) { "" }
|
||||
|
||||
//short circuit when possible because it's cheaper.
|
||||
if (lines.size == 1) {
|
||||
@@ -20,8 +28,28 @@ fun splitLines(message: String, perLineLimit: Int = 54) : Array<String> {
|
||||
val line = StringBuilder()
|
||||
var accumulator = 0
|
||||
|
||||
val openTags = LinkedList<String>()
|
||||
|
||||
fun pushLine() {
|
||||
if (line.isEmpty()) return
|
||||
|
||||
// find all tags that were opened or closed in the line
|
||||
for (lineTag in DialUtils.tagRegex.findAll(line)) {
|
||||
if (lineTag.value.get(1) == '/') {
|
||||
// closing tag encountered; remove it from the list of open tags
|
||||
for (openTag in openTags.descendingIterator()) {
|
||||
val lineTagName = lineTag.value.substring(2, lineTag.value.length - 1)
|
||||
val openTagName = openTag.substring(1, lineTag.value.length - 2)
|
||||
if (lineTagName == openTagName) {
|
||||
openTags.remove(openTag)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
openTags.add(lineTag.value)
|
||||
}
|
||||
}
|
||||
|
||||
//allow array to be resized - there are specific edgecases where it becomes necessary. (Check the unit test for example)
|
||||
if (lines.size == index)
|
||||
lines = lines.plus(line.toString())
|
||||
@@ -30,11 +58,15 @@ fun splitLines(message: String, perLineLimit: Int = 54) : Array<String> {
|
||||
index++
|
||||
line.clear()
|
||||
accumulator = 0
|
||||
|
||||
// if any unclosed tags remain, add them to the beginning of the new line
|
||||
for (tag in openTags) line.append(tag)
|
||||
openTags.clear()
|
||||
}
|
||||
|
||||
while (!tokenQueue.isEmpty()) {
|
||||
val shouldSpace = line.isNotEmpty()
|
||||
accumulator += tokenQueue.peek().length
|
||||
val shouldSpace = DialUtils.removeMatches(line.toString(), DialUtils.tagRegex).isNotEmpty()
|
||||
accumulator += DialUtils.removeMatches(tokenQueue.peek(), DialUtils.tagRegex).length
|
||||
|
||||
if (shouldSpace) accumulator += 1
|
||||
if (accumulator > perLineLimit) {
|
||||
@@ -49,10 +81,10 @@ fun splitLines(message: String, perLineLimit: Int = 54) : Array<String> {
|
||||
pushLine()
|
||||
|
||||
// If there's 5 lines, merge lines 4 and 5 into line 4.
|
||||
if (lines.size > 4){
|
||||
if (lines.size > 4) {
|
||||
lines[3] = lines[3] + "<br>" + lines[4]
|
||||
lines = lines.sliceArray(0..3)
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user