Thread: [Ruse/Any] Dialogue System - Kotlin/Java | Intelligent Message Splitting Included

Page 3 of 5 FirstFirst 12345 LastLast
Results 21 to 30 of 45
  1. #21  
    (Official) Thanksgiver

    Arham's Avatar
    Join Date
    Jan 2013
    Age
    23
    Posts
    3,415
    Thanks given
    7,254
    Thanks received
    1,938
    Rep Power
    3905
    Quote Originally Posted by Serious ipwxy View Post
    You mean that nasty piece of dialogue code they released 4 years ago? Who would want to emulate that?

    Kotlin hates null. If you're gonna join the Kotlin community, I highly recommend straying away from purposefully using null. In fact, a lot of newer languages are getting rid of it, and for a good reason. Using null in Kotlin is similar to using improper naming conventions in Java, except worse with the potential of blowing up.

    The let expression is 1 line, less syntax. It's similar to using optionals in Java, which would be the proper solution to this. But it's your code, so can do whatever you want with it. May be hard to wrap your mind around coding without null, but I'm sure down the line, you'll be preaching this same thing.

    Thanks for the contribution. It's good to know Kotlin is slowly gaining popularity around here.
    I've preached the same thing, and I agree with you. I don't really know why I used null in this case, just was explaining to you my choice.
    Attached image
    Attached image
    Quote Originally Posted by MrClassic View Post
    Arham is the official thanker!
    List of my work here!
    Reply With Quote  
     

  2. #22  
    Registered Wizard

    Jesse's Avatar
    Join Date
    Sep 2009
    Age
    29
    Posts
    5,119
    Thanks given
    1,519
    Thanks received
    1,148
    Rep Power
    5000
    This would be good if you could jump into different dialogues if needed eg. quests is a good one, this is also the only tutorial I have seen on r-s in ages thats decent lol so nice



    Reply With Quote  
     

  3. Thankful user:


  4. #23  
    (Official) Thanksgiver

    Arham's Avatar
    Join Date
    Jan 2013
    Age
    23
    Posts
    3,415
    Thanks given
    7,254
    Thanks received
    1,938
    Rep Power
    3905
    Quote Originally Posted by Jesse View Post
    This would be good if you could jump into different dialogues if needed eg. quests is a good one, this is also the only tutorial I have seen on r-s in ages thats decent lol so nice
    Are you referring to sending singular dialogue? Or having an easy way to make a dialogue without having to make a new class? If so, doing so just needs this added in Dialogue.kt:
    Code:
        companion object {
            @JvmStatic
            fun build(player: Player, execute: Dialogue.() -> Unit, closeable: Boolean = true): Dialogue {
                return object : Dialogue(player, closeable) {
                    override fun execute() {
                        execute()
                    }
                }
            }
        }
    Doing so allows dialogues to be built like this:
    Code:
        fun handleDeath(player: Player, killer: Player) {
            // handle death stuff lol
            Dialogue.build(player, {
                npcMessage(0, "Hi my names Hans I just came to tell you how much of a loser you are for dying.")
                playerMessage("Thanks man!")
                npcMessage(0, "Anytime bro.")
                npcMessage(0, "To emphasize how much of a noob you are, I'll make your dialogue uncloseable.", DialogueExpression.MANIC_FACE)
            }, closeable = false) // the "closeable =" is not required here, but is put for readability.
            Dialogue.build(killer, {
                npcMessage(0, "Hey man, just wanted to tell you, thank you for killing that noob ${player.username}.")
                playerMessage("Yeah no problem, anytime.")
            })
        }
    The con to this code right now, however, is that in Java, things won't be as simple due to my lack of overloaded methods and usage of default parameters. Could be fixed, however.
    Attached image
    Attached image
    Quote Originally Posted by MrClassic View Post
    Arham is the official thanker!
    List of my work here!
    Reply With Quote  
     

  5. #24  
    Registered Wizard

    Jesse's Avatar
    Join Date
    Sep 2009
    Age
    29
    Posts
    5,119
    Thanks given
    1,519
    Thanks received
    1,148
    Rep Power
    5000
    Quote Originally Posted by arham 4 View Post
    Are you referring to sending singular dialogue? Or having an easy way to make a dialogue without having to make a new class? If so, doing so just needs this added in Dialogue.kt:

    The con to this code right now, however, is that in Java, things won't be as simple due to my lack of overloaded methods and usage of default parameters. Could be fixed, however.
    I mean being able to jump back into a certain stage of the dioalogue. I was testing it at the moment and that was the biggest issue I saw with it

    eg. Dialogues going back to the options if you wanted it to. I can show you what I mean on discord if i'm maybe not wording it right



    Reply With Quote  
     

  6. #25  
    (Official) Thanksgiver

    Arham's Avatar
    Join Date
    Jan 2013
    Age
    23
    Posts
    3,415
    Thanks given
    7,254
    Thanks received
    1,938
    Rep Power
    3905
    Quote Originally Posted by Jesse View Post
    I mean being able to jump back into a certain stage of the dioalogue. I was testing it at the moment and that was the biggest issue I saw with it

    eg. Dialogues going back to the options if you wanted it to. I can show you what I mean on discord if i'm maybe not wording it right
    Ohh, right. I should look into that. Currently, the only possible way is making two seperate classes (a hassle) as shown in my example in my latest update comment.
    Attached image
    Attached image
    Quote Originally Posted by MrClassic View Post
    Arham is the official thanker!
    List of my work here!
    Reply With Quote  
     

  7. #26  
    Registered Wizard

    Jesse's Avatar
    Join Date
    Sep 2009
    Age
    29
    Posts
    5,119
    Thanks given
    1,519
    Thanks received
    1,148
    Rep Power
    5000
    Quote Originally Posted by arham 4 View Post
    Ohh, right. I should look into that. Currently, the only possible way is making two seperate classes (a hassle) as shown in my example in my latest update comment.
    ya if you made that possible it would make this really nice hopefully in the future



    Reply With Quote  
     

  8. #27  
    (Official) Thanksgiver

    Arham's Avatar
    Join Date
    Jan 2013
    Age
    23
    Posts
    3,415
    Thanks given
    7,254
    Thanks received
    1,938
    Rep Power
    3905
    Quote Originally Posted by Faris View Post
    How is this any better, this has more hard coding than the other systems? You can't really avoid it, but storing dialogue in a JSON / XML type of file is better than storing it in actual classes.
    Thanks for your explanation.
    Attached image
    Attached image
    Quote Originally Posted by MrClassic View Post
    Arham is the official thanker!
    List of my work here!
    Reply With Quote  
     

  9. #28  
    Registered Member

    Join Date
    Sep 2008
    Posts
    4,833
    Thanks given
    894
    Thanks received
    1,439
    Rep Power
    2924
    Quote Originally Posted by Kris View Post
    ...what?
    How is this more hardcoding..? You don't have to define any stages or anything writing dialogues with this. It's one of the least verbose methods of writing dialogues. Even Jagex's own dialogue system is actually fairly similar to this; theirs is heavily dependent on indentation though as opposed to wrapping in brackets.
    Do you know what hard-coding is?
    "Know thy self, know thy enemy. A thousand battles, a thousand victories." - Sun Tzu
    GitHub: https://github.com/Faris-Mckay
    Reply With Quote  
     

  10. #29  
    What's a sundial in the shade?

    Lumiere's Avatar
    Join Date
    May 2013
    Age
    27
    Posts
    543
    Thanks given
    224
    Thanks received
    100
    Rep Power
    113
    Quote Originally Posted by arham 4 View Post
    Spoiler for Quote:
    Attached image

    I took a look at how Ruse, more specifically Necrotic, did their dialogue and was utterly disgusted. There was a JSON file to handle dialogues and there was hardcoding EVERYWHERE. The sight led to making a new dialogue system. If any of you recall, I made a dialogue system 2 years ago, and the following system is thoroughly inspired from the comments in that thread.

    I would like to thank Whis, netherfoam, and Kaleem for their input in that thread.

    The following system uses Kotlin. It is worth noting, if you do not know, that Kotlin and Java are 100% interoperable. That is, if your source doesn't contain Kotlin, don't be afraid to add this as your first, and maybe even only (but I hope not), Kotlin code. Even I have done such a thing:
    Attached image
    Yep, that's right, this is the only Kotlin in my source right now.

    Implementing the System
    Dialogue.kt
    Code:
    package com.ruse.world.content.dialogue
    
    import com.ruse.world.entity.impl.player.Player
    import java.util.*
    
    abstract class Dialogue(val player: Player, val closeable: Boolean = true) {
        val queue: Queue<DialogueMessage> = LinkedList<DialogueMessage>()
    
        abstract fun execute()
    
        protected fun playerMessage(message: String, expression: DialogueExpression = DialogueExpression.NORMAL, action: DialogueAction.() -> Unit = {}) {
            queue.add(PlayerMessage(message, expression, action))
        }
    
        protected fun npcMessage(npcId: Int, message: String, expression: DialogueExpression = DialogueExpression.NORMAL, action: DialogueAction.() -> Unit = {}) {
            queue.add(NPCMessage(message, npcId, expression, action))
        }
    
        protected fun itemMessage(itemId: Int, title: String = "", message: String, action: DialogueAction.() -> Unit = {}) {
            queue.add(ItemMessage(itemId, title, message, action))
        }
    
        protected fun plainMessage(message: String, continueText: String = "Click here to continue", action: DialogueAction.() -> Unit = {}) {
            queue.add(PlainMessage(message, continueText, noContinue = false, action = action))
        }
    
        protected fun plainMessageNoContinue(message: String, action: DialogueAction.() -> Unit = {}) {
            queue.add(PlainMessage(message, noContinue = true, action = action))
        }
    
        protected fun optionMessage(vararg options: String,
                                    option1: Dialogue.() -> Unit = {}, option2: Dialogue.() -> Unit = {},
                                    option3: Dialogue.() -> Unit = {}, option4: Dialogue.() -> Unit = {},
                                    option5: Dialogue.() -> Unit = {}, action: DialogueAction.() -> Unit = {}, title: String = "Choose an option") {
            queue.add(OptionMessage(*options, option1 = option1, option2 = option2, option3 = option3, option4 = option4, option5 = option5, action = action, title = title))
        }
    
        protected fun closeMessage(action: DialogueAction.() -> Unit = {}) {
            queue.add(CloseMessage(action))
        }
    }
    Dialogue.kt is the abstract class that all dialogues will extend. Within it are helper functions to add to the queue new messages. There is a lot of flexibility in the system to allow for lots of things to be customizably changed, or just defaulted to their respective defaults. For example, an entity can choose to have an expression, or be defaulted to the DEFAULT expression. An item dialogue can have a title, or be defaulted to no title, as per usual. Every single message contains an action that can be commenced, such as giving an item to a player, or making them perform an emote.

    One thing to note about option dialogue is specific is that each option branches off with a new function passed. This is important as then the system delays adding to the queue until a singular option is evoked by a button click. This also allows for option dialogues to default to closing by click, since the end of a queue signifies a closing of a dialogue. Due to this nature, one does not need to bother specifying endings to their dialogues.

    Going back on flexibility, I provided a closeMessage() function that allows for customizable behavior for when a message closes. For example, ending the dialogue entirely could progress a quest. In the example I will provide, it will make the player cry. Along with customizability for the closing, you may also specify if the dialogue can even be closed by walking by the constructor.

    DialogueMessage.kt
    Code:
    package com.ruse.world.content.dialogue
    
    import com.ruse.model.definitions.NpcDefinition
    import com.ruse.world.entity.impl.player.Player
    
    abstract class DialogueMessage(val action: DialogueAction.() -> Unit) {
        open val message: String = ""
        abstract fun display(player: Player)
        fun entityDisplay(frameIds: Array<Int>, expression: DialogueExpression?, title: String, player: Player, headDisplay: (Int) -> Unit) {
            val split = message.splitDialogue(this)
            val startingId = frameIds[split.size - 1]
            val nameId = startingId - 1
            val headId = startingId - 2
            val interfaceId = startingId - 3
            split.forEachIndexed { index, line -> player.packetSender.sendString(startingId + index, line) }
            headDisplay(headId)
            player.packetSender.sendString(nameId, title)
            if (expression != null) {
                player.packetSender.sendInterfaceAnimation(headId, expression.animation)
            }
            player.packetSender.sendChatboxInterface(interfaceId)
        }
    }
    
    class PlayerMessage(override val message: String, private val expression: DialogueExpression, action: DialogueAction.() -> Unit) : DialogueMessage(action) {
        private val frameIds = arrayOf(971, 976, 982, 989)
        override fun display(player: Player) = entityDisplay(frameIds, expression, player.username, player) { headId ->
            player.packetSender.sendPlayerHeadOnInterface(headId)
        }
    }
    
    class NPCMessage(override val message: String, private val npcId: Int, private val expression: DialogueExpression, action: DialogueAction.() -> Unit) : DialogueMessage(action) {
        private val frameIds = arrayOf(4885, 4890, 4896, 4903)
        override fun display(player: Player) = entityDisplay(frameIds, expression, NpcDefinition.forId(npcId).name, player) { headId ->
            player.packetSender.sendNpcHeadOnInterface(npcId, headId)
        }
    }
    
    class ItemMessage(private val itemId: Int, private val title: String, override val message: String, action: DialogueAction.() -> Unit) : DialogueMessage(action) {
        private val frameIds = arrayOf(4885, 4890, 4896, 4903)
        override fun display(player: Player) = entityDisplay(frameIds, null, title, player) { headId ->
            player.packetSender.sendInterfaceModel(headId, itemId, 150) // not sure if zoom should be 150
        }
    }
    
    class PlainMessage(override val message: String, val continueText: String = "", val noContinue: Boolean, action: DialogueAction.() -> Unit) : DialogueMessage(action) {
        private val frameIds = arrayOf(357, 360, 364, 369, 375)
        private val frameIdsNoContinue = arrayOf(12789, 12791, 12794, 12798, 12803)
        override fun display(player: Player) {
            val split = message.splitDialogue(this)
            val startingId = if (noContinue) frameIdsNoContinue[split.size - 1] else frameIds[split.size - 1]
            val interfaceId = startingId - 1
            split.forEachIndexed { index, line ->
                player.packetSender.sendString(startingId + index, line)
            }
            if (!noContinue) {
                player.packetSender.sendString(startingId + split.size, continueText)
            }
            player.packetSender.sendChatboxInterface(interfaceId)
    
        }
    }
    
    /**
     * An empty option lambda means that the dialogue will default to closing.
     */
    class OptionMessage(vararg val options: String,
                        val option1: Dialogue.() -> Unit, val option2: Dialogue.() -> Unit,
                        val option3: Dialogue.() -> Unit, val option4: Dialogue.() -> Unit,
                        val option5: Dialogue.() -> Unit, action: DialogueAction.() -> Unit,
                        val title: String = "Choose an option") : DialogueMessage(action) {
        val frameIds = arrayOf(13760, 2461, 2471, 2482, 2494)
        override fun display(player: Player) {
            val startingId = frameIds[options.size - 1]
            val titleId = startingId - 1
            val interfaceId = startingId - 2
            player.packetSender.sendString(titleId, title)
            options.forEachIndexed { index, option -> player.packetSender.sendString(startingId + index, option) }
            player.packetSender.sendChatboxInterface(interfaceId)
        }
    }
    
    /**
     * If one wants a custom close action (for example, giving an item AFTER the dialogue is finished), then they must
     * add a close message to the queue themselves. By default, a dialogue ends when the queue is empty, with no action
     * being commenced.
     */
    class CloseMessage(action: DialogueAction.() -> Unit = {}) : DialogueMessage(action) {
        override fun display(player: Player) {
            player.packetSender.sendInterfaceRemoval()
            player.dialogueIterator = null
        }
    }
    
    /**
     * A custom made splitDialogue extension function to determine the splits in dialogue itself rather than having to go through
     * trial and error to splitDialogue the lines of messages to fit the message frame. One can make new lines themselves
     * by adding "\n" to the location.
     */
    fun String.splitDialogue(dialogueMessageType: DialogueMessage): Array<String> {
        val message = this
        val messageSplit = ArrayList<String>()
        var currentLine = ""
        var chars = 0
        val limit = if (dialogueMessageType is PlainMessage) 75 else 50
        for (word in message.split(" ")) {
            val length = word.length + 2
            if (word.contains("\n")) {
                chars = limit * (messageSplit.size + 1)
                messageSplit.add("$currentLine ${word.replace("\n", "")}")
                currentLine = ""
            } else {
                if (length + chars >= limit * (messageSplit.size + 1)) {
                    messageSplit.add(currentLine)
                    currentLine = word
                } else {
                    currentLine += " $word"
                }
                chars += length
            }
        }
        if (currentLine.isNotEmpty()) {
            messageSplit.add(currentLine)
        }
        return messageSplit.toTypedArray()
    }
    A majority of these classes have already been discussed in the above paragraph. However, it is important to note the splitDialogue() function. This is why the title includes "Intelligent Message Splitting Included," for I haven't seen such a thing in a 317 dialogue system. This was inspired by higher revision's client-sided splitting of messages (though I'm not sure how they do it, it is worth looking into if splitDialogue() does not suffice your needs and turns faulty). Essentially, per word, it added the length to a variable, and if the line exceeds 50 with the new word, it make a line out of the previous words, excluding the current word, and makes the current word the start of a new line. This process continues till the dialogue has been completely split.

    With this intelligence, a message can be written simply as:
    Code:
    playerMessage("Lorem ipsum dolor sit amet consectetur adipiscing elit. Integer dictum lorem ac condimentum egestas. Mauris molestie ligula vitae fermentum finibus. Lorem ipsum dolor sit")
    Rather than:
    Code:
    playerMessage("Lorem ipsum dolor sit amet consectetur",
                          "adipiscing elit. Integer dictum lorem ac",
                          "condimentum egestas. Mauris molestie ligula vitae",
                          "fermentum finibus. Lorem ipsum dolor sit")
    DialogueAction.kt
    Code:
    package com.ruse.world.content.dialogue
    
    import com.ruse.model.Animation
    import com.ruse.model.Item
    
    
    class DialogueAction {
        fun Dialogue.openNewDialogue(dialogue: Dialogue) {
            DialogueExecutor.startDialogue(player, dialogue)
        }
    
        fun Dialogue.giveItem(item: Item) {
            player.inventory.add(item)
        }
    
        fun Dialogue.giveItem(id: Int) {
            giveItem(Item(id))
        }
    
        fun Dialogue.performAnimation(animation: Animation) {
            player.performAnimation(animation)
        }
    
        fun Dialogue.performAnimation(id: Int) {
            performAnimation(Animation(id))
        }
    }
    DialogueAction will serve as a means of having predefined actions to choose from in our dialogue. The intention behind the class was that many dialogues require the same things out of a player and thus, following the same principle as the Dialogue.kt class above, should have helper functions to do those very actions.

    DialogueExpression.kt
    Code:
    package com.ruse.world.content.dialogue
    
    import com.ruse.model.Animation
    
    enum class DialogueExpression(animationId: Int) {
        NO_EXPRESSION(9760),
        NO_EXPRESSION_TWO(9772),
        SAD(9764),
        SAD_TWO(9768),
        WHY(9776),
        SCARED(9780),
        MILDY_ANGRY(9784),
        ANGRY(9788),
        VERY_ANGRY(9792),
        ANGRY_TWO(9796),
        MANIC_FACE(9800),
        JUST_LISTEN(9804),
        PLAIN_TALKING(9808),
        LOOK_DOWN(9812),
        CONFUSED(9816),
        CONFUSED_TWO(9820),
        WIDEN_EYES(9824),
        CROOKED_HEAD(9828),
        GLANCE_DOWN(9832),
        UNSURE(9836),
        LISTEN_LAUGH(9840),
        TALK_SWING(9844),
        NORMAL(9847),
        GOOFY_LAUGH(9851),
        NORMAL_STILL(9855),
        THINKING_STILL(9859),
        LOOKING_UP(9862), CALM(9805);
    
        val animation: Animation = Animation(animationId)
    }
    This simply contains the expressions. This class already existed in Ruse. Credits to relax lawl for the expressions list.

    DialogueExecutor.kt
    Code:
    package com.ruse.world.content.dialogue
    
    import com.ruse.world.entity.impl.player.Player
    
    object DialogueExecutor {
        @JvmStatic
        fun startDialogue(player: Player, dialogue: Dialogue) {
            player.dialogueIterator = makeIterator(player, dialogue)
            player.dialogueIterator.broadcastMessage()
        }
    
        private fun makeIterator(player: Player, dialogue: Dialogue): DialogueIterator {
            return DialogueIterator(player, dialogue)
        }
    }
    
    class DialogueIterator(private val player: Player, private val dialogue: Dialogue) {
        private lateinit var currentMessage: DialogueMessage
        private var lastMessage: DialogueMessage? = null
    
        init {
            dialogue.execute()
            assignCurrentMessage()
        }
    
        fun broadcastMessage() {
            currentMessage.display(player)
            currentMessage.action(DialogueAction)
            lastMessage = currentMessage
            assignCurrentMessage()
        }
    
        private fun assignCurrentMessage() {
            currentMessage = if (dialogue.queue.peek() != null) dialogue.queue.poll() else CloseMessage()
        }
    
        fun handleWalk() {
            if (dialogue.closeable) player.packetSender.sendInterfaceRemoval()
        }
    
        fun forceCloseDialogue() {
            currentMessage = CloseMessage()
            broadcastMessage()
        }
    
        fun handleOptionClick(buttonId: Int) {
            val optionMessage = run { if (lastMessage == null) currentMessage else lastMessage } as OptionMessage
            val option1 = optionMessage.frameIds[optionMessage.options.size - 1]
            when (buttonId) {
                option1 -> optionMessage.option1(dialogue)
                option1 + 1 -> optionMessage.option2(dialogue)
                option1 + 2 -> optionMessage.option3(dialogue)
                option1 + 3 -> optionMessage.option4(dialogue)
                option1 + 4 -> optionMessage.option5(dialogue)
            }
            broadcastMessage()
        }
    }
    It is worth noting that handleOptionClick() is the reason for the unique behavior of option dialogues, for only when the option is clicked is the function invoked. Another thing to note is here is how it is determined if a dialogue is to be closed or not (assignCurrentMessage()).

    Integrating the System
    There are four steps. One, replace the case for the dialogue opcode in DialoguePacketListener:
    Code:
                case DIALOGUE_OPCODE:
                    player.getDialogueIterator().broadcastMessage();
                    break;
    Two, find where the following is in ButtonClickPacketListener:
    Code:
    case 2485:
    And replace:
    Code:
    DialogueOptions.handle(player, id)
    with:
    Code:
    player.getDialogueIterator().handleOptionClick(id)
    Three, declare the following somewhere in Player:
    Code:
        private DialogueIterator dialogueIterator;
    
        public DialogueIterator getDialogueIterator() {
            return dialogueIterator;
        }
    
        public void setDialogueIterator(DialogueIterator dialogueIterator) {
            this.dialogueIterator = dialogueIterator;
        }
    Four, go to MovementPacketListener and find:
    Code:
    player.getPacketSender().sendInterfaceRemoval();
    Replace it with:
    Code:
            if (player.getDialogueIterator() != null) {
                player.getDialogueIterator().handleWalk();
            } else {
                player.getPacketSender().sendInterfaceRemoval();
            }
    You should now be ready to rock and roll with the new dialogue system.
    Example
    For old traditions sakes (every dialogue system I've released, I've done this), let's use Hans as the culprit of our dialogue system again. Make a package in your dialogue package called impl, and add a file called Hans.kt. Here's an example of dialogue in Kotlin:
    Code:
    package com.ruse.world.content.dialogue.impl
    
    import com.ruse.world.content.Emotes
    import com.ruse.world.content.dialogue.Dialogue
    import com.ruse.world.entity.impl.player.Player
    
    class Hans(player: Player) : Dialogue(player) {
        private val npcId = 0
    
        override fun execute() {
            playerMessage("Wow, this surprisingly works!") {
                performAnimation(Emotes.EmoteData.DANCE.animation)
            }
            npcMessage(npcId, "Yeah man, I didn't think the day would come. But it has, alas, and I am just waiting for one more thing: option dialogues.")
            optionMessage("Option 1", "Option 2", "Option 3",
                    option1 = {
                        playerMessage("Hey man, this is option 1")
                        npcMessage(npcId, "Seems to have worked.") // makes weird head, need to see
                        playerMessage("Yes indeed.")
                        itemMessage(4151, message = "To items! Take a whip!") {
                            giveItem(4151)
                        }
                        playerMessage("Thank you!")
                        plainMessage("You proceed to express your gratitude... in other ways.")
                        plainMessage("Now, let's test the custom close dialogue by making you cry.")
                        closeMessage { performAnimation(Emotes.EmoteData.CRY.animation) }
                    },
                    option2 = {
                        playerMessage("Hey dude, this is option 2")
                        npcMessage(npcId, "I believe this works.. too?")
                        playerMessage("Yes indeed, now we need to see if option3 closes the dialogue.")
                    }) // option 3 is not implemented to see if it will close the dialogue
        }
    }
    Spoiler for Prettier syntax highlighting:

    Attached image

    But Arham, doesn't the title say Kotlin/Java?
    Yeah, well, I kinda sorta lied to you so you won't shoo away from "Kotlin." Yes, you can write your dialogues in Java, but they don't look as pretty:
    Spoiler for Java Implementation:

    Footnote: This java implementation showcases the dialogue system before multiple changes. I can't really be bothered to change it.
    Code:
    package com.ruse.world.content.dialogue.impl;
    
    import com.ruse.model.Item;
    import com.ruse.world.content.Emotes;
    import com.ruse.world.content.dialogue.Dialogue;
    import com.ruse.world.content.dialogue.DialogueExpression;
    import com.ruse.world.entity.impl.player.Player;
    import org.jetbrains.annotations.NotNull;
    
    public class HansJava extends Dialogue {
        private int npcId = 0;
    
        @Override
        public void execute(@NotNull Player player) {
            playerMessage("Wow, this surprisingly works!", DialogueExpression.NORMAL, () -> {
                player.performAnimation(Emotes.EmoteData.DANCE.animation);
                return null;
            });
            npcMessage(npcId, "Yeah man, I didn't think the day would come. But it has, alas, and I am just waiting for one more thing: option dialogues.", DialogueExpression.NORMAL, () -> null);
            optionMessage(new String[]{"Option 1", "Option 2", "Option 3"},
                    option1 -> {
                        playerMessage("Hey man, this is option 1", DialogueExpression.NORMAL, () -> null);
                        npcMessage(npcId, "Seems to have worked.", DialogueExpression.NORMAL, () -> null);
                        playerMessage("Yes indeed.", DialogueExpression.NORMAL, () -> null);
                        itemMessage(4151, "", "To items! Take a whip!", () -> {
                            player.getInventory().add(new Item(4151));
                            return null;
                        });
                        playerMessage("Thank you!", DialogueExpression.NORMAL, () -> null);
                        plainMessage("You proceed to express your gratitude... in other ways.", () -> null);
                        plainMessage("Now, let's test the custom close dialogue by making you cry.", () -> null);
                        closeMessage(() -> {
                            player.performAnimation(Emotes.EmoteData.CRY.animation);
                            return null;
                        });
                        return null;
                    },
                    option2 -> {
                        playerMessage("Hey dude, this is option 2", DialogueExpression.NORMAL, () -> null);
                        npcMessage(npcId, "I believe this works.. too?", DialogueExpression.NORMAL, () -> null);
                        playerMessage("Yes indeed, now we need to see if option3 closes the dialogue.", DialogueExpression.NORMAL, () -> null);
                        return null;
                    },
                    option3 -> null,
                    option4 -> null,
                    option5 -> null,
                    () -> null);
        }
    }

    This is because a lot of my functions in Kotlin would be implemented in Java with overloaded methods, but instead I just used default parameters in Kotlin to achieve the same thing. Sorry, but come on, Kotlin is beautiful.

    To run the above classes, I made a test command, likeso:
    Code:
            if (command[0].equalsIgnoreCase("testdialogue")) {
                DialogueExecutor.startDialogue(player, new Hans(player));
            }
    oOoOoOoOOoOo hotstuff, thanks friendo

    Spoiler for Revy is perfect:
    Reply With Quote  
     

  11. Thankful user:


  12. #30  
    (Official) Thanksgiver

    Arham's Avatar
    Join Date
    Jan 2013
    Age
    23
    Posts
    3,415
    Thanks given
    7,254
    Thanks received
    1,938
    Rep Power
    3905
    Quote Originally Posted by Faris View Post
    Do you know what hard-coding is?
    Why talk so pretentiously? Just make points to perhaps educate.

    Quote Originally Posted by Lumiere View Post
    oOoOoOoOOoOo hotstuff, thanks friendo
    Thank you friend, glad to see you around again.
    Attached image
    Attached image
    Quote Originally Posted by MrClassic View Post
    Arham is the official thanker!
    List of my work here!
    Reply With Quote  
     

Page 3 of 5 FirstFirst 12345 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Advanced Kotlin Dialogue System
    By CrazyPanda in forum Snippets
    Replies: 7
    Last Post: 04-07-2016, 02:16 AM
  2. Kotlin Based Dialogue System
    By PinocchioOrWot in forum Show-off
    Replies: 11
    Last Post: 02-10-2016, 06:18 AM
  3. Ruse dialogue system.
    By Lotr M eurth in forum Help
    Replies: 3
    Last Post: 12-31-2015, 06:26 PM
  4. [ANY] Dialogue System
    By frostbit3 in forum Tutorials
    Replies: 15
    Last Post: 06-27-2014, 11:18 AM
  5. is ther any tool that cleans java files up
    By T-Sex in forum Downloads
    Replies: 7
    Last Post: 08-03-2008, 01:39 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •