Implemented Creature of Fenkenstrain quest
This commit is contained in:
+17
-17
@@ -61,12 +61,12 @@ public class ItemDefinition extends Definition<Item> {
|
||||
/**
|
||||
* The model rotation.
|
||||
*/
|
||||
private int modelRotationY;
|
||||
private int modelRotationX;
|
||||
|
||||
/**
|
||||
* The model rotation.
|
||||
*/
|
||||
private int modelRotationX;
|
||||
private int modelRotationY;
|
||||
|
||||
/**
|
||||
* The model offset.
|
||||
@@ -320,9 +320,9 @@ public class ItemDefinition extends Definition<Item> {
|
||||
} else if (opcode == 4) {
|
||||
def.modelZoom = buffer.getShort() & 0xFFFF;
|
||||
} else if (opcode == 5) {
|
||||
def.modelRotationY = buffer.getShort() & 0xFFFF;
|
||||
} else if (opcode == 6) {
|
||||
def.modelRotationX = buffer.getShort() & 0xFFFF;
|
||||
} else if (opcode == 6) {
|
||||
def.modelRotationY = buffer.getShort() & 0xFFFF;
|
||||
} else if (opcode == 7) {
|
||||
def.modelOffsetX = buffer.getShort() & 0xFFFF;
|
||||
if (def.modelOffsetX > 32767)
|
||||
@@ -495,11 +495,11 @@ public class ItemDefinition extends Definition<Item> {
|
||||
modelOffsetY = templateReference.modelOffsetY;
|
||||
textureColour1 = templateReference.textureColour1;
|
||||
value = reference.value;
|
||||
modelRotationX = templateReference.modelRotationX;
|
||||
modelRotationY = templateReference.modelRotationY;
|
||||
stackable = true;
|
||||
unnoted = false;
|
||||
modifiedModelColors = templateReference.modifiedModelColors;
|
||||
modelRotationY = templateReference.modelRotationY;
|
||||
modelRotationX = templateReference.modelRotationX;
|
||||
modelZoom = templateReference.modelZoom;
|
||||
textureColour1 = templateReference.textureColour1;
|
||||
handlers.put(ItemConfigParser.TRADEABLE, true);
|
||||
@@ -518,8 +518,8 @@ public class ItemDefinition extends Definition<Item> {
|
||||
textureColour2 = reference.textureColour2;
|
||||
groundActions = reference.groundActions;
|
||||
unknownArray1 = reference.unknownArray1;
|
||||
modelRotationY = templateReference.modelRotationY;
|
||||
modelRotationX = templateReference.modelRotationX;
|
||||
modelRotationY = templateReference.modelRotationY;
|
||||
originalModelColors = reference.originalModelColors;
|
||||
name = reference.name;
|
||||
maleWornModelId1 = reference.maleWornModelId1;
|
||||
@@ -548,7 +548,7 @@ public class ItemDefinition extends Definition<Item> {
|
||||
public void transferRecolourDefinition(ItemDefinition reference, ItemDefinition templateReference) {
|
||||
femaleWornModelId2 = reference.femaleWornModelId2;
|
||||
options = new String[5];
|
||||
modelRotationX = templateReference.modelRotationX;
|
||||
modelRotationY = templateReference.modelRotationY;
|
||||
name = reference.name;
|
||||
maleWornModelId1 = reference.maleWornModelId1;
|
||||
modelOffsetY = templateReference.modelOffsetY;
|
||||
@@ -557,7 +557,7 @@ public class ItemDefinition extends Definition<Item> {
|
||||
modelOffsetX = templateReference.modelOffsetX;
|
||||
unknownArray1 = reference.unknownArray1;
|
||||
stackable = reference.stackable;
|
||||
modelRotationY = templateReference.modelRotationY;
|
||||
modelRotationX = templateReference.modelRotationX;
|
||||
textureColour1 = reference.textureColour1;
|
||||
colourEquip1 = reference.colourEquip1;
|
||||
textureColour2 = reference.textureColour2;
|
||||
@@ -803,32 +803,32 @@ public class ItemDefinition extends Definition<Item> {
|
||||
* Gets the modelRotation1.
|
||||
* @return The modelRotation1.
|
||||
*/
|
||||
public int getModelRotation1() {
|
||||
return modelRotationY;
|
||||
public int getModelRotationX() {
|
||||
return modelRotationX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the modelRotation1.
|
||||
* @param modelRotation1 The modelRotation1 to set.
|
||||
*/
|
||||
public void setModelRotation1(int modelRotation1) {
|
||||
this.modelRotationY = modelRotation1;
|
||||
public void setModelRotationX(int modelRotation1) {
|
||||
this.modelRotationX = modelRotation1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modelRotation2.
|
||||
* @return The modelRotation2.
|
||||
*/
|
||||
public int getModelRotation2() {
|
||||
return modelRotationX;
|
||||
public int getModelRotationY() {
|
||||
return modelRotationY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the modelRotation2.
|
||||
* @param modelRotation2 The modelRotation2 to set.
|
||||
*/
|
||||
public void setModelRotation2(int modelRotation2) {
|
||||
this.modelRotationX = modelRotation2;
|
||||
public void setModelRotationY(int modelRotation2) {
|
||||
this.modelRotationY = modelRotation2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
package core.game.dialogue
|
||||
|
||||
import core.api.splitLines
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.END_DIALOGUE
|
||||
import java.util.regex.Pattern
|
||||
|
||||
val DEBUG_DIALOGUE = true
|
||||
val NUMBER_PATTERN1 = Pattern.compile("^(\\d+) \\[label", Pattern.MULTILINE)
|
||||
val NUMBER_PATTERN2 = Pattern.compile("(\\d+) -> (\\d+)")
|
||||
|
||||
abstract class DialogueBuilderFile : DialogueFile() {
|
||||
var data: ArrayList<DialogueClause> = ArrayList()
|
||||
@@ -8,6 +15,37 @@ abstract class DialogueBuilderFile : DialogueFile() {
|
||||
abstract fun create(b: DialogueBuilder)
|
||||
init {
|
||||
create(DialogueBuilder(this))
|
||||
if(DEBUG_DIALOGUE) {
|
||||
var graphSb = StringBuilder("digraph {\n")
|
||||
var nodeIndex = 0
|
||||
for((i, clause) in data.iterator().withIndex()) {
|
||||
var clauseSb = StringBuilder()
|
||||
for(j in 0 until clause.nodes.size) {
|
||||
if(!(clause.nodes[j] is OptionsDispatchNode)) {
|
||||
clauseSb.append("${j} ${clause.nodes[j].toString().replace("@indexPlus", "${j+1}").replace("@index", "${j}")}\n")
|
||||
}
|
||||
}
|
||||
graphSb.append("subgraph cluster_${i} {\n")
|
||||
var tmpSb = StringBuilder()
|
||||
var m = NUMBER_PATTERN1.matcher(clauseSb)
|
||||
while(m.find()) {
|
||||
var x = Integer.valueOf(m.group(1))
|
||||
m.appendReplacement(tmpSb, "${x+nodeIndex} [label")
|
||||
}
|
||||
m.appendTail(tmpSb)
|
||||
m = NUMBER_PATTERN2.matcher(tmpSb)
|
||||
while(m.find()) {
|
||||
var x = Integer.valueOf(m.group(1))
|
||||
var y = Integer.valueOf(m.group(2))
|
||||
m.appendReplacement(graphSb, "${x+nodeIndex} -> ${y+nodeIndex}")
|
||||
}
|
||||
m.appendTail(graphSb)
|
||||
graphSb.append("}\n")
|
||||
nodeIndex += clause.nodes.size
|
||||
}
|
||||
graphSb.append("}\n")
|
||||
System.out.println(graphSb.toString())
|
||||
}
|
||||
}
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
for((i, clause) in data.iterator().withIndex()) {
|
||||
@@ -26,43 +64,137 @@ interface DialogueNode {
|
||||
fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int
|
||||
}
|
||||
|
||||
class NpcLNode(val value: String): DialogueNode {
|
||||
class NpcLNode(val expression: FacialExpression, val value: String): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"npcl(FacialExpression.${expression.name}, \\\"${value}\\\")\"]; @index -> @indexPlus;"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.npcl(value)
|
||||
df.npcl(expression, value)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class NpcNode(val values: Array<String>): DialogueNode {
|
||||
class NpcNode(val expression: FacialExpression, val values: Array<String>): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"npc(FacialExpression.${expression.name}, \\\"${values.contentDeepToString()}\\\")\"]; @index -> @indexPlus;"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.npc(*values)
|
||||
df.npc(expression, *values)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class PlayerLNode(val value: String): DialogueNode {
|
||||
class ItemNode(val item: Int, val values: Array<String>): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"item(${item}, \\\"${values.contentDeepToString()}\\\")\"]; @index -> @indexPlus;"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.playerl(value)
|
||||
df.interpreter!!.sendItemMessage(item, *values)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class ClosureNode(val f: (Player) -> Int): DialogueNode {
|
||||
class PlayerLNode(val expression: FacialExpression, val value: String): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"playerl(FacialExpression.${expression.name}, \\\"${value}\\\")\"]; @index -> @indexPlus;"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
return f(df.player!!)
|
||||
df.playerl(expression, value)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class PlayerNode(val expression: FacialExpression, val values: Array<String>): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"player(FacialExpression.${expression.name}, \\\"${values.contentDeepToString()}\\\")\"]; @index -> @indexPlus;"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.player(expression, *values)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class BetweenStageNode(val f: (DialogueFile, Player, Int, Int) -> Unit): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"betweenstage(${(f as java.lang.Object).getClass().getName()})\"]; @index -> @indexPlus"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.stage = stage + 1 // Simulates moving to this stage.
|
||||
f(df, df.player!!, componentID, buttonID) // Calls callback function.
|
||||
df.handle(componentID, buttonID) // Handles the current stage
|
||||
return stage + 2 // Skips over the current stage.
|
||||
}
|
||||
}
|
||||
class ManualStageNode(val f: (DialogueFile, Player, Int, Int) -> Unit): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"manualstage(${(f as java.lang.Object).getClass().getName()})\"]; @index -> @indexPlus"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
f(df, df.player!!, componentID, buttonID)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class ManualStageWithGotoNode(val f: (DialogueFile, Player, Int, Int, Int) -> Int, g: (Int) -> Int): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"manualstagewithgoto(${(f as java.lang.Object).getClass().getName()})\"]; @index -> @indexPlus"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
return f(df, df.player!!, componentID, buttonID, stage)
|
||||
}
|
||||
}
|
||||
|
||||
class PlaceholderNode(val dbf: DialogueBuilderFile, val clauseIndex: Int, var targetStage: Int): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"placeholder(${targetStage})\"]; @index -> ${targetStage}"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.stage = targetStage
|
||||
df.handle(componentID, buttonID)
|
||||
return df.stage
|
||||
}
|
||||
|
||||
fun builder(): DialogueBuilder {
|
||||
targetStage = dbf.data[clauseIndex].nodes.size
|
||||
return DialogueBuilder(dbf, clauseIndex)
|
||||
}
|
||||
}
|
||||
|
||||
class GotoNode(val node: PlaceholderNode): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"goto(${node.targetStage})\"]; @index -> ${node.targetStage}"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.stage = node.targetStage
|
||||
df.handle(componentID, buttonID)
|
||||
return df.stage
|
||||
}
|
||||
}
|
||||
|
||||
class OptionEntry(val text: String, val nextStage: Int, val predicate: (Player) -> Boolean = { _ -> true }) {}
|
||||
class OptionsData(val header: String, val entries: ArrayList<OptionEntry>, var attr: String? = null) {}
|
||||
|
||||
class OptionsNode(var options: ArrayList<OptionEntry>): DialogueNode {
|
||||
class OptionsNode(var options: OptionsData): DialogueNode {
|
||||
override fun toString(): String {
|
||||
var ret = "[label=\"options(\\\"${options.header}\\\")\"]; "
|
||||
for(entry in options.entries) {
|
||||
ret += "@index -> ${entry.nextStage} [label=\"\\\"${entry.text}\\\"\"]; "
|
||||
}
|
||||
return ret
|
||||
}
|
||||
fun optionNames(player: Player): Array<String?> {
|
||||
return options.asSequence().filter({ it.predicate(player) }).map({ it.text }).toList().toTypedArray()
|
||||
return options.entries.asSequence().filter({ it.predicate(player) }).map({ it.text }).toList().toTypedArray()
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
val tmp: Array<String?> = optionNames(df.player!!)
|
||||
if(tmp.size > 1) {
|
||||
df.options(*tmp)
|
||||
if(DEBUG_DIALOGUE) {
|
||||
System.out.println("OptionsNode: ${tmp.size}")
|
||||
for(i in 0 until tmp.size) {
|
||||
System.out.println("tmp[${i}]: ${tmp[i]}")
|
||||
}
|
||||
}
|
||||
if(tmp.size > 5) {
|
||||
System.out.printf("Only a maximum of 5 options are supported by the interface")
|
||||
return END_DIALOGUE
|
||||
} else if(tmp.size > 1) {
|
||||
df.interpreter!!.sendOptions(options.header, *tmp)
|
||||
return stage + 1
|
||||
} else if(tmp.size == 1) {
|
||||
val tmp: List<OptionEntry> = options.asSequence().filter({ it.predicate(df.player!!) }).toList()
|
||||
val tmp: List<OptionEntry> = options.entries.asSequence().filter({ it.predicate(df.player!!) }).toList()
|
||||
df.stage = tmp[0].nextStage
|
||||
df.handle(componentID, 0)
|
||||
return df.stage
|
||||
@@ -71,9 +203,18 @@ class OptionsNode(var options: ArrayList<OptionEntry>): DialogueNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
class OptionsDispatchNode(var options: ArrayList<OptionEntry>): DialogueNode {
|
||||
class OptionsDispatchNode(var options: OptionsData): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"OptionsDispatchNode\"]"
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
val tmp: List<OptionEntry> = options.asSequence().filter({ it.predicate(df.player!!) }).toList()
|
||||
val tmp: List<OptionEntry> = options.entries.asSequence().filter({ it.predicate(df.player!!) }).toList()
|
||||
if(DEBUG_DIALOGUE) {
|
||||
System.out.println("OptionsDispatchNode: ${tmp.size}")
|
||||
}
|
||||
if(options.attr != null) {
|
||||
df.player!!.setAttribute(options.attr, buttonID-1)
|
||||
}
|
||||
df.stage = tmp[buttonID-1].nextStage
|
||||
df.handle(componentID, 0)
|
||||
return df.stage
|
||||
@@ -90,19 +231,70 @@ class DialogueClause(val predicate: (player: Player) -> Boolean, val nodes: Arra
|
||||
}
|
||||
}
|
||||
|
||||
class DialogueOptionsBuilder(var target: DialogueBuilderFile, val clauseIndex: Int, var options: ArrayList<OptionEntry>) {
|
||||
class DialogueOptionsBuilder(var target: DialogueBuilderFile, val clauseIndex: Int, var options: OptionsData) {
|
||||
fun option(value: String): DialogueBuilder {
|
||||
options.add(OptionEntry(value, target.data[clauseIndex].nodes.size))
|
||||
options.entries.add(OptionEntry(value, target.data[clauseIndex].nodes.size))
|
||||
return DialogueBuilder(target, clauseIndex)
|
||||
}
|
||||
|
||||
fun optionIf(value: String, predicate: (Player) -> Boolean): DialogueBuilder {
|
||||
options.add(OptionEntry(value, target.data[clauseIndex].nodes.size, predicate))
|
||||
options.entries.add(OptionEntry(value, target.data[clauseIndex].nodes.size, predicate))
|
||||
return DialogueBuilder(target, clauseIndex)
|
||||
}
|
||||
|
||||
fun option_playerl(value: String): DialogueBuilder {
|
||||
return option(value).playerl(value)
|
||||
}
|
||||
|
||||
fun recordAttribute(name: String): DialogueOptionsBuilder {
|
||||
options.attr = name
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
class BranchesData(val branches: HashMap<Int, Int>, val f: (Player) -> Int) {}
|
||||
class BranchNode(val branches: BranchesData): DialogueNode {
|
||||
override fun toString(): String {
|
||||
var ret = "[label=\"branch(\\\"${(branches.f as Object).getClass().getName()}\\\")\"]; "
|
||||
for(entry in branches.branches) {
|
||||
ret += "@index -> ${entry.value} [label=\"\\\"${entry.key}\\\"\"]; "
|
||||
}
|
||||
return ret
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.stage = branches.branches[branches.f(df.player!!)] ?: END_DIALOGUE
|
||||
df.handle(componentID, buttonID)
|
||||
return df.stage
|
||||
}
|
||||
}
|
||||
class DialogueBranchBuilder(var target: DialogueBuilderFile, val clauseIndex: Int, var branches: BranchesData) {
|
||||
fun onValue(value: Boolean): DialogueBuilder {
|
||||
return onValue(if(value) { 1 } else { 0 })
|
||||
}
|
||||
fun onValue(value: Int): DialogueBuilder {
|
||||
val index = target.data[clauseIndex].nodes.size
|
||||
branches.branches.put(value, index)
|
||||
return DialogueBuilder(target, clauseIndex)
|
||||
}
|
||||
}
|
||||
|
||||
class EndWithNode(val f: (DialogueFile, Player) -> Unit): DialogueNode {
|
||||
override fun toString(): String {
|
||||
return "[label=\"endWith(${(f as java.lang.Object).getClass().getName()})\"]";
|
||||
}
|
||||
override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
f(df, df.player!!)
|
||||
return END_DIALOGUE
|
||||
}
|
||||
}
|
||||
|
||||
class DialogueBuilder(var target: DialogueBuilderFile, var clauseIndex: Int = -1) {
|
||||
companion object DialogueBuilderStatic {
|
||||
@JvmStatic
|
||||
fun endWithNoop(df: DialogueFile, player: Player) {
|
||||
}
|
||||
}
|
||||
|
||||
fun onPredicate(predicate: (player: Player) -> Boolean): DialogueBuilder {
|
||||
target.data.add(DialogueClause(predicate, ArrayList()))
|
||||
clauseIndex = target.data.size - 1
|
||||
@@ -115,34 +307,104 @@ class DialogueBuilder(var target: DialogueBuilderFile, var clauseIndex: Int = -1
|
||||
}
|
||||
}
|
||||
fun playerl(value: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(PlayerLNode(value))
|
||||
target.data[clauseIndex].nodes.add(PlayerLNode(FacialExpression.NEUTRAL, value))
|
||||
return this
|
||||
}
|
||||
fun playerl(expression: FacialExpression, value: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(PlayerLNode(expression, value))
|
||||
return this
|
||||
}
|
||||
fun player(vararg values: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(PlayerNode(FacialExpression.NEUTRAL, values as Array<String>))
|
||||
return this
|
||||
}
|
||||
fun player(expression: FacialExpression, vararg values: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(PlayerNode(expression, values as Array<String>))
|
||||
return this
|
||||
}
|
||||
fun npcl(value: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(NpcLNode(value))
|
||||
target.data[clauseIndex].nodes.add(NpcLNode(FacialExpression.NEUTRAL, value))
|
||||
return this
|
||||
}
|
||||
fun npcl(expression: FacialExpression, value: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(NpcLNode(expression, value))
|
||||
return this
|
||||
}
|
||||
fun npc(vararg values: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(NpcNode(values as Array<String>))
|
||||
target.data[clauseIndex].nodes.add(NpcNode(FacialExpression.NEUTRAL, values as Array<String>))
|
||||
return this
|
||||
}
|
||||
fun endWith(f: (Player) -> Unit) {
|
||||
target.data[clauseIndex].nodes.add(ClosureNode({ player ->
|
||||
f(player)
|
||||
return@ClosureNode END_DIALOGUE
|
||||
}))
|
||||
fun npc(expression: FacialExpression, vararg values: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(NpcNode(expression, values as Array<String>))
|
||||
return this
|
||||
}
|
||||
fun item(item: Int, vararg values: String): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(ItemNode(item, values as Array<String>))
|
||||
return this
|
||||
}
|
||||
fun iteml(item: Int, value: String): DialogueBuilder {
|
||||
return item(item, *splitLines(value))
|
||||
}
|
||||
fun line(vararg values: String): DialogueBuilder {
|
||||
return manualStage() { df, player, _, _ ->
|
||||
df.interpreter!!.sendDialogue(*(values as Array<String>))
|
||||
}
|
||||
}
|
||||
fun linel(value: String): DialogueBuilder {
|
||||
return manualStage() { df, player, _, _ ->
|
||||
df.interpreter!!.sendDialogue(*splitLines(value))
|
||||
}
|
||||
}
|
||||
fun endWith(f: (DialogueFile, Player) -> Unit) {
|
||||
target.data[clauseIndex].nodes.add(EndWithNode(f))
|
||||
}
|
||||
fun end() {
|
||||
target.data[clauseIndex].nodes.add(ClosureNode({ _ ->
|
||||
return@ClosureNode END_DIALOGUE
|
||||
}))
|
||||
target.data[clauseIndex].nodes.add(EndWithNode(::endWithNoop))
|
||||
}
|
||||
/** Runs block without the need for a DialogueFile df.something call. */
|
||||
fun betweenStage(f: (DialogueFile, Player, Int, Int) -> Unit): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(BetweenStageNode(f))
|
||||
return this
|
||||
}
|
||||
fun manualStage(f: (DialogueFile, Player, Int, Int) -> Unit): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(ManualStageNode(f))
|
||||
return this
|
||||
}
|
||||
fun manualStageWithGoto(f: (DialogueFile, Player, Int, Int, Int) -> Int, g: (Int) -> Int): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(ManualStageWithGotoNode(f, g))
|
||||
return this
|
||||
}
|
||||
fun options(): DialogueOptionsBuilder {
|
||||
var options: ArrayList<OptionEntry> = ArrayList()
|
||||
val node = OptionsNode(options)
|
||||
val dispatchNode = OptionsDispatchNode(options)
|
||||
return options("Select an Option")
|
||||
}
|
||||
fun options(header: String): DialogueOptionsBuilder {
|
||||
val options: ArrayList<OptionEntry> = ArrayList()
|
||||
val optionsData = OptionsData(header, options)
|
||||
val node = OptionsNode(optionsData)
|
||||
val dispatchNode = OptionsDispatchNode(optionsData)
|
||||
target.data[clauseIndex].nodes.add(node)
|
||||
target.data[clauseIndex].nodes.add(dispatchNode)
|
||||
return DialogueOptionsBuilder(target, clauseIndex, options)
|
||||
return DialogueOptionsBuilder(target, clauseIndex, optionsData)
|
||||
}
|
||||
|
||||
fun placeholder(): PlaceholderNode {
|
||||
val node = PlaceholderNode(target, clauseIndex, END_DIALOGUE)
|
||||
target.data[clauseIndex].nodes.add(node)
|
||||
return node
|
||||
}
|
||||
|
||||
fun goto(node: PlaceholderNode): DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(GotoNode(node))
|
||||
return this
|
||||
}
|
||||
|
||||
fun branch(f: (Player) -> Int): DialogueBranchBuilder {
|
||||
var branches = BranchesData(HashMap(), f)
|
||||
target.data[clauseIndex].nodes.add(BranchNode(branches))
|
||||
return DialogueBranchBuilder(target, clauseIndex, branches)
|
||||
}
|
||||
|
||||
fun branchBoolAttribute(attrName: String, defaultVal: Boolean): DialogueBranchBuilder {
|
||||
return branch({ player -> return@branch if(player.getAttribute(attrName, defaultVal)) { 1 } else { 0 } })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static core.tools.DialogueConstKt.END_DIALOGUE;
|
||||
|
||||
@@ -323,13 +325,61 @@ public final class DialogueInterpreter {
|
||||
* @param itemId The item id.
|
||||
*/
|
||||
public Component sendItemMessage(int itemId, String... messages) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
if(1 <= messages.length && messages.length < 4) {
|
||||
ArrayList<String> packedMessages = new ArrayList();
|
||||
for(int i = 0; i < messages.length/2; i++) {
|
||||
packedMessages.add(messages[i] + "<br>" + messages[i+1]);
|
||||
}
|
||||
if(messages.length % 2 == 1) {
|
||||
packedMessages.add(messages[messages.length-1]);
|
||||
}
|
||||
|
||||
int interfaceId = 241 + (packedMessages.size() - 1);
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, interfaceId, 1);
|
||||
ItemDefinition itemDef = ItemDefinition.forId(itemId);
|
||||
player.getPacketDispatch().sendAngleOnInterface(interfaceId, 1, itemDef.getModelZoom() / 2, itemDef.getModelRotationX(), itemDef.getModelRotationY());
|
||||
player.getPacketDispatch().sendString("", interfaceId, 3);
|
||||
for(int i = 0; i < packedMessages.size(); i++) {
|
||||
//System.out.printf("sendItemMessage[%d]: %s\n", i, packedMessages[i]);
|
||||
player.getPacketDispatch().sendString(packedMessages.get(i), interfaceId, 4+i);
|
||||
}
|
||||
} else {
|
||||
int interfaceId = 131;
|
||||
//int interfaceId = 173;
|
||||
//int interfaceId = 519;
|
||||
//int interfaceId = 757;
|
||||
//int interfaceId = 760;
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
}
|
||||
switch(interfaceId) {
|
||||
case 131:
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2);
|
||||
break;
|
||||
case 173:
|
||||
player.getPacketDispatch().sendString(message, 173, 4);
|
||||
player.getPacketDispatch().sendString("", 173, 3);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 173, 1);
|
||||
break;
|
||||
case 519:
|
||||
player.getPacketDispatch().sendString(message, 519, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 519, 0);
|
||||
break;
|
||||
case 757:
|
||||
player.getPacketDispatch().sendString(message, 757, 2);
|
||||
player.getPacketDispatch().sendString("", 757, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 757, 0);
|
||||
break;
|
||||
case 760:
|
||||
player.getPacketDispatch().sendString(message, 760, 0);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 760, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
@@ -337,14 +387,7 @@ public final class DialogueInterpreter {
|
||||
* Send a message with an item next to it.
|
||||
*/
|
||||
public Component sendItemMessage(final Item item, String... messages) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
}
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(item.getId(), item.getAmount(), 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
return sendItemMessage(item.getId(), messages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,6 +498,19 @@ public final class DialogueInterpreter {
|
||||
return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
}
|
||||
|
||||
static Pattern GENDERED_SUBSTITUTION = Pattern.compile("@g\\[([^,]*),([^\\]]*)\\]");
|
||||
public static String doSubstitutions(Player player, String msg) {
|
||||
msg = msg.replace("@name", player.getUsername());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Matcher m = GENDERED_SUBSTITUTION.matcher(msg);
|
||||
int index = player.isMale() ? 1 : 2;
|
||||
while(m.find()) {
|
||||
m.appendReplacement(sb, m.group(index));
|
||||
}
|
||||
m.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
@@ -474,6 +530,7 @@ public final class DialogueInterpreter {
|
||||
}
|
||||
player.getPacketDispatch().sendAnimationInterface(expression, interfaceId, 2);
|
||||
if (npc) {
|
||||
player.getPacketDispatch().sendItemOnInterface(-1, 1, interfaceId, 1);
|
||||
player.getPacketDispatch().sendNpcOnInterface(npcId, interfaceId, 2);
|
||||
player.getPacketDispatch().sendString(NPCDefinition.forId(npcId).getName(), interfaceId, 3);
|
||||
} else {
|
||||
@@ -481,7 +538,7 @@ public final class DialogueInterpreter {
|
||||
player.getPacketDispatch().sendString(player.getUsername(), interfaceId, 3);
|
||||
}
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i].toString().replace("@name", player.getUsername()), interfaceId, (i + 4));
|
||||
player.getPacketDispatch().sendString(doSubstitutions(player, messages[i].toString()), interfaceId, (i + 4));
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, false);
|
||||
|
||||
@@ -4,9 +4,11 @@ package core.game.dialogue
|
||||
* Topic/IfTopic system backported from my personal project
|
||||
* @author Ceikry
|
||||
*/
|
||||
open class Topic<T>(val expr: FacialExpression, val text: String, val toStage: T, val skipPlayer: Boolean = false) {
|
||||
open class Topic<T> @JvmOverloads constructor(val expr: FacialExpression, val text: String, val toStage: T, val skipPlayer: Boolean = false) {
|
||||
@JvmOverloads
|
||||
constructor(text: String, toStage: T, skipPlayer: Boolean = false) : this(FacialExpression.ASKING, text, toStage, skipPlayer)
|
||||
}
|
||||
class IfTopic<T>(expr: FacialExpression, text: String, toStage: T, val showCondition: Boolean, skipPlayer: Boolean = false) : Topic<T>(expr, text, toStage, skipPlayer) {
|
||||
constructor(text: String, toStage: T, showCondition: Boolean, skipPlayer: Boolean = false) : this(FacialExpression.ASKING, text, toStage, showCondition, skipPlayer)
|
||||
}
|
||||
class IfTopic<T> @JvmOverloads constructor(expr: FacialExpression, text: String, toStage: T, val showCondition: Boolean, skipPlayer: Boolean = false) : Topic<T>(expr, text, toStage, skipPlayer) {
|
||||
@JvmOverloads
|
||||
constructor(text: String, toStage: T, showCondition: Boolean, skipPlayer: Boolean = false) : this(core.game.dialogue.FacialExpression.ASKING, text, toStage, showCondition, skipPlayer)
|
||||
}
|
||||
|
||||
@@ -145,6 +145,12 @@ public abstract class Quest implements Plugin<Object> {
|
||||
playJingle(player, questJingles[new Random().nextInt(3)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the quest. This is called when ::setQuestStage is set to 0.
|
||||
* Useful to override and reset quest player attributes.
|
||||
*/
|
||||
public void reset(Player player) {}
|
||||
|
||||
/**
|
||||
* Draws a line on the journal component.
|
||||
* @param player The player.
|
||||
|
||||
@@ -35,8 +35,13 @@ class QuestCommandSet : CommandSet(Privilege.ADMIN){
|
||||
}
|
||||
val quest = args[1].toIntOrNull() ?: reject(player,"INVALID QUEST")
|
||||
val stage = args[2].toIntOrNull() ?: reject(player,"INVALID STAGE")
|
||||
player.questRepository.setStageNonmonotonic(player.questRepository.forIndex(quest as Int), stage as Int)
|
||||
notify(player, "<col=209dff>Setting " + player.questRepository.forIndex(quest).name + " to stage $stage</col>")
|
||||
val questObject = player.questRepository.forIndex(quest as Int)
|
||||
player.questRepository.setStageNonmonotonic(questObject, stage as Int)
|
||||
if (stage == 0){
|
||||
questObject.reset(player)
|
||||
}
|
||||
questObject.updateVarps(player)
|
||||
notify(player, "<col=209dff>Setting " + questObject.name + " to stage $stage</col>")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,7 +77,7 @@ public final class PacketRepository {
|
||||
OUTGOING_PACKETS.put(Varbit.class, new Varbit());
|
||||
OUTGOING_PACKETS.put(ResetInterface.class, new ResetInterface());
|
||||
OUTGOING_PACKETS.put(VarcUpdate.class, new VarcUpdate());
|
||||
OUTGOING_PACKETS.put(InterfaceSetAngle.class, new InterfaceSetAngle());
|
||||
OUTGOING_PACKETS.put(InterfaceSetAngle.class, new InterfaceSetAngle());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user