mirror of
https://gitgud.io/BondageProjects/Bondage-College.git
synced 2025-04-25 17:59:34 +00:00
Merge branch 'preference_extension' into 'master'
Add Extensions Preferences to Character Preferences See merge request BondageProjects/Bondage-College!4840
This commit is contained in:
commit
8da9779b4f
6 changed files with 207 additions and 11 deletions
BondageClub
Icons
Screens/Character/Preference
Scripts
BIN
BondageClub/Icons/Extensions.png
Normal file
BIN
BondageClub/Icons/Extensions.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.8 KiB |
|
@ -103,6 +103,13 @@ let PreferenceScriptTimeoutHandle = null;
|
|||
/** @type {null | number} */
|
||||
let PreferenceScriptTimer = null;
|
||||
let PreferenceScriptWarningAccepted = false;
|
||||
/** @type {Record<string,PreferenceExtensionsSettingItem>} */
|
||||
let PreferenceExtensionsSettings = {};
|
||||
/** @type {PreferenceExtensionsMenuButtonInfo[]} */
|
||||
let PreferenceExtensionsDisplay = [];
|
||||
/** @type {PreferenceExtensionsSettingItem | null}*/
|
||||
let PreferenceExtensionsCurrent = null;
|
||||
|
||||
|
||||
const ScriptPermissionLevel = Object.freeze({
|
||||
SELF: "Self",
|
||||
|
@ -725,12 +732,14 @@ function PreferenceRun() {
|
|||
DrawText(TextGet("Preferences"), 500, 125, "Black", "Gray");
|
||||
MainCanvas.textAlign = "center";
|
||||
|
||||
// Draw all the buttons to access the submenus
|
||||
for (let A = 0; A < PreferenceSubscreenList.length; A++) {
|
||||
DrawButton(500 + 420 * Math.floor(A / 7), 160 + 110 * (A % 7), 400, 90, "", "White", "Icons/" + PreferenceSubscreenList[A] + ".png");
|
||||
DrawTextFit(TextGet("Homepage" + PreferenceSubscreenList[A]), 745 + 420 * Math.floor(A / 7), 205 + 110 * (A % 7), 310, "Black");
|
||||
}
|
||||
// Only show the Extension settings if there are any registered
|
||||
const adjustedSubscreenList = Object.keys(PreferenceExtensionsSettings).length > 0 ? PreferenceSubscreenList.concat("Extensions") : PreferenceSubscreenList;
|
||||
|
||||
// Draw all the buttons to access the submenus
|
||||
for (let A = 0; A < adjustedSubscreenList.length; A++) {
|
||||
DrawButton(500 + 420 * Math.floor(A / 7), 160 + 110 * (A % 7), 400, 90, "", "White", "Icons/" + adjustedSubscreenList[A] + ".png");
|
||||
DrawTextFit(TextGet("Homepage" + adjustedSubscreenList[A]), 745 + 420 * Math.floor(A / 7), 205 + 110 * (A % 7), 310, "Black");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -863,14 +872,16 @@ function PreferenceClick() {
|
|||
// Exit button
|
||||
if (MouseIn(1815, 75, 90, 90)) PreferenceExit();
|
||||
|
||||
const adjustedSubscreenList = Object.keys(PreferenceExtensionsSettings).length > 0 ? PreferenceSubscreenList.concat("Extensions") : PreferenceSubscreenList;
|
||||
|
||||
// Open the selected subscreen
|
||||
for (let A = 0; A < PreferenceSubscreenList.length; A++)
|
||||
for (let A = 0; A < adjustedSubscreenList.length; A++)
|
||||
if (MouseIn(500 + 420 * Math.floor(A / 7), 160 + 110 * (A % 7), 400, 90)) {
|
||||
if (typeof window["PreferenceSubscreen" + PreferenceSubscreenList[A] + "Load"] === "function")
|
||||
CommonDynamicFunction("PreferenceSubscreen" + PreferenceSubscreenList[A] + "Load()");
|
||||
PreferenceSubscreen = PreferenceSubscreenList[A];
|
||||
if (typeof window["PreferenceSubscreen" + adjustedSubscreenList[A] + "Load"] === "function")
|
||||
CommonDynamicFunction("PreferenceSubscreen" + adjustedSubscreenList[A] + "Load()");
|
||||
PreferenceSubscreen = adjustedSubscreenList[A];
|
||||
PreferencePageCurrent = 1;
|
||||
if (PreferenceSubscreenList[A] === "Scripts") {
|
||||
if (adjustedSubscreenList[A] === "Scripts") {
|
||||
PreferenceScriptTimer = Date.now() + 5000;
|
||||
PreferenceScriptTimeoutHandle = setTimeout(() => {
|
||||
PreferenceScriptTimer = null;
|
||||
|
@ -3070,3 +3081,111 @@ var PreferenceOnlineSharedSettingsValidate = {
|
|||
};
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers a new extension setting to the preference screen
|
||||
* @param {PreferenceExtensionsSettingItem} Setting - The extension setting to register
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function PreferenceRegisterExtensionSetting(Setting) {
|
||||
if((typeof Setting.Identifier !== "string" || Setting.Identifier.length < 1)
|
||||
|| typeof Setting.load !== "function"
|
||||
|| typeof Setting.run !== "function"
|
||||
|| typeof Setting.click !== "function"
|
||||
|| (typeof Setting.ButtonText !== "string" && typeof Setting.ButtonText !== "function")
|
||||
|| (typeof Setting.Image !== "string" && typeof Setting.Image !== "function" && typeof Setting.Image !== "undefined")) {
|
||||
console.error("Invalid extension setting");
|
||||
return;
|
||||
}
|
||||
// Setting Names must be unique
|
||||
const existing = PreferenceExtensionsSettings[Setting.Identifier];
|
||||
if(existing) {
|
||||
console.error(`Extension setting "${existing.Identifier}" already exists`);
|
||||
return;
|
||||
}
|
||||
PreferenceExtensionsSettings[Setting.Identifier] = Setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the loading of the preference subscreen for extensions
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function PreferenceSubscreenExtensionsLoad() {
|
||||
PreferenceExtensionsDisplay = Object.keys(PreferenceExtensionsSettings).map(
|
||||
k => (
|
||||
s=>({
|
||||
Button: typeof s.ButtonText === "function" ? s.ButtonText() : s.ButtonText,
|
||||
Image: s.Image && (typeof s.Image === "function" ? s.Image() : s.Image),
|
||||
click: () => {
|
||||
PreferenceExtensionsCurrent = s;
|
||||
s?.load();
|
||||
}
|
||||
}))(PreferenceExtensionsSettings[k]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and draws the preference subscreen for extensions
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function PreferenceSubscreenExtensionsRun() {
|
||||
if(PreferenceExtensionsCurrent === null) {
|
||||
DrawCharacter(Player, 50, 50, 0.9);
|
||||
|
||||
MainCanvas.textAlign = "left";
|
||||
DrawText(TextGet("ExtensionsPreferences"), 500, 125, "Black", "Gray");
|
||||
|
||||
MainCanvas.textAlign = "center";
|
||||
PreferenceExtensionsDisplay.forEach((s, i) => {
|
||||
const X = 500 + Math.floor(i / 7) * 420;
|
||||
const Y = 160 + (i % 7) * 110;
|
||||
DrawButton(X, Y, 400, 90, "", "White", s.Image || null);
|
||||
DrawTextFit(s.Button, X + 245, Y + 45, 310, "Black");
|
||||
});
|
||||
|
||||
DrawButton(1815, 75, 90, 90, "", "White", "Icons/Exit.png");
|
||||
} else {
|
||||
PreferenceExtensionsCurrent.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles clicks in the preference subscreen for extensions
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function PreferenceSubscreenExtensionsClick() {
|
||||
if(PreferenceExtensionsCurrent === null) {
|
||||
if (MouseIn(1815, 75, 90, 90)) PreferenceSubscreenExtensionsExit();
|
||||
PreferenceExtensionsDisplay.forEach((s, i) => {
|
||||
const X = 500 + Math.floor(i / 7) * 420;
|
||||
const Y = 160 + (i % 7) * 110;
|
||||
if (MouseIn(X, Y, 400, 90)) s.click();
|
||||
});
|
||||
} else {
|
||||
PreferenceExtensionsCurrent.click();
|
||||
}
|
||||
}
|
||||
|
||||
function PreferenceSubscreenExtensionsUnload() {
|
||||
PreferenceExtensionsCurrent?.unload?.();
|
||||
}
|
||||
|
||||
function PreferenceSubscreenExtensionsExit() {
|
||||
if(PreferenceExtensionsCurrent === null) {
|
||||
PreferenceSubscreen = "";
|
||||
} else if(PreferenceExtensionsCurrent.exit()) {
|
||||
PreferenceSubscreenExtensionsClear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit the preference subscreen for extensions, should be called when
|
||||
* leaving custom menu of extensions if the extension exits the menu from itself.
|
||||
* @returns {void} - Nothing
|
||||
*/
|
||||
function PreferenceSubscreenExtensionsClear() {
|
||||
if(PreferenceSubscreen !== "Extensions" || PreferenceExtensionsCurrent === null) return;
|
||||
PreferenceExtensionsCurrent.unload();
|
||||
PreferenceExtensionsCurrent = null;
|
||||
// Reload the extension settings
|
||||
PreferenceSubscreenExtensionsLoad();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ ControllerPreferences,- Controller Preferences -
|
|||
NotificationsPreferences,- Notification Preferences -
|
||||
GenderPreferences,- Gender Preferences -
|
||||
ScriptsPreferences,- Script Permission Preferences -
|
||||
ExtensionsPreferences,- Extensions Preferences -
|
||||
HomepageGeneral,General
|
||||
HomepageDifficulty,Difficulty
|
||||
HomepageRestriction,Restriction
|
||||
|
@ -30,6 +31,7 @@ HomepageController,Controller
|
|||
HomepageNotifications,Notifications
|
||||
HomepageGender,Gender
|
||||
HomepageScripts,Scripts
|
||||
HomepageExtensions,Extensions
|
||||
DifficultyTitle,The difficulty mode enforces BDSM restrictions in multi-player only. Click for details.
|
||||
DifficultyLevel0,Roleplay
|
||||
Difficulty0Text0,Roleplay - This mode is fully open to customise your experience.
|
||||
|
|
|
|
@ -30,6 +30,8 @@
|
|||
- 性别设置 -
|
||||
- Script Permission Preferences -
|
||||
- 脚本权限设置 -
|
||||
- Extensions Preferences -
|
||||
- 扩展组件设置 -
|
||||
General
|
||||
通用
|
||||
Difficulty
|
||||
|
@ -62,6 +64,8 @@ Gender
|
|||
性别
|
||||
Scripts
|
||||
脚本
|
||||
Extensions
|
||||
扩展组件
|
||||
The difficulty mode enforces BDSM restrictions in multi-player only. Click for details.
|
||||
难度模式仅在多人游戏中使BDSM限制强制生效。点击以了解更多
|
||||
Roleplay
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
- 性別設置 -
|
||||
- Script Permission Preferences -
|
||||
- 腳本權限設定 -
|
||||
- Extensions Preferences -
|
||||
- 擴充組件設定 -
|
||||
General
|
||||
通用
|
||||
Difficulty
|
||||
|
@ -62,6 +64,8 @@ Gender
|
|||
性別
|
||||
Scripts
|
||||
腳本
|
||||
Extensions
|
||||
擴充組件
|
||||
The difficulty mode enforces BDSM restrictions in multi-player only. Click for details.
|
||||
難度模式僅在多人遊戲中使BDSM限制強制生效。點擊以了解更多
|
||||
Roleplay
|
||||
|
|
69
BondageClub/Scripts/Typedef.d.ts
vendored
69
BondageClub/Scripts/Typedef.d.ts
vendored
|
@ -355,7 +355,7 @@ type GraphicsFontName =
|
|||
type PreferenceSubscreenName =
|
||||
"General" | "Difficulty" | "Restriction" | "Chat" | "CensoredWords" | "Audio" | "Arousal" |
|
||||
"Security" | "Online" | "Visibility" | "Immersion" | "Graphics" | "Controller" | "Notifications" |
|
||||
"Gender" | "Scripts"
|
||||
"Gender" | "Scripts" | "Extensions"
|
||||
;
|
||||
|
||||
type FetishName =
|
||||
|
@ -3762,6 +3762,73 @@ interface ArousalSettingsType {
|
|||
DisableAdvancedVibes: boolean;
|
||||
}
|
||||
|
||||
/** Preference Menu info for extensions settings*/
|
||||
interface PreferenceExtensionsSettingItem {
|
||||
/**
|
||||
* The identifier of the extension.
|
||||
* This is used to identify the extension and should be unique.
|
||||
*/
|
||||
Identifier: string;
|
||||
|
||||
/**
|
||||
* The button text for the button of extension.
|
||||
* If it's a Function, it will be called once when entering
|
||||
* the extension setting menu. Use the return value as button text.
|
||||
*/
|
||||
ButtonText: string | (()=>string);
|
||||
|
||||
/**
|
||||
* The image path of the extension, and is passed
|
||||
* into {@link DrawButton} for creating the HTMLImageElement
|
||||
* that is needed for drawing the Button image.
|
||||
* If it's a Function, it will be called once when entering
|
||||
* the extension setting menu. Use the return value as image
|
||||
* path.
|
||||
* If it's undefined, there will be no image for the button
|
||||
*/
|
||||
Image?: string | (()=>string);
|
||||
|
||||
/** Handles loading on entering the extension setting */
|
||||
load?: () => void;
|
||||
|
||||
/** Handles the clicks of the extension setting */
|
||||
click: () => void;
|
||||
|
||||
/** Handles the run and draws of the extension setting */
|
||||
run: () => void;
|
||||
|
||||
/**
|
||||
* Handles the unloading of the extension setting, typically
|
||||
* from {@link CommonSetScreen}, when the player is disconnected.
|
||||
* If it's undefined, there will be no unloading for the extension
|
||||
* setting.
|
||||
* Remind to check those HTML elements that are created in the
|
||||
* extension setting, and hide/remove them from the DOM.
|
||||
* Note that HTML elements with `HideOnPopup` class will be hidden
|
||||
* automatically when a popup is shown.
|
||||
*/
|
||||
unload?: () => void;
|
||||
|
||||
/**
|
||||
* Handles the exits of the extension setting, typically when
|
||||
* user press `Esc` key.
|
||||
* If a extension wants to exit the menu by itself
|
||||
* (clicking `exit` button, etc.), the extension should call
|
||||
* `PreferenceSubscreenExtensionsClear`.
|
||||
* @returns If it returns `true`, the extension setting will be unload.
|
||||
* And `unload` will be called once if it's defined and then main extension
|
||||
* setting page is shown.
|
||||
*/
|
||||
exit: () => boolean | void;
|
||||
}
|
||||
|
||||
/** Preference Menu info for extensions settings*/
|
||||
type PreferenceExtensionsMenuButtonInfo = {
|
||||
Button: string;
|
||||
Image?: string;
|
||||
click: () => void;
|
||||
}
|
||||
|
||||
// #end region
|
||||
|
||||
// #region fortune wheel
|
||||
|
|
Loading…
Add table
Reference in a new issue