From a03b4e1b7b78be2aab0381a78ddc74ab0ff405d7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Jun 2019 19:51:51 +0100 Subject: Extract humiliation into a module --- scripts/toy.groovy | 166 +--------------------------------------- scripts/toy/humiliation.groovy | 168 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 165 deletions(-) create mode 100644 scripts/toy/humiliation.groovy diff --git a/scripts/toy.groovy b/scripts/toy.groovy index cea79c0..3bf51a3 100644 --- a/scripts/toy.groovy +++ b/scripts/toy.groovy @@ -255,27 +255,7 @@ return new Object() { } return tt; }; - // Pre-tease - def preStrip = { imageSpec = [DRESSED] -> - if (stateIs(NAKED)) return 1.1; - present(imageSpec, [ - ["Clothes off!", "Get naked, slut!"]]); - wait(10); - present(imageSpec, [ - ["All of them off!", "And the rest!", "Keep going."]]); - set(NAKED, true); - showButtonGT("Naked, ${dommeTitle()}", "naked", 60, 5); - present(null, [ - ["Very good. Now...", "I see..."], - ["on your knees before me,", "kneel,", "stand up straight,", "on your feet,"], - ["hands behind your head,", "arms up,", "hands high up,"], - ["let me see you properly.", "let's see what we have.", "I want a good view."]]); - wait(10); - sessionToys[COCK] = getTime(); - return 1.1; - }; - // Post // Play def playNothing = { (getRandom(3) + 2).times { @@ -303,148 +283,6 @@ return new Object() { sessionToys[SPOON] = getTime(); } }; - def playKneel = { - present([DRESSED], [ - ["Right, slut.", "Come here, toy."], - ["On the floor, right there.", "Kneel at my feet."]]); - showButtonGT("Yes, ${dommeTitle()}.", "ok", 20, 1); - present([DRESSED], [ - ["When I say go,", "In a moment,"], - ["you'll crawl", "turn and crawl"], - ["away until I ring my bell."], - ["You'll stay there,", "And then you won't move,"], - ["head bowed", "face down"], - ["until I call you back.", "until you're summoned."]]); - showButtonG("Yes, ${dommeTitle()}.", "ok"); - present(null, [["Wait..."]]); - wait(getRandom(10) + 10); - present([DRESSED], [["Ok, go!", "Now! Off you go."]]); - wait(getRandom(5) + 5); - playBackgroundSound("bell.wav"); - show(null); - def kneelTime = 60 + getRandom(240); - wait(kneelTime); - while (playBackgroundSound("bell.wav") || true) { - if (showButtonG("Back, ${dommeTitle()}", "back", 20) != 20) break; - } - present([DRESSED], [ - ["Good boy.", "Very good."], - ["Stay down there.", "Don't move."]]); - wait(getRandom(5) + 5); - return kneelTime / 20.0; - }; - def playSuck = { - def playWait = { file, time -> - playBackgroundSound(file); - wait(time); - playBackgroundSound(null); - }; - def suck = { file, n, delay -> - n.times { - playWait(file, delay); - }; - }; - def suckBeat = { beat, n -> - suck("toy/${beat}bpm.mp3", n, 2 * (60 / beat)); - }; - def completed = loadInteger("toy.deepthroat.completed") ?: 0; - if (completed >= 4) { - preStrip(); - preCollar(); - preClamps(); - getCuffs(); - } - if (sessionToys.containsKey(DILDO)) { - present([DRESSED], [ - ["Back to your dildo.", "Amuse me some more with that dildo."], - ["Same as before, listen for my bell, slut."]]); - showButtonG("Yes, ${dommeTitle()}", "ok"); - } - else { - present([DRESSED], [ - ["Time for you to amuse me, you little slut."], - ["Get your dildo and secure it somewhere nearby, about eye level when kneeling."]]); - wait(10); - showButtonGT("Done, ${dommeTitle()}", "done", 60, 1); - sessionToys[DILDO] = getTime(); - present([DRESSED], [ - ["The rules are simple:\n"], - ["On my first bell, you take the head in your mouth and start to pleasure it.\n"], - ["When you hear the beat, you suck the shaft, one beat in, one beat out again.\n"], - ["Lastly, on the crack of my whip, you take the whole thing in and suck from the base.\n"], - ["I know you'll enjoy it, don't be shy.\n"], - ["One more thing..."], - ["That cock doesn't doesn't leave your mouth until I say so, listen for second bell and then return to me."]]); - showButtonGT("Understood, ${dommeTitle()}", "understood", 30, 1); - } - if (sessionToys[HANDCUFFS]) { - present([DRESSED, nTEASE], [ - ["Cuff yourself,", "Hands cuffed,"], - ["behind your back of course.", "behind you."]]); - wait(20); - set(CUFFED, true); - } - present([TEASE], [ - ["Get ready"]]); - showButtonGT("Ready, ${dommeTitle()}", "ready", 10, 1); - show(null); - - final target = loadInteger("toy.deepthroat.goal") ?: 5; - def session = 0; - - wait(randRange(10, 20)); - playWait("bell.wav", randRange(10, 40)); // Head - while (session < target) { - suckBeat(30, randRange(5, 15)); // Slow - suckBeat(90, randRange(10, 30)); // Quick - wait(0.5); - final deep = randRange(target / 4, target / 2); - suck("shortwhip.wav", deep, 2.5); // Deep - session += deep; - } - suckBeat(30, randRange(5, 15)); // Slow - wait(randRange(10, 20)); // Head - playBackgroundSound("bell.wav"); // End - - showButtonGT("Back, ${dommeTitle()}", "back", 15, 1); - if (stateIs(CUFFED)) { - present([DRESSED, TEASE], [ - ["Let yourself out.", "Unlock the cuffs."]]); - wait(10); - showButtonGT("Freed, ${dommeTitle()}", "freed", 120, 1); - set(CUFFED, false); - } - if (getBoolean("Did you perform as ordered?", "Yes, ${dommeTitle()}", "No, ${dommeTitle()}")) { - present([DRESSED], [ - ["Good boy"]]); - adjustPunish(-4 * target); - completed += 1; - if (completed >= 5) { - save("toy.deepthroat.goal", target + 1); - completed = 0; - } - } - else { - final missed = getInteger("How many deep sucks did you miss?", 1); - if (missed > 5) { - present([DRESSED], [ - ["Very disappointing."]]); - } - else { - present([DRESSED], [ - ["Mmm"], - ["More practice required."]]); - } - adjustPunish(10 * missed); - completed -= 1; - if (completed <= -5) { - save("toy.deepthroat.goal", target - 1); - completed = 0; - } - } - save("toy.deepthroat.completed", completed); - wait(10); - }; def stateToyName = { state -> switch (state) { case CUFFED: @@ -505,10 +343,7 @@ return new Object() { return false; }; final activityList = [ - 'preStrip': preStrip, - 'playKneel': playKneel, 'playNothing': playNothing, - 'playSuck': playSuck, ]; final addActivity = { String name, func -> activityList[name] = func; @@ -953,6 +788,7 @@ return new Object() { * scripts/toy/cbt.groovy * scripts/toy/chastity.groovy * scripts/toy/confession.groovy + * scripts/toy/humiliation.groovy * scripts/toy/imagery.groovy * scripts/toy/intro.groovy * scripts/toy/orgasmControl.groovy diff --git a/scripts/toy/humiliation.groovy b/scripts/toy/humiliation.groovy new file mode 100644 index 0000000..8050145 --- /dev/null +++ b/scripts/toy/humiliation.groovy @@ -0,0 +1,168 @@ +{ toy -> + toy.metaClass.preStrip { imageSpec = [DRESSED] -> + if (stateIs(NAKED)) return 1.1; + present(imageSpec, [ + ["Clothes off!", "Get naked, slut!"]]); + pause(10); + present(imageSpec, [ + ["All of them off!", "And the rest!", "Keep going."]]); + set(NAKED, true); + showButtonGT("Naked, ${dommeTitle()}", "naked", 60, 5); + present(null, [ + ["Very good. Now...", "I see..."], + ["on your knees before me,", "kneel,", "stand up straight,", "on your feet,"], + ["hands behind your head,", "arms up,", "hands high up,"], + ["let me see you properly.", "let's see what we have.", "I want a good view."]]); + pause(10); + sessionToys[COCK] = getTime(); + return 1.1; + }; + + toy.metaClass.playKneel { + present([DRESSED], [ + ["Right, slut.", "Come here, toy."], + ["On the floor, right there.", "Kneel at my feet."]]); + showButtonGT("Yes, ${dommeTitle()}.", "ok", 20, 1); + present([DRESSED], [ + ["When I say go,", "In a moment,"], + ["you'll crawl", "turn and crawl"], + ["away until I ring my bell."], + ["You'll stay there,", "And then you won't move,"], + ["head bowed", "face down"], + ["until I call you back.", "until you're summoned."]]); + showButtonG("Yes, ${dommeTitle()}.", "ok"); + present(null, [["Wait..."]]); + pause(getRandom(10) + 10); + present([DRESSED], [["Ok, go!", "Now! Off you go."]]); + pause(getRandom(5) + 5); + playBackgroundSound("bell.wav"); + show(null); + def kneelTime = 60 + getRandom(240); + pause(kneelTime); + while (playBackgroundSound("bell.wav") || true) { + if (showButtonG("Back, ${dommeTitle()}", "back", 20) != 20) break; + } + present([DRESSED], [ + ["Good boy.", "Very good."], + ["Stay down there.", "Don't move."]]); + pause(getRandom(5) + 5); + return kneelTime / 20.0; + }; + + toy.metaClass.playSuck { + def playWait = { file, time -> + playBackgroundSound(file); + pause(time); + playBackgroundSound(null); + }; + def suck = { file, n, delay -> + n.times { + playWait(file, delay); + }; + }; + def suckBeat = { beat, n -> + suck("toy/${beat}bpm.mp3", n, 2 * (60 / beat)); + }; + def completed = loadInteger("toy.deepthroat.completed") ?: 0; + if (completed >= 4) { + preStrip(); + preCollar(); + preClamps(); + getCuffs(); + } + if (sessionToys.containsKey(DILDO)) { + present([DRESSED], [ + ["Back to your dildo.", "Amuse me some more with that dildo."], + ["Same as before, listen for my bell, slut."]]); + showButtonG("Yes, ${dommeTitle()}", "ok"); + } + else { + present([DRESSED], [ + ["Time for you to amuse me, you little slut."], + ["Get your dildo and secure it somewhere nearby, about eye level when kneeling."]]); + pause(10); + showButtonGT("Done, ${dommeTitle()}", "done", 60, 1); + sessionToys[DILDO] = getTime(); + present([DRESSED], [ + ["The rules are simple:\n"], + ["On my first bell, you take the head in your mouth and start to pleasure it.\n"], + ["When you hear the beat, you suck the shaft, one beat in, one beat out again.\n"], + ["Lastly, on the crack of my whip, you take the whole thing in and suck from the base.\n"], + ["I know you'll enjoy it, don't be shy.\n"], + ["One more thing..."], + ["That cock doesn't doesn't leave your mouth until I say so, listen for second bell and then return to me."]]); + showButtonGT("Understood, ${dommeTitle()}", "understood", 30, 1); + } + if (sessionToys[HANDCUFFS]) { + present([DRESSED, nTEASE], [ + ["Cuff yourself,", "Hands cuffed,"], + ["behind your back of course.", "behind you."]]); + pause(20); + set(CUFFED, true); + } + present([TEASE], [ + ["Get ready"]]); + showButtonGT("Ready, ${dommeTitle()}", "ready", 10, 1); + show(null); + + final target = loadInteger("toy.deepthroat.goal") ?: 5; + def session = 0; + + pause(randRange(10, 20)); + playWait("bell.wav", randRange(10, 40)); // Head + while (session < target) { + suckBeat(30, randRange(5, 15)); // Slow + suckBeat(90, randRange(10, 30)); // Quick + pause(0.5); + final deep = randRange(target / 4, target / 2); + suck("shortwhip.wav", deep, 2.5); // Deep + session += deep; + } + suckBeat(30, randRange(5, 15)); // Slow + pause(randRange(10, 20)); // Head + playBackgroundSound("bell.wav"); // End + + showButtonGT("Back, ${dommeTitle()}", "back", 15, 1); + if (stateIs(CUFFED)) { + present([DRESSED, TEASE], [ + ["Let yourself out.", "Unlock the cuffs."]]); + pause(10); + showButtonGT("Freed, ${dommeTitle()}", "freed", 120, 1); + set(CUFFED, false); + } + if (getBoolean("Did you perform as ordered?", "Yes, ${dommeTitle()}", "No, ${dommeTitle()}")) { + present([DRESSED], [ + ["Good boy"]]); + adjustPunish(-4 * target); + completed += 1; + if (completed >= 5) { + save("toy.deepthroat.goal", target + 1); + completed = 0; + } + } + else { + final missed = getInteger("How many deep sucks did you miss?", 1); + if (missed > 5) { + present([DRESSED], [ + ["Very disappointing."]]); + } + else { + present([DRESSED], [ + ["Mmm"], + ["More practice required."]]); + } + adjustPunish(10 * missed); + completed -= 1; + if (completed <= -5) { + save("toy.deepthroat.goal", target - 1); + completed = 0; + } + } + save("toy.deepthroat.completed", completed); + pause(10); + }; + + toy.addActivity("preStrip", { toy.preStrip() }); + toy.addActivity("playKneel", { toy.playKneel() }); + toy.addActivity("playSuck", { toy.playSuck() }); +} -- cgit v1.2.3