Skip to content

Coding FAQ

GodDragoner edited this page Feb 15, 2020 · 22 revisions

How do I run/execute another file?

Use the run method for this. Example:

run("Modules/Tease/first.js")

The path is always based on your main personality directory. Which means the absolute/resulting path for this would look something like this: D:/Programs/Java AI/Personalities/YourPersonalityFolderName/Modules/Tease/first.js

You can also use the native load method of java nashorn, however the path now refers to the main directory of the tease ai java installation which means the code would look something like this:

run("Personalities/YourPersonalityFolderName/Modules/Tease/first.js")

I do not recommend this method because whenever your personality folder name changes (for example if you change the version and append it to the name: "Example Personality 1.1") it will break.

Keep in mind when using "\" instead of "/" you'll have to go with "\\" because "\" escapes the next character in javascript. The path run("Personalities/YourPersonalityFolderName/Modules/Tease/first.js") would then look like this: run("Personalities\\YourPersonalityFolderName\\Modules\\Tease\\first.js")


How do I send a message to the sub and directly execute the following code?

By default the program adds a delay after each message before continuing that is based on the length of the message so the sub has the time to read it. If you want to skip this delay just use:

sendMessage("Your message", 0);

This will send the message and sets the delay to 0 seconds, which means it will automatically continue with the following code. This can be used to executed directly afterwards/kinda "simultaneously" or send rapid messages.


How can I print the sub name or dom name?

Look up the vocabularies that are provided by the system here in the "Vocabularies provided by the system" section.


How can I make other doms join the chat?

To let other doms use the chat you can just use the setSender function. Look it up here.


How would I wait for the sub to be on the edge?

Code example:

//Start by sending the message and IMMEDIATELY executing the code afterwards (thats why the 0 is there)
sendMessage("Edge!", 0);
startStroking(250);
startEdge();

//Now we will check whether the sub is on the egde every 100 milliseconds
while(!isOnEdge()) {
   java.lang.Thread.sleep(100);
}

//Okay sub is on edge, we can do our thing now
stopStroking();
sendMessage("Hold the edge!", 10);
endEdge();
sendMessage("Let go!");

So what does this exactly do? Well first of all it sends the message "Edge!" to the sub and waits for 0 seconds. The 0 is important here because by default the program adds a default delay after each message so the sub has the time to read it, however in this case we want to directly execute the next two statements. Afterwards it starts the metronome and registers the sub as edging. Then it checks whether the sub is on the edge every 100 MILLISECONDS. It does that by looping java.lang.Thread.sleep(100); while the sub is NOT on the edge. java.lang.Thread.sleep(x) waits/sleeps the current execution of the code for x milli seconds. In this case 100. If isOnEdge() returns true because the sub is on the edge it will exit this loop and will then continue with the following code.


How would I implement edging taunts?

Yes there is no native feature for this however it is quite easy to implement on your own. I think I can just give you a quick example so you understand how I would handle it:

//Call this function somewhere after loading/running this file first
function edge() {
   //Start stroking and send edging stuff
   sendMessage("Edge!", 0);
   startStroking(250);
   startEdge();
   //Start the edging taunts
   sendEdgeTaunts();
   //If this is executed the sub is on the edge and the taunt cycle was broken
   endEdge();
   //Yea do whatever you want to do now
   sendMessage("Okay, let's continue!");
}

function sendEdgeTaunts() {
   //Select a random amount of iterations and we will wait based on that random amount before sending a taunt message
   iterationsToGo = randomInteger(4, 12);
   
   //Just how long you want each iteration to take
   var millisecondsToWait = 500;
   //Start our loop and continue until iterationsToGo are equal or less than zero
   while(iterationsToGo > 0) {
      //Is the sub on the edge?
      if(isOnEdge()) {
         //Okay stop stroking and exit this loop and function
         stopStroking();
         sendMessage("You are on the edge!");
         return;
      }
      //Sub is not on edge, which means we subtract one from our iterations and wait for 500 milliseconds afterwards
      iterationsToGo--;
      java.lang.Thread.sleep(millisecondsToWait);
   }

   //You can chose a random fitting taunt message somehow here
   sendMessage("Come on!");
   //Start the whole thing all over again
   sendEdgeTaunts();
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive)
 * Using Math.round() will give you a non-uniform distribution!
 */
