From 26552137297af32fbe97121458783032381edf2b Mon Sep 17 00:00:00 2001
From: TechTheAwesome <technicalcreepers@gmail.com>
Date: Sat, 16 Mar 2019 01:07:45 +0700
Subject: [PATCH 1/4] Organize Private Activity List

Anotherway to organize activity list withouth bunch of if statement and loop 100 time. Also easier to update and add new content
---
 BondageClub/Screens/Room/Private/Private.js | 127 +++++++++++++++++++-
 1 file changed, 123 insertions(+), 4 deletions(-)

diff --git a/BondageClub/Screens/Room/Private/Private.js b/BondageClub/Screens/Room/Private/Private.js
index 9df7880f4e..2049b84017 100644
--- a/BondageClub/Screens/Room/Private/Private.js
+++ b/BondageClub/Screens/Room/Private/Private.js
@@ -9,10 +9,116 @@ var PrivateReleaseTimer = 0;
 var PrivateActivity = "";
 var PrivateActivityCount = 0;
 var PrivateActivityAffectLove = true;
-var PrivateActivityList = ["Gag", "Ungag", "Restrain", "FullRestrain", "Release", "Tickle", "Spank", "Pet", "Slap", "Kiss", "Fondle", "Naked", "Underwear", "RandomClothes", "Shibari", "Gift"];
+//var PrivateActivityList = ["Gag", "Ungag", "Restrain", "FullRestrain", "Release", "Tickle", "Spank", "Pet", "Slap", "Kiss", "Fondle", "Naked", "Underwear", "RandomClothes", "Shibari", "Gift"];
+//Because "use strict"; need a new set of local variables
+
+var PrivateActivityList = [
+	{//Gag
+		name: "Gag",
+		Conditions: [
+			() => Player.CanTalk()	
+		]
+	},{//Ungag
+		name: "Ungag",
+		Conditions: [
+			() => !Player.CanTalk(),
+			() => (CommonTime() > PrivateReleaseTimer)? true : false
+		]
+	},{//Restrain
+		name:"Restrain",
+		Conditions: [
+			() => InventoryGet(Player, "ItemArms") == null
+		]
+	},{//FullRestrain
+		name: "FullRestrain",
+		Conditions:[
+			() => InventoryGet(Player, "ItemArms") == null
+		]
+	},{//Release
+		name: "Release",
+		Conditions:[
+			() => Player.IsRestrained(),
+			() => CommonTime() > PrivateReleaseTimer
+		]
+	},{//Tickle
+		name: "Tickle",
+		Conditions:[
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Playful"),
+			() => NPCTraitGet(CurrentCharacter, "Playful") >= 0
+		]
+	},{//Spank
+		name: "Spank",
+		Conditions:[
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Violent"),
+			() => NPCTraitGet(CurrentCharacter, "Violent") >= 0
+		]
+	},{//Pet
+		name: "Pet",
+		Conditions:[
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Peaceful"),
+			() => NPCTraitGet(CurrentCharacter, "Peaceful") > 0
+		]
+	},{//Slap
+		name: "Slap",
+		Conditions:[
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Violent"),
+			()=> NPCTraitGet(CurrentCharacter, "Violent") > 0,
+			() => CurrentCharacter.Love < 50,
+		]
+	},{//Kiss
+		name: "Kiss",
+		Conditions:[
+			() => Player.CanTalk(),
+			() => CurrentCharacter.Love >= 50,
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
+			() => NPCTraitGet(CurrentCharacter, "Horny") >= 0
+		]
+	},{//Fondle
+		name: "Fondle",
+		Conditions:[
+			() => !Player.IsBreastChaste(),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
+			() => NPCTraitGet(CurrentCharacter, "Horny") > 0
+		]
+	},{//Naked
+		name: "Naked",
+		Conditions:[
+			() => !CharacterIsNaked(Player),
+			() => Player.CanChange(),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
+			() => NPCTraitGet(CurrentCharacter, "Horny") > 0,
+		]
+	},{//Underwear
+		name: "Underwear",
+		Conditions:[
+			() => !CharacterIsInUnderwear(Player),
+			() => Player.CanChange(),
+		]
+	},{//RandomClothes
+		name: "RandomClothes",
+		Conditions:[
+			() => Player.CanChange()
+		]
+	},{//Shibari
+		name: "Shibari",
+		Conditions:[
+			() => Player.CanChange(),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Wise"),
+			() => NPCTraitGet(CurrentCharacter, "Wise") >= 0,
+		]
+	},{//Gift
+		name: "Gift",
+		Conditions:[
+			() => Player.Owner != "",
+			() => CurrentTime >= NPCEventGet(CurrentCharacter, "LastGift") + 86400000,
+			() => CurrentCharacter.Love >= 90
+		]
+	}
+	]
 var PrivatePunishment = "";
 var PrivatePunishmentList = ["Cage", "Bound", "BoundPet", "ChastityBelt", "ChastityBra", "ForceNaked", "ConfiscateKey", "ConfiscateCrop", "ConfiscateWhip", "SleepCage"];
 
