Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5513733
Livingwood Chastity Updated to include Bra and Shared Parameters.
Pyra-Tech Feb 3, 2026
15460c9
Merge branch 'Enraa:main' into pyra_chastity
Pyra-Tech Feb 8, 2026
f4b7e75
Livingwood Reference Updates
Pyra-Tech Feb 8, 2026
247cac0
Merge branch 'pyra_chastity' of https://github.com/Pyra-Tech/Gagbot i…
Pyra-Tech Feb 8, 2026
dfbd0a7
Updated Livingwood to resolve issues with fetching types and functions.
Pyra-Tech Feb 8, 2026
e825f06
Added Livingwood Texts and Blacklist it from those that mention Steel
Pyra-Tech Feb 8, 2026
15ab338
Resolved issues with checks.
Pyra-Tech Feb 8, 2026
ad1634c
Added Blocking function on Steel Chastity Bra text, and added another…
Pyra-Tech Feb 8, 2026
3522aa8
Merge branch 'Enraa:main' into pyra_chastity
Pyra-Tech Feb 8, 2026
78e3429
Minor Grammar changes and update to Bra text
Pyra-Tech Feb 8, 2026
1b700ac
Merge branch 'pyra_chastity' of https://github.com/Pyra-Tech/Gagbot i…
Pyra-Tech Feb 8, 2026
7befd49
Merge branch 'main' into pyra_chastity
Pyra-Tech Feb 11, 2026
5d7466d
Added Defensive code to text checks
Pyra-Tech Feb 11, 2026
a3133dd
Small updates to Livingwood Belt. Testing completed without throwing …
Pyra-Tech Feb 11, 2026
aae4eb2
Changes ported to bra
Pyra-Tech Feb 11, 2026
6348f88
When the World Needed Release the most...
Pyra-Tech Feb 12, 2026
87090aa
Merge branch 'Enraa:main' into pyra_chastity
Pyra-Tech Feb 12, 2026
105123e
Minor Tweak to Earth to allow faster decay at low levels
Pyra-Tech Feb 12, 2026
f5a907f
Removed Console.log
Pyra-Tech Feb 12, 2026
c724edd
Merge branch 'Enraa:main' into pyra_chastity
Pyra-Tech Feb 12, 2026
a7e5c23
Seal Texts Stage 1
Pyra-Tech Feb 14, 2026
dde49bb
Seal Texts Stage 2
Pyra-Tech Feb 14, 2026
647c69c
Merge branch 'Enraa:main' into pyra_chastity
Pyra-Tech Feb 16, 2026
9bd4ee6
Corrected Livingwood logic to check for undefined values
Enraa Feb 17, 2026
f32f646
Merge branch 'pyra_chastity' of https://github.com/Pyra-Tech/Gagbot i…
Enraa Feb 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions chastity/belt/belt_livingwood.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
const { getUserVar, setUserVar } = require("../../functions/usercontext")
const { getChastityBra } = require("../../functions/vibefunctions.js");