function randomInteger(min, max) {
    if(min >= max) {
        return max;
    }
    
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

How does this work? Well it starts the edging process. Afterwards it checks whether the sub is on the edge every 500 milli seconds. If the sub is on the edge it will send the message "You are on the edge!" to the chat and exit the taunt cycle and go back to the edge() method. Now after this loop was run x times (iterationsToGo = randomInteger(4, 12);) it will exit the loop and send a message such as "Come on!" to the sub. Afterwards it will start all over again. This allows you to create stroking or edging taunts.


How would I send a "system" message or a custom message?

This is going more into the depth and thus it might require you to know more about java etc.. However here is a short example:

textVar = new javafx.scene.text.Text("Test");
textVar.setFill(javafx.scene.paint.Color.MEDIUMVIOLETRED);
textVar.setFont(javafx.scene.text.Font.font(null, javafx.scene.text.FontWeight.BOLD, 13));

sendCustomMessage(textVar);

This displays a purple bold message with the font size set to 13 that reads "Test" in the chat window. If you want more information on all the possibilities check this out. Regarding the "javafx.scene.text." stuff: This is something like a folder path for java class files called packages. Because we are accessing java stuff from javascript we'll need to hand the program the exact package location that the program needs to look for.

This function actually accepts a text enumeration and will add them all together to form one line. Which means:

textVar = new javafx.scene.text.Text("Test: ");
textVar.setFill(javafx.scene.paint.Color.MEDIUMVIOLETRED);
textVar.setFont(javafx.scene.text.Font.font(null, javafx.scene.text.FontWeight.BOLD, 13));

textVar2 = new javafx.scene.text.Text("Hello");
textVar2.setFill(javafx.scene.paint.Color.AQUA);
textVar2.setFont(javafx.scene.text.Font.font(null, javafx.scene.text.FontWeight.BOLD, 13));

sendCustomMessage(textVar, textVar2);

will display "Test: Hello" in the chat. "Test: " being purple and "Hello" being aqua. Of course you can always message me if you want to do something like this and are kinda stuck.


I want to know when to end the session based on the subs preference

This is fairly simply:

//Get the preferred session length in minutes
preferredSessionLength = getVar("prefSessionLength");
//Send the messages just to show of what the variable values are
sendMessage("Your preference is " + preferredSessionLength*60 + " seconds.");
sendMessage("Seconds passed since start: " + (getMillisPassed()/(1000));

//Turn the minutes into seconds and the milliseconds into seconds
if(preferredSessionLength*60 < (getMillisPassed()/1000)) {
   //I guess we reached the time limit
   sendMessage("Should we end the session?");
}

//Get the amount of milliseconds that passed since the start of the session
function getMillisPassed() {
   var startedAt = getVariable("startDate").getTimeInMillis();
   var n = new Date().getTime();
   return n - startedAt;
}

Mind that this is just something that you can use to determine the session length. You can also use any custom solution of course based on custom dates and a custom duration.


How do I end the session in the middle of the code?

endSession() is the function to go with. Example:

sendMessage("Hello %subName%");
endSession();

How to show pictures from a custom tumblr url/pool?

createMediaURL() is the function to go with. You'll need a file that follows the layout of the files inside your TeaseAI-Java/Images/System/URL Files folder. Best way to go is register your url in the gui, wait for it to finish and then copy its file to a location inside your personality. Why would you want this? Well if you for example don't want the user to download a folder full of sepcific pictures you can just find a tumblr blog that has these pictures, register it in your settings ui, copy the file to your personality and then just load it in your personality's code and show pictures from that blog like it was a pre-set categorized url or tease url. You can even point to a selection of files and let the computer choose one at random. So you could allow your users to copy all url files that they want to add to a specific folder for example Personalities/Your Personality/URL Files/Trees and then you could select a random file from that folder everytime you want to show a picture. This would also allow your users to customize the pictures shown for a "custom" case/category. This method would also be they way to go if you wish to add custom categories to the system. You'd provide an url or urls and the user could extent this collection.

Example:

//Select a random file inside the Trees folder
const someTreeURL = createMediaURL("Personalities/Your Personality/URL Files/Trees/*.txt");
showImage(someTreeURL, 10);

//Or a specific file
const specificURL = createMediaURL("Personalities/Your Personality/URL Files/damn-she-is-hot.tumblr.com.txt");
showImage(specificURL, 10);

How to show a previous picture again afterwards?

Example:

//Load a custom url media file
const sexyGirlURL = createMediaURL("URLs/sexygirlsandporn.tumblr.com.txt");
lockImages();
//Show a random image from that file
showImage(sexyGirlURL);
//Store the url of the image currently shown
const url = getCurrentImageURL();
//Print the url 
sendMessage("Current url being shown is: " + url);
//Wait 5 seconds
sleep(5);
//Show another random image for 5 seconds
showImage(sexyGirlURL, 5);
//Show the previous image using the url for 5 seconds again
showImage(url, 5);
unlockImages();

Different approach using files instead of urls:

lockImages();
//Show a random image from the boobs category
const image = showCategoryImage("BOOBS");
sendMessage("Current path to image: " + image.getPath());
//....
//Show the stored image for 5 seconds again
showImage(image, 5);

How do I jump into a video or end the video early?

Basically you can call the playVideo function with a boolean as a second parameter after the location of your file. By default the code will continue. If you want to wait you need to set the boolean to true so that it will only return to your code once the player stopped playing. However what if you want to jump into the video or want it to end after a certain time? Well you'll need to handle this inside you code like this:

End player after certain time:

const player = playVideo("https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_10mb.mp4");
//We need to wait for the player to ready up and start playing before continuing
while(!player.getStatus().equals(javafx.scene.media.MediaPlayer.Status.PLAYING)) {
    wait(100, 'MILLISECONDS');
}

let startDate = setDate().getTimeInMillis();
//Max duration in second for the video to play
let maxSecondsToWatch = 9999;

while(player.getStatus().equals(javafx.scene.media.MediaPlayer.Status.PLAYING) && (setDate().getTimeInMillis() - startDate) < maxSecondsToWatch*1000) {
    //We are waiting for it to finish in intervals fo 1/10 of a second
    wait(100, 'MILLISECONDS');
}

player.stop();
sendMessage('Finished playing');

If you want to jump into the video

const player = playVideo("https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_10mb.mp4");
//We need to wait for the player to ready up and start playing before continuing
while(!player.getStatus().equals(javafx.scene.media.MediaPlayer.Status.PLAYING)) {
    wait(100, 'MILLISECONDS');
}

//percantage of the video we want to jump to
let percentageToJumpTo = 50;
let jumpSeconds = player.getStopTime().multiply(percentageToJumpTo/100).toSeconds();
sendMessage('Jumping to ' + jumpSeconds);
player.seek(new javafx.util.Duration(1000*jumpSeconds));
//The code will now continue so if you want to wait here you will have to use the code I provided below which does both

Both

const player = playVideo("https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_10mb.mp4");
while(!player.getStatus().equals(javafx.scene.media.MediaPlayer.Status.PLAYING)) {
    wait(100, 'MILLISECONDS');
    sendMessage('waiting to startup');
}

//percantage of the video we want to jump to
let percentageToJumpTo = 50;
let jumpSeconds = player.getStopTime().multiply(percentageToJumpTo/100).toSeconds();
sendMessage('Jumping to ' + jumpSeconds);
player.seek(new javafx.util.Duration(1000*jumpSeconds));

let startDate = setDate().getTimeInMillis();
//Max duration in second for the video to play
let maxSecondsToWatch = 9999;

while(player.getStatus().equals(javafx.scene.media.MediaPlayer.Status.PLAYING) && (setDate().getTimeInMillis() - startDate) < maxSecondsToWatch*1000) {
    //We are waiting for it to finish in intervals fo 1/10 of a second
    wait(100, 'MILLISECONDS');
}

player.stop();
sendMessage('Finished playing');