+//#region DIALOG CONDITIONS
 // Returns TRUE if a specific dialog option is allowed
 function PrivateIsCaged() { return (CurrentCharacter.Cage == null) ? false : true }
 function PrivateVendorCanPlay() { return (LogQuery("RentRoom", "PrivateRoom") && LogQuery("Wardrobe", "PrivateRoom") && LogQuery("Cage", "PrivateRoom") && Player.CanInteract() && PrivateVendor.CanInteract()) }
@@ -55,7 +161,9 @@ function PrivateIsNeutral() { return ((CurrentCharacter.Love >= -30) && (Current
 function PrivateSubTrialInProgress() { return ((NPCEventGet(CurrentCharacter, "EndDomTrial") > 0) && (CurrentTime < CheatFactor("SkipTrialPeriod", 0) * NPCEventGet(CurrentCharacter, "EndDomTrial"))) }
 function PrivateSubTrialOverWilling() { return ((NPCEventGet(CurrentCharacter, "EndDomTrial") > 0) && (CurrentTime >= CheatFactor("SkipTrialPeriod", 0) * NPCEventGet(CurrentCharacter, "EndDomTrial")) && (CurrentCharacter.Love >= 90)) }
 function PrivateSubTrialOverUnwilling() { return ((NPCEventGet(CurrentCharacter, "EndDomTrial") > 0) && (CurrentTime >= CheatFactor("SkipTrialPeriod", 0) * NPCEventGet(CurrentCharacter, "EndDomTrial")) && (CurrentCharacter.Love < 90)) }
+//#endregion
 
+//#region temp not touch
 // Loads the private room vendor NPC
 function PrivateLoad() {
 
@@ -341,15 +449,17 @@ function PrivatePlayerIsOwned() {
 			return true;
 	return false;
 }
+//#endregion
 
 // Starts a random activity for the player as submissive
 function PrivateStartActivity() {
 
+	/*
 	// Finds a valid activity for the player
 	var Act = "";
 	var Count = 0;
 	while (true) {
-
+		
 		// Picks an activity at random
 		Act = CommonRandomItemFromList(PrivateActivity, PrivateActivityList);
 
@@ -379,9 +489,18 @@ function PrivateStartActivity() {
 		}
 
 	}
-
+	*/
+	//filter out activities that doesnt fufill all avaliable conditions. 
+	//aka if some(or even one)condition === false then filter out
+	//and then map only the name (activity in string out as array)
+	
+	let Act = PrivateActivityList.filter(n => !n.Conditions.some(x => x() === false))
+								.map(x => x.name);
+	
 	// Starts the activity (any activity adds +2 love automatically)
-	PrivateActivity = Act;
+	//PrivateActivity = Act;
+	//Pick random item from filtered list
+	PrivateActivity = CommonRandomItemFromList(PrivateActivity,Act);
 	PrivateNPCInteraction(2);
 	PrivateActivityAffectLove = true;
 	PrivateActivityCount = 0;
-- 
GitLab


From 4bdd822d3f3733201be7bb8734171e8d57f45deb Mon Sep 17 00:00:00 2001
From: TechTheAwesome <technicalcreepers@gmail.com>
Date: Sat, 16 Mar 2019 11:39:37 +0700
Subject: [PATCH 2/4] Update some more of activity organization

---
 BondageClub/Screens/Room/Private/Private.js | 207 ++++++++++++++++++--
 1 file changed, 191 insertions(+), 16 deletions(-)

diff --git a/BondageClub/Screens/Room/Private/Private.js b/BondageClub/Screens/Room/Private/Private.js
index 2049b84017..c289649b0f 100644
--- a/BondageClub/Screens/Room/Private/Private.js
+++ b/BondageClub/Screens/Room/Private/Private.js
@@ -10,53 +10,97 @@ var PrivateActivity = "";
 var PrivateActivityCount = 0;
 var PrivateActivityAffectLove = true;
 //var PrivateActivityList = ["Gag", "Ungag", "Restrain", "FullRestrain", "Release", "Tickle", "Spank", "Pet", "Slap", "Kiss", "Fondle", "Naked", "Underwear", "RandomClothes", "Shibari", "Gift"];
-//Because "use strict"; need a new set of local variables
-
-var PrivateActivityList = [
+// PrivateActivityList objects consits of {name}, {Conditions}, and {Run}
+// {name} contains the string variable to start dialogs 
+//{Conditions} is an array of function that returns a boolean (preferabily arrow functions "() =>" for easy reading)
+//{Conditions} is used to sort out valid activity based on CurrentCharacter
+//Unless all {Conditions} returns true, the activity is not valid
+// Lastly the {Run} array of functions (again prefer "() =>")
+//{Run} is a replica of current if(PrivateActivity == "(Acts)") //do something...
+//To use, just call the object.Run.forEach(x => x())
+//{Run} is more easier to maintain so please use it ;) 
+const PrivateActivityList = [
 	{//Gag
 		name: "Gag",
 		Conditions: [
 			() => Player.CanTalk()	
+		],
+		Run: [
+			() => InventoryWearRandom(Player, "ItemMouth"),
+			() => PrivateReleaseTimer = CommonTime() + (Math.random() * 60000) + 60000
 		]
 	},{//Ungag
 		name: "Ungag",
 		Conditions: [
 			() => !Player.CanTalk(),
 			() => (CommonTime() > PrivateReleaseTimer)? true : false
+		],
+		Run: [
+			() => {
+				 InventoryRemove(Player, "ItemMouth"); 
+				 InventoryRemove(Player, "ItemHead"); 
+			}
 		]
 	},{//Restrain
 		name:"Restrain",
 		Conditions: [
 			() => InventoryGet(Player, "ItemArms") == null
+		],
+		Run: [
+			() => InventoryWearRandom(Player, "ItemArms"),
+			() => PrivateReleaseTimer = CommonTime() + (Math.random() * 60000) + 60000
 		]
-	},{//FullRestrain
+	},{//FullRestrain (Restrain activity are harsher for serious NPCs)
 		name: "FullRestrain",
 		Conditions:[
 			() => InventoryGet(Player, "ItemArms") == null
+		],
+		Run: [
+			() => {
+				if(NPCTraitGet(CurrentCharacter, "Playful") > 0)
+					CharacterFullRandomRestrain(Player, "Few");
+				if(NPCTraitGet(CurrentCharacter, "Playful") == 0)
+					CharacterFullRandomRestrain(Player);
+				if(NPCTraitGet(CurrentCharacter, "Serious") > 0)
+					CharacterFullRandomRestrain(Player, "Lot");	
+			},
+			() => PrivateReleaseTimer = CommonTime() + (Math.random() * 60000) + 60000
 		]
 	},{//Release
 		name: "Release",
 		Conditions:[
 			() => Player.IsRestrained(),
 			() => CommonTime() > PrivateReleaseTimer
+		],
+		Run: [
+			() => CharacterRelease(Player)
 		]
 	},{//Tickle
 		name: "Tickle",
 		Conditions:[
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Playful"),
 			() => NPCTraitGet(CurrentCharacter, "Playful") >= 0
+		],
+		Run: [
+
 		]
 	},{//Spank
 		name: "Spank",
 		Conditions:[
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Violent"),
 			() => NPCTraitGet(CurrentCharacter, "Violent") >= 0
+		],
+		Run: [
+
 		]
 	},{//Pet
 		name: "Pet",
 		Conditions:[
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Peaceful"),
 			() => NPCTraitGet(CurrentCharacter, "Peaceful") > 0
+		],
+		Run: [
+
 		]
 	},{//Slap
 		name: "Slap",
@@ -64,6 +108,9 @@ var PrivateActivityList = [
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Violent"),
 			()=> NPCTraitGet(CurrentCharacter, "Violent") > 0,
 			() => CurrentCharacter.Love < 50,
+		],
+		Run: [
+
 		]
 	},{//Kiss
 		name: "Kiss",
@@ -72,6 +119,9 @@ var PrivateActivityList = [
 			() => CurrentCharacter.Love >= 50,
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
 			() => NPCTraitGet(CurrentCharacter, "Horny") >= 0
+		],
+		Run: [
+
 		]
 	},{//Fondle
 		name: "Fondle",
@@ -79,6 +129,9 @@ var PrivateActivityList = [
 			() => !Player.IsBreastChaste(),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
 			() => NPCTraitGet(CurrentCharacter, "Horny") > 0
+		],
+		Run: [
+
 		]
 	},{//Naked
 		name: "Naked",
@@ -87,36 +140,126 @@ var PrivateActivityList = [
 			() => Player.CanChange(),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
 			() => NPCTraitGet(CurrentCharacter, "Horny") > 0,
+		],
+		Run: [
+			() => CharacterNaked(Player),
 		]
 	},{//Underwear
 		name: "Underwear",
 		Conditions:[
 			() => !CharacterIsInUnderwear(Player),
 			() => Player.CanChange(),
+		],
+		Run: [
+			() => CharacterRandomUnderwear(Player)
 		]
 	},{//RandomClothes
 		name: "RandomClothes",
 		Conditions:[
 			() => Player.CanChange()
+		],
+		Run: [
+			() => CharacterAppearanceFullRandom(Player, true)
 		]
-	},{//Shibari
+	},{//Shibari (In Shibari, the player gets naked and fully roped in hemp)
 		name: "Shibari",
 		Conditions:[
 			() => Player.CanChange(),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Wise"),
 			() => NPCTraitGet(CurrentCharacter, "Wise") >= 0,
+		],
+		Run: [
+			() => {
+				CharacterNaked(Player);
+				CharacterSetActivePose(Player, null);
+				InventoryWear(Player, "HempRope", "ItemArms", "Default", Math.floor(Math.random() * 10) + 1);
+				InventoryWear(Player, "HempRope", "ItemLegs", "Default", Math.floor(Math.random() * 10) + 1);
+				InventoryWear(Player, "SuspensionHempRope", "ItemFeet", "Default", Math.floor(Math.random() * 10) + 1);
+				InventoryWear(Player, "HempRopeHarness", "ItemTorso", "Default", Math.floor(Math.random() * 10) + 1);
+				InventoryWearRandom(Player, "ItemMouth");
+				PrivateReleaseTimer = CommonTime() + (Math.random() * 60000) + 60000;
+			}
 		]
-	},{//Gift
+	},{//Gift (gift can only happen once a day if the player is fully collared)
 		name: "Gift",
 		Conditions:[
 			() => Player.Owner != "",
 			() => CurrentTime >= NPCEventGet(CurrentCharacter, "LastGift") + 86400000,
 			() => CurrentCharacter.Love >= 90
+		],
+		Run: [
+			() => {
+				CharacterChangeMoney(Player, 50);
+				NPCEventAdd(CurrentCharacter, "LastGift", CurrentTime);
+			}
 		]
 	}
 	]
 var PrivatePunishment = "";
-var PrivatePunishmentList = ["Cage", "Bound", "BoundPet", "ChastityBelt", "ChastityBra", "ForceNaked", "ConfiscateKey", "ConfiscateCrop", "ConfiscateWhip", "SleepCage"];
+//var PrivatePunishmentList = ["Cage", "Bound", "BoundPet", "ChastityBelt", "ChastityBra", "ForceNaked", "ConfiscateKey", "ConfiscateCrop", "ConfiscateWhip", "SleepCage"];
+const PrivatePunishmentList =[
+	{//Cage
+		name: "Cage",
+		Conditions:[
+			() => LogQuery("Cage", "PrivateRoom"),
+		]
+	},{//Bound
+		name: "Bound",
+		Conditions:[
+			() => true,
+		]
+	},{//BoundPet
+		name: "BoundPet",
+		Conditions:[
+			() => !Player.IsVulvaChaste(),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Playful"),
+			() => NPCTraitGet(CurrentCharacter, "Playful") >= 0
+		]
+	},{//ChastityBelt
+		name: "ChastityBelt",
+		Conditions:[
+			() => !Player.IsVulvaChaste(),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Frigid"),
+			() => NPCTraitGet(CurrentCharacter, "Frigid") >= 0
+		]
+	},{//ChastityBra
+		name: "ChastityBra",
+		Conditions:[
+			() => !Player.IsBreastChaste(),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Frigid"),
+			() => NPCTraitGet(CurrentCharacter, "Frigid") >= 0
+		]
+	},{//ForcedNaked
+		name: "ForcedNaked",
+		Conditions:[
+			() => !LogQuery("BlockChange", "Rule"),
+			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
+			() => NPCTraitGet(CurrentCharacter, "Horny") >= 0
+		]
+	},{//ConfisticateKey
+		name: "ConfisticateKey",
+		Conditions:[
+			() => InventoryAvailable(Player, "MetalCuffsKey", "ItemArms"),
+
+		]
+	},{//ConfisticateCrop
+		name: "ConfisticateCrop",
+		Conditions:[
+			() => InventoryAvailable(Player, "LeatherCrop", "ItemPelvis")
+		]
+	},{//ConfisticateWip
+		name: "ConfisticateWip",
+		Conditions:[
+			() => InventoryAvailable(Player, "LeatherWhip", "ItemPelvis")
+		]
+	},{//SleepCage
+		name: "SleepCage",
+		Conditions:[
+			() => LogQuery("Cage", "PrivateRoom"),
+			() => !LogQuery("SleepCage", "Rule")
+		]
+	}
+]
 
 //#region DIALOG CONDITIONS
 // Returns TRUE if a specific dialog option is allowed
@@ -383,6 +526,7 @@ function PrivateChange(NewCloth) {
 }
 
 // Returns TRUE if the player owner is already in the room
+//Should this be in the DIALOG CONDITIONS section? <<<<<<
 function PrivateOwnerInRoom() {
 	for(var C = 1; C < PrivateCharacter.length; C++)
 		if (PrivateCharacter[C].IsOwner() && (PrivateCharacter[C].ID != CurrentCharacter.ID))
@@ -442,6 +586,7 @@ function PrivateShowTrialHours() {
 }
 
 // Returns TRUE if the player is owned (from the room or not)
+//Should this be in the DIALOG CONDITIONS section? <<<<<<
 function PrivatePlayerIsOwned() {
 	if (Player.Owner != "") return true;
 	for(var C = 0; C < PrivateCharacter.length; C++)
@@ -451,6 +596,7 @@ function PrivatePlayerIsOwned() {
 }
 //#endregion
 
+//#region tempDone
 // Starts a random activity for the player as submissive
 function PrivateStartActivity() {
 
@@ -493,14 +639,25 @@ function PrivateStartActivity() {
 	//filter out activities that doesnt fufill all avaliable conditions. 
 	//aka if some(or even one)condition === false then filter out
 	//and then map only the name (activity in string out as array)
+
+	let ActList = PrivateActivityList.filter(n => !n.Conditions.some(x => x() === false)).map(x => x.name);
+	//Pick random item from filtered list
+	console.log(ActList);
+	//Set to no activity if there's no more new activity avaliable
+	if(ActList.length == 1){
+		PrivateActivity = ActList[0];
+		console.log(PrivateActivity + " called if");
+	}	
+	else{
+		//CommonRandomItemFromList is buggy if list only have one object that is the same as PrivateActivity
+		PrivateActivity = CommonRandomItemFromList(PrivateActivity,ActList);
+		console.log(PrivateActivity + " called else");
+	}
+		
+		
 	
-	let Act = PrivateActivityList.filter(n => !n.Conditions.some(x => x() === false))
-								.map(x => x.name);
-	
-	// Starts the activity (any activity adds +2 love automatically)
 	//PrivateActivity = Act;
-	//Pick random item from filtered list
-	PrivateActivity = CommonRandomItemFromList(PrivateActivity,Act);
+	// Starts the activity (any activity adds +2 love automatically)
 	PrivateNPCInteraction(2);
 	PrivateActivityAffectLove = true;
 	PrivateActivityCount = 0;
@@ -544,7 +701,7 @@ function PrivateActivityRun(LoveFactor) {
 		}
 
 	}
-
+	/*
 	// The restraining activities are harsher for serious NPCs
 	if (PrivateActivity == "Gag") InventoryWearRandom(Player, "ItemMouth");
 	if (PrivateActivity == "Restrain") InventoryWearRandom(Player, "ItemArms");
@@ -557,7 +714,8 @@ function PrivateActivityRun(LoveFactor) {
 	if (PrivateActivity == "Naked") CharacterNaked(Player);
 	if (PrivateActivity == "Underwear") CharacterRandomUnderwear(Player);
 	if (PrivateActivity == "RandomClothes") CharacterAppearanceFullRandom(Player, true);
-
+	
+	
 	// The gift can only happen once a day if the player is fully collared
 	if (PrivateActivity == "Gift") {
 		CharacterChangeMoney(Player, 50);
@@ -575,6 +733,17 @@ function PrivateActivityRun(LoveFactor) {
 		InventoryWearRandom(Player, "ItemMouth");
 		PrivateReleaseTimer = CommonTime() + (Math.random() * 60000) + 60000;
 	}
+	*/
+	
+	//Filter out selected activity again (prefer not have to do this *shrug*)
+	//Run selected activity (call all Run functions)
+	//Notes for actions are in PrivateActivityList
+	let selectedActivity = PrivateActivityList.filter(x => x.name == PrivateActivity);
+	if(selectedActivity.length != 1)
+		Console.log("There is posibily matching name for Activities in PrivateActivityList, >>the first in list will be used<<");
+	//if there are run functions, run it 
+	if(selectedActivity[0].Run.length > 0)	
+		selectedActivity[0].Run.forEach(x => x());
 
 	// After running the activity a few times, we stop
 	if (PrivateActivityCount >= Math.floor(Math.random() * 4) + 2) {
@@ -590,6 +759,7 @@ function PrivateBlockChange(Minutes) {
 	ServerPlayerAppearanceSync();
 }
 
+//#endregion
 // Starts a random punishment for the player as submissive
 function PrivateSelectPunishment() {
 	
@@ -610,6 +780,7 @@ function PrivateSelectPunishment() {
 	}
 	
 	// Finds a valid punishment for the player
+	/*
 	var Count = 0;
 	while (true) {
 
@@ -629,7 +800,11 @@ function PrivateSelectPunishment() {
 		if ((PrivatePunishment == "SleepCage") && LogQuery("Cage", "PrivateRoom") && !LogQuery("SleepCage", "Rule")) break;
 
 	}
-
+	*/
+	//filter for valid punishments
+	let ValidPunishments = PrivatePunishmentList.filter(x => !x.Conditions.some(false));
+	//pick random from list of punishments
+	PrivatePunishment = CommonRandomItemFromList(PrivatePunishment,ValidPunishments);
 	// Starts the punishment
 	CurrentCharacter.Stage = "Punish" + PrivatePunishment;
 	CurrentCharacter.CurrentDialog = DialogFind(CurrentCharacter, "Punish" + PrivatePunishment + "Intro");
-- 
GitLab


From 64c83184483c8a40377c7fadc7587323867d6b39 Mon Sep 17 00:00:00 2001
From: TechTheAwesome <technicalcreepers@gmail.com>
Date: Sat, 16 Mar 2019 12:00:35 +0700
Subject: [PATCH 3/4] Fixed some bug

---
 BondageClub/Screens/Room/Private/Private.js | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/BondageClub/Screens/Room/Private/Private.js b/BondageClub/Screens/Room/Private/Private.js
index c289649b0f..b73ea9fd36 100644
--- a/BondageClub/Screens/Room/Private/Private.js
+++ b/BondageClub/Screens/Room/Private/Private.js
@@ -645,13 +645,12 @@ function PrivateStartActivity() {
 	console.log(ActList);
 	//Set to no activity if there's no more new activity avaliable
 	if(ActList.length == 1){
-		PrivateActivity = ActList[0];
-		console.log(PrivateActivity + " called if");
+		CurrentCharacter.CurrentDialog = DialogFind(CurrentCharacter, "ActivityNone");
+		return;
 	}	
 	else{
 		//CommonRandomItemFromList is buggy if list only have one object that is the same as PrivateActivity
 		PrivateActivity = CommonRandomItemFromList(PrivateActivity,ActList);
-		console.log(PrivateActivity + " called else");
 	}
 		
 		
-- 
GitLab


From 0934ca18f2168221a1779c11cf708bb77555b197 Mon Sep 17 00:00:00 2001
From: TechTheAwesome <technicalcreepers@gmail.com>
Date: Sat, 16 Mar 2019 17:54:25 +0700
Subject: [PATCH 4/4] Updated PrivatePunishmentList with the same setup

---
 BondageClub/Screens/Room/Private/Private.js | 60 +++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/BondageClub/Screens/Room/Private/Private.js b/BondageClub/Screens/Room/Private/Private.js
index b73ea9fd36..e9a1541171 100644
--- a/BondageClub/Screens/Room/Private/Private.js
+++ b/BondageClub/Screens/Room/Private/Private.js
@@ -202,11 +202,21 @@ const PrivatePunishmentList =[
 		name: "Cage",
 		Conditions:[
 			() => LogQuery("Cage", "PrivateRoom"),
+		],Run:[
+			() => Player.Cage = true,
+			() => LogAdd("BlockCage", "Rule", CurrentTime + 120000),
+			() =>  DialogLeave()
 		]
 	},{//Bound
 		name: "Bound",
 		Conditions:[
 			() => true,
+		],Run:[
+			() => PrivateReleaseTimer = CommonTime() + 240000,
+			() => CharacterFullRandomRestrain(Player, "All"),
+			() => InventoryRemove(Player, "ItemArms"),
+			() => InventoryWear(Player, "HempRope", "ItemArms"),
+			() => InventorySetDifficulty(Player, "ItemArms", 12)
 		]
 	},{//BoundPet
 		name: "BoundPet",
@@ -214,13 +224,31 @@ const PrivatePunishmentList =[
 			() => !Player.IsVulvaChaste(),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Playful"),
 			() => NPCTraitGet(CurrentCharacter, "Playful") >= 0
+		],Run:[
+			() => PrivateReleaseTimer = CommonTime() + 240000,
+			() => CharacterSetActivePose(Player, "Kneel"),
+			() => InventoryWear(Player, "LeatherBelt", "ItemLegs"),
+			() => InventoryWear(Player, "TailButtPlug", "ItemButt"),
+			() => InventoryWear(Player, "Ears" + (Math.floor(Math.random() * 2) + 1).toString(), "Hat"),
+			() => InventoryWear(Player, "LeatherArmbinder", "ItemArms"),
+			() => InventorySetDifficulty(Player, "ItemArms", 15)
 		]
-	},{//ChastityBelt
+	},{//ChastityBelt (if character is horny, add plug and vibrator)
 		name: "ChastityBelt",
 		Conditions:[
 			() => !Player.IsVulvaChaste(),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Frigid"),
 			() => NPCTraitGet(CurrentCharacter, "Frigid") >= 0
+		],Run:[
+			() =>{
+				if(NPCTraitGet(CurrentCharacter, "Horny") >= 0){
+					if(InventoryGet(Player, "ItemVulva") == null)
+						InventoryWear(Player, "VibratingEgg", "ItemVulva");
+					if(InventoryGet(Player, "ItemButt") == null)
+						InventoryWear(Player, "BlackButtPlug", "ItemButt");
+				}	
+			},
+			() => InventoryWear(Player, "MetalChastityBelt", "ItemPelvis")
 		]
 	},{//ChastityBra
 		name: "ChastityBra",
@@ -228,6 +256,8 @@ const PrivatePunishmentList =[
 			() => !Player.IsBreastChaste(),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Frigid"),
 			() => NPCTraitGet(CurrentCharacter, "Frigid") >= 0
+		],Run:[
+			() => InventoryWear(Player, "MetalChastityBra", "ItemBreast")
 		]
 	},{//ForcedNaked
 		name: "ForcedNaked",
@@ -235,28 +265,40 @@ const PrivatePunishmentList =[
 			() => !LogQuery("BlockChange", "Rule"),
 			() => CurrentCharacter.Trait.map(n=>n.Name).includes("Horny"),
 			() => NPCTraitGet(CurrentCharacter, "Horny") >= 0
+		],Run:[
+			() => LogAdd("BlockChange", "Rule", CurrentTime + 1800000)
 		]
 	},{//ConfisticateKey
 		name: "ConfisticateKey",
 		Conditions:[
 			() => InventoryAvailable(Player, "MetalCuffsKey", "ItemArms"),
 
+		],Run:[
+			() => InventoryDelete(Player, "MetalCuffsKey", "ItemArms")
 		]
 	},{//ConfisticateCrop
 		name: "ConfisticateCrop",
 		Conditions:[
 			() => InventoryAvailable(Player, "LeatherCrop", "ItemPelvis")
+		],Run:[
+			() =>  InventoryDelete(Player, "LeatherCrop", "ItemPelvis"),
+			() => InventoryDelete(Player, "LeatherCrop", "ItemBreast")
 		]
 	},{//ConfisticateWip
 		name: "ConfisticateWip",
 		Conditions:[
 			() => InventoryAvailable(Player, "LeatherWhip", "ItemPelvis")
+		],Run:[
+			() => InventoryDelete(Player, "LeatherWhip", "ItemPelvis"),
+			() => InventoryDelete(Player, "LeatherWhip", "ItemBreast")
 		]
 	},{//SleepCage
 		name: "SleepCage",
 		Conditions:[
 			() => LogQuery("Cage", "PrivateRoom"),
 			() => !LogQuery("SleepCage", "Rule")
+		],Run:[
+			() => LogAdd("SleepCage", "Rule", CurrentTime + 604800000)
 		]
 	}
 ]
@@ -739,7 +781,7 @@ function PrivateActivityRun(LoveFactor) {
 	//Notes for actions are in PrivateActivityList
 	let selectedActivity = PrivateActivityList.filter(x => x.name == PrivateActivity);
 	if(selectedActivity.length != 1)
-		Console.log("There is posibily matching name for Activities in PrivateActivityList, >>the first in list will be used<<");
+		Console.log("Might have two activites with same {name}, >>the first in list will be used<<");
 	//if there are run functions, run it 
 	if(selectedActivity[0].Run.length > 0)	
 		selectedActivity[0].Run.forEach(x => x());
@@ -801,7 +843,7 @@ function PrivateSelectPunishment() {
 	}
 	*/
 	//filter for valid punishments
-	let ValidPunishments = PrivatePunishmentList.filter(x => !x.Conditions.some(false));
+	let ValidPunishments = PrivatePunishmentList.filter(x => !x.Conditions.some(x => x() === false)).map(x => x.name);
 	//pick random from list of punishments
 	PrivatePunishment = CommonRandomItemFromList(PrivatePunishment,ValidPunishments);
 	// Starts the punishment
@@ -814,6 +856,7 @@ function PrivateSelectPunishment() {
 function PrivateRunPunishment(LoveFactor) {
 	NPCLoveChange(CurrentCharacter, LoveFactor);
 	NPCEventAdd(CurrentCharacter, "RefusedActivity", CurrentTime);
+	/*
 	if (PrivatePunishment == "Cage") { Player.Cage = true; LogAdd("BlockCage", "Rule", CurrentTime + 120000); DialogLeave(); }
 	if (PrivatePunishment == "Bound") { PrivateReleaseTimer = CommonTime() + 240000; CharacterFullRandomRestrain(Player, "All"); InventoryRemove(Player, "ItemArms"); InventoryWear(Player, "HempRope", "ItemArms"); InventorySetDifficulty(Player, "ItemArms", 12); }
 	if (PrivatePunishment == "BoundPet") { PrivateReleaseTimer = CommonTime() + 240000; CharacterSetActivePose(Player, "Kneel"); InventoryWear(Player, "LeatherBelt", "ItemLegs"); InventoryWear(Player, "TailButtPlug", "ItemButt"); InventoryWear(Player, "Ears" + (Math.floor(Math.random() * 2) + 1).toString(), "Hat"); InventoryWear(Player, "LeatherArmbinder", "ItemArms"); InventorySetDifficulty(Player, "ItemArms", 15); }
@@ -826,6 +869,17 @@ function PrivateRunPunishment(LoveFactor) {
 	if (PrivatePunishment == "ConfiscateCrop") { InventoryDelete(Player, "LeatherCrop", "ItemPelvis"); InventoryDelete(Player, "LeatherCrop", "ItemBreast"); }
 	if (PrivatePunishment == "ConfiscateWhip") { InventoryDelete(Player, "LeatherWhip", "ItemPelvis"); InventoryDelete(Player, "LeatherWhip", "ItemBreast"); }
 	if (PrivatePunishment == "SleepCage") LogAdd("SleepCage", "Rule", CurrentTime + 604800000);
+	*/
+	//Filter out again the pinishment picked
+	let punishment = PrivatePunishmentList.filter(x => x.name == PrivatePunishment)
+	if(punishment.length > 1)
+		console.log("might have two or more punishment with same {name}, >>first in list will be use<<")
+	//if theres no punishment, throw error
+	if(punishment.length < 1){
+		throw "there are no punishment object, check conditios in PrivatePunishmentList"
+	}
+	//if nothing happens run the punishment
+	punishment[0].Run.forEach(x => x());
 }
 
 // Sets up the player collaring ceremony cutscene
-- 
GitLab