// Livingwood Belt
// This belt has a higher growth coefficient. Notably however,
// it will increase it's minimum vibe to return the amount of failed orgasms
// or every 15 minutes, until the wearer successfully orgasms.
exports.growthCoefficient = (data) => { return 1 }
exports.decayCoefficient = (data) => { return 0.1 }
exports.minVibe = (data) => {
return Math.max(Math.min(Math.floor((Date.now() - (getUserVar(data.userID, "livingwoodbelt") ?? Date.now())) / 900000), 20), getUserVar(data.userID, "livingwoodvibe"))
// Never Fully Clear Arousal
exports.minArousal = (data) => { return 0.5 }
exports.minVibe = function(data) {
return Math.max(Math.min(Math.floor((Date.now() - (getUserVar(data.userID, "livingwood_chastity") ?? Date.now())) / 900000), 20), getUserVar(data.userID, "livingwood_vibe"))
}
// Note, we must use a regular function context to retrieve a this correctly.
exports.onOrgasm = function(data) {
setUserVar(data.userID, "livingwoodvibe", Math.max((this.minVibe(data) - 10), 0))
setUserVar(data.userID, "livingwoodbelt", Date.now());
exports.onOrgasm = (data) => {
setUserVar(data.userID, "livingwood_vibe", Math.max((this.minVibe(data) - 10), 0))
setUserVar(data.userID, "livingwood_chastity", Date.now());
}
exports.onFailedOrgasm = function(data) {
console.log(this);
setUserVar(data.userID, "livingwoodvibe", Math.min((this.minVibe(data) + 1), 20));
exports.onFailedOrgasm = (data) => {
//console.log(this);
setUserVar(data.userID, "livingwood_vibe", Math.min((this.minVibe(data) + 1), 20));
}
exports.onEquip = (data) => {
setUserVar(data.userID, "livingwoodvibe", 0);
setUserVar(data.userID, "livingwoodbelt", Date.now());
if (!getUserVar(data.userID, "livingwood_vibe") || getUserVar(data.userID, "livingwood_vibe") == undefined) setUserVar(data.userID, "livingwood_vibe", 0);
if (!getUserVar(data.userID, "livingwood_chastity") || getUserVar(data.userID, "livingwood_chastity") == undefined) setUserVar(data.userID, "livingwood_chastity", Date.now());
}
exports.onUnequip = (data) => {
setUserVar(data.userID, "livingwoodvibe", 0);
setUserVar(data.userID, "livingwoodbelt", Date.now());
// Check if user is wearing a Livingwood Bra otherwise Null Out Vars
if (!getChastityBra(data.userID)?.chastitytype != "bra_livingwood") {
setUserVar(data.userID, "livingwood_vibe", undefined);
setUserVar(data.userID, "livingwood_chastity", undefined);
}
}

// Tags
exports.tags = ["living"]

// Name
exports.name = "Livingwood Belt"
23 changes: 23 additions & 0 deletions chastity/belt/belt_seal_air.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { getUserVar, setUserVar } = require("../../functions/usercontext")
const { addArousal } = require("../../functions/vibefunctions")

// Seal of the Capricious Breeze
// This Seal randomly adds an amount of arousal between 0 and the Wearer's current value when orgasming
// No Increase to denial when worn
exports.denialCoefficient = (data) => { return 1 }
exports.growthCoefficient = (data) => { return 1.5 }
exports.decayCoefficient = (data) => { return 0.15 }

// Orgasm Cooldown randomised between 0 and 2x default
exports.orgasmCooldown = (data) => { return 2 * Math.random() }

// Events
// Randomly reduce the level of arousal by a random percentage, then reduce by a further 10%
exports.onOrgasm = (data) => {
addArousal(data.userID, data.prevArousal * Math.random() * 0.9);
}

// Tags
exports.tags = ["seal"]
// Name
exports.name = "Seal of the Capricious Breeze"
38 changes: 38 additions & 0 deletions chastity/belt/belt_seal_earth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { getUserVar, setUserVar } = require("../../functions/usercontext")
const { getArousal, addArousal } = require("../../functions/vibefunctions")

// Seal of the Unmoving Stone
// This Seal locks the user's arousal to within a small range of their current level. The Range shifts gradually as they remain above or below the median. Also doubles the Orgasm Cooldown
exports.growthCoefficient = (data) => { return 1 }
exports.decayCoefficient = (data) => { return 1 }
exports.orgasmCooldown = (data) => { return 2 }
exports.denialCoefficient = (data) => { return 1 }

// Set Min Arousal to be equal to the base Arousal + 5% when equipped
exports.minArousal = function(data) { return getUserVar(data.userID, "base_arousal") * 0.90}
exports.maxArousal = function(data) { return getUserVar(data.userID, "base_arousal") * 1.10}

// Events
exports.onOrgasm = (data) => {
// Maintain Arousal level and Increase Base Arousal to raise cap as the 'rock' jolts slightly forwards
addArousal(data.userID, getUserVar(data.userID, "base_arousal"));
setUserVar(data.userID, "base_arousal", getUserVar(data.userID, "base_arousal") * 1.1)
console.log(getUserVar(data.userID, "base_arousal"))
}
exports.afterArousalChange = (data) => {
// Earth only allows slow shifts in the arousal values regardless of vibe strength
if(getArousal(data.userID) > getUserVar(data.userID, "base_arousal")) setUserVar(data.userID, "base_arousal", Math.max(getUserVar(data.userID, "base_arousal") * 1.02, getUserVar(data.userID, "base_arousal") + 0.01))
else if(getArousal(data.userID) < getUserVar(data.userID, "base_arousal")) setUserVar(data.userID, "base_arousal", Math.max(Math.min(getUserVar(data.userID, "base_arousal") * 0.98, getUserVar(data.userID, "base_arousal") - 0.01), 0))
}
exports.onEquip = (data) => {
// Configure base arousal value
if (!getUserVar(data.userID, "base_arousal") || getUserVar(data.userID, "base_arousal") == undefined) setUserVar(data.userID, "base_arousal", getArousal(data.userID));
}
exports.onUnequip = (data) => {
setUserVar(data.userID, "base_arousal", undefined);
}

// Tags
exports.tags = ["seal"]
// Name
exports.name = "Seal of the Unmoving Stone"
34 changes: 34 additions & 0 deletions chastity/belt/belt_seal_fire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const { getUserVar, setUserVar } = require("../../functions/usercontext")
const { getArousal, addArousal } = require("../../functions/vibefunctions")

// Seal of the Ardent Flame
// This Seal locks the user's min arousal at their current level, and increases the growth coefficient along with reducing the decay rate. Also halves the Orgasm Cooldown
exports.growthCoefficient = (data) => { return 3 }
exports.decayCoefficient = (data) => { return 0.6 }
exports.orgasmCooldown = (data) => { return 0.5 }
exports.denialCoefficient = (data) => { return 1 }

// Set Min Arousal to be equal to the initial Arousal when equipped
exports.minArousal = function(data) { return getUserVar(data.userID, "base_arousal") }

// Events
exports.onOrgasm = (data) => {
// Reset Arousal to Base
addArousal(data.userID, getUserVar(data.userID, "base_arousal"));
}
exports.onFailedOrgasm = (data) => {
// Add a small amount of arousal with each failed attempt
addArousal(data.userID, 2 * Math.random());
}
exports.onEquip = (data) => {
// Configure base arousal value
if (!getUserVar(data.userID, "base_arousal") || getUserVar(data.userID, "base_arousal") == undefined) setUserVar(data.userID, "base_arousal", getArousal(data.userID));
}
exports.onUnequip = (data) => {
setUserVar(data.userID, "base_arousal", undefined);
}

// Tags
exports.tags = ["seal"]
// Name
exports.name = "Seal of the Ardent Flame"
38 changes: 38 additions & 0 deletions chastity/belt/belt_seal_ice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { getUserVar, setUserVar } = require("../../functions/usercontext")
const { getArousal, addArousal } = require("../../functions/vibefunctions")

// Seal of the Enduring Ice
// This Seal locks the user's max arousal at their current level + 5%, and decreases the growth coefficient along with increasing the decay rate. Also doubles the Orgasm Cooldown
exports.growthCoefficient = (data) => { return 0.5 }
exports.decayCoefficient = (data) => { return 0.1 }
exports.orgasmCooldown = (data) => { return 2 }
exports.denialCoefficient = (data) => { return 1 }

// Set Min Arousal to be equal to the base Arousal + 5% when equipped
exports.maxArousal = function(data) { return getUserVar(data.userID, "base_arousal") * 1.05}

// Events
exports.onOrgasm = (data) => {
// Decrease Base Arousal as the ice refreezes
setUserVar(data.userID, "base_arousal", getUserVar(data.userID, "base_arousal") * 0.5)
}
exports.onFailedOrgasm = (data) => {
// Remove a small amount of arousal with each failed attempt
addArousal(data.userID, -0.5);
}
exports.afterArousalChange = (data) => {
// Gradually raise the arousal cap as the ice slowly melts
if(getArousal(data.userID) > getUserVar(data.userID, "base_arousal")) setUserVar(data.userID, "base_arousal", getUserVar(data.userID, "base_arousal") * 1.001)
}
exports.onEquip = (data) => {
// Configure base arousal value
if (!getUserVar(data.userID, "base_arousal") || getUserVar(data.userID, "base_arousal") == undefined) setUserVar(data.userID, "base_arousal", getArousal(data.userID) ?? 5);
}
exports.onUnequip = (data) => {
setUserVar(data.userID, "base_arousal", undefined);
}

// Tags
exports.tags = ["seal"]
// Name
exports.name = "Seal of the Enduring Ice"
38 changes: 22 additions & 16 deletions chastity/bra/bra_livingwood.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
const { getUserVar, setUserVar } = require("../../functions/usercontext")
const { getChastity } = require("../../functions/vibefunctions.js");

// Livingwood Bra
// This bra has a higher growth coefficient. Notably however,
// it will increase it's minimum vibe to return the amount of failed orgasms
// or every 15 minutes, until the wearer successfully orgasms.
//
// This code is copied from chastity/belt/belt_livingwood.js and should be reviewed. Commented out for now.
/*

exports.growthCoefficient = (data) => { return 1 }
exports.decayCoefficient = (data) => { return 0.1 }
exports.minVibe = (data) => {
return Math.max(Math.min(Math.floor((Date.now() - (getUserVar(data.userID, "livingwoodbelt") ?? Date.now())) / 900000), 20), getUserVar(user, "livingwoodvibe"))
// Never Fully Clear Arousal
exports.minArousal = (data) => { return 0.5 }
exports.minVibe = function(data) {
return Math.max(Math.min(Math.floor((Date.now() - (getUserVar(data.userID, "livingwood_chastity") ?? Date.now())) / 900000), 20), getUserVar(data.userID, "livingwood_vibe"))
}
// Note, we must use a regular function context to retrieve a this correctly.
exports.onOrgasm = function(data) {
setUserVar(data.userID, "livingwoodvibe", Math.max((this.minVibe() - 10), 0))
setUserVar(data.userID, "livingwoodbelt", Date.now());
exports.onOrgasm = (data) => {
setUserVar(data.userID, "livingwood_vibe", Math.max((this.minVibe(data) - 10), 0))
setUserVar(data.userID, "livingwood_chastity", Date.now());
}
exports.onFailedOrgasm = function(data) {
setUserVar(data.userID, "livingwoodvibe", Math.min((this.minVibe() + 1), 20));
exports.onFailedOrgasm = (data) => {
//console.log(this);
setUserVar(data.userID, "livingwood_vibe", Math.min((this.minVibe(data) + 1), 20));
}
exports.onEquip = (data) => {
setUserVar(data.userID, "livingwoodvibe", 0);
setUserVar(data.userID, "livingwoodbelt", Date.now());
if (!getUserVar(data.userID, "livingwood_vibe") || getUserVar(data.userID, "livingwood_vibe") == undefined) setUserVar(data.userID, "livingwood_vibe", 0);
if (!getUserVar(data.userID, "livingwood_chastity") || getUserVar(data.userID, "livingwood_chastity") == undefined) setUserVar(data.userID, "livingwood_chastity", Date.now());
}
exports.onUnequip = (data) => {
setUserVar(data.userID, "livingwoodvibe", 0);
setUserVar(data.userID, "livingwoodbelt", Date.now());
}*/
// Check if user is wearing a Livingwood Belt otherwise Null Out Vars
if (!getChastity(data.userID)?.chastitytype != "belt_livingwood") {
setUserVar(data.userID, "livingwood_vibe", undefined);
setUserVar(data.userID, "livingwood_chastity", undefined);
}
}

// Tags
exports.tags = ["living"]
// Name
exports.name = "Livingwood Bra"

exports.tags = ["living"]
Loading