Thread: DialogueScript by Runite :: FINALLY, the easiest & quickest way to create dialogue.

Page 1 of 2 12 LastLast
Results 1 to 10 of 18
  1. #1 DialogueScript by Runite :: FINALLY, the easiest & quickest way to create dialogue. 
    Member #35, most veteran member left? :D


    Join Date
    Jul 2006
    Age
    30
    Posts
    2,660
    Thanks given
    53
    Thanks received
    331
    Rep Power
    925
    DialogueScript
    by Runite

    CREATE FULL DIALOGUES FOR YOUR SERVER IN MINUTES, EVEN SECONDS.

    Check this shit out:
    • Everything is handled via a text file cleverly called dialogue.txt (you can change this if you want).
    • Because it is handled in a text file, you can update your dialogue LIVE - even if your server is still running.
    • It's never been easier to create and READ your dialogue - You simply put a symbol or two in front of what you want and everything else is handled for you!.
    • Line breaks are created automatically, so you don't need to figure out where to split your sentences.
    • Variables such as @name (replaced by the player's name) are INSANELY easy to add, with a couple of examples already there.
    • FULLY supports NPC chats, player chats, options (as many in a row as you want), and simple statements (no chat heads).
    • Customizable (with a few already added) COMMAND SYSTEM, which allows you to open shops, interfaces, send messages, and anything else you need FROM THE DIALOGUE.TXT FILE.
    • SO MUCH MORE!


    This was created for a RuneFusion 1.0.5 source, but with a few tiny fixes it'll work for literally anything.

    * Please keep in mind this is just the release immediately after all of the functionalities had been added. It still needs some fixing up ;P

    THE TUTORIAL

    1. Create this file (you will need to change the package and what not to work with your own server):
    Code:
    /*
     * DialogueScript by Runite
     * version 1.0
     *
     * Completely, 100% written from scratch. Yup.
     *
     * The easiest, quickest, and most efficient way to handle dialogue for your server.
     */
    
    package server.model.players;
    
    import server.util.*;
    
    import java.io.*;
    import java.util.*;
    
    public class DialogueScript {
    
    	private Client c;
    	public DialogueScript(Client Client) {
    		this.c = Client;
    	}
    	
    	public String getDialogue(int npc) {
    		try {
    			BufferedReader br = new BufferedReader(new FileReader("./data/dialogue.txt"));
    			try {
    				StringBuilder sb = new StringBuilder();
    				String line = br.readLine();
    				
    				boolean record = false;
    				while (line != "[END DIALOGUES]") {
    					if(line.startsWith("NPCID:")) {
    						String[] info = line.split(" ");
    						if(Integer.parseInt(info[1]) == npc) {
    							c.currentDialogueNPC = npc;
    							record = true;
    						}
    					}
    
    					line = br.readLine();
    					if(record) {
    						sb.append(line);
    						sb.append("\n");
    						if((line.equals("[end]")) && record) {
    							break;
    						}
    					}
    				}
    				return sb.toString();
    			} finally {
    				br.close();
    			}
    		} catch(Exception e) {
    			e.printStackTrace();
    		}
    		return "";
    	}
    	
    	public void endDialogue() {
    		c.currentDialogueStage = 0;
    		c.currentDialogueNPC = 0;
    		c.currentDialogueOption = 0;
    		c.dialoguePaths = new ArrayList<Integer>();
    	}
    	
    	public void initiateNPCDialogue(int npc) {
    		c.currentDialogueStage = 1;
    		doNPCDialogue(npc);
    	}
    	
    	public void setDialogueOption(int opt) {
    		if(c.currentDialogueOption <= 0) {
    			c.currentDialogueOption = opt;
    		}
    	}
    	
    	public boolean doNPCDialogue(int npc) {
    		String script = getDialogue(npc);
    		String[] line = script.split("\n");
    		
    		String dialogue = "", currentLine = "";
    		String[] formattedDialogue = new String[5];
    		
    		int lineNumber = 0, optionNumber = 0;
    		
    		for(int i=0; i<line.length; i++) {
    			
    			if(line[i].startsWith("> ") || line[i].startsWith("< ") || line[i].startsWith("! ") || line[i].startsWith("? ") || line[i].startsWith("?-- ") || line[i].startsWith("{ ") || line[i].startsWith("(")) {
    				boolean correctPath = true, countLine = true;
    				if(line[i].startsWith("(")) {
    					if(!c.dialoguePaths.isEmpty()) {
    						String paths = line[i].replaceAll("\\(|\\).*", "");
    						String[] pathOptions = paths.split(", ");
    						for(int p=0; p<pathOptions.length; p++) {
    							if(c.dialoguePaths.get(p).intValue() == Integer.parseInt(pathOptions[p])) {
    								countLine = false;
    								if(p+1 == pathOptions.length) {
    									if(c.dialoguePaths.size() == pathOptions.length) {
    										countLine = true;
    									}
    									line[i] = line[i].substring(line[i].indexOf(")")+2);
    									break;
    								}
    								continue;
    							} else {
    								correctPath = false;
    								break;
    							}
    						}
    					}
    				} else {
    					if(!c.dialoguePaths.isEmpty()) {
    						countLine = false;
    					}
    				}
    				
    				if(line[i].startsWith("?-- ")) {
    					if(correctPath && countLine) {
    						optionNumber++;
    						if(c.currentDialogueOption > 0 && optionNumber == c.currentDialogueOption) {
    							currentLine = line[i].substring(4);
    							break;
    						}
    					}
    				} else {
    					if(correctPath) {
    						optionNumber = 0;
    						lineNumber++;
    						if(lineNumber == c.currentDialogueStage) {
    							currentLine = line[i];
    							break;
    						}
    					}
    				}
    			} else
    			if(line[i].equals("[end]")) {
    				endDialogue();
    				return false;
    			} else {
    				continue;
    			}
    			
    		}
    		
    		if(currentLine != null) {
    			dialogue = currentLine.substring(2);
    			String[] breaks = dialogue.split(" :: ");
    			
    			if(c.currentDialogueOption > 0) {
    				c.dialoguePaths.add(c.currentDialogueOption);
    				c.currentDialogueOption = 0;
    			}
    					
    			if(currentLine.startsWith("? ")) {
    				formattedDialogue[4] = Integer.toString(breaks.length);
    				for(int b=0; b<breaks.length; b++) {
    					if(b < 4) {
    						formattedDialogue[b] = breaks[b];
    					}
    				}
    			} else
    			if(currentLine.startsWith("{ ")) {
    				String[] commands = dialogue.split("; ");
    				for(int x=0; x<commands.length; x++) {
    					String cmd = commands[x];
    					String mod = (cmd.substring(cmd.indexOf("(")+1, cmd.indexOf(")")) != null ? cmd.substring(cmd.indexOf("(")+1, cmd.indexOf(")")) : "");
    					
    					if(cmd.startsWith("sendMessage")) {
    						try {
    							c.sendMessage(mod);
    						} catch(Exception e) {
    							e.printStackTrace();
    						}
    					}
    					
    					if(cmd.startsWith("openShop")) {
    						try {
    							c.isShopping = true;
    							c.getShops().openShop(Integer.parseInt(mod));
    							endDialogue();
    						} catch(Exception e) {
    							e.printStackTrace();
    						}
    					}
    					
    					if(cmd.startsWith("showInterface")) {
    						try {
    							if(Integer.parseInt(mod) == 14670) {
    								c.getCrafting().showTanningInterface();
    							} else {
    								c.getPA().showInterface(Integer.parseInt(mod));
    							}
    							endDialogue();
    						} catch(Exception e) {
    							e.printStackTrace();
    						}
    					}
    					
    					if(cmd.startsWith("endDialogue")) {
    						endDialogue();
    						formattedDialogue = null;
    						return false;
    					}
    				}
    			} else {
    				if(breaks.length < 2) {
    					String[] words = dialogue.split(" ");
    					int chars = 0, charBreak = 0, wordCount = 0, prevWordCount = 0, lineCount = 0;
    					for(int w=0; w<words.length; w++) {
    						int wl = words[w].length();
    						if((chars+wordCount < 50 && lineCount < 3) || lineCount == 3) {
    							chars += wl;
    							wordCount += 1;
    						}
    						if((chars+wordCount >= 50 && lineCount < 3) || (lineCount == 3 && w+1 == words.length) || w+1 == words.length) {
    							for(int c=0; c<4; c++) {
    								if(formattedDialogue[c] == null) {
    									int stopPoint = charBreak+chars+(wordCount-1)+prevWordCount;
    									if(stopPoint > dialogue.length()) {
    										stopPoint = dialogue.length();
    									}
    									formattedDialogue[c] = dialogue.substring(charBreak+prevWordCount, stopPoint);
    									prevWordCount += wordCount;
    									wordCount = 0;
    									lineCount += 1;
    									break;
    								}
    							}
    							charBreak += chars;
    							chars = 0;
    							if(w+1 == words.length) {
    								formattedDialogue[4] = Integer.toString(((charBreak < 200 ? charBreak : 199)/50)+1);
    								break;
    							}
    						}
    					}
    				} else {
    					formattedDialogue[4] = Integer.toString(breaks.length);
    					for(int b=0; b<breaks.length; b++) {
    						if(b < 4) {
    							formattedDialogue[b] = breaks[b];
    						}
    					}
    				}
    			}
    			
    			if(formattedDialogue != null) {
    				if(currentLine.startsWith("> ")) {
    					sendNPCChat(formattedDialogue, npc);
    				} else
    				if(currentLine.startsWith("< ")) {
    					sendPlayerChat(formattedDialogue);
    				} else
    				if(currentLine.startsWith("! ")) {
    					sendLine(formattedDialogue);
    				} else
    				if(currentLine.startsWith("? ")) {
    					sendOption(formattedDialogue);
    				}
    
    				if(optionNumber <= 0) {
    					c.currentDialogueStage++;
    				}
    				return true;
    			}
    		}
    		return false;
    	}
    	
    	public Integer tryParse(String s) { // not mine :(
    		Integer retVal;
    		try {
    			retVal = Integer.parseInt(s);
    		} catch (NumberFormatException nfe) {
    			retVal = -1;
    		}
    		return retVal;
    	}
    	
    	public String replaceVars(String s) {
    		String s1 = s;
    		
    		s1 = s1.replace("@name", c.playerName);
    		s1 = s1.replace("@attack", Integer.toString(c.playerAttack)); // example
    		
    		return s1;
    	}
    	
    	public void sendLine(String[] s) {
    		int f = 0;
    		int length = Integer.parseInt(s[4]);
    		switch(length) {
    			case 1: f = 356; break;
    			case 2: f = 359; break;
    			case 3: f = 363; break;
    			case 4: f = 368; break;
    		}
    		
    		for(int i=0; i<length; i++) {
    			if(i <= 3) {
    				c.getPA().sendFrame126(replaceVars(s[i]), (f+1)+i);
    			}
    		}
    		c.getPA().sendFrame164(f);
    	}
    	
    	public void sendOption(String[] s) {
    		int f = 0;
    		int length = Integer.parseInt(s[4]);
    		switch(length) {
    			case 2: f = 2459; break;
    			case 3: f = 2469; break;
    			case 4: f = 2480; break;
    			case 5: f = 2492; break;
    		}
    		
    		for(int i=0; i<length; i++) {
    			if(i <= 4) {
    				c.getPA().sendFrame126(replaceVars(s[i]), (f+2)+i);
    			}
    		}
    		c.getPA().sendFrame164(f);
    	}
    	
    	public void sendPlayerChat(String[] s) {
    		int f = 0;
    		int length = Integer.parseInt(s[4]);
    		switch(length) {
    			case 1: f = 969; break;
    			case 2: f = 974; break;
    			case 3: f = 980; break;
    			case 4: f = 987; break;
    		}
    		
    		c.getPA().sendFrame200(f, 591);
    		c.getPA().sendFrame126(Misc.formatPlayerName(c.playerName), f+1);
    		for(int i=0; i<length; i++) {
    			if(i <= 3) {
    				c.getPA().sendFrame126(replaceVars(s[i]), (f+2)+i);
    			}
    		}
    		c.getPA().sendFrame185(f);
    		c.getPA().sendFrame164(f-1);
    	}
    	
    	public String npcName(int npc) {
    		switch(npc) {
    		
    			case 0: return "Hans";
    			case 1: return "Man";
    			case 494: return "Banker";
    			case 550: return "Lowe";
    			case 554: return "Fancy-dress shop owner";
    			case 804: return "Tanner";
    			
    			default: return "n/a";
    		}
    		// return yourNPCNameMethodHere(npc); // remove/comment out above if you have a method for getting NPC names
    	}
    	
    	public void sendNPCChat(String[] s, int npc) {
    		String name = npcName(npc);
    		int f = 0;
    		int length = Integer.parseInt(s[4]);
    		switch(length) {
    			case 1: f = 4888; break;
    			case 2: f = 4888; break;
    			case 3: f = 4894; break;
    			case 4: f = 4901; break;
    		}
    		
    		c.getPA().sendFrame200(f, 591);
    		c.getPA().sendFrame126(name, f+1);
    		for(int i=0; i<length; i++) {
    			if(i <= 3) {
    				if(length > 1) {
    					c.getPA().sendFrame126(replaceVars(s[i]), (f+2)+i);
    				} else {
    					c.getPA().sendFrame126(replaceVars(s[i]), (f+2)+i);
    					c.getPA().sendFrame126("", (f+2)+i+1);
    				}
    			}
    		}
    		c.getPA().sendFrame75(npc, f);
    		c.getPA().sendFrame164(f-1);
    	}
    	
    }
    2. Add these in your player class:
    Code:
    public int currentDialogueStage = 0, currentDialogueNPC = 0, currentDialogueOption = 0;
    public ArrayList<Integer> dialoguePaths = new ArrayList<Integer>();
    3. Throw this stuff in your client class, or wherever necessary:
    Code:
    private DialogueScript dialogueScript = new DialogueScript(this);
    
    public DialogueScript dialogueScript() {
    	return dialogueScript;
    }
    4. This is for when you click an NPC to open the dialogue:
    Code:
    c.dialogueScript().initiateNPCDialogue(NPC_ID);
    5. This is for when you click one of the lines in the option interface (option number 1, 2, 3, 4 respectively):
    Code:
    c.getDialogue2().setDialogueOption(OPTION_NUMBER);
    6. And HERE'S an example of dialogue.txt:
    Code:
    // Sample dialogue.txt, pointless and stupid, just to show off how to use it and its functionality ;D <3 Runite
    
    NPCID: 550 (Lowe)
    < Hey Lowe.
    > Fuck off, @name.
    < Why?
    > You tell me.
    ? Because you're mean. :: I smell bad. :: You're trying to get it in. :: May I see your wares?
    ?-- < Because you're mean?
    ?-- < Well, I mean I try to shower regularly, but is it because I smell bad?
    ?-- < Silly Lowe, you're trying to get it in, aren't you?
    ?-- < Can I just see your shop?
    
    (1) > Yup.
    (1) < Why are you mean?
    (1) > You tell me.
    (1) ? I don't know. :: No.
    (1) ?-- < I have no idea, Lowe.
    (1) ?-- < Nope, I don't want to play this stupid game with you anymore.
    (1, 1) > You suck.
    (1, 1) < Stupid Lowe life. Hehe...
    (1, 1) ? Lol :: Lol2
    (1, 1) ?-- < LOL
    (1, 1) ?-- < LOL2
    (1, 1, 1) > ...
    (1, 1, 1) { openShop(9); }
    (1, 1, 2) > ... ...
    (1, 2) > Fine.
    (1, 2) < Fine.
    
    (2) > No.
    (2) < Okay, good!
    (2) ? Yo? :: Swag
    (2) ?-- < YO LOWE!
    (2) ?-- < Swag 420 blaze it.
    (2, 1) > LOL!!!!! Or, LOWEL. HAH!
    (2, 2) > No, fag.
    
    (3) > Shh! No. Well, yes.
    (3) ! Lowe looks embarassed and turns away.
    
    (4) > Ugh, fine.
    (4) { openShop(9); sendMessage(Lowe reluctantly shows you his wares.); }
    
    < Does this work still?
    > This shit :: manually breaks :: yo.
    [end]
    
    
    
    NPCID: 804 (Tanner)
    > Hello there! :: How may I assist you?
    ? Can you tan my hides? :: I'd like to see your wares.
    ?-- < Can you tan my hides for me?
    ?-- < I'd like to see your wares.
    
    (1) > Certainly! :: However, I do charge a small fee.
    (1) { showInterface(14670); }
    
    (2) { openShop(3); }
    [end]
    
    
    
    [END DIALOGUES]


    HOW TO USE IT

    Here's a super duper quick crash course on how to create your own dialogue.txt the right way, and also a few other little tweaks you can make.
    'NPCID: ID' - This begins all dialogue, and determines the NPC you are speaking to.
    '[end]' - Placed at the very end of each dialogue, signifying that the dialogue is finished.
    '[END DIALOGUES]' - Placed at the very end of the dialogue.txt to say that there is no more dialogue beyond that point.

    '<' - Putting this before your text will make the NPC speak.
    '>' - Putting this before your text will make your player speak.
    '?' - Putting this before your text will signify an option needs to be selected.
    '!' - Putting this before your text will show lines of text without chat heads.
    '{' - Putting this before your text will mark the line as being used for commands, such as openShop(SHOP_ID).

    '::' - Putting this between text will either: 1) Break up options after the '?' or 2) Manually break dialogue, which will disregard the auto-breaking completely for that line.
    '?--' - Putting this before your text will signify the response for an option. The option number it responds to is respective to the order of options after the '?' and between the '::'s. (NOTE: You will still need to use the '<', '>', '?', or '!' symbols after the '?--')
    ';' - This is to be placed directly after commands (on a line started with '{') to separate them, i.e. { openShop(1); sendMessage(Opened shop 1); }.

    '(#)', '(#, #)', etc. - Putting this at the beginning of a line (where # are the corresponding option numbers, in order) will determine which option number the line goes with.
    Once you're comfortable creating the actual dialogues, you can tweak the DialogueScript class in pretty much any way you like. Changing most parts will screw it up though, but feel free to look at these parts:

    • Search if(currentLine.startsWith("{ ")) { - Look right past here and you'll find where your commands are.
    • Search public String replaceVars(String s) - This method contains the variables that you can use in the dialogue.
    • Search public String npcName(int npc) - This method contains the NPC names that correspond to NPC IDs. Chances are you have a method to handle this elsewhere, so edit however you need to.



    There it is! DialogueScript, brought to you 100% by yours truly. If you have any comments, concerns, or questions, PLEASE feel free to post. I'll try my best to answer anything.

    I hope you guys enjoy it and find some use out of it! I'm hoping this is a big release for everyone.



    Credits: Me and some guy from Stack Overflow who made the tryParse method (which isn't much LOL).


    `Ex-global moderator x3 (resigned)
     


  2. #2  
    Donator


    Join Date
    Jul 2011
    Posts
    921
    Thanks given
    199
    Thanks received
    178
    Rep Power
    189
    Good job! Very creative, but i'd still prefer the old way cause this looks a bit messy.
     

  3. #3  
    Typical Swede


    Join Date
    Jul 2008
    Posts
    1,162
    Thanks given
    204
    Thanks received
    154
    Rep Power
    217
    This looks really great

    'Strange things did happen here no stranger would it be'
    ______________________________________________
     

  4. #4  
    q.q


    Join Date
    Dec 2010
    Posts
    6,519
    Thanks given
    1,072
    Thanks received
    3,535
    Rep Power
    4752
    Quote Originally Posted by IxInDrEkxI View Post
    Good job! Very creative, but i'd still prefer the old way cause this looks a bit messy.
    what lol? hope you're joking
     

  5. Thankful users:


  6. #5  
    Registered Member

    Join Date
    Mar 2011
    Posts
    1,226
    Thanks given
    245
    Thanks received
    475
    Rep Power
    294
    Nice, but why the hell are you creating a new instance per player?
     

  7. Thankful users:


  8. #6  
    Chemist

    Advocatus's Avatar
    Join Date
    Dec 2009
    Posts
    2,622
    Thanks given
    201
    Thanks received
    813
    Rep Power
    1462
    This looks inefficient as hell.
    Quote Originally Posted by blakeman8192 View Post
    Quitting is the only true failure.
     

  9. Thankful users:


  10. #7  
    Registered Member
    Join Date
    Jan 2013
    Posts
    61
    Thanks given
    31
    Thanks received
    21
    Rep Power
    15
    Are you seriously not loading all dialogues on startup. Whats the point of loading dialogues when the person talks to npc. Good luck dealing with game freezes when someone talks to a npc.
     

  11. Thankful user:


  12. #8  
    Member #35, most veteran member left? :D


    Join Date
    Jul 2006
    Age
    30
    Posts
    2,660
    Thanks given
    53
    Thanks received
    331
    Rep Power
    925
    Quote Originally Posted by Advocatus Diaboli View Post
    This looks inefficient as hell.
    Why do you say that? This is the very first version of it so I'm sure there are inefficiencies, let me know and I'll rewrite those parts ;D

    Quote Originally Posted by GoLang View Post
    Are you seriously not loading all dialogues on startup. Whats the point of loading dialogues when the person talks to npc. Good luck dealing with game freezes when someone talks to a npc.
    Well then that's a quick fix isn't it? Hahaha


    `Ex-global moderator x3 (resigned)
     

  13. #9  
    Renown Programmer


    Join Date
    Dec 2006
    Posts
    1,715
    Thanks given
    268
    Thanks received
    217
    Rep Power
    1836
    you should use a script interpreter to evaluate code within brackets and give it the player as context

    better yet, create something like this:

    Code:
      dialogue = create_dialogue {
        add_entry :first_dialogue do
          type PlayerInteraction
          animation Sad
          title "Sad dialogue"
          message << "I am sad :("
          action AdvanceDialogueAction.new(player, :second_dialogue)
        end
        add_entry :second_dialogue do
          type PlayerInteraction
          animation Angry
          title "I like 2 hack"
          message << "GRRR I AM ANGRY"
          action AdvanceDialogueAction.new(player, :third_dialogue)
        end
        add_entry :third_dialogue do
          type NpcInteraction
          model 3
          animation Happy
          title "I like 2 hack"
          message << "Hello, Shiver, this is a simple"
          message << "dialogue! However, this one tests..."
          message << "Lots of lines!"
          message << "Lots of lines!"
          action CloseDialogueAction.new(player)
        end
      }
     


  14. #10  
    DialogueScript by Runite :: FINALLY, the easiest &amp; quickest way to create dialogue.



    Scu11's Avatar
    Join Date
    Aug 2007
    Age
    30
    Posts
    16,307
    Thanks given
    7,215
    Thanks received
    12,308
    Rep Power
    5000
    not at all keen on this whole ! ? < > stuff at all

    Attached image
     

Page 1 of 2 12 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. What's the best way to handle dialogue?
    By Paketa in forum Help
    Replies: 3
    Last Post: 04-11-2009, 02:37 AM
  2. learn java in the easiest way!
    By VanZile in forum Tutorials
    Replies: 2
    Last Post: 08-03-2008, 12:13 AM
  3. changing floor colours ( the easiest way)
    By Cup-o-cino in forum Tutorials
    Replies: 10
    Last Post: 03-21-2008, 02:40 AM
  4. Finally the 4D pic of my son!!
    By Systəx in forum Chat
    Replies: 20
    Last Post: 02-14-2008, 06:03 PM
  5. The New Super Easy Way to Make Java Work!
    By mysticdie in forum Tutorials
    Replies: 4
    Last Post: 12-15-2007, 04:39 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •