diff --git a/BondageClub/Assets/Female3DCG/Female3DCGExtended.js b/BondageClub/Assets/Female3DCG/Female3DCGExtended.js index 44aaf3a7ee2884a4255b1f6cd2b551e6ad01208a..32a2b7fbfbac73f08200c54b908369ca79a047a0 100644 --- a/BondageClub/Assets/Female3DCG/Female3DCGExtended.js +++ b/BondageClub/Assets/Female3DCG/Female3DCGExtended.js @@ -4246,6 +4246,32 @@ var AssetFemale3DCGExtended = { ], }, }, //LockingSwimsuit + FuturisticHarness: { + Archetype: ExtendedArchetype.TYPED, + Config: { + Options: [ + { + Name: "Full", + Property: { Type: null, Difficulty: 2 }, + }, + { + Name: "Upper", + Property: { Type: "Upper", Difficulty: 0 }, + }, + { + Name: "Lower", + Property: { Type: "Lower", Difficulty: 0 }, + }, + ], + ScriptHooks: { + Load: FuturisticAccessLoad, + Click: InventoryItemTorsoFuturisticHarnessClick, + Draw: InventoryItemTorsoFuturisticHarnessDraw, + Exit: FuturisticAccessExit, + Validate: FuturisticAccessValidate, + }, + }, + }, // FuturisticHarness }, // ItemTorso ItemTorso2: { LockingSwimsuit: { @@ -4284,6 +4310,17 @@ var AssetFemale3DCGExtended = { Archetype: ExtendedArchetype.TYPED, CopyConfig: { GroupName: "ItemTorso", AssetName: "ThinLeatherStraps" }, }, // ThinLeatherStraps + FuturisticHarness: { + Archetype: ExtendedArchetype.TYPED, + CopyConfig: { GroupName: "ItemTorso", AssetName: "FuturisticHarness" }, + Config: { + Dialog: { + Load: "ItemTorsoFuturisticHarnessSelect", + TypePrefix: "ItemTorsoFuturisticHarness", + ChatPrefix: "ItemTorsoFuturisticHarnessSet", + }, + } + }, // FuturisticHarness }, //ItemTorso2 Shoes: { FuturisticHeels2: { diff --git a/BondageClub/Assets/Female3DCG/LayerNames.csv b/BondageClub/Assets/Female3DCG/LayerNames.csv index d9b6586e63808c4521573131adc8fd5d6d8e67e1..dd7a177f0790a00f0788c6ce0b38af5109fdec3c 100644 --- a/BondageClub/Assets/Female3DCG/LayerNames.csv +++ b/BondageClub/Assets/Female3DCG/LayerNames.csv @@ -1109,6 +1109,10 @@ ItemTorsoFuturisticHarnessBand,Straps ItemTorsoFuturisticHarnessDisplay,Display ItemTorsoFuturisticHarnessMesh,Module ItemTorsoFuturisticHarnessLock,Lock +ItemTorso2FuturisticHarnessBand,Straps +ItemTorso2FuturisticHarnessDisplay,Display +ItemTorso2FuturisticHarnessMesh,Module +ItemTorso2FuturisticHarnessLock,Lock ItemBreastFuturisticBraBra,Body ItemBreastFuturisticBraDisplay,Display ItemBreastFuturisticBraMesh,Mesh diff --git a/BondageClub/Screens/Character/Player/Dialog_Player.csv b/BondageClub/Screens/Character/Player/Dialog_Player.csv index a793f11180a454cb8f58e7737abfbea19a74f5ac..12c7b52f56cc5626a7732ac315eb4f667473c2d1 100644 --- a/BondageClub/Screens/Character/Player/Dialog_Player.csv +++ b/BondageClub/Screens/Character/Player/Dialog_Player.csv @@ -1130,13 +1130,13 @@ ItemDevicesFuturisticCrateSeth1,,,SourceCharacter configures the harness on Dest ItemDevicesFuturisticCrateSeth2,,,SourceCharacter configures the harness on DestinationCharacter crate.,, ItemDevicesFuturisticCrateSeth3,,,SourceCharacter configures the harness on DestinationCharacter crate.,, ItemDevicesFuturisticCrateSeth4,,,SourceCharacter configures the harness on DestinationCharacter crate.,, -FuturisticHarnessType,,,Select device mode:,, -FuturisticHarnessTypeFull,,,Full,, -FuturisticHarnessTypeUpper,,,Upper,, -FuturisticHarnessTypeLower,,,Lower,, -FuturisticHarnessSetLower,,,SourceCharacter moves DestinationCharacter harness to the lower body.,, -FuturisticHarnessSetUpper,,,SourceCharacter moves DestinationCharacter harness to the upper body.,, -FuturisticHarnessSetFull,,,SourceCharacter configures DestinationCharacter harness to surround the whole body in straps.,, +ItemTorsoFuturisticHarnessSelect,,,Select device mode:,, +ItemTorsoFuturisticHarnessFull,,,Full,, +ItemTorsoFuturisticHarnessUpper,,,Upper,, +ItemTorsoFuturisticHarnessLower,,,Lower,, +ItemTorsoFuturisticHarnessSetLower,,,SourceCharacter moves DestinationCharacter harness to the lower body.,, +ItemTorsoFuturisticHarnessSetUpper,,,SourceCharacter moves DestinationCharacter harness to the upper body.,, +ItemTorsoFuturisticHarnessSetFull,,,SourceCharacter configures DestinationCharacter harness to surround the whole body in straps.,, HighSecurityHarnessType,,,Select device mode:,, HighSecurityHarnessTypeLowSec,,,Belt,, HighSecurityHarnessTypeMedSec,,,Pelvis,, diff --git a/BondageClub/Screens/Inventory/Futuristic/Futuristic.js b/BondageClub/Screens/Inventory/Futuristic/Futuristic.js index c5c3d59617315baaf47360d717f6125a37384846..89bee68c245f3e500db05cc066c4f603ae733ab2 100644 --- a/BondageClub/Screens/Inventory/Futuristic/Futuristic.js +++ b/BondageClub/Screens/Inventory/Futuristic/Futuristic.js @@ -45,39 +45,47 @@ var FuturisticAccessLegGroups = ["ItemLegs", "ItemFeet", "ItemBoots"]; var FuturisticAccessChastityGroups = ["ItemPelvis", "ItemTorso", "ItemButt", "ItemVulva", "ItemVulvaPiercings", "ItemBreast", "ItemNipples", "ItemNipplesPiercings"]; /** - * Hook script for injecting futuristic features into an archetypical item - * @param {function} OriginalFunction - The function that is normally called when an archetypical item reaches this point. - * @returns {void} - Nothing + * Helper function for the futuristic hook scripts. + * @param {() => void} OriginalFunction - The function that is normally called when an archetypical item reaches this point. + * @param {() => void} DeniedFunction - The function that is called when validation fails. + * @returns {boolean} - Whether the validation was successful or not. */ -function FuturisticAccessLoad(OriginalFunction) { +function FuturisticAccess(OriginalFunction, DeniedFunction) { var C = CharacterGetCurrent(); if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticLoadAccessDenied() - } else OriginalFunction(); + DeniedFunction(); + return false; + } else { + OriginalFunction(); + return true; + } } /** * Hook script for injecting futuristic features into an archetypical item - * @param {function} OriginalFunction - The function that is normally called when an archetypical item reaches this point. - * @returns {void} - Nothing + * @param {() => void} OriginalFunction - The function that is normally called when an archetypical item reaches this point. + * @returns {boolean} - Whether the validation was successful or not. + */ +function FuturisticAccessLoad(OriginalFunction) { + return FuturisticAccess(OriginalFunction, InventoryItemFuturisticLoadAccessDenied); +} + +/** + * Hook script for injecting futuristic features into an archetypical item + * @param {() => void} OriginalFunction - The function that is normally called when an archetypical item reaches this point. + * @returns {boolean} - Whether the validation was successful or not. */ function FuturisticAccessClick(OriginalFunction) { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticClickAccessDenied() - } else OriginalFunction(); + return FuturisticAccess(OriginalFunction, InventoryItemFuturisticClickAccessDenied); } /** * Hook script for injecting futuristic features into an archetypical item - * @param {function} OriginalFunction - The function that is normally called when an archetypical item reaches this point. - * @returns {void} - Nothing + * @param {() => void} OriginalFunction - The function that is normally called when an archetypical item reaches this point. + * @returns {boolean} - Whether the validation was successful or not. */ function FuturisticAccessDraw(OriginalFunction) { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticDrawAccessDenied() - } else OriginalFunction(); + return FuturisticAccess(OriginalFunction, InventoryItemFuturisticDrawAccessDenied); } /** diff --git a/BondageClub/Screens/Inventory/ItemTorso/FuturisticHarness/FuturisticHarness.js b/BondageClub/Screens/Inventory/ItemTorso/FuturisticHarness/FuturisticHarness.js index fc5898b42fde5caee387a217efef3c4cfa088252..63ee5112ed99e8d0b0f92c38cfc1ea96d37083ab 100644 --- a/BondageClub/Screens/Inventory/ItemTorso/FuturisticHarness/FuturisticHarness.js +++ b/BondageClub/Screens/Inventory/ItemTorso/FuturisticHarness/FuturisticHarness.js @@ -1,71 +1,36 @@ "use strict"; -var InventoryItemTorsoFuturisticHarnessOptions = [ - { - Name: "Full", - Property: { Type: null, Difficulty: 2}, - }, - { - Name: "Upper", - Property: { Type: "Upper", Difficulty: 0}, - }, - { - Name: "Lower", - Property: { Type: "Lower", Difficulty: 0}, - }, -]; - -// Loads the item extension properties -function InventoryItemTorsoFuturisticHarnessLoad() { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticLoadAccessDenied(); - } else - ExtendedItemLoad(InventoryItemTorsoFuturisticHarnessOptions, "FuturisticHarnessType"); -} - -// Draw the item extension screen -function InventoryItemTorsoFuturisticHarnessDraw() { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticDrawAccessDenied(); - } else { - ExtendedItemDraw(InventoryItemTorsoFuturisticHarnessOptions, "FuturisticHarnessType"); - - DrawAssetPreview(1387, 75, DialogFocusItem.Asset); - - var FuturisticCollarItems = InventoryItemNeckFuturisticCollarGetItems(C); - - if (FuturisticCollarItems.length > 0) { - DrawButton(1400, 910, 200, 55, DialogFindPlayer("FuturisticCollarColor"), "White"); - } +/** + * Draw the item extension screen + * @param {() => void} OriginalFunction - The function that is normally called when an archetypical item reaches this point. + * @returns {void} - Nothing + */ +function InventoryItemTorsoFuturisticHarnessDraw(OriginalFunction) { + if (!FuturisticAccessDraw(OriginalFunction)) { + return; + } + const C = CharacterGetCurrent(); + const FuturisticCollarItems = InventoryItemNeckFuturisticCollarGetItems(C); + if (FuturisticCollarItems.length > 0) { + DrawButton(1385, 800, 225, 55, DialogFindPlayer("FuturisticCollarColor"), "White"); } } - -function InventoryItemTorsoFuturisticHarnessPublishAction(C, Option) { - var msg = "FuturisticHarnessSet" + Option.Name; - var Dictionary = [ - { Tag: "SourceCharacter", Text: CharacterNickname(Player), MemberNumber: Player.MemberNumber }, - { Tag: "DestinationCharacter", Text: CharacterNickname(C), MemberNumber: C.MemberNumber }, - ]; - ChatRoomPublishCustomAction(msg, true, Dictionary); -} - -// Catches the item extension clicks -function InventoryItemTorsoFuturisticHarnessClick() { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticClickAccessDenied(); - } else { - - ExtendedItemClick(InventoryItemTorsoFuturisticHarnessOptions); - - var FuturisticCollarItems = InventoryItemNeckFuturisticCollarGetItems(C); - if (MouseIn(1400, 910, 200, 55) && FuturisticCollarItems.length > 0 && DialogFocusItem) { InventoryItemNeckFuturisticCollarColor(C, DialogFocusItem); InventoryItemTorsoFuturisticHarnessExit();} +/** + * Catches the item extension clicks + * @param {() => void} OriginalFunction - The function that is normally called when an archetypical item reaches this point. + * @returns {void} - Nothing + */ +function InventoryItemTorsoFuturisticHarnessClick(OriginalFunction) { + if (!FuturisticAccessClick(OriginalFunction)) { + return; + } + if (MouseIn(1385, 800, 225, 55)) { + const C = CharacterGetCurrent(); + const FuturisticCollarItems = InventoryItemNeckFuturisticCollarGetItems(C); + if (FuturisticCollarItems.length > 0 && DialogFocusItem) { + InventoryItemNeckFuturisticCollarColor(C, DialogFocusItem); + FuturisticAccessExit(); + } } } - -function InventoryItemTorsoFuturisticHarnessExit() { - InventoryItemFuturisticExitAccessDenied(); -} \ No newline at end of file diff --git a/BondageClub/Screens/Inventory/ItemTorso2/FuturisticHarness/FuturisticHarness.js b/BondageClub/Screens/Inventory/ItemTorso2/FuturisticHarness/FuturisticHarness.js deleted file mode 100644 index 8a6b7d569c553b9cf9529a1c22a27cb52763d1bf..0000000000000000000000000000000000000000 --- a/BondageClub/Screens/Inventory/ItemTorso2/FuturisticHarness/FuturisticHarness.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -var InventoryItemTorso2FuturisticHarnessOptions = [ - { - Name: "Full", - Property: { Type: null, Difficulty: 2}, - }, - { - Name: "Upper", - Property: { Type: "Upper", Difficulty: 0}, - }, - { - Name: "Lower", - Property: { Type: "Lower", Difficulty: 0}, - }, -]; - -// Loads the item extension properties -function InventoryItemTorso2FuturisticHarnessLoad() { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticLoadAccessDenied(); - } else - ExtendedItemLoad(InventoryItemTorso2FuturisticHarnessOptions, "FuturisticHarnessType"); -} - -// Draw the item extension screen -function InventoryItemTorso2FuturisticHarnessDraw() { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticDrawAccessDenied(); - } else { - ExtendedItemDraw(InventoryItemTorso2FuturisticHarnessOptions, "FuturisticHarnessType"); - - DrawAssetPreview(1387, 75, DialogFocusItem.Asset); - - var FuturisticCollarItems = InventoryItemNeckFuturisticCollarGetItems(C); - - if (FuturisticCollarItems.length > 0) { - DrawButton(1400, 910, 200, 55, DialogFindPlayer("FuturisticCollarColor"), "White"); - } - } -} - - -function InventoryItemTorso2FuturisticHarnessPublishAction(C, Option) { - var msg = "FuturisticHarnessSet" + Option.Name; - var Dictionary = [ - { Tag: "SourceCharacter", Text: CharacterNickname(Player), MemberNumber: Player.MemberNumber }, - { Tag: "DestinationCharacter", Text: CharacterNickname(C), MemberNumber: C.MemberNumber }, - ]; - ChatRoomPublishCustomAction(msg, true, Dictionary); -} - -// Catches the item extension clicks -function InventoryItemTorso2FuturisticHarnessClick() { - var C = CharacterGetCurrent(); - if (InventoryItemFuturisticValidate(C) !== "") { - InventoryItemFuturisticClickAccessDenied(); - } else { - - ExtendedItemClick(InventoryItemTorso2FuturisticHarnessOptions); - - var FuturisticCollarItems = InventoryItemNeckFuturisticCollarGetItems(C); - if (MouseIn(1400, 910, 200, 55) && FuturisticCollarItems.length > 0 && DialogFocusItem) { InventoryItemNeckFuturisticCollarColor(C, DialogFocusItem); InventoryItemTorso2FuturisticHarnessExit();} - } -} - -function InventoryItemTorso2FuturisticHarnessExit() { - InventoryItemFuturisticExitAccessDenied(); -} \ No newline at end of file diff --git a/BondageClub/Scripts/Inventory.js b/BondageClub/Scripts/Inventory.js index 3907342f71448e1ecbe0528c1880053b09d20b51..72f6b9af86b92826330031255fbc279a764c2a79 100644 --- a/BondageClub/Scripts/Inventory.js +++ b/BondageClub/Scripts/Inventory.js @@ -534,16 +534,7 @@ function InventoryWearCraftModular(Item, Type) { * @returns {void} */ function InventoryWearCraftTyped(Item, Type) { - const Config = AssetFemale3DCGExtended[Item.Asset.Group.Name][Item.Asset.Name].Config; - if ((Config == null) || (Config.Options == null)) { - return; - } - for (const O of Config.Options) { - if (O.Name == Type) { - Item.Property = JSON.parse(JSON.stringify(O.Property)); - return; - } - } + TypedItemSetOptionByName(CharacterGetCurrent(), Item, Type); } /** diff --git a/BondageClub/Scripts/Typedef.d.ts b/BondageClub/Scripts/Typedef.d.ts index dae4e3db9103f64dbf9de67d9defff4d67366e17..b853b95b9fb6670fe37027c62a0fd1729bf71d73 100644 --- a/BondageClub/Scripts/Typedef.d.ts +++ b/BondageClub/Scripts/Typedef.d.ts @@ -1668,7 +1668,7 @@ type ModularItemAssetConfig = ExtendedItemAssetConfig<"modular", ModularItemConf /** An object defining all of the required configuration for registering a modular item */ interface ModularItemConfig { /** The module definitions for the item */ - Modules: ModularItemModule[]; + Modules?: ModularItemModule[]; /** * The item's chatroom message setting. Determines the level of * granularity for chatroom messages when the item's module values change. @@ -1689,7 +1689,8 @@ interface ModularItemConfig { Dialog?: ModularItemDialogConfig; /** * A recond 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 + * and parameters passed on to them. If undefined, these are ignored. + * Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`. */ ScriptHooks?: { Load?: (next: () => void) => void; @@ -1835,7 +1836,8 @@ interface ModularItemData { changeWhenLocked: boolean; /** * A recond 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 + * and parameters passed on to them. If undefined, these are ignored. + * Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`. */ scriptHooks?: { load?: (next: () => void) => void, @@ -1867,7 +1869,7 @@ type TypedItemAssetConfig = ExtendedItemAssetConfig<"typed", TypedItemConfig>; /** An object defining all of the required configuration for registering a typed item */ interface TypedItemConfig { /** The list of extended item options available for the item */ - Options: ExtendedItemOption[]; + Options?: ExtendedItemOption[]; /** The optional text configuration for the item. Custom text keys can be configured within this object */ Dialog?: TypedItemDialogConfig; /** @@ -1899,7 +1901,8 @@ interface TypedItemConfig { Dictionary?: TypedItemDictionaryCallback[]; /** * A recond 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 + * and parameters passed on to them. If undefined, these are ignored. + * Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`. */ ScriptHooks?: { Load?: (next: () => void) => void, @@ -1989,7 +1992,8 @@ interface TypedItemData { validate?: ExtendedItemValidateCallback<ExtendedItemOption>; /** * A recond 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 + * and parameters passed on to them. If undefined, these are ignored. + * Note that scripthook functions must be loaded before `Female3DCGExtended.js` in `index.html`. */ scriptHooks?: { load?: (next: () => void) => void, diff --git a/BondageClub/index.html b/BondageClub/index.html index 212d62ebb9a946af6eeb2b1dd0bb8961660cde33..a347f9042187b1c39bd3fb20a92f33c13e8a3710 100644 --- a/BondageClub/index.html +++ b/BondageClub/index.html @@ -64,6 +64,7 @@ <script src="Scripts/VariableHeight.js"></script> <script src="Assets/Female3DCG/Female3DCG.js"></script> <script src="Screens/Inventory/Futuristic/Futuristic.js"></script> +<script src="Screens/Inventory/ItemTorso/FuturisticHarness/FuturisticHarness.js"></script> <script src="Assets/Female3DCG/Female3DCGExtended.js"></script> <script src="Screens/Character/Login/Login.js"></script> <script src="Screens/Character/Appearance/Appearance.js"></script> @@ -193,8 +194,6 @@ <script src="Screens/Inventory/ItemMouth/FuturisticHarnessPanelGag/FuturisticHarnessPanelGag.js"></script> <script src="Screens/Inventory/ItemMouth/FuturisticHarnessBallGag/FuturisticHarnessBallGag.js"></script> <script src="Screens/Inventory/ItemNeck/FuturisticCollar/FuturisticCollar.js"></script> -<script src="Screens/Inventory/ItemTorso/FuturisticHarness/FuturisticHarness.js"></script> -<script src="Screens/Inventory/ItemTorso2/FuturisticHarness/FuturisticHarness.js"></script> <script src="Screens/Inventory/ItemHands/SpankingToys/SpankingToy.js"></script> <script src="Screens/Inventory/ItemFeet/HempRope/HempRope.js"></script> <script src="Screens/Inventory/ItemFeet/NylonRope/NylonRope.js"></script>