diff options
Diffstat (limited to 'scripts/toy/play.groovy')
| -rw-r--r-- | scripts/toy/play.groovy | 322 | 
1 files changed, 322 insertions, 0 deletions
diff --git a/scripts/toy/play.groovy b/scripts/toy/play.groovy new file mode 100644 index 0000000..a383bef --- /dev/null +++ b/scripts/toy/play.groovy @@ -0,0 +1,322 @@ +{ toy -> +	final PLAY = "play"; +	final REDRESS = "redress"; +	final RELEASEFROM = "releaseFrom"; + +	toy.metaClass.stateToyName { state -> +		switch (state) { +			case CUFFED: +				return "cuffs"; +			case COLLARED: +				return "collar"; +			case CLAMPED: +				return "nipple clamps"; +			case GAGGED: +				return "gag"; +		} +		return null; +	}; + +	toy.metaClass.removeToy { state, imageSpec -> +		if (!stateIs(state)) return; +		def toyName = stateToyName(state); +		present(imageSpec, [ +				["OK,"], +				["you may remove your $toyName.", "the $toyName can come off.", "take the $toyName off."]]); +		showButtonG("Thank you, ${dommeTitle()}", "ok"); +		pause(5); +		set(state, false); +		removeEvent("$RELEASEFROM-$state"); +		showButtonGT("Removed, ${dommeTitle()}", "removed", 20, 1); +	}; + +	toy.metaClass.sessionPlay { +		if (stateIs(CHASTE)) sessionToys[CHASTITY] = getTime(); +		def playScope = [ +			'randRange': { min, max -> randRange(min, max) }, +			'currentPunishment': { getPunish() }, +			'sessionAborted': { return sessionAborted }, +			'can': { return can(it) }, +			'has': { return has(it) }, +			'is': { return stateIs(it) }, +			'likes': { return likes(it) }, +			'punishMultiple': (float)1.0, +			'prop': load('toy') ?: [:] +		]; +		def apply = { activitity, use = null -> +			if (!activitity) return; +			def val = activitity(); +			playBackgroundSound(null); +			if (use && val instanceof Number) { +				use(val); +			} +		}; +		def interval = { activities -> +			if (activities) { +				apply(activities[getRandom(activities.size())], null); +			} +		}; +		def funcMap = [ +			'use': [ +				'punishMultiply': { val -> +					if (val) { +						playScope.punishMultiple *= val; +					} +				}, +				'punishApply': { val -> +					if (val) { +						adjustPunish(-val * playScope.punishMultiple); +					} +				} +			], +			'select': [ +				'repeat': { amount, activities, intervals, use = null -> +					amount.times { +						if (!sessionAborted) { +							apply(activities[getRandom(activities.size())], use); +							interval(intervals); +						} +					}; +				}, +				'take': { amount, activities, intervals, use = null -> +					Collections.shuffle(activities); +					activities.take(amount).each { +						if (!sessionAborted) { +							apply(it, use); +							interval(intervals); +						} +					}; +				} +			], +			'activities': activityList +		]; +		final eval = { expr -> Eval.me('toy', playScope, expr.toString()) }; +		if (stateIs("DEBUG")) { +			// Check everything in DOMME evaluates and resolves +			final checkIsFunc = { group, name -> +				if (!name) return; +				show("checking $group:$name is a function"); +				if (!(funcMap[group][name] instanceof Closure)) { +					showPopup("$group:$name is not a function"); +				} +			} +			final checkEval = { expr -> +				show("checking $expr evaluates"); +				eval(expr); +			}; +			DOMME.sessions.forEach { session -> +				checkEval(session.require ?: true); +				checkEval(session.probability); +				session.phases.forEach { phase -> +					checkEval(phase.require ?: true); +					checkIsFunc("select", phase.select); +					checkEval(phase.number ?: 1); +					phase.activities.forEach { a -> +						checkIsFunc("activities", a); +					} +					(phase.intervals ?: []).forEach { i -> +						checkIsFunc("activities", i); +					} +					checkIsFunc("use", phase.use); +				}; +			}; +		} +		final sessions = DOMME.sessions.findAll { s -> eval(s.require ?: true) }; +		final probabilities = sessions.withIndex().collect { s, idx -> [idx] * s.probability }.sum(); +		final sessionIdx = probabilities[getRandom(probabilities.size)]; +		sessions[sessionIdx].phases.forEach { phase -> +			if (eval(phase.require ?: true)) { +				funcMap.select[phase.select ?: 'take'](eval(phase.number ?: 1), +						(phase.activities ?: []).collect { f -> funcMap.activities[f] }, +						(phase.intervals ?: []).collect { f -> funcMap.activities[f] }, +						funcMap.use[phase.use]); +			} +		}; +	}; + +	toy.metaClass.sessionRelease { goodToy -> +		if (goodToy) { +			present([DRESSED], [ +					["Ahhh,", "OK,"], +					["I'm done with you for now.", "That was fun... for me at least."]]); +		} +		else { +			present([DRESSED], [ +					["I don't ask much of you, toy."]]); +			pause(getRandom(10) + 5); +			postChastity(); +		} +		pause(getRandom(10) + 5); +		def toys = TOYTOYS.findAll { t -> stateIs(t) }; +		Collections.shuffle(toys); +		if (toys) { +			if (!goodToy) { +				present([DRESSED], [ +						["I should leave you like that.", "I suppose you still want letting free?"], +						["Maybe.", "Let me ponder on it."]]); +				pause(getRandom(20) + 20); +			} +			toys.each { toyState -> +				if (getRandom(100) > ((goodToy && (getPunish() < 100)) ? 10 : 80)) { +					removeToy(toyState, [DRESSED]); +				} +				else { +					addEvent("$RELEASEFROM-$toyState", getTime() + 100 + getRandom(10 * (getPunish() + 1)), +							RELEASEFROM, toyState); +					adjustPunish(-5); +				} +			}; +		} +		if (stateIs(NAKED)) { +			if (goodToy && getRandom(1)) { +				present([DRESSED], [ +						["Put some clothes back on.", "Cover yourself up!"]]); +				pause(getRandom(10) + 15); +				set(NAKED, false); +			} +			else { +				present([DRESSED], [ +						["No clothes now for a while,", "Keep those clothes off,"], +						["you don't get clothes until I say.", "I like seeing you naked."]]); +				addEvent(REDRESS, getTime() + 600 + getRandom(1200), "redress"); +				showButtonG("Yes, ${dommeTitle()}", "ok"); +			} +		} +		if (goodToy) { +			present([DRESSED], [ +					["Off you go.", "You may leave."]]); +		} +		else { +			present([DRESSED], [ +					["Get out of my sight.", "Go!"]]); +			removeEvent(CUM); +			revokePermission(CUM); +		} +		pause(10); +		save("toy.lastPlay", getTime()); +		showLounge(); +		sessionAborted = null; +		sessionToys = [:]; +		if (goodToy) { +			adjustPunish(-20); +		} +		else { +			setProp(DISAPPOINT, getProp(DISAPPOINT, loadI, 0) + 1); +		} +		show(null); +	}; + +	toy.metaClass.playWait { +		present([DRESSED,nTEASE], [ +				["Hello,", "Hi,", "Hey there,"], +				["toy.", "slut.", "slave."], +				["On your knees,", "On the floor,", "Down... at my feet,",], +				["wait there.", "wait patiently.", "don't move."], +				["I'll be with you shortly.", "I won't be a moment."]]); +		showButtonGT("Yes, ${dommeTitle()}", "ok", 10, 1); +		showLounge(); +		show(null); +		pause(20 + getRandom(20)); +	}; + +	toy.metaClass.playSchedule { +		if (getAway()) return; +		final lastPlay = loadInteger("toy.lastPlay") ?: 0; +		if (lastPlay < getTime() - (4 * HOUR)) { +			addEventIfMissing(PLAY, getTime() + 120 + getRandom(480), PLAY, true); // 2-10mins +		} +		else { +			addEventIfMissing(PLAY, getTime() + 1200 + getRandom(5400), PLAY, false); // 20-90mins +		} +	}; + +	toy.metaClass.playEvent { rt = true, first = true -> +		if (!rt || getAway()) { +			playSchedule(); +			return; +		} +		dress([[DRESSED,nTEASE],[DRESSED,TEASE],[TITS],[STOOD]]); +		if (sessionSummon([DRESSED,nTEASE])) { +			if (first.asBoolean()) { +				playWait(); +			} +			sessionPlay(); +			sessionRelease(sessionAborted == null); +		} +		else { +			adjustPunish(25); +		} +		playSchedule(); +		showLounge(); +	} + +	toy.metaClass.redress { rt -> +		if (!rt || !sessionSummon([DRESSED])) { +			addEvent(REDRESS, getTime() + 300, "redress"); +			return; +		} +		present([DRESSED], [ +				["OK, toy,"], +				["you can put some clothes back on now.", "get yourself covered up."]]); +		pause(getRandom(10) + 15); +		showButtonG("Thank you, ${dommeTitle()}", "ok"); +		set(NAKED, false); +		showLounge(); +	}; + +	toy.metaClass.releaseFrom { rt, arg, name -> +		if (!rt || !sessionSummon([DRESSED])) { +			addEvent(name, getTime() + 300, RELEASEFROM, arg); +			return; +		} +		removeToy(arg, [DRESSED]); +		showLounge(); +	}; + +	toy.metaClass.requestClothes { +		adjustPunish(5); +		present([DRESSED], [ +				["Really?", "Disappointing."], +				["You want to clothes back on?", "You wish to cover up?"]]); +		if (getBoolean(null)) { +			present([DRESSED], [["Hmm, very well.", "If you must."]]); +			adjustPunish(50); +			set(NAKED, false); +			removeEvent(REDRESS); +		} +		else { +			present([DRESSED], [["Good boy."]]); +		} +		showButtonG("Thank you, ${dommeTitle()}", "ok"); +		showLounge(); +	}; + +	toy.metaClass.requestRelease { toyState -> +		adjustPunish(5); +		present([DRESSED], [ +				["Really?", "Disappointing."], +				["You wish to be un-$toyState?"]]); +		if (getBoolean(null)) { +			adjustPunish(10); +			if (getRandom(100) > getPunish()) { +				present([DRESSED], [["No.", "You may not."], +						["Not yet.", "Not until later."]]); +			} +			else { +				present([DRESSED], [["Hmm, very well.", "If you must."]]); +				set(toyState, false); +				removeEvent("$RELEASEFROM-$toyState"); +			} +		} +		else { +			present([DRESSED], [["Good boy."]]); +		} +		showButtonG("Thank you, ${dommeTitle()}", "ok"); +		showLounge(); +	}; + +	toy.addNamedEvent(PLAY, { name, arg, schedTime, rt -> toy.playEvent(rt, arg) }); +	toy.addNamedEvent(RELEASEFROM, { name, arg, schedTime, rt -> toy.releaseFrom(rt, arg, name) }); +	toy.addNamedEvent(REDRESS, { name, arg, schedTime, rt -> toy.redress(rt) }); +	toy.playSchedule(); +}  | 
