New Theresa NPC joins MagicSchoolFindsAround bringing a new Seraph wing asset with it | by Felix & Rosa & Tifa
|
|
@ -6889,6 +6889,19 @@ WingsDragonWingsSpread,Spread
|
|||
WingsDragonWingsFolded,Folded
|
||||
WingsDragonWingsBound,Bound
|
||||
WingsDragonWingsSelect,Select the state
|
||||
WingsSeraphWingsSelectBase,Toggle Wings
|
||||
WingsSeraphWingsSelectWing1,Wing 1
|
||||
WingsSeraphWingsSelectWing2,Wing 2
|
||||
WingsSeraphWingsSelectWing3,Wing 3
|
||||
WingsSeraphWingsModuleWing1,Wing 1
|
||||
WingsSeraphWingsModuleWing2,Wing 2
|
||||
WingsSeraphWingsModuleWing3,Wing 3
|
||||
WingsSeraphWingsOptionshow10,Show
|
||||
WingsSeraphWingsOptionshow11,Hide
|
||||
WingsSeraphWingsOptionshow20,Show
|
||||
WingsSeraphWingsOptionshow21,Hide
|
||||
WingsSeraphWingsOptionshow30,Show
|
||||
WingsSeraphWingsOptionshow31,Hide
|
||||
YourRoom,<i>Your private room</i>
|
||||
ZipBondageZipFeetFull,Full Binding
|
||||
ZipBondageZipFeetLight,Light Binding
|
||||
|
|
|
|||
|
Can't render this file because it is too large.
|
|
|
@ -171,3 +171,6 @@ ShoesZipperLeatherBootsLeft,Left
|
|||
ShoesZipperLeatherBootsRight,Right
|
||||
TailStrapsKitsuneTailStrapsTails,Tails
|
||||
TailStrapsKitsuneTailStrapsTips,Tips
|
||||
WingsSeraphWingsBases,Bases
|
||||
WingsSeraphWingsTips,Tips
|
||||
WingsSeraphWingsWings,Wings
|
||||
|
|
|
@ -2048,3 +2048,4 @@ Wings,SuccubusFeather,Succubus Feather
|
|||
Wings,SuccubusWings,Succubus Wings
|
||||
Wings,DragonWings,Dragon Wings
|
||||
Wings,Wing1,Low Bat Wings
|
||||
Wings,SeraphWings,Seraph Wings
|
||||
|
|
|
|||
|
|
|
@ -12866,7 +12866,15 @@ var AssetFemale3DCG = [
|
|||
Spread: 0,
|
||||
},
|
||||
Priority: 12,
|
||||
DefaultColor: ["#351C1C", "#351C1C", "#1C1111", "#1C1111", "#170E0E", "#170E0E", "#000000"],
|
||||
DefaultColor: [
|
||||
"#351C1C",
|
||||
"#351C1C",
|
||||
"#1C1111",
|
||||
"#1C1111",
|
||||
"#170E0E",
|
||||
"#170E0E",
|
||||
"#000000",
|
||||
],
|
||||
Layer: [
|
||||
{
|
||||
Name: "UpperSocks",
|
||||
|
|
@ -24120,6 +24128,499 @@ var AssetFemale3DCG = [
|
|||
License: "CC BY-SA-NC 4.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "SeraphWings",
|
||||
InventoryID: 2302,
|
||||
DefaultColor: [],
|
||||
Value: -1,
|
||||
BodyCosplay: true,
|
||||
PoseMapping: {
|
||||
...AssetPoseMapping.Wings,
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
Layer: [
|
||||
{
|
||||
Name: "Base1",
|
||||
ColorGroup: "Bases",
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 101,
|
||||
AllFours: 140,
|
||||
Hogtied: 140,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 175,
|
||||
AllFours: 60,
|
||||
Hogtied: 60,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "Base2",
|
||||
ColorGroup: "Bases",
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 97,
|
||||
AllFours: 130,
|
||||
Hogtied: 130,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 243,
|
||||
AllFours: 28,
|
||||
Hogtied: 28,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "Base3",
|
||||
ColorGroup: "Bases",
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 89,
|
||||
AllFours: 145,
|
||||
Hogtied: 145,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 379,
|
||||
AllFours: 30,
|
||||
Hogtied: 30,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show3: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase1",
|
||||
ColorGroup: "Wings",
|
||||
Priority: 50,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 28,
|
||||
AllFours: 40,
|
||||
Hogtied: 40,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 170,
|
||||
AllFours: 50,
|
||||
Hogtied: 50,
|
||||
},
|
||||
PoseMapping: {
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: PoseType.HIDE,
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase1Extra1",
|
||||
CopyLayerColor: "WingBase1",
|
||||
Left: 28,
|
||||
Top: 170,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: "OverTheHead",
|
||||
Yoked: PoseType.HIDE,
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase1Extra2",
|
||||
CopyLayerColor: "WingBase1",
|
||||
Priority: 54,
|
||||
Left: 28,
|
||||
Top: 170,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: "OverTheHead",
|
||||
Yoked: "OverTheHead",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase1Extra3",
|
||||
CopyLayerColor: "WingBase1",
|
||||
Priority: 54,
|
||||
Left: 28,
|
||||
Top: 170,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: "Yoked",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase2",
|
||||
ColorGroup: "Wings",
|
||||
Priority: 50,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 308,
|
||||
AllFours: 260,
|
||||
Hogtied: 260,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 170,
|
||||
AllFours: 50,
|
||||
Hogtied: 50,
|
||||
},
|
||||
PoseMapping: {
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: PoseType.HIDE,
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase2Extra1",
|
||||
CopyLayerColor: "WingBase2",
|
||||
Left: 308,
|
||||
Top: 170,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: "OverTheHead",
|
||||
Yoked: PoseType.HIDE,
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase2Extra2",
|
||||
CopyLayerColor: "WingBase2",
|
||||
Priority: 54,
|
||||
Left: 308,
|
||||
Top: 170,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: "OverTheHead",
|
||||
Yoked: "OverTheHead",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase2Extra3",
|
||||
CopyLayerColor: "WingBase2",
|
||||
Priority: 54,
|
||||
Left: 308,
|
||||
Top: 170,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: "Yoked",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase3",
|
||||
ColorGroup: "Wings",
|
||||
Priority: 49,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 1,
|
||||
AllFours: 34,
|
||||
Hogtied: 34,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 238,
|
||||
AllFours: 27,
|
||||
Hogtied: 27,
|
||||
},
|
||||
PoseMapping: {
|
||||
Yoked: PoseType.HIDE,
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase3Extra1",
|
||||
CopyLayerColor: "WingBase3",
|
||||
Left: 1,
|
||||
Top: 238,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: "Yoked",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase3Extra2",
|
||||
CopyLayerColor: "WingBase3",
|
||||
Priority: 52,
|
||||
Left: 1,
|
||||
Top: 238,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: "Yoked",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase4",
|
||||
ColorGroup: "Wings",
|
||||
Priority: 49,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 267,
|
||||
AllFours: 260,
|
||||
Hogtied: 260,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 240,
|
||||
AllFours: 30,
|
||||
Hogtied: 30,
|
||||
},
|
||||
PoseMapping: {
|
||||
Yoked: PoseType.HIDE,
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase4Extra1",
|
||||
CopyLayerColor: "WingBase4",
|
||||
Left: 267,
|
||||
Top: 240,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: "Yoked",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase4Extra2",
|
||||
CopyLayerColor: "WingBase4",
|
||||
Priority: 52,
|
||||
Left: 267,
|
||||
Top: 240,
|
||||
PoseMapping: {
|
||||
AllFours: PoseType.HIDE,
|
||||
BackBoxTie: PoseType.HIDE,
|
||||
BackCuffs: PoseType.HIDE,
|
||||
BackElbowTouch: PoseType.HIDE,
|
||||
BaseUpper: PoseType.HIDE,
|
||||
Hogtied: PoseType.HIDE,
|
||||
OverTheHead: PoseType.HIDE,
|
||||
Yoked: "Yoked",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase5",
|
||||
ColorGroup: "Wings",
|
||||
Priority: 48,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 22,
|
||||
AllFours: 58,
|
||||
Hogtied: 58,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 375,
|
||||
AllFours: 28,
|
||||
Hogtied: 28,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show3: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingBase6",
|
||||
ColorGroup: "Wings",
|
||||
Priority: 48,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 292,
|
||||
AllFours: 260,
|
||||
Hogtied: 260,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 375,
|
||||
AllFours: 30,
|
||||
Hogtied: 30,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show3: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingTip1",
|
||||
ColorGroup: "Tips",
|
||||
Priority: 55,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 28,
|
||||
AllFours: 40,
|
||||
Hogtied: 40,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 260,
|
||||
AllFours: 130,
|
||||
Hogtied: 130,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingTip2",
|
||||
ColorGroup: "Tips",
|
||||
Priority: 55,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 259,
|
||||
AllFours: 341,
|
||||
Hogtied: 341,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 266,
|
||||
AllFours: 140,
|
||||
Hogtied: 140,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show1: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingTip3",
|
||||
ColorGroup: "Tips",
|
||||
Priority: 53,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 0,
|
||||
AllFours: 34,
|
||||
Hogtied: 34,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 376,
|
||||
AllFours: 131,
|
||||
Hogtied: 131,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingTip4",
|
||||
ColorGroup: "Tips",
|
||||
Priority: 53,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 204,
|
||||
AllFours: 336,
|
||||
Hogtied: 336,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 364,
|
||||
AllFours: 134,
|
||||
Hogtied: 134,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show2: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingTip5",
|
||||
ColorGroup: "Tips",
|
||||
Priority: 51,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 22,
|
||||
AllFours: 55,
|
||||
Hogtied: 55,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 491,
|
||||
AllFours: 130,
|
||||
Hogtied: 130,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show3: 0 },
|
||||
},
|
||||
{
|
||||
Name: "WingTip6",
|
||||
ColorGroup: "Tips",
|
||||
Priority: 51,
|
||||
Left: {
|
||||
[PoseType.DEFAULT]: 232,
|
||||
AllFours: 330,
|
||||
Hogtied: 330,
|
||||
},
|
||||
Top: {
|
||||
[PoseType.DEFAULT]: 499,
|
||||
AllFours: 132,
|
||||
Hogtied: 132,
|
||||
},
|
||||
PoseMapping: {
|
||||
AllFours: "AllFours",
|
||||
Hogtied: "AllFours",
|
||||
},
|
||||
AllowTypes: { show3: 0 },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
Color: [
|
||||
"Default",
|
||||
|
|
|
|||
|
|
@ -22177,6 +22177,38 @@ var AssetFemale3DCGExtended = {
|
|||
},
|
||||
],
|
||||
}, // SteampunkWings
|
||||
SeraphWings: {
|
||||
Archetype: ExtendedArchetype.MODULAR,
|
||||
Modules: [
|
||||
{
|
||||
Name: "Wing1",
|
||||
Key: "show1",
|
||||
DrawImages: false,
|
||||
Options: [
|
||||
{}, //show1_0 - Show
|
||||
{}, //show1_1 - Hide
|
||||
],
|
||||
},
|
||||
{
|
||||
Name: "Wing2",
|
||||
Key: "show2",
|
||||
DrawImages: false,
|
||||
Options: [
|
||||
{}, //show2_0 - Show
|
||||
{}, //show2_1 - Hide
|
||||
],
|
||||
},
|
||||
{
|
||||
Name: "Wing3",
|
||||
Key: "show3",
|
||||
DrawImages: false,
|
||||
Options: [
|
||||
{}, //show3_0 - Show
|
||||
{}, //show3_1 - Hide
|
||||
],
|
||||
},
|
||||
],
|
||||
}, // SeraphWings
|
||||
DragonWings: {
|
||||
Archetype: ExtendedArchetype.TYPED,
|
||||
DrawImages: true,
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ interface AssetGroupDefinitionBase extends AssetCommonPropertiesGroupAsset, Asse
|
|||
MirrorActivitiesFrom?: AssetGroupItemName;
|
||||
|
||||
/**
|
||||
* The group actually recieving arousal events
|
||||
* The group actually receiving arousal events
|
||||
*
|
||||
* Used to proxy around a group that does not have activities
|
||||
* enabled (and thus arousal settings.
|
||||
|
|
@ -939,7 +939,7 @@ interface ExtendedItemConfig<OptionType extends ExtendedItemOption> {
|
|||
/** A record containing various dialog keys used by the extended item screen */
|
||||
DialogPrefix?: ExtendedItemCapsDialog<any, OptionType>;
|
||||
/**
|
||||
* A recond containing functions that are run on load, click, draw, exit, and validate, with the original archetype function
|
||||
* A record containing functions that are run on load, click, draw, exit, and validate, with the original archetype function
|
||||
* and parameters passed on to them. If undefined, these are ignored.
|
||||
* Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`.
|
||||
*/
|
||||
|
|
@ -1140,7 +1140,7 @@ interface TypedItemConfig extends ExtendedItemConfig<TypedItemOption> {
|
|||
*/
|
||||
ChangeWhenLocked?: boolean;
|
||||
/**
|
||||
* A recond containing functions that are run on load, click, draw, exit, validate and publishaction,
|
||||
* A record containing functions that are run on load, click, draw, exit, validate and publishaction,
|
||||
* with the original archetype function and parameters passed on to them. If undefined, these are ignored.
|
||||
* Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`.
|
||||
*/
|
||||
|
|
@ -1195,7 +1195,7 @@ interface ModularItemConfig extends ExtendedItemConfig<ModularItemOption> {
|
|||
Chat?: string | ExtendedItemChatCallback<ModularItemOption>;
|
||||
};
|
||||
/**
|
||||
* A recond containing functions that are run on load, click, draw, exit, and validate, with the original archetype function
|
||||
* A record containing functions that are run on load, click, draw, exit, and validate, with the original archetype function
|
||||
* and parameters passed on to them. If undefined, these are ignored.
|
||||
* Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3684,3 +3684,18 @@ WingsDragonWingsBuckles,Binding buckles
|
|||
WingsDragonWingsStraps,Binding straps
|
||||
WingsWing1WingBone,Wing Bone
|
||||
WingsWing1WingMembrane,Wing Membrane
|
||||
WingsSeraphWingsBase1,Base1
|
||||
WingsSeraphWingsBase2,Base2
|
||||
WingsSeraphWingsBase3,Base3
|
||||
WingsSeraphWingsWingBase1,Wing Base1
|
||||
WingsSeraphWingsWingBase2,Wing Base2
|
||||
WingsSeraphWingsWingBase3,Wing Base3
|
||||
WingsSeraphWingsWingBase4,Wing Base4
|
||||
WingsSeraphWingsWingBase5,Wing Base5
|
||||
WingsSeraphWingsWingBase6,Wing Base6
|
||||
WingsSeraphWingsWingTip1,Wing Tip1
|
||||
WingsSeraphWingsWingTip2,Wing Tip2
|
||||
WingsSeraphWingsWingTip3,Wing Tip3
|
||||
WingsSeraphWingsWingTip4,Wing Tip4
|
||||
WingsSeraphWingsWingTip5,Wing Tip5
|
||||
WingsSeraphWingsWingTip6,Wing Tip6
|
||||
|
|
|
|||
|
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 105 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/Preview/SeraphWings.png
Normal file
|
After Width: | Height: | Size: 427 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_Base1.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_Base2.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_Base3.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingBase1.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingBase2.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingBase3.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingBase4.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingBase5.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingBase6.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingTip1.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingTip2.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingTip3.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingTip4.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingTip5.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
BondageClub/Assets/Female3DCG/Wings/SeraphWings_WingTip6.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 90 KiB |
BIN
BondageClub/Icons/Castle.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
BondageClub/Icons/Flower.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
|
|
@ -3,7 +3,7 @@ ClubCardVictory,0,,"Good work~ you have potential to be a great player, enjoy yo
|
|||
ClubCardDefeat,,,Now time for my reward: [~More Coming Soon~],,
|
||||
BattleSuccess,70,,"(She looks at you with hate in her eyes, but you can feel some weakness behind her bravado)",,
|
||||
BattleFail,70,,Now time for my reward~,,
|
||||
CompleteQuestRelief,,,"Finally! I can feel the essence you gathered. Good Work~ ",,
|
||||
CompleteQuestRelief,,,"Finally! I can feel the essence you gathered. Good work~ ",,
|
||||
0,,,(Her predatory gaze locks onto you as her nine tails swaying lazily behind her.) “Welcome~”,,
|
||||
0,5,Who are you?,"(She smiles softly, though something dangerous lurks behind it.) “My name is Daji. I’m a kitsune… and I’ve been waiting for someone like you~”",,
|
||||
0,30,Do you play club cards?,I enjoy them~ but if you want to play be ready~ I always play for something ,,
|
||||
|
|
@ -11,21 +11,21 @@ CompleteQuestRelief,,,"Finally! I can feel the essence you gathered. Good Work~
|
|||
5,10,What you want from me?,"“I have a task just for you.” (A glint of hunger flickers in her eyes.) “Collect the essence of nine students and bring it to me.”",,
|
||||
10,15,And what's in it for me?,I will grand you some of kitsune powers,,
|
||||
10,20,Forget it,You will regret this! (She gets ready to fight.),,
|
||||
15,95,I will do it,Good~ then I will wait for you here.,StartQuest(),
|
||||
15,95,I will do it,Good~ then I will wait for you here.,KitsuneStartQuest(),
|
||||
15,20,Forget it,"(Her ears flatten, power crackling around her.) “Oh… you stupid little thing.”",,
|
||||
20,90,(Run away),"Oh, you came back?",RunAway()
|
||||
20,,(Fight her),,MagicBattleStart()
|
||||
30,35,What are the stakes?,"If you win I will give you a card, but if you lose... I will tie you up and enjoy myself~",,
|
||||
30,35,What are the stakes?,"If you win I will give you a card, but if you lose… I will tie you up and enjoy myself~",,
|
||||
35,,Let's play.,,ClubCardStart()
|
||||
35,0,I dont want to risk,Shame~,,
|
||||
70,110,(Reach for her power),"(You sense the weakness she hides and reach for it. Slowly, irresistibly, her power flows into you. She resists, but it is in vain. At last, she lies spent on the ground… and her power is yours.) [(~Kitsune tails unlocked~)]",GiveTails(),
|
||||
70,110,(Reach for her power),"(You sense the weakness she hides and reach for it. Slowly, irresistibly, her power flows into you. She resists, but it is in vain. At last, she lies spent on the ground… and her power is yours.) [(~Kitsune tails unlocked~)]",GiveTails(),
|
||||
90,,(Fight her),"(Her ears flatten, power crackling around her.) “Oh… you stupid little thing.”",MagicBattleStart(),
|
||||
90,95,Wait! I want to work with you!,"(She smiles, clearly pleased.) “I knew you’d make the right decision~”",StartQuest(),
|
||||
95,100,How I'm supposed to do this?,"Go back to school, after you defeat students, when they are bound and helpless, use this spell. (She teaches you a spell to drain essence)",StartQuest(),"QuestStarted()"
|
||||
100,,(Leave for School),"How long I need to wait? You are still missing LEFTDEFEATCOUNT students to defeat!!!",RunAway(),"!QuestCompleted()"
|
||||
100,105,I did it!,"“Good work~” (A soft pink fog envelops you as she leans closer, her lips brushing your skin.) “Come… I will share secrets of my power~” (You hear her whisper and everything goes dark)",,"QuestCompleted()"
|
||||
90,95,Wait! I want to work with you!,"(She smiles, clearly pleased.) “I knew you’d make the right decision~”",KitsuneStartQuest(),
|
||||
95,100,How I'm supposed to do this?,"Go back to school, after you defeat students, when they are bound and helpless, use this spell. (She teaches you a spell to drain essence)",KitsuneStartQuest(),"KitsuneQuestStarted()"
|
||||
100,,(Leave for School),"How long I need to wait? You are still missing LEFTDEFEATCOUNT students to defeat!!!",RunAway(),"!KitsuneQuestCompleted()"
|
||||
100,105,I did it!,"“Good work~” (A soft pink fog envelops you as she leans closer, her lips brushing your skin.) “Come… I will share secrets of my power~” (You hear her whisper and everything goes dark)",,"KitsuneQuestCompleted()"
|
||||
105,130,(You look around), Daji is nowhere to be seen. You’re alone… yet you can feel your new power dwelling inside… and ready to be unleashed… [(~Kitsune tails unlocked~)],KitsuneDisappear(),
|
||||
110,0,(Leave with your new powers),,RunAwayEnd()
|
||||
105,130,(You look around), Daji is nowhere to be seen. You’re alone… yet you can feel your new power dwelling inside... and ready to be unleashed... [(~Kitsune tails unlocked~)],HideNPC(),
|
||||
130,0,(Leave with your new powers),,RunAwayEnd()
|
||||
200,210,(Struggle and test your bondage.),(She smiles and removes your gag.) You're cute when you struggle. I won't let you go that easily.,UngagPlayer(0),
|
||||
200,210,(Bow your head and whimper silently.),(She smirks and removes your gag.) Such a cute subbie in bondage. I won't let you go easily.,UngagPlayer(-3),
|
||||
|
|
@ -49,7 +49,7 @@ SpellHogtie,,I need to master that spell.,,LoserSpell(0),
|
|||
SpellHogtie,,This is tight!,,LoserSpell(0),
|
||||
SpellHogtie,,(Struggle playfully.),,LoserSpell(0),
|
||||
SpellReleaseHogtieIntro,,,"(After many incantations, she successfully releases you from your hogtie, using her magic.)",,
|
||||
SpellReleaseHogtie,,Thanks... I guess.,,LoserSpell(0),
|
||||
SpellReleaseHogtie,,Thanks… I guess.,,LoserSpell(0),
|
||||
SpellReleaseHogtie,,Will you release me now?,,LoserSpell(0),
|
||||
SpellFlyingHogtieIntro,,,"(She summons the spirits of bondage. You slowly start to move in the air in your hogtie. Going up and down, floating and helpless.)",,
|
||||
SpellFlyingHogtie,,Weeeeeeeee!,,LoserSpell(0),
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 10.
|
|
|
@ -0,0 +1,38 @@
|
|||
PlayerGagged,,,"(She smiles as she sees you gagged) My my, it seems like you had some fun dear. Mhm! But I can't understand you like this",,
|
||||
TooRude,,,Seems like you're not as nice as I thought!,
|
||||
TooRudeRepeat,,,Seems like you don't even learn from your previous mistakes,
|
||||
0,,,"(As you stroll through the garden, a woman appears and waves at you)",,!TheresaQuestStarted()
|
||||
0,,,"Don't know what to do? oh you silly, go to Maid Quarters and offer your help with chores, help with 6 rescue missions and return to me",,TheresaQuestIsOngoing()
|
||||
0,,,"(On the place where the nun was, an angel now stands, looking at you)",,TheresaQuestCompleted()
|
||||
0,5,Let me try again,"Alright, let's see if you improved…~",,TheresaBeenRudeBefore()
|
||||
0,5,(Walk to the woman.),"Hello there dear, I am Theresa. So very nice to meet you!",,TheresaFirstMet()
|
||||
0,22,"I've helped someone!","Oh, I'm glad to hear that. But a little birdie tells me there's still REMAINING people to help!",,TheresaQuestIsOngoing()
|
||||
0,30,(You walk to the new girl.),"Oh welcome there cutie, you did what I asked?",,TheresaQuestCompleted()
|
||||
0,100,"Hello? Theresa?","Oh! Welcome back DialogPlayerName, how have you been~ I hope you're enjoying my gift~",,TheresaTimerUp()
|
||||
0,100,Where have you been?,,TheresaGiveBadWordPoint(""100""),TheresaTimerUp()
|
||||
0,,(Leave her.),,DialogLeave(),
|
||||
|
||||
5,10,"Hello, nice to meet you too.","Hehe, you seem really sweet. I have a small favor to ask… and there might be something in it for you.",,
|
||||
5,10,Why do you look so strange?,"I do? I'm from... somewhere far away... but since we met here, can you help me with something?",TheresaGiveBadWordPoint(""5""),
|
||||
5,,"Nevermind, bye. (Leave her.)",,DialogLeave(),
|
||||
|
||||
10,20,"Sure, what would the favor be?",Can you help six people for me? I got lost in here and my time ran out so would you be so kind?,TheresaStartQuest(),
|
||||
10,11,"Sounds suspicious, what do I get?","What is suspicious about helping others? And why should I spoil the fun! So… will you help me or not?",TheresaGiveBadWordPoint(""10""),
|
||||
11,20,Okay I will help you.,"Okay then come back after you helped six different people, I heard the maids are always searching for helping hands~",TheresaStartQuest(),
|
||||
11,12,"No, I only help when I know what is in it for me.",And I should spoil the mystery?,TheresaGiveBadWordPoint(""15""),
|
||||
12,20,So how can I help you?,"Okay then come back after you helped six different people, I heard the maids always search for helping hands~",TheresaStartQuest(""bad""),
|
||||
12,20,"Okay, Okay, what do you need?","Could you help six different people out, I heard the maids are always looking for some helping hands~",TheresaStartQuest(),
|
||||
|
||||
20,21,On my way,"Thank you so much! I'll be waiting for you here.",
|
||||
21,22,"(You sigh) Okay, I guess I'll be back soon…","Thank you for your time!",
|
||||
22,0,(You leave),(Leave.),DialogLeave(),
|
||||
|
||||
30,33,I like to help where I can.,"You did well! I am proud of you, let me reward you… (A bright light shines from above, bathing you in. You feel a warm power grow in you). You deserve this gift.",TheresaGiveGift(),
|
||||
30,33,Wait… Who are you?,"I am still Theresa. You did well! I am proud of you, (She smiles and you recognise that smile, its really Theresa!)",TheresaGiveGift(),
|
||||
33,34,What happened?,"You proven worthy to see my true form, but my time is short, please accept your gift ( A bright light shines upon you, you close your eyes enjoying the warmth gently enveloping you, it feels almost like a tender hug)"
|
||||
34,35,(Open your eyes),"(You look around but Theresa is nowhere to be seen, you are alone but her warmth is still with you. You have a feeling you will be seeing her again)",HideTheresa(),
|
||||
35,100,(Leave with your new gift.),,DialogLeave(),
|
||||
|
||||
100,,,I may have another task for you [~More Coming Soon~],,
|
||||
|
||||
LandingPage,DestinationPage,ButtonText,NpcAnswer,CommandToHappen(),PrerequisiteCheck()
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -1,23 +1,39 @@
|
|||
"use strict";
|
||||
var MagicSchoolFindsAroundBackground = "ForestPath";
|
||||
var MagicSchoolFindsAroundBackground = "Castle";
|
||||
/** @type {"" | "Garden" | "Forest"} */
|
||||
var MagicSchoolFindsAroundArea = "";
|
||||
/** @type {NPCCharacter} */
|
||||
// This cursed thing is because I can't use @ts-expect-error here, as non-strict TS flags it
|
||||
// but not doing that causes 30 strictness errors
|
||||
var MagicSchoolFindsAroundKitsune = /** @type {NPCCharacter} */ (/** @type {unknown} */ (null));
|
||||
var MagicSchoolFindsAroundKitsune = /** @type {never} */ (null);
|
||||
/** @type {NPCCharacter} */
|
||||
var MagicSchoolFindsAroundTheresa = /** @type {never} */ (null);
|
||||
var MagicSchoolFindsAroundSpellCount = 0;
|
||||
var MagicSchoolFindsAroundLastSpell = "";
|
||||
/** @type {MagicSchoolSpell | undefined} */
|
||||
var MagicSchoolFindsAroundLastSpell;
|
||||
//Angel Nun variables
|
||||
var AngelNunOutfit = "";
|
||||
var CurrentAngelNunName = "Therese";
|
||||
var CurrentAngelNunStage = "0";
|
||||
/** @satisfies {Record<string, RectTuple>} */
|
||||
var MagicSchoolFindsAroundButtons = ({
|
||||
exit: [1885, 25, 90, 90],
|
||||
profile: [1885, 145, 90, 90],
|
||||
goToGarden: [1885, 265, 90, 90],
|
||||
goToForest: [1885, 385, 90, 90],
|
||||
soloCharacter: [750, 0, 500, 1000],
|
||||
dualCharacterFirst: [500, 0, 500, 1000],
|
||||
dualCharacterSecond: [1000, 0, 500, 1000],
|
||||
});
|
||||
|
||||
/**
|
||||
* Uncompress a string containing an appearance, then applies that appearance data to the NPC
|
||||
* @param {NPCCharacter} C - The NPC character that loads its new appearance
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundPrepareFoundNPC(C) {
|
||||
function MagicSchoolFindsAroundDressUpKitsune(C) {
|
||||
|
||||
CharacterNaked(C, false);
|
||||
CharacterRelease(C, false);
|
||||
|
||||
// BASE APPEARANCE
|
||||
InventoryWear(C, "EchoV2", "BodyStyle", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyebrows1", "Eyebrows", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "NoEars", "Head", undefined, undefined, undefined, undefined, false);
|
||||
|
|
@ -79,21 +95,120 @@ function MagicSchoolFindsAroundPrepareFoundNPC(C) {
|
|||
CharacterRefresh(C);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uncompress a string containing an appearance, then applies that appearance data to the NPC
|
||||
* @param {NPCCharacter} C - The NPC character that loads its new appearance
|
||||
* @param {"Angel" | "Nun"} outfit - The outfit to use
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundDressUpTheresa(C, outfit) {
|
||||
|
||||
CharacterNaked(C, false);
|
||||
CharacterRelease(C, false);
|
||||
|
||||
switch (outfit) {
|
||||
case "Angel": {
|
||||
InventoryWear(C, "Original", "BodyStyle", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyebrows1", "Eyebrows", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Default", "Head", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Normal", "BodyLower", "White", undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "XLarge", "BodyUpper", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "H0900", "Height", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Regular", "Mouth", ["#A68096", "Default"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "HairBack80", "HairBack", ["#DCBB19", "#7486C7", "#3D3D81", "#524ABB"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "HairFront64", "HairFront", ["#DCBB19", "#67B3B1"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyes11", "Eyes", ["#7EDBE3"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyes11", "Eyes2", ["#3645BA"], undefined, undefined, undefined, false);
|
||||
|
||||
// Angel accessories and clothing
|
||||
InventoryWear(C, "Panties14", "Panties", ["#CBE9E6"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "SleevelessSlimLatexLeotard", "Bra", ["#A4A4A4"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "RuffledSkirt", "ClothLower", ["#898989"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Stockings2", "Socks", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "SeraphWings", "Wings", ["#868383", "#868383", "#868383", "#868383", "#868383", "#868383", "#868383", "#868383", "#868383", "#969797", "#969797", "#969797", "#969797", "#969797", "#969797"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "ShoulderlessTop", "Cloth", ["#828282"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "TightCorset", "Corset", ["#D9D9D9", "#ADADAD"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "FaceScars", "BodyMarkings", ["#EEE08C"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "BodyChainNecklace", "Necklace", ["#D2B51A", "#D2B51A"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "WitchShawl", "ClothAccessory", ["#B0B5FF", "#B0B5FF", "#B0B5FF", "#B0B5FF", "#B0B5FF", "#B0B5FF", "#B0B5FF"], undefined, undefined, undefined, false);
|
||||
|
||||
// HALO
|
||||
const halo = InventoryWear(C, "Halo", "HairAccessory1", ["#FDF8EE", "#FFEB87", "#FFD800"], undefined, undefined, undefined, false);
|
||||
if (halo) {
|
||||
halo.Property ??= {};
|
||||
Object.assign(halo.Property, { Opacity: 0.85});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "Nun": {
|
||||
InventoryWear(C, "EchoV2", "BodyStyle", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyebrows1", "Eyebrows", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Default", "Head", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Normal", "BodyLower", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Large", "BodyUpper", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "H0940", "Height", undefined, undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Regular", "Mouth", ["#BE737E", "Default"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "HairBack76b", "HairBack", ["#5A1D1D"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "HairFront25", "HairFront", ["#5A1D1D"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyes11", "Eyes", ["#7EDBE3"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Eyes11", "Eyes2", ["#3645BA"], undefined, undefined, undefined, false);
|
||||
|
||||
// Angel accessories and clothing
|
||||
InventoryWear(C, "StringPasty1", "Panties", ["#181818"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "StrapBra", "Bra", ["#2B2B2B"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "LongFishnets", "Socks", ["#121212"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Socks5", "SocksLeft", ["#222222"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Socks5", "SocksRight", ["#222222"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "NunRobes", "Cloth", ["#494949", "Default", "Default", "#424242"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Corset1", "Corset", ["#1C1C1C"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Glitter", "Mask", ["#E3C6B6", "#E3C6B6"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "AnkleStrapShoes", "Shoes", ["#381717"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "NunVeil", "Hat", ["Default", "#343434", "#515151"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Gloves2", "Gloves", ["#222222"], undefined, undefined, undefined, false);
|
||||
InventoryWear(C, "Wings", "EyeShadow", ["#919F9E", "#131313"], undefined, undefined, undefined, false);
|
||||
|
||||
// JEWEL
|
||||
const jewel = InventoryWear(C, "JewelrySet", "Jewelry", ["#908B3A", "#908B3A", "#908B3A"], undefined, undefined, undefined, false);
|
||||
if (jewel) {
|
||||
jewel.Property ??= {};
|
||||
Object.assign(jewel.Property, { TypeRecord: {e: 3, a: 3, n: 0, f: 0} });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CharacterRefresh(C);
|
||||
}
|
||||
|
||||
// #region Screen management
|
||||
|
||||
/**
|
||||
* Loads the magic school finds around screen and the NPC
|
||||
* @type {ScreenLoadHandler}
|
||||
*/
|
||||
async function MagicSchoolFindsAroundLoad() {
|
||||
if (MagicSchoolFindsAroundKitsune == null) {
|
||||
// Load Kitsune NPC and prepare her appearance
|
||||
MagicSchoolFindsAroundKitsune = CharacterLoadNPC("NPC_MagicSchoolFindsAround_Kitsune");
|
||||
MagicSchoolFindsAroundPrepareFoundNPC(MagicSchoolFindsAroundKitsune);
|
||||
MagicSchoolFindsAroundDressUpKitsune(MagicSchoolFindsAroundKitsune);
|
||||
// FIXME: janky wait to make sure the dialog's done loading
|
||||
await CommonWaitFor(() => MagicSchoolFindsAroundKitsune.Dialog.length !== 0);
|
||||
MagicSchoolFindsAroundKitsune.LabelColor = "#4E1313";
|
||||
MagicSchoolFindsAroundKitsune.AllowItem = false;
|
||||
MagicSchoolFindsAroundKitsune.Name = "Daji";
|
||||
MagicSchoolFindsAroundKitsune.Stage = "0";
|
||||
delete MagicSchoolFindsAroundKitsune.FixedImage;
|
||||
MagicSchoolFindsAroundKitsuneQuestUpdate();
|
||||
}
|
||||
MagicSchoolLaboratoryKitsuneQuestUpdate();
|
||||
|
||||
if (MagicSchoolFindsAroundTheresa == null) {
|
||||
MagicSchoolFindsAroundTheresa = CharacterLoadNPC("NPC_MagicSchoolFindsAround_Theresa");
|
||||
// FIXME: janky wait to make sure the dialog's done loading
|
||||
await CommonWaitFor(() => MagicSchoolFindsAroundTheresa.Dialog.length !== 0);
|
||||
MagicSchoolFindsAroundTheresa.LabelColor = "#5FEBE8";
|
||||
MagicSchoolFindsAroundTheresa.AllowItem = false;
|
||||
}
|
||||
|
||||
MagicSchoolFindsAroundTheresaQuestUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -101,11 +216,51 @@ async function MagicSchoolFindsAroundLoad() {
|
|||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundRun() {
|
||||
// Draw the background and the characters
|
||||
DrawCharacter(Player, 500, 0, 1);
|
||||
DrawCharacter(MagicSchoolFindsAroundKitsune, 1000, 0, 1);
|
||||
DrawButton(1885, 25, 90, 90, "", Player.CanWalk() ? "White" : "Pink", "Icons/Exit.png", TextGet("Exit"));
|
||||
DrawButton(1885, 145, 90, 90, "", "White", "Icons/Character.png", TextGet("Profile"));
|
||||
if (MagicSchoolFindsAroundArea === "") {
|
||||
/** @type {RectTuple} */
|
||||
const introRect = [100, 800, 1782, 200];
|
||||
DrawTextWrap(TextGet("ScreenIntro"), ...(RectGetFrame(RectOffset(RectMakeRect(...introRect), 2, 2))), "Black");
|
||||
DrawTextWrap(TextGet("ScreenIntro"), ...introRect, "White");
|
||||
}
|
||||
DrawButton(...MagicSchoolFindsAroundButtons.exit, "", Player.CanWalk() ? "White" : "Pink", "Icons/Exit.png", TextGet("Exit"));
|
||||
DrawButton(...MagicSchoolFindsAroundButtons.profile, "", "White", "Icons/Character.png", TextGet("Profile"));
|
||||
if (MagicSchoolFindsAroundArea === "") {
|
||||
DrawButton(...MagicSchoolFindsAroundButtons.goToGarden, "", "White", "Icons/Flower.png", TextGet("GoToGarden"));
|
||||
DrawButton(...MagicSchoolFindsAroundButtons.goToForest, "", "White", "Icons/Tree.png", TextGet("GoToForest"));
|
||||
} else if (MagicSchoolFindsAroundArea == "Forest") {
|
||||
if (MagicSchoolFindsAroundKitsune) {
|
||||
DrawCharacter(Player, ...RectGetOrigin(MagicSchoolFindsAroundButtons.dualCharacterFirst), 1);
|
||||
DrawCharacter(MagicSchoolFindsAroundKitsune, ...RectGetOrigin(MagicSchoolFindsAroundButtons.dualCharacterSecond), 1);
|
||||
}
|
||||
} else if (MagicSchoolFindsAroundArea == "Garden") {
|
||||
if (MagicSchoolFindsAroundTheresa && !MagicSchoolFindsAroundTheresaVanished()) {
|
||||
DrawCharacter(Player, ...RectGetOrigin(MagicSchoolFindsAroundButtons.dualCharacterFirst), 1);
|
||||
DrawCharacter(MagicSchoolFindsAroundTheresa, ...RectGetOrigin(MagicSchoolFindsAroundButtons.dualCharacterSecond), 1);
|
||||
} else {
|
||||
DrawCharacter(Player, ...RectGetOrigin(MagicSchoolFindsAroundButtons.soloCharacter), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {"" | "Forest" | "Garden"} screenName
|
||||
*/
|
||||
function MagicSchoolFindsAroundChangeScreen(screenName) {
|
||||
MagicSchoolFindsAroundArea = screenName;
|
||||
if (MagicSchoolFindsAroundArea == "Forest") {
|
||||
MagicSchoolFindsAroundBackground = "ForestPath";
|
||||
if (MagicSchoolFindsAroundKitsune) {
|
||||
CharacterSetCurrent(MagicSchoolFindsAroundKitsune);
|
||||
}
|
||||
} else if (MagicSchoolFindsAroundArea == "Garden") {
|
||||
MagicSchoolFindsAroundBackground = "Garden1";
|
||||
if (MagicSchoolFindsAroundTheresa && !MagicSchoolFindsAroundTheresaVanished()) {
|
||||
CharacterSetCurrent(MagicSchoolFindsAroundTheresa);
|
||||
}
|
||||
} else {
|
||||
MagicSchoolFindsAroundBackground = "Castle";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -113,26 +268,205 @@ function MagicSchoolFindsAroundRun() {
|
|||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundClick() {
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.exit) && Player.CanWalk()) {
|
||||
if (MagicSchoolFindsAroundArea !== "") {
|
||||
MagicSchoolFindsAroundChangeScreen("");
|
||||
} else {
|
||||
CommonSetScreen("Room", "MagicSchoolLaboratory");
|
||||
}
|
||||
}
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.profile)) {
|
||||
InformationSheetLoadCharacter(Player);
|
||||
}
|
||||
|
||||
if (MagicSchoolFindsAroundArea === "") {
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.goToGarden)) {
|
||||
MagicSchoolFindsAroundChangeScreen("Garden");
|
||||
return;
|
||||
}
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.goToForest)) {
|
||||
MagicSchoolFindsAroundChangeScreen("Forest");
|
||||
MagicSchoolFindsAroundKitsuneQuestUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for clicks on the characters
|
||||
if (MouseIn(500, 0, 500, 1000)) CharacterSetCurrent(Player);
|
||||
if (MouseIn(1000, 0, 500, 1000)) CharacterSetCurrent(MagicSchoolFindsAroundKitsune,);
|
||||
if (MouseIn(1885, 25, 90, 90) && Player.CanWalk()) CommonSetScreen("Room", "MagicSchoolLaboratory");
|
||||
if (MouseIn(1885, 145, 90, 90)) InformationSheetLoadCharacter(Player);
|
||||
if (MagicSchoolFindsAroundArea === "") {
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.soloCharacter)) {
|
||||
CharacterSetCurrent(Player);
|
||||
}
|
||||
} else if (MagicSchoolFindsAroundArea === "Forest") {
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.dualCharacterFirst)) {
|
||||
CharacterSetCurrent(Player);
|
||||
}
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.dualCharacterSecond)) {
|
||||
CharacterSetCurrent(MagicSchoolFindsAroundKitsune);
|
||||
}
|
||||
} else if (MagicSchoolFindsAroundArea === "Garden") {
|
||||
if (MagicSchoolFindsAroundTheresaVanished()) {
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.soloCharacter)) {
|
||||
CharacterSetCurrent(Player);
|
||||
}
|
||||
} else {
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.dualCharacterFirst)) {
|
||||
CharacterSetCurrent(Player);
|
||||
}
|
||||
if (MouseIn(...MagicSchoolFindsAroundButtons.dualCharacterSecond)) {
|
||||
CharacterSetCurrent(MagicSchoolFindsAroundTheresa);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Shared
|
||||
|
||||
/**
|
||||
* Sets a boolean flag on the player to indicate they have learned about the prizes
|
||||
* Returns the fully initialized and validated parameters for the FindsAround game
|
||||
* @returns {Required<GameMagicSchoolFindsAroundParameters>} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundGetData() {
|
||||
if (!CommonIsObject(Player.Game.MagicSchoolFindsAround)) Player.Game.MagicSchoolFindsAround = {};
|
||||
const data = /** @type {Required<GameMagicSchoolFindsAroundParameters>} */ (Player.Game.MagicSchoolFindsAround);
|
||||
data.KitsuneQuestProgress = CommonClamp(data.KitsuneQuestProgress ?? -1, -1, 9);
|
||||
data.TheresaQuestProgress = CommonClamp(data.TheresaQuestProgress ?? -1, -1, 6);
|
||||
data.TheresaBadWords = data.TheresaBadWords ?? [];
|
||||
data.TheresaHideUntil = data.TheresaHideUntil ?? 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the player the reward tails
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundLearnAboutPrizes() {}
|
||||
function MagicSchoolFindsAroundGiveTails() {
|
||||
InventoryAdd(Player, "KitsuneTailStraps", "TailStraps");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the player the reward wings
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundGiveWings() {
|
||||
InventoryAdd(Player, "SeraphWings", "Wings");
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when the player lost and get untied by the Kitsune, can affect reputation
|
||||
* @param {string} RepChange
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundReleasePlayer(RepChange) {
|
||||
DialogChangeReputation("Dominant", CommonParseInt(RepChange) ?? 0);
|
||||
CharacterRelease(Player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player in the main hall in her current bondage
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundPlayerMainHall() {
|
||||
DialogLeave();
|
||||
CommonSetScreen("Room", "MainHall");
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Kitsune
|
||||
|
||||
/**
|
||||
* Starts the quest to gather essences for Kitsune
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundKitsuneStartQuest() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
data.KitsuneQuestProgress = 0;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
MagicSchoolFindsAroundKitsuneQuestUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current progress of the Kitsune quest
|
||||
* @returns {number}
|
||||
*/
|
||||
function MagicSchoolFindsAroundKitsuneGetQuestProgress() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
return data.KitsuneQuestProgress ?? -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the Kitsune quest in-progress?
|
||||
* @returns {boolean} - True if in progress
|
||||
*/
|
||||
function MagicSchoolFindsAroundKitsuneQuestStarted() {
|
||||
return MagicSchoolFindsAroundKitsuneGetQuestProgress() >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the Kitsune quest complete?
|
||||
* @returns {boolean} - True if completed
|
||||
*/
|
||||
function MagicSchoolFindsAroundKitsuneQuestCompleted() {
|
||||
return MagicSchoolFindsAroundKitsuneGetQuestProgress() >= 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic School Finds Around Kitsune Quest in progress?
|
||||
* True if started but not completed (0–8)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function DialogKitsuneQuestInProgress() {
|
||||
const p = MagicSchoolFindsAroundKitsuneGetQuestProgress();
|
||||
return p >= 0 && p < 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give player essence from defeated student
|
||||
* @param {string} Amount - The amount of essence to give
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function DialogKitsuneGiveEssence(Amount) {
|
||||
if (!CurrentCharacter) return;
|
||||
DialogRemove();
|
||||
PoseSetActive(CurrentCharacter, 'Kneel');
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
data.KitsuneQuestProgress += CommonParseInt(Amount) ?? 0;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
MagicSchoolFindsAroundKitsuneQuestUpdate();
|
||||
}
|
||||
|
||||
function MagicSchoolFindsAroundKitsuneDisappear() {
|
||||
DialogHideNPC(MagicSchoolFindsAroundKitsune);
|
||||
MagicSchoolFindsAroundGiveTails();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Kitsune NPC's quest status as it progresses
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundKitsuneQuestUpdate() {
|
||||
if (MagicSchoolFindsAroundKitsune == null) return;
|
||||
if (!MagicSchoolFindsAroundKitsuneQuestStarted()) return;
|
||||
let Defeats = MagicSchoolFindsAroundKitsuneGetQuestProgress();
|
||||
// Quest already started, so set the state directly
|
||||
if (Defeats !== -1) MagicSchoolFindsAroundKitsune.Stage = "100";
|
||||
if (Defeats < 0) Defeats = 0;
|
||||
let MissingDefeats = 9 - Defeats;
|
||||
if (MissingDefeats !== 0) {
|
||||
MagicSchoolFindsAroundKitsune.CurrentDialog = DialogFind(MagicSchoolFindsAroundKitsune, "100").replace("LEFTDEFEATCOUNT", MissingDefeats.toString());
|
||||
} else {
|
||||
MagicSchoolFindsAroundKitsune.CurrentDialog = DialogFind(MagicSchoolFindsAroundKitsune, "CompleteQuestRelief");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a magic battle with the Kitsune NPC
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundMagicBattleStart() {
|
||||
MagicBattleStart(MagicSchoolFindsAroundKitsune,9,MagicSchoolLaboratoryBackground,"MagicSchoolFindsAroundKitsuneMagicBattleEnd");
|
||||
MagicBattleStart(MagicSchoolFindsAroundKitsune, 9, MagicSchoolLaboratoryBackground, "MagicSchoolFindsAroundKitsuneMagicBattleEnd");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -172,10 +506,11 @@ function MagicSchoolFindsAroundClubCardStart() {
|
|||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundClubCardEnd() {
|
||||
CommonSetScreen("Room", "MagicSchoolFindsAround");
|
||||
CharacterSetCurrent(MagicSchoolFindsAroundKitsune);
|
||||
if (!CurrentCharacter) return;
|
||||
CurrentCharacter.CurrentDialog = DialogFind(CurrentCharacter, MiniGameVictory ? "ClubCardVictory" : "ClubCardDefeat");
|
||||
CommonSetScreen("Room", "MagicSchoolFindsAround").then(() => {
|
||||
CharacterSetCurrent(MagicSchoolFindsAroundKitsune);
|
||||
if (!CurrentCharacter) return;
|
||||
CurrentCharacter.CurrentDialog = DialogFind(CurrentCharacter, MiniGameVictory ? "ClubCardVictory" : "ClubCardDefeat");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -193,8 +528,7 @@ function MagicSchoolFindsAroundRunAway() {
|
|||
*/
|
||||
function MagicSchoolFindsAroundRunAwayEnd() {
|
||||
DialogLeave();
|
||||
MagicSchoolFindsAroundKitsune.Name = "Daji";
|
||||
delete MagicSchoolFindsAroundKitsune.FixedImage;
|
||||
DialogRevealNPC(MagicSchoolFindsAroundKitsune);
|
||||
CharacterRelease(MagicSchoolFindsAroundKitsune);
|
||||
PoseSetActive(MagicSchoolFindsAroundKitsune, 'BaseLower');
|
||||
MagicSchoolFindsAroundGiveTails();
|
||||
|
|
@ -207,69 +541,6 @@ function MagicSchoolFindsAroundRunAwayEnd() {
|
|||
CommonSetScreen("Room", "MagicSchoolLaboratory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the quest to gather essences
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundStartQuest() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
data.KitsuneQuestProgress = 0;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current progress of the quest
|
||||
* @returns {number}
|
||||
*/
|
||||
function MagicSchoolFindsAroundKitsuneGetQuestProgress() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
return data.KitsuneQuestProgress ?? -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quest in-progress?
|
||||
* @returns {boolean} - True if in progress
|
||||
*/
|
||||
function MagicSchoolFindsAroundQuestStarted() {
|
||||
return MagicSchoolFindsAroundKitsuneGetQuestProgress() >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quest completed?
|
||||
* @returns {boolean} - True if completed
|
||||
*/
|
||||
function MagicSchoolFindsAroundQuestCompleted() {
|
||||
return MagicSchoolFindsAroundKitsuneGetQuestProgress() >= 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully initialized and validated parameters for the FindsAround game
|
||||
* @returns {Required<GameMagicSchoolFindsAroundParameters>} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundGetData() {
|
||||
if (!CommonIsObject(Player.Game.MagicSchoolFindsAround)) Player.Game.MagicSchoolFindsAround = {};
|
||||
const data = /** @type {Required<GameMagicSchoolFindsAroundParameters>} */ (Player.Game.MagicSchoolFindsAround);
|
||||
data.KitsuneQuestProgress = CommonClamp(data.KitsuneQuestProgress ?? -1, -1, 9);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the player the reward tails
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundGiveTails() {
|
||||
InventoryAdd(Player, "KitsuneTailStraps", "TailStraps");
|
||||
}
|
||||
|
||||
/** Hide the NPC
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundHideNPC() {
|
||||
MagicSchoolFindsAroundGiveTails();
|
||||
MagicSchoolFindsAroundKitsune.Name = "";
|
||||
MagicSchoolFindsAroundKitsune.FixedImage = "Screens/Room/MovieStudio/Empty.png";
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when the player lost and get ungagged by the Kitsune, can affect reputation
|
||||
* @param {string} RepChange
|
||||
|
|
@ -299,129 +570,153 @@ function MagicSchoolFindsAroundLoserSpell(RepChange) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Finds a valid spell based on the player current predicament. Some spells can only be done by specific houses.
|
||||
let Spell = "";
|
||||
while (Spell == "") {
|
||||
Spell = CommonRandomItemFromList(MagicSchoolFindsAroundLastSpell, ["Hogtie", "ReleaseHogtie", "FlyingHogtie", "Arousal", "Tickle", "Pain", "SwitchRope", "SwitchChain", "Fail", "Tight"]);
|
||||
if ((Spell == "Hogtie") && Player.PoseMapping.BodyFull === "Hogtied") Spell = "";
|
||||
if ((Spell == "ReleaseHogtie") && Player.PoseMapping.BodyFull !== "Hogtied") Spell = "";
|
||||
if ((Spell == "FlyingHogtie") && Player.PoseMapping.BodyFull !== "Hogtied") Spell = "";
|
||||
if ((Spell == "SwitchRope") && ((InventoryGet(Player, "ItemArms")?.Asset.Name == "HempRope") || Player.PoseMapping.BodyFull === "Hogtied")) Spell = "";
|
||||
if ((Spell == "SwitchChain") && ((InventoryGet(Player, "ItemArms")?.Asset.Name == "Chains") || Player.PoseMapping.BodyFull === "Hogtied")) Spell = "";
|
||||
if ((Spell == "Arousal") && (MagicSchoolFindsAroundKitsune.House != "Maiestas")) Spell = "";
|
||||
if ((Spell == "FlyingHogtie") && (MagicSchoolFindsAroundKitsune.House != "Vincula")) Spell = "";
|
||||
if ((Spell == "Tickle") && (MagicSchoolFindsAroundKitsune.House != "Amplector")) Spell = "";
|
||||
if ((Spell == "Pain") && (MagicSchoolFindsAroundKitsune.House != "Corporis")) Spell = "";
|
||||
}
|
||||
|
||||
// Applies the spell effect
|
||||
if (Spell == "Arousal") { CharacterSetFacialExpression(Player, "Blush", "High", 8); CharacterSetFacialExpression(Player, "Eyes", "Horny", 8); }
|
||||
if (Spell == "Tickle") { CharacterSetFacialExpression(Player, "Blush", "Medium", 8); CharacterSetFacialExpression(Player, "Eyes", "Surprised", 8); }
|
||||
if (Spell == "Pain") { CharacterSetFacialExpression(Player, "Blush", "Medium", 8); CharacterSetFacialExpression(Player, "Eyes", "Closed", 8); }
|
||||
if (Spell == "Tight") { CharacterSetFacialExpression(Player, "Blush", "Low", 8); CharacterSetFacialExpression(Player, "Eyes", "Closed", 8); }
|
||||
if (Spell == "Fail") { CharacterSetFacialExpression(MagicSchoolFindsAroundKitsune, "Blush", "Medium", 8); CharacterSetFacialExpression(MagicSchoolFindsAroundKitsune, "Eyes", "Angry", 8); }
|
||||
if (Spell == "FlyingHogtie") {
|
||||
const item = InventoryGet(Player, "ItemArms");
|
||||
if (item) {
|
||||
TypedItemSetOptionByName(Player, item, "SuspensionHogtied");
|
||||
const Height = 0.67 * Math.random();
|
||||
item.Property ??= {};
|
||||
item.Property.OverrideHeight = {
|
||||
Height: Height * (Pose.find(p => p.Name === "Hogtied")?.OverrideHeight?.Height ?? 1),
|
||||
HeightRatioProportion: Height,
|
||||
Priority: 0,
|
||||
};
|
||||
}
|
||||
CharacterSetFacialExpression(Player, "Blush", "High", 8);
|
||||
CharacterSetFacialExpression(Player, "Eyes", "Surprised", 8);
|
||||
}
|
||||
if (Spell == "Hogtie") {
|
||||
TypedItemSetOptionByName(Player, "ItemArms", "Hogtied");
|
||||
}
|
||||
if (Spell == "ReleaseHogtie") {
|
||||
TypedItemSetOptionByName(Player, "ItemArms", "Basic");
|
||||
}
|
||||
if (Spell == "SwitchRope") {
|
||||
if (InventoryGet(Player, "ItemLegs") != null) InventoryWear(Player, "HempRope", "ItemLegs");
|
||||
if (InventoryGet(Player, "ItemFeet") != null) InventoryWear(Player, "HempRope", "ItemFeet");
|
||||
if (InventoryGet(Player, "ItemTorso") != null) InventoryWear(Player, "HempRopeHarness", "ItemTorso");
|
||||
if (InventoryGet(Player, "ItemArms") != null) InventoryWear(Player, "HempRope", "ItemArms");
|
||||
}
|
||||
if (Spell == "SwitchChain") {
|
||||
if (InventoryGet(Player, "ItemLegs") != null) InventoryWear(Player, "Chains", "ItemLegs");
|
||||
if (InventoryGet(Player, "ItemFeet") != null) InventoryWear(Player, "Chains", "ItemFeet");
|
||||
if (InventoryGet(Player, "ItemTorso") != null) InventoryWear(Player, "CrotchChain", "ItemTorso");
|
||||
if (InventoryGet(Player, "ItemArms") != null) InventoryWear(Player, "Chains", "ItemArms");
|
||||
}
|
||||
if ((Spell == "FlyingHogtie") || (Spell == "Hogtie") || (Spell == "ReleaseHogtie") || (Spell == "SwitchRope") || (Spell == "SwitchChain")) CharacterRefresh(Player);
|
||||
const Spell = MagicSchoolLaboratoryApplyRandomSpellEffects(MagicSchoolFindsAroundKitsune, MagicSchoolFindsAroundLastSpell);
|
||||
|
||||
// Shows the spell dialog
|
||||
MagicSchoolFindsAroundLastSpell = Spell;
|
||||
MagicSchoolFindsAroundKitsune.Stage = "Spell" + Spell;
|
||||
MagicSchoolFindsAroundSpellCount++;
|
||||
MagicSchoolFindsAroundKitsune.CurrentDialog = DialogFind(MagicSchoolFindsAroundKitsune, "Spell" + Spell + "Intro");
|
||||
|
||||
}
|
||||
|
||||
// #endregion Kitsune
|
||||
|
||||
// #region Theresa
|
||||
|
||||
/**
|
||||
* Triggered when the player lost and get untied by the Kitsune, can affect reputation
|
||||
* @param {string} RepChange
|
||||
* Starts the quest to gather essences for Theresa
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundReleasePlayer(RepChange) {
|
||||
DialogChangeReputation("Dominant", CommonParseInt(RepChange) ?? 0);
|
||||
CharacterRelease(Player);
|
||||
function MagicSchoolFindsAroundTheresaStartQuest() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
if (data.TheresaTooRude && data.TheresaBadWords.length >= 3 ) {
|
||||
MagicSchoolFindsAroundTheresa.Stage = "0";
|
||||
MagicSchoolFindsAroundTheresa.CurrentDialog = DialogFind(MagicSchoolFindsAroundTheresa, "TooRudeRepeat");
|
||||
data.TheresaBadWords = [];
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
return;
|
||||
}
|
||||
if (data.TheresaBadWords.length >= 3) {
|
||||
MagicSchoolFindsAroundTheresa.Stage = "0";
|
||||
MagicSchoolFindsAroundTheresa.CurrentDialog = DialogFind(MagicSchoolFindsAroundTheresa, "TooRude");
|
||||
data.TheresaTooRude = true;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
return;
|
||||
}
|
||||
data.TheresaQuestProgress = 0;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
MagicSchoolFindsAroundTheresaQuestUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player in the main hall in her current bondage
|
||||
* Return the current progress of the Theresa quest
|
||||
* @returns {number}
|
||||
*/
|
||||
function MagicSchoolFindsAroundTheresaGetQuestProgress() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
return data.TheresaQuestProgress;
|
||||
}
|
||||
|
||||
/** Whether the Theresa quest has started */
|
||||
function MagicSchoolFindsAroundTheresaQuestStarted() { return MagicSchoolFindsAroundTheresaGetQuestProgress() !== -1; }
|
||||
/** Whether the Theresa quest is ongoing */
|
||||
function MagicSchoolFindsAroundTheresaQuestIsOngoing() { return MagicSchoolFindsAroundTheresaQuestStarted() && !MagicSchoolFindsAroundTheresaQuestCompleted(); }
|
||||
/** Whether the Theresa quest is complete and can be rewarded */
|
||||
function MagicSchoolFindsAroundTheresaQuestCompleted() { return MagicSchoolFindsAroundTheresaGetQuestProgress() >= 6; }
|
||||
/** Whether it's the first time we meet Theresa */
|
||||
function MagicSchoolFindsAroundTheresaFirstMet() { return !MagicSchoolFindsAroundTheresaQuestStarted() && !MagicSchoolFindsAroundTheresaBeenRudeBefore(); }
|
||||
/** Whether we've been rude to Theresa already */
|
||||
function MagicSchoolFindsAroundTheresaBeenRudeBefore() { return MagicSchoolFindsAroundGetData().TheresaTooRude && !MagicSchoolFindsAroundTheresaQuestStarted(); }
|
||||
/** Whether we've been rude to Theresa already */
|
||||
function MagicSchoolFindsAroundTheresaVanished() { return CurrentTime < MagicSchoolFindsAroundGetData().TheresaHideUntil; }
|
||||
/** Whether the player owns the reward */
|
||||
function MagicSchoolFindsAroundTheresaTimerUp() {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
return data.TheresaHideUntil !== 0 && CurrentTime >= data.TheresaHideUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Theresa NPC's quest status as it progresses
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolFindsAroundPlayerMainHall() {
|
||||
DialogLeave();
|
||||
CommonSetScreen("Room", "MainHall");
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic School Finds Around Kitsune Quest in progress?
|
||||
* True if started but not completed (0–8)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function DialogKitsuneQuestInProgress() {
|
||||
const p = MagicSchoolFindsAroundKitsuneGetQuestProgress();
|
||||
return p >= 0 && p < 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Kitsune NPC's quest status as it progresses
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolLaboratoryKitsuneQuestUpdate() {
|
||||
if (MagicSchoolFindsAroundKitsune == null) return;
|
||||
if (!MagicSchoolFindsAroundQuestStarted()) return;
|
||||
let Defeats = MagicSchoolFindsAroundKitsuneGetQuestProgress();
|
||||
// Quest already started, so set the state directly
|
||||
if (Defeats !== -1) MagicSchoolFindsAroundKitsune.Stage = "100";
|
||||
if (Defeats < 0) Defeats = 0;
|
||||
let MissingDefeats = 9 - Defeats;
|
||||
if (MissingDefeats !== 0) {
|
||||
MagicSchoolFindsAroundKitsune.CurrentDialog = DialogFind(MagicSchoolFindsAroundKitsune, "100").replace("LEFTDEFEATCOUNT", MissingDefeats.toString());
|
||||
function MagicSchoolFindsAroundTheresaQuestUpdate() {
|
||||
if (MagicSchoolFindsAroundTheresa == null) return;
|
||||
if (MagicSchoolFindsAroundTheresaQuestIsOngoing()) {
|
||||
let helped = MagicSchoolFindsAroundTheresaGetQuestProgress();
|
||||
if (helped < 0) helped = 0;
|
||||
let remaining = 6 - helped;
|
||||
const line = MagicSchoolFindsAroundTheresa.Dialog.find(({Stage, NextStage}) => Stage === "0" && NextStage === "22");
|
||||
if (!line) {
|
||||
console.error("failed to locate line");
|
||||
} else {
|
||||
line.Result = line.Result.replace(/(REMAINING|\d+)/, remaining.toString());
|
||||
}
|
||||
}
|
||||
if (MagicSchoolFindsAroundTheresaTimerUp()) {
|
||||
if (MagicSchoolFindsAroundTheresaVanished()) {
|
||||
DialogHideNPC(MagicSchoolFindsAroundTheresa);
|
||||
} else {
|
||||
if (MagicSchoolFindsAroundTheresaGetQuestProgress() >= 6) {
|
||||
DialogRevealNPC(MagicSchoolFindsAroundTheresa);
|
||||
MagicSchoolFindsAroundDressUpTheresa(MagicSchoolFindsAroundTheresa, "Angel");
|
||||
MagicSchoolFindsAroundTheresa.Name = "Theresa";
|
||||
} else {
|
||||
DialogRevealNPC(MagicSchoolFindsAroundTheresa);
|
||||
MagicSchoolFindsAroundDressUpTheresa(MagicSchoolFindsAroundTheresa, "Nun");
|
||||
MagicSchoolFindsAroundTheresa.Name = "Theresa";
|
||||
}
|
||||
}
|
||||
} else if (MagicSchoolFindsAroundTheresaQuestCompleted()) {
|
||||
MagicSchoolFindsAroundDressUpTheresa(MagicSchoolFindsAroundTheresa, "Angel");
|
||||
if (MagicSchoolFindsAroundTheresa.Stage == "0") {
|
||||
MagicSchoolFindsAroundTheresa.Name = "Angel";
|
||||
} else {
|
||||
MagicSchoolFindsAroundTheresa.Name = "Theresa";
|
||||
}
|
||||
} else {
|
||||
MagicSchoolFindsAroundKitsune.CurrentDialog = DialogFind(MagicSchoolFindsAroundKitsune, "CompleteQuestRelief");
|
||||
MagicSchoolFindsAroundDressUpTheresa(MagicSchoolFindsAroundTheresa, "Nun");
|
||||
MagicSchoolFindsAroundTheresa.Name = "Theresa";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Give player essence from defeated student
|
||||
* Give player essence from rescued person
|
||||
* @param {string} Amount - The amount of essence to give
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function DialogKitsuneGiveEssence(Amount) {
|
||||
function DialogTheresaGiveEssence(Amount) {
|
||||
if (!CurrentCharacter) return;
|
||||
if (!MagicSchoolFindsAroundTheresaQuestIsOngoing()) return;
|
||||
DialogRemove();
|
||||
PoseSetActive(CurrentCharacter, 'Kneel');
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
data.KitsuneQuestProgress += CommonParseInt(Amount) ?? 0;
|
||||
data.TheresaQuestProgress += CommonParseInt(Amount) ?? 0;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
MagicSchoolFindsAroundTheresaQuestUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} stage
|
||||
*/
|
||||
function MagicSchoolFindsAroundTheresaGiveBadWordPoint(stage) {
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
if (!data.TheresaBadWords.includes(stage)) {
|
||||
data.TheresaBadWords.push(stage);
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
}
|
||||
}
|
||||
|
||||
function MagicSchoolFindsAroundTheresaGiveGift() {
|
||||
MagicSchoolFindsAroundGiveWings();
|
||||
DrawFlashScreen("#FFFFFF", 2000, 300);
|
||||
MagicSchoolFindsAroundTheresa.Name = "Theresa";
|
||||
}
|
||||
|
||||
function MagicSchoolFindsAroundHideTheresa() {
|
||||
DialogHideNPC(MagicSchoolFindsAroundTheresa);
|
||||
const data = MagicSchoolFindsAroundGetData();
|
||||
// Hide for 42 hours
|
||||
data.TheresaHideUntil = CurrentTime + 42 * 60 * 60 * 1000;
|
||||
data.TheresaQuestProgress = 7;
|
||||
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||
MagicSchoolLaboratoryKitsuneQuestUpdate();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,5 @@
|
|||
Exit,Back to the Magic School
|
||||
Profile,Your Profile
|
||||
ScreenIntro,"You leave the school and fresh air hits your face. You take a look around; there are many interesting places around. Close to the school you see a garden filled with flowers, and a bit further away you can see a forest brimming with magic."
|
||||
GoToGarden,Check out the garden
|
||||
GoToForest,Walk to the forest
|
||||
|
|
|
|||
|
|
|
@ -6,7 +6,8 @@ var MagicSchoolLaboratoryTeacher = null;
|
|||
/** @type {null | NPCCharacter} */
|
||||
var MagicSchoolLaboratoryStudent = null;
|
||||
var MagicSchoolLaboratoryBattleWage = "";
|
||||
var MagicSchoolLaboratoryLastSpell = "";
|
||||
/** @type {MagicSchoolSpell | undefined} */
|
||||
var MagicSchoolLaboratoryLastSpell;
|
||||
var MagicSchoolLaboratorySpellCount = 0;
|
||||
|
||||
/**
|
||||
|
|
@ -98,7 +99,7 @@ function MagicSchoolLaboratoryRun() {
|
|||
DrawButton(1885, 145, 90, 90, "", "White", "Icons/Character.png", TextGet("Profile"));
|
||||
if (!MagicSchoolLaboratoryInHouse("")) DrawButton(1885, 265, 90, 90, "", "White", "Icons/Wardrobe.png", TextGet("Dress"));
|
||||
if (!MagicSchoolLaboratoryInHouse("")) DrawButton(1885, 385, 90, 90, "", "White", "Icons/Explore.png", TextGet("Explore"));
|
||||
if (!MagicSchoolLaboratoryInHouse("")) DrawButton(1885, 505, 90, 90, "", "White", "Icons/Tree.png", TextGet("ExploreAround"));
|
||||
if (!MagicSchoolLaboratoryInHouse("")) DrawButton(1885, 505, 90, 90, "", "White", "Icons/Castle.png", TextGet("ExploreAround"));
|
||||
if (!MagicSchoolLaboratoryInHouse("")) DrawButton(1885, 625, 90, 90, "", "White", "Icons/Kidnap.png", TextGet("Escape"));
|
||||
}
|
||||
|
||||
|
|
@ -442,34 +443,46 @@ function MagicSchoolLaboratoryReleasePlayer(RepChange) {
|
|||
}
|
||||
|
||||
/**
|
||||
* When the player lost a battle and the student tests a spell on her
|
||||
* @returns {void} - Nothing
|
||||
* @param {NPCCharacter} npc
|
||||
*/
|
||||
function MagicSchoolLaboratoryLoserSpell(RepChange) {
|
||||
|
||||
// If we must change the player dom/sub reputation
|
||||
if ((RepChange != "") && (RepChange != "0")) DialogChangeReputation("Dominant", parseInt(RepChange));
|
||||
|
||||
// After many spells, the event ends CHANGE TO 5
|
||||
if (MagicSchoolLaboratorySpellCount >= 5) {
|
||||
MagicSchoolLaboratoryStudent.Stage = "240";
|
||||
MagicSchoolLaboratoryStudent.CurrentDialog = DialogFind(MagicSchoolLaboratoryStudent, "SpellEnd");
|
||||
return;
|
||||
function MagicSchoolLaboratoryGetAllSpellsForNpc(npc) {
|
||||
/** @type {MagicSchoolSpell[]} */
|
||||
const allCommonSpells = ["Hogtie", "ReleaseHogtie", "SwitchRope", "SwitchChain", "Fail", "Tight"];
|
||||
switch (npc.House) {
|
||||
case "Maiestas":
|
||||
allCommonSpells.push("Arousal");
|
||||
break;
|
||||
case "Vincula":
|
||||
allCommonSpells.push("FlyingHogtie");
|
||||
break;
|
||||
case "Amplector":
|
||||
allCommonSpells.push("Tickle");
|
||||
break;
|
||||
case "Corporis":
|
||||
allCommonSpells.push("Pain");
|
||||
break;
|
||||
}
|
||||
return allCommonSpells;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NPCCharacter} npc
|
||||
* @param {MagicSchoolSpell | undefined} lastSpell
|
||||
*/
|
||||
function MagicSchoolLaboratoryApplyRandomSpellEffects(npc, lastSpell) {
|
||||
|
||||
const allSpells = MagicSchoolLaboratoryGetAllSpellsForNpc(npc);
|
||||
|
||||
// Finds a valid spell based on the player current predicament. Some spells can only be done by specific houses.
|
||||
let Spell = "";
|
||||
while (Spell == "") {
|
||||
Spell = CommonRandomItemFromList(MagicSchoolLaboratoryLastSpell, ["Hogtie", "ReleaseHogtie", "FlyingHogtie", "Arousal", "Tickle", "Pain", "SwitchRope", "SwitchChain", "Fail", "Tight"]);
|
||||
if ((Spell == "Hogtie") && Player.PoseMapping.BodyFull === "Hogtied") Spell = "";
|
||||
if ((Spell == "ReleaseHogtie") && Player.PoseMapping.BodyFull !== "Hogtied") Spell = "";
|
||||
if ((Spell == "FlyingHogtie") && Player.PoseMapping.BodyFull !== "Hogtied") Spell = "";
|
||||
if ((Spell == "SwitchRope") && ((InventoryGet(Player, "ItemArms").Asset.Name == "HempRope") || Player.PoseMapping.BodyFull === "Hogtied")) Spell = "";
|
||||
if ((Spell == "SwitchChain") && ((InventoryGet(Player, "ItemArms").Asset.Name == "Chains") || Player.PoseMapping.BodyFull === "Hogtied")) Spell = "";
|
||||
if ((Spell == "Arousal") && (MagicSchoolLaboratoryStudent.House != "Maiestas")) Spell = "";
|
||||
if ((Spell == "FlyingHogtie") && (MagicSchoolLaboratoryStudent.House != "Vincula")) Spell = "";
|
||||
if ((Spell == "Tickle") && (MagicSchoolLaboratoryStudent.House != "Amplector")) Spell = "";
|
||||
if ((Spell == "Pain") && (MagicSchoolLaboratoryStudent.House != "Corporis")) Spell = "";
|
||||
/** @type {MagicSchoolSpell | undefined} */
|
||||
let Spell;
|
||||
while (!Spell) {
|
||||
Spell = CommonRandomItemFromList(lastSpell, allSpells);
|
||||
if ((Spell == "Hogtie") && Player.PoseMapping.BodyFull === "Hogtied") Spell = undefined;
|
||||
if ((Spell == "ReleaseHogtie") && Player.PoseMapping.BodyFull !== "Hogtied") Spell = undefined;
|
||||
if ((Spell == "FlyingHogtie") && Player.PoseMapping.BodyFull !== "Hogtied") Spell = undefined;
|
||||
if ((Spell == "SwitchRope") && ((InventoryGet(Player, "ItemArms").Asset.Name == "HempRope") || Player.PoseMapping.BodyFull === "Hogtied")) Spell = undefined;
|
||||
if ((Spell == "SwitchChain") && ((InventoryGet(Player, "ItemArms").Asset.Name == "Chains") || Player.PoseMapping.BodyFull === "Hogtied")) Spell = undefined;
|
||||
}
|
||||
|
||||
// Applies the spell effect
|
||||
|
|
@ -477,7 +490,7 @@ function MagicSchoolLaboratoryLoserSpell(RepChange) {
|
|||
if (Spell == "Tickle") { CharacterSetFacialExpression(Player, "Blush", "Medium", 8); CharacterSetFacialExpression(Player, "Eyes", "Surprised", 8); }
|
||||
if (Spell == "Pain") { CharacterSetFacialExpression(Player, "Blush", "Medium", 8); CharacterSetFacialExpression(Player, "Eyes", "Closed", 8); }
|
||||
if (Spell == "Tight") { CharacterSetFacialExpression(Player, "Blush", "Low", 8); CharacterSetFacialExpression(Player, "Eyes", "Closed", 8); }
|
||||
if (Spell == "Fail") { CharacterSetFacialExpression(MagicSchoolLaboratoryStudent, "Blush", "Medium", 8); CharacterSetFacialExpression(MagicSchoolLaboratoryStudent, "Eyes", "Angry", 8); }
|
||||
if (Spell == "Fail") { CharacterSetFacialExpression(npc, "Blush", "Medium", 8); CharacterSetFacialExpression(npc, "Eyes", "Angry", 8); }
|
||||
if (Spell == "FlyingHogtie") {
|
||||
const item = InventoryGet(Player, "ItemArms");
|
||||
TypedItemSetOptionByName(Player, item, "SuspensionHogtied");
|
||||
|
|
@ -508,14 +521,35 @@ function MagicSchoolLaboratoryLoserSpell(RepChange) {
|
|||
if (InventoryGet(Player, "ItemTorso") != null) InventoryWear(Player, "CrotchChain", "ItemTorso");
|
||||
if (InventoryGet(Player, "ItemArms") != null) InventoryWear(Player, "Chains", "ItemArms");
|
||||
}
|
||||
if ((Spell == "FlyingHogtie") || (Spell == "Hogtie") || (Spell == "ReleaseHogtie") || (Spell == "SwitchRope") || (Spell == "SwitchChain")) CharacterRefresh(Player);
|
||||
if ((Spell == "FlyingHogtie") || (Spell == "Hogtie") || (Spell == "ReleaseHogtie") || (Spell == "SwitchRope") || (Spell == "SwitchChain")) {
|
||||
CharacterRefresh(Player);
|
||||
}
|
||||
return Spell;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the player lost a battle and the student tests a spell on her
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function MagicSchoolLaboratoryLoserSpell(RepChange) {
|
||||
|
||||
// If we must change the player dom/sub reputation
|
||||
if ((RepChange != "") && (RepChange != "0")) DialogChangeReputation("Dominant", parseInt(RepChange));
|
||||
|
||||
// After many spells, the event ends CHANGE TO 5
|
||||
if (MagicSchoolLaboratorySpellCount >= 5) {
|
||||
MagicSchoolLaboratoryStudent.Stage = "240";
|
||||
MagicSchoolLaboratoryStudent.CurrentDialog = DialogFind(MagicSchoolLaboratoryStudent, "SpellEnd");
|
||||
return;
|
||||
}
|
||||
|
||||
const Spell = MagicSchoolLaboratoryApplyRandomSpellEffects(MagicSchoolLaboratoryStudent, MagicSchoolLaboratoryLastSpell);
|
||||
|
||||
// Shows the spell dialog
|
||||
MagicSchoolLaboratoryLastSpell = Spell;
|
||||
MagicSchoolLaboratoryStudent.Stage = "Spell" + Spell;
|
||||
MagicSchoolLaboratorySpellCount++;
|
||||
MagicSchoolLaboratoryStudent.CurrentDialog = DialogFind(MagicSchoolLaboratoryStudent, "Spell" + Spell + "Intro");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -462,6 +462,7 @@ function MaidQuartersRescuePay() {
|
|||
MaidQuartersMaid.CurrentDialog = MaidQuartersMaid.CurrentDialog.replace("REPLACEMONEY", M.toString());
|
||||
CharacterChangeMoney(Player, M);
|
||||
IntroductionJobProgress("SubMaid");
|
||||
DialogTheresaGiveEssence("1");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5893,3 +5893,25 @@ function DialogKeyDown(event) {
|
|||
function DialogMouseDown(event) {
|
||||
if (CurrentCharacter) StruggleMouseDown(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an NPC invisible
|
||||
* @param {NPCCharacter} npc
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function DialogHideNPC(npc) {
|
||||
npc.SavedName = npc.Name;
|
||||
npc.Name = "";
|
||||
npc.FixedImage = "Screens/Room/MovieStudio/Empty.png";
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an NPC invisible
|
||||
* @param {NPCCharacter} npc
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function DialogRevealNPC(npc) {
|
||||
npc.Name = npc.SavedName;
|
||||
delete npc.SavedName;
|
||||
delete npc.FixedImage;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1924,6 +1924,15 @@ function RectGetFrame(rect) {
|
|||
return [rect.x, rect.y, rect.w, rect.h];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rect's origin point
|
||||
* @param {Rect | RectTuple} rect
|
||||
* @return {[x: number, y: number]}
|
||||
*/
|
||||
function RectGetOrigin(rect) {
|
||||
return Array.isArray(rect) ? [rect[0], rect[1]] : [rect.x, rect.y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offsets a rect by the given amount
|
||||
* @param {Rect} rect
|
||||
|
|
|
|||
16
BondageClub/Scripts/Typedef.d.ts
vendored
|
|
@ -754,8 +754,6 @@ type BackgroundTag =
|
|||
"Club" | "College" | "Regular house" | "Dungeon" | "Asylum" | "Pandora" | "Club Cards"
|
||||
;
|
||||
|
||||
type MagicSchoolHouse = "Maiestas" | "Vincula" | "Amplector" | "Corporis";
|
||||
|
||||
interface ModuleScreens {
|
||||
Character:
|
||||
| "Appearance"
|
||||
|
|
@ -2209,6 +2207,7 @@ interface NPCCharacter extends Character {
|
|||
Event?: NPCEvent[];
|
||||
Affection?: number;
|
||||
Domination?: number;
|
||||
SavedName?: string;
|
||||
}
|
||||
|
||||
/** Movie Studio */
|
||||
|
|
@ -3978,7 +3977,11 @@ interface GamePrisonParameters {
|
|||
}
|
||||
|
||||
interface GameMagicSchoolFindsAroundParameters {
|
||||
KitsuneQuestProgress?: number;
|
||||
KitsuneQuestProgress?: number;
|
||||
TheresaQuestProgress?: number;
|
||||
TheresaBadWords?: string[];
|
||||
TheresaTooRude?: boolean;
|
||||
TheresaHideUntil?: number;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
|
@ -4031,6 +4034,13 @@ interface GameGGTSParameters {
|
|||
|
||||
// #endregion
|
||||
|
||||
// #region Magic Battle & School stuff
|
||||
|
||||
type MagicSchoolHouse = "Maiestas" | "Vincula" | "Amplector" | "Corporis";
|
||||
type MagicSchoolSpell = "Hogtie" | "ReleaseHogtie" | "FlyingHogtie" | "Arousal" | "Tickle" | "Pain" | "SwitchRope" | "SwitchChain" | "Fail" | "Tight";
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Audio
|
||||
|
||||
type AudioSoundEffect = [string, number];
|
||||
|
|
|
|||