Rewrote splitLines using Test-Driven Development, words should no longer get lost
This commit is contained in:
@@ -353,7 +353,7 @@ public abstract class DialoguePlugin implements Plugin<Player> {
|
|||||||
* @param msg the message for the NPC to say
|
* @param msg the message for the NPC to say
|
||||||
*/
|
*/
|
||||||
public Component npcl(FacialExpression expr, String msg){
|
public Component npcl(FacialExpression expr, String msg){
|
||||||
return npc(expr, splitLines(msg));
|
return npc(expr, splitLines(msg, 54));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -362,7 +362,7 @@ public abstract class DialoguePlugin implements Plugin<Player> {
|
|||||||
* @param msg the message for the player to say
|
* @param msg the message for the player to say
|
||||||
*/
|
*/
|
||||||
public Component playerl(FacialExpression expr, String msg){
|
public Component playerl(FacialExpression expr, String msg){
|
||||||
return player(expr, splitLines(msg));
|
return player(expr, splitLines(msg, 54));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showTopics(Topic<?>... topics) {
|
public void showTopics(Topic<?>... topics) {
|
||||||
|
|||||||
@@ -1,50 +1,46 @@
|
|||||||
package api
|
package api
|
||||||
import rs09.game.system.SystemLogger
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.system.exitProcess
|
import kotlin.math.ceil
|
||||||
|
|
||||||
//Number of chars per line. Line is split at the nearest whole word that doesn't exceed this length. This should remain constant once a perfect value is found
|
|
||||||
const val LINE_SIZE = 52.0
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically split a single continuous string into multiple comma-separated lines.
|
* 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.
|
* Should this not work out for any reason, you should fallback to standard npc and player methods for dialogue.
|
||||||
*/
|
*/
|
||||||
fun splitLines(message: String): Array<String>{
|
fun splitLines(message: String, perLineLimit: Int = 54) : Array<String> {
|
||||||
val chars = message.split("").toTypedArray().size.toDouble()
|
val lines = Array(ceil(message.length / perLineLimit.toFloat()).toInt()) {""}
|
||||||
val words = message.split(" ").toTypedArray()
|
|
||||||
val lines = Math.ceil(chars / LINE_SIZE).toInt()
|
|
||||||
|
|
||||||
if(lines > 4){
|
//short circuit when possible because it's cheaper.
|
||||||
SystemLogger.logErr("INVALID NUM LINES. NUM CHARS: $chars")
|
if (lines.size == 1) {
|
||||||
|
lines[0] = message
|
||||||
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
val messages = ArrayList<String>()
|
val tokenQueue = LinkedList(message.split(" "))
|
||||||
|
|
||||||
var index = 0
|
var index = 0
|
||||||
|
|
||||||
for (msg in 0 until lines) {
|
|
||||||
var length = 0
|
|
||||||
val line = StringBuilder()
|
val line = StringBuilder()
|
||||||
while (length <= LINE_SIZE && !(index == words.size)) {
|
var accumulator = 0
|
||||||
var currentWord = ""
|
|
||||||
try {
|
fun pushLine() {
|
||||||
currentWord = words[index] + if (length + words[index].length + 1 <= LINE_SIZE) " " else ""
|
if (line.isEmpty()) return
|
||||||
} catch (e: Exception){
|
lines[index++] = line.toString()
|
||||||
SystemLogger.logWarn("INDEX: $index WORDSIZE: ${words.size}")
|
line.clear()
|
||||||
for(word in words.indices){
|
accumulator = 0
|
||||||
SystemLogger.logErr("Word $word: ${words[word]}")
|
|
||||||
}
|
|
||||||
exitProcess(0)
|
|
||||||
}
|
|
||||||
length += currentWord.length
|
|
||||||
if (length <= LINE_SIZE) {
|
|
||||||
line.append(currentWord)
|
|
||||||
++index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
messages.add(line.toString())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return messages.toTypedArray()
|
while (!tokenQueue.isEmpty()) {
|
||||||
|
val shouldSpace = line.isNotEmpty()
|
||||||
|
accumulator += tokenQueue.peek().length
|
||||||
|
|
||||||
|
if (shouldSpace) accumulator += 1
|
||||||
|
if (accumulator > perLineLimit) {
|
||||||
|
pushLine()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSpace) line.append(" ")
|
||||||
|
line.append(tokenQueue.pop())
|
||||||
|
}
|
||||||
|
|
||||||
|
pushLine()
|
||||||
|
return lines
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,14 @@
|
|||||||
import api.IfaceSettingsBuilder
|
import api.IfaceSettingsBuilder
|
||||||
import core.game.node.entity.player.Player
|
import api.splitLines
|
||||||
import core.game.node.entity.player.info.PlayerDetails
|
|
||||||
import core.game.node.entity.skill.slayer.Master
|
import core.game.node.entity.skill.slayer.Master
|
||||||
import core.game.node.entity.skill.slayer.Tasks
|
import core.game.node.entity.skill.slayer.Tasks
|
||||||
import org.json.simple.JSONObject
|
import org.json.simple.JSONObject
|
||||||
import org.json.simple.parser.JSONParser
|
import org.json.simple.parser.JSONParser
|
||||||
import org.junit.Assert
|
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import rs09.game.node.entity.skill.slayer.SlayerFlags
|
|
||||||
import rs09.game.node.entity.skill.slayer.SlayerManager
|
import rs09.game.node.entity.skill.slayer.SlayerManager
|
||||||
import rs09.game.system.SystemLogger
|
|
||||||
|
|
||||||
object APITests {
|
class APITests {
|
||||||
val testPlayer = TestUtils.getMockPlayer("test")
|
val testPlayer = TestUtils.getMockPlayer("test")
|
||||||
val testPlayer2 = TestUtils.getMockPlayer("test2")
|
val testPlayer2 = TestUtils.getMockPlayer("test2")
|
||||||
|
|
||||||
@@ -142,4 +138,29 @@ object APITests {
|
|||||||
Assertions.assertNotEquals(0, manager.flags.getPoints())
|
Assertions.assertNotEquals(0, manager.flags.getPoints())
|
||||||
Assertions.assertEquals(true, manager.flags.isHelmUnlocked())
|
Assertions.assertEquals(true, manager.flags.isHelmUnlocked())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun lineSplitShouldSplitAtLimitAndPreserveAllWords() {
|
||||||
|
var testCase = "The monks are running a ship from Port Sarim to Entrana, I hear too. Now leave me alone yer elephant!"
|
||||||
|
var expectedLine1 = "The monks are running a ship from Port Sarim to"
|
||||||
|
var expectedLine2 = "Entrana, I hear too. Now leave me alone yer elephant!"
|
||||||
|
var lines = splitLines(testCase, 54)
|
||||||
|
Assertions.assertEquals(expectedLine1, lines.getOrNull(0) ?: "")
|
||||||
|
Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "")
|
||||||
|
Assertions.assertEquals(2, lines.size)
|
||||||
|
|
||||||
|
testCase = "Dramenwood staffs are crafted from branches of the Dramen tree, so they are. I hear there's a Dramen tree over on the island of Entrana in a cave."
|
||||||
|
expectedLine1 = "Dramenwood staffs are crafted from branches of the"
|
||||||
|
expectedLine2 = "Dramen tree, so they are. I hear there's a Dramen tree"
|
||||||
|
var expectedLine3 = "over on the island of Entrana in a cave."
|
||||||
|
lines = splitLines(testCase, 54)
|
||||||
|
Assertions.assertEquals(expectedLine1, lines.getOrNull(0) ?: "")
|
||||||
|
Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "")
|
||||||
|
Assertions.assertEquals(expectedLine3, lines.getOrNull(2) ?: "")
|
||||||
|
Assertions.assertEquals(3, lines.size)
|
||||||
|
|
||||||
|
testCase = "This should be one line."
|
||||||
|
lines = splitLines(testCase)
|
||||||
|
Assertions.assertEquals(testCase, lines[0])
|
||||||
|
Assertions.assertEquals(1, lines.size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user