-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCYOA.js
736 lines (613 loc) · 26.7 KB
/
CYOA.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
// @ts-check
function ElliesStory() {
let S = new Story("Ellies");
class Flags {
IsTookCuffs = false;
IsTookGag = false;
IsDoorOpen = false;
IsEntryRead = false;
/**@type {number} */
CorrectButton = Math.round(Math.random() * 23);
/**@type {number} */
AtButton = null;
}
/**@type {Flags} */
let flags;
/**@type {Engine} */
let E = null;
/**Current Player */
let C = null;
S.OnStart = () => {
E = S.Engine;
C = E.Players[0];
S.Flags = flags = new Flags();
};
S.OnReset = () => {
S.Flags = flags = new Flags();
var UpdatedRoom = {
Name: ChatRoomData.Name,
Description: ChatRoomData.Description,
Background: "AbandonedBuilding",
Limit: (ChatRoomCharacter.length + 1).toString(),
Admin: ChatRoomData.Admin,
Ban: ChatRoomData.Ban,
Private: false,
Locked: false
}
ServerSend("ChatRoomAdmin", { MemberNumber: Player.ID, Room: UpdatedRoom, Action: "Update" });
ChatAdminMessage = "UpdatingRoom";
};
S.OnCharEnter = char => {
E.ChatEmote("As you enter, the door slams shut behind you with the light, mechanical click of a closing lock. Before you is the wide interior of what appears to be an abbandoned warehouse");
// Remove all players
E.Players.splice(0);
// Add the entering player
E.Players.push(char);
C = char;
E.GotoLevel("Entrance", false);
setTimeout(FollowUp, 3000);
setTimeout(Explanation, 7000);
setTimeout(Explanation2, 15000);
E.ChangeRoomSettings(
{
Background: "AbandonedBuilding",
Limit: (ChatRoomCharacter.length + 1).toString(),
Locked: true,
Private: false
});
};
S.OnCharExit = char => {
if (ArrayRemove(E.Players, char)) {
// Remove player if leaves and reset
E.Reset()
}
};
//Entrance
{
let r = new Level("Entrance");
//Triggers
let goDown = new Trigger("down");
goDown.Action = () => E.GotoLevel("Basement");
r.Triggers.push(goDown);
let checkLocker = new Trigger("locker");
checkLocker.Action = () => E.GotoLevel("Locker");
r.Triggers.push(checkLocker);
{
let t = new Trigger("window");
t.Action = function () {
E.ChatEmote("You find a window, and it slides open at first try. Apparently someone was a bit careless with the security");
};
r.Triggers.push(t);
}
r.Entry = "The dim lights of closed and covered windows lights the room as you return your attention to the main hall. " +
"You can check the " + checkLocker.Print() + " again or go (down) to the basement";
S.Levels.push(r);
}
//Locker
{
let r = new Level("Locker");
//Triggers
let tryCuffs = new Trigger("cuff");
tryCuffs.Action = function () {
if (C.ItemPermission > 2) {
E.ChatAction("You need to adjust your item permissions to perform this action")
} else if (C.BlockItems.map(function(e) { return e.Name; }).indexOf('LeatherCuffs') >= 0) {
E.ChatAction("Leather cuffs needs to be unblocked in your inventory to perform this action")
} else {
InventoryWear(C, "LeatherCuffs", "ItemArms", "Default", 40);
ChatRoomCharacterUpdate(C);
E.ChatEmote("The cuffs slide on nicely. There doesn't seem to be anything overly unusual about them");
setTimeout(lock, 8000);
flags.IsTookCuffs = true;
}
};
let tryGag = new Trigger("gag");
tryGag.Action = function () {
if (C.ItemPermission > 2) {
E.ChatAction("You need to adjust your item permissions to perform this action")
} else if (C.BlockItems.map(function(e) { return e.Name; }).indexOf('BallGag') >= 0) {
E.ChatAction("Normal ball gag needs to be unblocked in your inventory to perform this action")
} else {
InventoryWear(C, "BallGag", "ItemMouth", "Default", 45);
InventoryLock(C, InventoryGet(C, "ItemMouth"), "ExclusivePadlock", 2313);
ChatRoomCharacterUpdate(C)
E.ChatEmote("The gag fits snugly between your lips to keep them appart. And a light mechanical sound and a 'click' sounds as the straps pull a bit together and a mechanism on the buckle locks it tightly in place");
flags.IsTookGag = true;
}
};
let goBack = new Trigger("back");
goBack.Action = () => E.GotoLevel("Entrance");
r.Prepare = level => {
var d = "The locker contains";
level.Triggers = [];
var isContainsAny = false;
if (!flags.IsTookCuffs) {
d += " a set of leather cuffs";
if (flags.IsTookGag) d += " You could try them on. (cuffs)"
isContainsAny = true;
level.Triggers.push(tryCuffs);
}
if (!flags.IsTookGag) {
if (isContainsAny)
d += " and";
d += " a ball gag."
if (!flags.IsTookCuffs) { d += " You could try them on. (cuffs) or (gag)" }
else { d += " You could try it on. (gag)" }
isContainsAny = true;
level.Triggers.push(tryGag);
}
if (isContainsAny == false) {
d = "The locker is empty";
}
level.Triggers.push(goBack);
level.Entry = d + ". You could of course also go (back)";
};
S.Levels.push(r);
}
//Basement
{
let r = new Level("Basement");
//Triggers
let acceptFate = new Trigger("door");
acceptFate.Action = () => E.ChatEmote("The door is simply too solid, and any attempt at prying it open seems meaningless");
let lens = new Trigger("lens");
lens.Action = function () {
if (InventoryGet(C, "ItemArms") && InventoryGet(C, "ItemMouth")) {
if (InventoryGet(C, "ItemArms").Asset.Name == "LeatherCuffs") {
if (InventoryGet(C, "ItemArms").Property) {
if (CharacterIsNaked(C) && InventoryGet(C, "ItemArms").Property.Restrain == "Both" && InventoryGet(C, "ItemMouth").Asset.Name == "BallGag") {
var r = S.GetLevel("Basement");
flags.IsDoorOpen = true;
E.ChatEmote("The door opens");
r.Entry = "With the door open you can now either go (through) the door or go (back) upstairs";
E.GotoLevel("Basement");
}
else {
E.GotoLevel("Hook");
}
}
else {
InventoryGet(C, "ItemArms").Property = { Restrain: null };
E.GotoLevel("Hook");
}
}
else {
E.ChatEmote("The sensor moves a bit, but nothing seems to happen")
}
}
else {
E.ChatEmote("The sensor moves a bit, but nothing seems to happen")
}
for (var i = 0; i < ChatRoomCharacter.length; i++) {
var X = ChatRoomCharacter[i]
if (InventoryGet(X, "ItemVulva")) {
if (InventoryGet(X, "ItemVulva").Asset.Name == "VibratingDildo") {
if (!InventoryGet(X, "ItemVulva").Property) InventoryGet(X, "ItemVulva").Property = { Intensity: -1 }
if (InventoryGet(X, "ItemVulva").Property.Intensity < 1) {
InventoryGet(X, "ItemVulva").Property.Effect = ["Egged", "Vibrating"]
InventoryGet(X, "ItemVulva").Property.Intensity = InventoryGet(X, "ItemVulva").Property.Intensity + 1
ServerSend("ChatRoomChat", { Content: "Dildo" + ((1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(X, "ItemVulva").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: X.Name, MemberNumber: X.MemberNumber }] })
CharacterLoadEffect(X)
ChatRoomCharacterUpdate(X)
} else {
InventoryGet(X, "ItemVulva").Property.Effect = ["Egged", "Vibrating"]
InventoryGet(X, "ItemVulva").Property.Intensity = InventoryGet(X, "ItemVulva").Property.Intensity - 1
ServerSend("ChatRoomChat", { Content: "Dildo" + ((-1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(X, "ItemVulva").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: X.Name, MemberNumber: X.MemberNumber }] })
CharacterLoadEffect(X)
ChatRoomCharacterUpdate(X)
}
}
}
}
};
let goThroughDoor = new Trigger("through")
goThroughDoor.Action = function () {
E.GotoLevel("Room2");
if (C.BlockItems.map(function(e) { return e.Name; }).indexOf('VibratingDildo') >= 0) {
setTimeout(dildo, 2000);
}
E.ChangeRoomSettings({ Background: "VaultCorridor" });
}
let goBack = new Trigger("back");
goBack.Action = () => E.GotoLevel("Entrance");
r.Prepare = level => {
var d = "At the end of the basement stairs is a large metal door with the picture of a naked girl with her arms cuffed at her wrist and elbows behind her back, and a ballgag strapped tight between her lips. " +
"Next to the door is some kind of lens. You could try to get the " + acceptFate.Print() + " open, go " + goBack.Print() + " upstairs, or stand in front of the (lens)";
level.Triggers = [];
if (!flags.IsDoorOpen) {
level.Triggers.push(lens);
level.Triggers.push(acceptFate);
} else {
d = "With the door open you can now either go " + goThroughDoor.Print() + " the door, or go" + goBack.Print() + " upstairs";
level.Triggers.push(goThroughDoor);
}
level.Triggers.push(goBack);
level.Entry = d;
};
S.Levels.push(r);
}
//Hook
{
let r = new Level("Hook");
//Triggers
let hookCloth = new Trigger("cloth");
{
hookCloth.Action = function () {
E.ChatEmote("The hook seems like it almost was made for this, and it even moves a bit to swiftly tear up your clothes, then retracts back into the wall. Standing in front of the (lens) again might extend it once more");
CharacterNaked(C);
ChatRoomCharacterUpdate(C);
E.GotoLevel("Basement", false);
};
r.Triggers.push(hookCloth);
}
let struggle = new Trigger("gag");
{
struggle.Action = function () {
E.ChatEmote("The hook retracts back into the wall at any attempt at moving the gag close to it. Maybe standing in front of the (lens) again will extend it again?");
E.GotoLevel("Basement", false);
};
r.Triggers.push(struggle);
}
let hookCuff = new Trigger("cuff");
{
hookCuff.Action = function () {
DialogFocusItem = InventoryGet(C, "ItemArms");
if (DialogFocusItem.Property == null) DialogFocusItem.Property = { Restrain: null };
if (InventoryGet(C, "ItemArms").Property.Restrain != "Both") {
var NewPose = "Both"
DialogFocusItem.Property.Restrain = NewPose;
DialogFocusItem.Property.SetPose = [(NewPose == "Wrist") ? "BackBoxTie" : "BackElbowTouch"];
DialogFocusItem.Property.Effect = ["Block", "Prone"];
DialogFocusItem.Property.SelfUnlock = (NewPose == "Wrist");
if (NewPose == "Both") DialogFocusItem.Property.Difficulty = 45;
CharacterRefresh(C);
ChatRoomCharacterUpdate(C)
E.ChatEmote("The hook moves and swiftly makes sure your cuffs are connected both at Wrists and Elbows. Maybe it will trigger again if you move something else close to it as well (hook gag), (hook clothes)")
} else {
E.ChatEmote("The cuffs slide onto the hook, but they're simply too sturdy to go anywhere. Maybe something else can trigger it (gag) or (clothes)")
}
};
r.Triggers.push(hookCuff);
}
r.Entry = "The sensor moves a bit, before a panel opens and a hook extends from the wall. Maybe somthing can be hooked onto it. (gag), (cuffs) or (clothes)";
S.Levels.push(r);
}
//Room2
{
let r = new Level("Room2");
//Triggers
let acceptFate = new Trigger("door");
{
acceptFate.Action = () => E.ChatEmote("The door seems to have locked behind you leaving no way back at the current moment.");
r.Triggers.push(acceptFate);
}
let struggle = new Trigger("platform");
{
struggle.Action = function () {
InventoryWear(C, "SpreaderMetal", "ItemFeet", "Default", 20);
InventoryWear(C, "Corset5", "ItemTorso", C.LabelColor, 20)
ChatRoomCharacterUpdate(C);
E.GotoLevel("Stuck");
};
r.Triggers.push(struggle);
}
r.Entry = "The door closes behind you" + acceptFate.Print() + " as you enter a round room, with a slightly elevated platform in the middle (stand on the platform)";
S.Levels.push(r);
}
//several stages of stuck
{
let r = new Level("Stuck");
//Triggers
let sameAction = () => {
InventoryWear(C, "VibratingDildo", "ItemVulva", "Default", 20)
InventoryWear(C, "OneBarPrison", "ItemDevices", "Default", 20)
ChatRoomCharacterUpdate(C)
if (!InventoryGet(C, "ItemVulva").Property) InventoryGet(C, "ItemVulva").Property = { Intensity: -1 }
InventoryGet(C, "ItemVulva").Property.Effect = ["Egged", "Vibrating"]
InventoryGet(C, "ItemVulva").Property.Intensity = InventoryGet(C, "ItemVulva").Property.Intensity + 4
ServerSend("ChatRoomChat", { Content: "Dildo" + ((1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(C, "ItemVulva").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: C.Name, MemberNumber: C.MemberNumber }] })
CharacterLoadEffect(C)
ChatRoomCharacterUpdate(C)
E.GotoLevel("Stuck2");
};
let acceptFate = new Trigger("relax");
acceptFate.Action = sameAction;
r.Triggers.push(acceptFate);
let struggle = new Trigger("struggle");
struggle.Action = sameAction;
r.Triggers.push(struggle);
r.Entry = "A light mechanical clatter fills the room, and small metal panels open on the platform, extending mechanical arms to grab and lock a set of cuffs with a spreader between your ankles." +
" More mechanical arms extend to snare a corset around your waist so it squeezes you tightly. The arms then lock in place to keep you still, while a pole extends towards your crotch from below, with a vibrating dildo at the end. You can " + struggle.Print() + " or try to " + acceptFate.Print() + "and accept your fate";
S.Levels.push(r);
}
{
let r = new Level("Stuck2");
let sameAction = () => {
InventoryRemove(C, "ItemDevices")
InventoryWear(C, "PolishedChastityBelt", "ItemPelvis", "Default", 20)
ChatRoomCharacterUpdate(C)
E.GotoLevel("Stuck3");
};
let acceptFate = new Trigger("relax");
acceptFate.Action = sameAction;
r.Triggers.push(acceptFate);
let struggle = new Trigger("struggle");
struggle.Action = sameAction;
r.Triggers.push(struggle);
r.Entry = "The pole pushes the vibrating dildo deep between your pussy lips. The mechanical arms keeps firmly locked around your waist while another set extends to lock a chastity belt over the dildo. You can still (struggle) or (relax)"
S.Levels.push(r);
}
{
let r = new Level("Stuck3");
let sameAction = () => {
InventoryWear(C, "Stockings1", "Socks", "Default", 20)
InventoryWear(C, "HarnessPanelGag", "ItemMouth2", "Default", 20)
InventoryRemove(C, "ItemFeet")
ChatRoomCharacterUpdate(C)
E.ChatEmote("The ankle cuffs loosen and is pulled down under the floor. With the vibrator buzzing, a female voice can be heard speaking through the room.")
setTimeout(Welcome, 5000);
setTimeout(NowYouAreStuck, 10000);
setTimeout(AWayOut, 15000);
setTimeout(goToKeyRoom, 20000)
setTimeout(setVibe, 15000);
};
let acceptFate = new Trigger("relax");
acceptFate.Action = sameAction;
r.Triggers.push(acceptFate);
let struggle = new Trigger("struggle");
struggle.Action = sameAction;
r.Triggers.push(struggle);
r.Entry = "The pole retracts, and the belt is secured tightly. With the belt securely in place, the ankle cuffs expand a little to allow a bit of fabric to be pulled up over your feet and underneathe the cuffs. the cuffs then move up along your legs while expanding to roll a pair of soft stockings onto your thighs. Another pair of arms extends, one to grab your hair, the other to secure a panel over that ball gag. (relax) or (struggle)"
S.Levels.push(r);
}
//press the right button game:
{
let r = new Level("KeyRoom");
let foot = new Trigger("foot");
foot.Action = () =>
E.ChatEmote('As you bring your foot close to the button it retracts into the floor, and the voice echoes through the room. "Sorry, but that is cheating. You will have to kneel down to press it."');
let moveToButton = new Trigger("crawl to button");
{
moveToButton.Regex = /^(?:crawl[s]? to button)\s+([0-9]+)$/i;
moveToButton.Action = txt => {
if (InventoryGet(C, "ItemLegs")){
E.ChatEmote("You can't move with your legs bound. You will have to struggle out")
} else {
let b = parseInt(txt.match(moveToButton.Regex)[1]);
flags.AtButton = b;
E.ChatEmote("Now at button " + b + ", you can press it(press button " + b + "), or crawl to a different button (crawl to button <n>)");
}
}
}
let buttonClickAction = () => {
//Pressing the button we currently on
var rng = Math.round(Math.random() * 5)
if (flags.AtButton == flags.CorrectButton) {
//Correct button
E.ChatEmote("As you press the button you hear a light 'click' and the door opens behind you leaving the exit free.");
UnlockRoom();
E.GotoLevel("EscapeChance");
} else if (rng ==3 ) {
InventoryWear(C, "NylonRope", "ItemLegs", InventoryGet(C, "HairFront").Color, 0)
ChatRoomCharacterUpdate(C)
E.ChatEmote("More mechanical arms extend from the floor, swiftly snaring together your legs to make movement harder. To proceed you will have to struggle out")
} else if (rng >3 && C.BlockItems.map(function(e) { return e.Name; }).indexOf('VibratingButtplug') == -1) {
if (!InventoryGet(C, "ItemButt") || InventoryGet(C, "ItemButt").Asset.Name != "VibratingButtplug") {
E.ChatEmote("A panel opens on the floor, just behind you, extending an arm to shove a butt plug through an opening on your castity belt, then swiftly closes it")
InventoryWear(C, "VibratingButtplug", "ItemButt", "Default", 20)
if (!InventoryGet(C, "ItemButt").Property) InventoryGet(C, "ItemButt").Property = { Intensity: -1 }
ChatRoomCharacterUpdate(C)
} else if (InventoryGet(C, "ItemButt").Property.Intensity < 4) {
InventoryGet(C, "ItemButt").Property.Effect = ["Egged", "Vibrating"]
InventoryGet(C, "ItemButt").Property.Intensity = InventoryGet(C, "ItemButt").Property.Intensity + 1
ServerSend("ChatRoomChat", { Content: "Buttplug" + ((1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(C, "ItemButt").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: C.Name, MemberNumber: C.MemberNumber }] })
CharacterLoadEffect(C)
ChatRoomCharacterUpdate(C)
setVibe()
E.ChatEmote("This button simply turns up the plug, and adjusts the intensity of the vibrator")
} else {
//Wrong button
E.ChatEmote("The button doesn't do anything, it simply sets the intensity of your vibrator");
setVibe();
}
} else {
//Wrong button
E.ChatEmote("The button doesn't do anything, it simply sets the intensity of your vibrator");
setVibe();
}
};
let pressSpecificButton = new Trigger("press button");
{
pressSpecificButton.Regex = /(?:press)(?:es|ed)?(?: button)? ([0-9]+)/i;
pressSpecificButton.Action = txt => {
let b = parseInt(txt.match(pressSpecificButton.Regex)[1]);
if (C.ActivePose == null) {
//Standing
flags.AtButton = b;
E.ChatEmote("You walk up to button " + b + " but it can't be reached while standing.");
return;
}
//Otherwise kneeling
if (flags.AtButton == b || flags.AtButton == null) {
//Pressing the button we currently on
flags.AtButton = b;
buttonClickAction();
} else {
E.ChatEmote("That button is too far away, you can stand up to walk there, or (crawl to button <number>) to remain on your knees.");
}
};
}
let justPress = new Trigger("press");
{
justPress.Regex = /press(es|ed)?/i;
justPress.Action = txt => {
if (flags.AtButton == null) {
//Not on any button, ignore
return;
}
if (C.ActivePose == null) {
E.ChatEmote("The button can't be reached while standing.");
return;
}
buttonClickAction();
};
}
let standsUp = new Trigger("standup");
standsUp.Type = Trigger.Types.Action;
standsUp.Action = txt => {
flags.AtButton = null;
E.ChatEmote("The chastity belt sends a sharp, electric jolt through your body as you stand up");
E.ChatEmote("Standing up makes it easy to move around. You simply need to kneel down again, to press the button you want (press button <n>)");
};
let orgasmResist = new Trigger("orgasmresist");
orgasmResist.Type = Trigger.Types.Activity;
let cum = new Trigger("orgasm");
cum.Type = Trigger.Types.Activity;
cum.Regex = /(orgasm|cum|cumming)/i;
cum.Action = () => {
if (InventoryGet(C, "ItemLegs")){
E.ChatEmote('Mechanical arms extend from the ground to cut the ropes again and free your legs.')
InventoryRemove(C, "ItemLegs")
ChatRoomCharacterUpdate(C)
}
E.GotoLevel("Doomed");
}
r.Triggers.push(foot);
r.Triggers.push(moveToButton);
r.Triggers.push(standsUp);
r.Triggers.push(pressSpecificButton);
r.Triggers.push(justPress);
r.Triggers.push(orgasmResist);
r.Triggers.push(cum);
r.Prepare = level => {
var d;
if (flags.IsEntryRead == false || flags.AtButton == null) {
d = "Several small panels open on the floor, accross the room and tiny stands, with numbered buttons between 0 and 23, extend. The buttons are all the way down on the floor, so either you can try pressing one with your foot(press button <number> with foot), or you will have to kneel to reach them (press button <number>) (without <>)";
flags.IsEntryRead = true;
} else {
d = "Now at button " + flags.AtButton + ", you can try to press it(press button "+ flags.AtButton + ") or crawl to another button(crawl to button <n>)"
}
level.Entry = d;
};
S.Levels.push(r);
}
//EscapeChance
{
let r = new Level("EscapeChance")
let esc = new Trigger("escape");
{
esc.Action = function () {
ChatRoomAdminChatAction("Kick", "/Kick " + C.MemberNumber.toString())
E.Reset()
}
r.Triggers.push(esc)
}
let stay = new Trigger("stay");
{
stay.Action = function () {
E.ChatEmote("After a short while the doors close again")
E.GotoLevel("Doomed")
}
r.Triggers.push(stay)
}
r.Entry = "With all the doors open. you can choose either to surrender your freedom to your captor and (stay) behind to see who else might stumble into the warehouse, or you can (escape) through the open doors to get help with your predicament. (Warning: escaping will kick you out of the room so it can be updated for new players)"
S.Levels.push(r);
}
//Doomed
{
let r = new Level("Doomed")
let enter = new Trigger("enter the opening")
{
enter.Action = function () {
var d = "The opening closes behind you, and mechanical arms grabs you to keep you in place while the floor starts moving upwards."
if (!InventoryGet(C, "ItemNeck")) {
InventoryWear(C, "LeatherChoker", "ItemNeck", "Default", 60)
ChatRoomCharacterUpdate(C)
d = d + " A leather collar is secured snugly around your neck so it hugs your skin all the way around, and"
}
InventoryWear(C, "CollarNameTag", "ItemNeckAccessories", "#ffffff", 20)
DialogFocusItem = InventoryGet(C, "ItemNeckAccessories");
if (DialogFocusItem.Property == null) DialogFocusItem.Property = { Type: null };
DialogFocusItem.Property.Type = "Slave";
DialogFocusItem.Property.Effect = [];
CharacterRefresh(C);
ChatRoomCharacterUpdate(C);
d = d + " A tag with the word 'slave' on it is attached to your collar."
E.ChatEmote(d)
if (InventoryGet(C, "ItemButt")){
if (InventoryGet(C, "ItemButt").Asset.Name == "VibratingButtplug") {
InventoryGet(C, "ItemButt").Property.Intensity = InventoryGet(C, "ItemButt").Property.Intensity - 3
ServerSend("ChatRoomChat", { Content: "Buttplug" + ((1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(C, "ItemButt").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: C.Name, MemberNumber: C.MemberNumber }] })
CharacterLoadEffect(C)
ChatRoomCharacterUpdate(C)
}
}
setTimeout(arrival, 9000)
}
r.Triggers.push(enter)
}
r.Entry = 'The buttons retract down into the floor and a hidden panel on the wall at the side of the room opens up. The voice from earlier resounds across the room. "seems you are mine then". The opening can be entered (enter the opening) beyond that the room is just empty.'
S.Levels.push(r)
}
function FollowUp(a) {
E.ChatEmote("- The warehouse is fairly big, but mostly empty. There's a (locker) you can check out on the wall to the right, or you can head (down) the stairs to the left, into the basement")
}
function Explanation(r) {
E.ChatEmote("Type an emote containing (*locker) or (*down) into chat, to get started.")
}
function Explanation2() {
E.ChatAction("triggers have to be emotes to work")
}
function Welcome() {
E.ChatEmote('"Congratulations, ' + C.Name + ', on finding your way in here. It has been a pleassure watching you get yourself into this position"')
}
function NowYouAreStuck() {
E.ChatEmote('"You are now my captive"')
}
function AWayOut() {
E.ChatEmote('"I will offer you a way out though. If you can find the button that opens the door without cumming, I will let you go. Otherwise you will be kept here as my toy and pet. Or possibly sold away as a slave"')
}
function goToKeyRoom() {
E.GotoLevel("KeyRoom");
}
function arrival() {
E.ChatEmote("Finally you arrive at the control room to meet your captor, and you can see the redheaded woman watching you with a calm smile. The room has a good overlook to the warehouse, and several screens to keep track of anyone that might enter")
ServerSend("ChatRoomAdmin", { MemberNumber: C.MemberNumber, Action: "MoveLeft", Publish: false});
E.Reset();
}
function lock() {
E.ChatEmote("After a few seconds, a light mechanical click can be hear from the mechanic buckles on the leather cuffs as they tighten slightly and locks themselves in place")
InventoryLock(C, InventoryGet(C, "ItemArms"), "ExclusivePadlock", 2313);
ChatRoomCharacterUpdate(C)
}
function dildo() {
E.ChatEmote("(You seem to have vibrating dildo blocked in your inventory, this part only works properly if you unblock it)")
}
function UnlockRoom() {
// Allow player to exit but keep the room private until then
E.ChangeRoomSettings(
{
Background: "AbandonedBuilding",
Limit: (ChatRoomCharacter.length + 1).toString(),
Private: true,
Locked: false
});
}
function setVibe() {
if (!InventoryGet(C, "ItemVulva").Property) InventoryGet(C, "ItemVulva").Property = { Intensity: -1 }
if (InventoryGet(C, "ItemVulva").Property.Intensity < 3) {
InventoryGet(C, "ItemVulva").Property.Effect = ["Egged", "Vibrating"]
InventoryGet(C, "ItemVulva").Property.Intensity = InventoryGet(C, "ItemVulva").Property.Intensity + 1
ServerSend("ChatRoomChat", { Content: "Dildo" + ((1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(C, "ItemVulva").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: C.Name, MemberNumber: C.MemberNumber }] })
CharacterLoadEffect(C)
ChatRoomCharacterUpdate(C)
} else {
InventoryGet(C, "ItemVulva").Property.Effect = ["Egged", "Vibrating"]
InventoryGet(C, "ItemVulva").Property.Intensity = InventoryGet(C, "ItemVulva").Property.Intensity - 1
ServerSend("ChatRoomChat", { Content: "Dildo" + ((-1 > 0) ? "Increase" : "Decrease") + "To" + InventoryGet(C, "ItemVulva").Property.Intensity, Type: "Action", Dictionary: [{ Tag: "DestinationCharacterName", Text: C.Name, MemberNumber: C.MemberNumber }] })
CharacterLoadEffect(C)
ChatRoomCharacterUpdate(C)
}
}
return S;
}