code:
var Remtairy = Remtairy || {};
Remtairy.CM = Remtairy.CM || {};

//=============================================================================
 /*:
 * @plugindesc ConfigManager
 * @author Remtairy
 *
 * @help
 * This is a private plugin.
 * Do not redistribute, use, or modify this plugin
 * without explicit written permission from Remtairy.
 *
 */
//=============================================================================

const EDICTS_OUTLINE_COLOR_OBTAINABLE_GREEN_ID = 0;
const EDICTS_OUTLINE_COLOR_OBTAINABLE_LIGHTBLUE_ID = 1;
const EDICTS_OUTLINE_COLOR_METREQ_YELLOW_ID = 0;
const EDICTS_OUTLINE_COLOR_METREQ_PURPLE_ID = 1;
const EDICTS_OUTLINE_COLOR_NOREQ_BLACK_ID = 0;
const EDICTS_OUTLINE_COLOR_NOREQ_GRAY_ID = 1;
const EDICTS_OUTLINE_COLOR_NOREQ_RED_ID = 2;

const YANFLY_CONFIG_GAUGE_Y_OFFSET = 6;

///////////
// ConfigManager
////////////////

ConfigManager.synchFps = false;
ConfigManager.safeMode = false;
ConfigManager.replayMode = false;
ConfigManager.pixelMovement = true;
ConfigManager.remMapEffect = true;
ConfigManager.remDisableScreenFlash = false;
ConfigManager.karrynLinesPrompt = true;
ConfigManager.remLinesFast = false;
ConfigManager.remCutinsFast = false;
ConfigManager.remCutinsSmootherLoading = false;
ConfigManager.remSmootherCGLoading = false;
ConfigManager.remCutinsDisabled = false;
ConfigManager.remShowSexualDamagePopup = true;
ConfigManager.disableFootjobs = false;
ConfigManager.disableRimjobs = false;
ConfigManager.disableSmegma = false;
ConfigManager.disableFeraMouth = false;
ConfigManager.keepVoicePlayback = false;
ConfigManager.autoContinueAfterVoice = true;
ConfigManager.remBattlelogDuration = 2;
ConfigManager.remBattlelogFontSize = 2;
ConfigManager.remMaleDialogueAppear = 3;
ConfigManager.sortPassivesAscending = false;
ConfigManager.cancelSkipMentalPhase = false;
ConfigManager.remLanguage = RemLanguageEN;
ConfigManager.remVoiceLanguage = RemLanguageEN;
ConfigManager.displayPubic = true;
ConfigManager.displayPleasureAsPercent = true;
ConfigManager.shorterDefeatBattles = false;
ConfigManager.masterVolume = 80;
ConfigManager.voiceVolume = 100;
ConfigManager.moanVolume = 40;
ConfigManager.seVolume = 40;
ConfigManager.bgmVolume = 40;
ConfigManager.maleVolume = 30;

ConfigManager.edictsOutlineColorObtainable = 0;
ConfigManager.edictsOutlineColorMeetReq = 0;
ConfigManager.edictsOutlineColorNoReq = 0;

ConfigManager.cheatEnemyDoublePhysicalDamage = false;
ConfigManager.cheatEnemyTriplePhysicalDamage = false;
ConfigManager.cheatEnemyDoubleSexualDamage = false;
ConfigManager.cheatEnemyTripleSexualDamage = false;
ConfigManager.cheatEnemyDoubleOrgasmPoint = false;
ConfigManager.cheatEnemyAlwaysAct = false;
ConfigManager.cheatActorDoublePassiveGain = false;
ConfigManager.cheatActorHalfStaminaRegen = false;
ConfigManager.cheatActorThirdStaminaRegen = false;
ConfigManager.cheatActorHalfExpRate = false;
ConfigManager.cheatActorNoEvasion = false;
ConfigManager.cheatLessControlFive = false;
ConfigManager.cheatLessControlTen = false;
ConfigManager.cheatInstantRiotsOne = false;
ConfigManager.cheatInstantRiotsTwo = false;
ConfigManager.cheatInstantRiotsThree = false;
ConfigManager.cheatInstantRiotsFour = false;
ConfigManager.cheatWaitressLog = false;
ConfigManager.cheatDisableAutosave = false;

Object.defineProperty(ConfigManager, 'bgmVolume', {
    get: function() {
        return AudioManager._bgmVolume;
    },
    set: function(value) {
        AudioManager.bgmVolume = value;
		AudioManager.meVolume = value;
    },
    configurable: true
});

Object.defineProperty(ConfigManager, 'bgsVolume', {
    get: function() {
        return AudioManager.seVolume;
    },
    set: function(value) {
        AudioManager.bgsVolume = value;
    },
    configurable: true
});

Object.defineProperty(ConfigManager, 'meVolume', {
    get: function() {
        return AudioManager._bgmVolume;
    },
    set: function(value) {
        AudioManager.meVolume = value;
    },
    configurable: true
});

Object.defineProperty(ConfigManager, 'seVolume', {
    get: function() {
        return AudioManager.seVolume;
    },
    set: function(value) {
        AudioManager.seVolume = value;
		AudioManager.bgsVolume = value;
    },
    configurable: true
});

Object.defineProperty(ConfigManager, 'voiceVolume', {
    get: function() {
        return AudioManager.voiceVolume;
    },
    set: function(value) {
        AudioManager.voiceVolume = value;
    },
    configurable: true
});

Object.defineProperty(ConfigManager, 'moanVolume', {
    get: function() {
        return AudioManager.moanVolume;
    },
    set: function(value) {
        AudioManager.moanVolume = value;
    },
    configurable: true
});

Object.defineProperty(ConfigManager, 'maleVolume', {
    get: function() {
        return AudioManager.maleVolume;
    },
    set: function(value) {
        AudioManager.maleVolume = value;
    },
    configurable: true
});

Remtairy.CM.ConfigManager_applyData = ConfigManager.applyData;
ConfigManager.applyData = function(config) {
	Remtairy.CM.ConfigManager_applyData.call(this, config);

	//this.remLanguage = config['remLanguage'];
	//if(this.remLanguage !== RemLanguageJP && this.remLanguage !== RemLanguageEN)
	//	this.remLanguage = KARRYN_PRISON_LANGUAGE;
	this.remLanguage = this.readRemConfig(config, 'remLanguage');
	this.remVoiceLanguage = this.readRemConfig(config, 'remVoiceLanguage');

	this.synchFps = this.readRemConfig(config, 'synchFps');
	this.safeMode = config['safeMode'];
	this.replayMode = config['replayMode'];
	this.pixelMovement = this.readRemConfig(config, 'pixelMovement');

	this.remMapEffect = this.readRemConfig(config, 'remMapEffect');
	this.remDisableScreenFlash = this.readRemConfig(config, 'remDisableScreenFlash');
	this.remLinesFast = config['remLinesFast'];
	this.karrynLinesPrompt = this.readRemConfig(config, 'karrynLinesPrompt');
	this.remCutinsFast = config['remCutinsFast'];
	this.remCutinsSmootherLoading = this.readRemConfig(config, 'remCutinsSmootherLoading');
	this.remSmootherCGLoading = this.readRemConfig(config, 'remSmootherCGLoading');
	this.remCutinsDisabled = this.readRemConfig(config, 'remCutinsDisabled');
	this.remShowSexualDamagePopup = this.readRemConfig(config, 'remShowSexualDamagePopup');

	this.disableFootjobs = this.readRemConfig(config, 'disableFootjobs');
	this.disableRimjobs = this.readRemConfig(config, 'disableRimjobs');
	this.disableSmegma = this.readRemConfig(config, 'disableSmegma');
	this.disableFeraMouth = this.readRemConfig(config, 'disableFeraMouth');

	this.keepVoicePlayback = this.readRemConfig(config, 'keepVoicePlayback');
	this.autoContinueAfterVoice = this.readRemConfig(config, 'autoContinueAfterVoice');

	this.remBattlelogDuration = this.readRemConfig(config, 'remBattlelogDuration');
	this.remBattlelogFontSize = this.readRemConfig(config, 'remBattlelogFontSize');
	this.remMaleDialogueAppear = this.readRemConfig(config, 'remMaleDialogueAppear');
	this.displayPleasureAsPercent = this.readRemConfig(config, 'displayPleasureAsPercent');

	this.voiceVolume = this.readRemVolume(config, 'voiceVolume');
    this.moanVolume = this.readRemVolume(config, 'moanVolume');
	this.masterVolume = this.readRemVolume(config, 'masterVolume');
	this.bgmVolume = this.readRemVolume(config, 'bgmVolume');
    this.seVolume = this.readRemVolume(config, 'seVolume');
	this.maleVolume = this.readRemVolume(config, 'maleVolume');

	this.sortPassivesAscending = this.readRemConfig(config, 'sortPassivesAscending');
	this.cancelSkipMentalPhase = this.readRemConfig(config, 'cancelSkipMentalPhase');
	this.displayPubic = this.readRemConfig(config, 'displayPubic');
	this.shorterDefeatBattles = this.readRemConfig(config, 'shorterDefeatBattles');

	this.edictsOutlineColorObtainable = this.readRemConfig(config, 'edictsOutlineColorObtainable');
	this.edictsOutlineColorMeetReq = this.readRemConfig(config, 'edictsOutlineColorMeetReq');
	this.edictsOutlineColorNoReq = this.readRemConfig(config, 'edictsOutlineColorNoReq');

	this.cheatEnemyDoublePhysicalDamage = this.readRemConfig(config, 'cheatEnemyDoublePhysicalDamage');
	this.cheatEnemyTriplePhysicalDamage = this.readRemConfig(config, 'cheatEnemyTriplePhysicalDamage');
	this.cheatEnemyDoubleSexualDamage = this.readRemConfig(config, 'cheatEnemyDoubleSexualDamage');
	this.cheatEnemyTripleSexualDamage = this.readRemConfig(config, 'cheatEnemyTripleSexualDamage');
	this.cheatEnemyDoubleOrgasmPoint = this.readRemConfig(config, 'cheatEnemyDoubleOrgasmPoint');
	this.cheatEnemyAlwaysAct = this.readRemConfig(config, 'cheatEnemyAlwaysAct');

	this.cheatActorDoublePassiveGain = this.readRemConfig(config, 'cheatActorDoublePassiveGain');
	this.cheatActorHalfStaminaRegen = this.readRemConfig(config, 'cheatActorHalfStaminaRegen');
	this.cheatActorThirdStaminaRegen = this.readRemConfig(config, 'cheatActorThirdStaminaRegen');
	this.cheatActorHalfExpRate = this.readRemConfig(config, 'cheatActorHalfExpRate');
	this.cheatActorNoEvasion = this.readRemConfig(config, 'cheatActorNoEvasion');
	this.cheatLessControlFive = this.readRemConfig(config, 'cheatLessControlFive');
	this.cheatLessControlTen = this.readRemConfig(config, 'cheatLessControlTen');
	this.cheatInstantRiotsOne = this.readRemConfig(config, 'cheatInstantRiotsOne');
	this.cheatInstantRiotsTwo = this.readRemConfig(config, 'cheatInstantRiotsTwo');
	this.cheatInstantRiotsThree = this.readRemConfig(config, 'cheatInstantRiotsThree');
	this.cheatInstantRiotsFour = this.readRemConfig(config, 'cheatInstantRiotsFour');
	this.cheatWaitressLog = this.readRemConfig(config, 'cheatWaitressLog');
	this.cheatDisableAutosave = this.readRemConfig(config, 'cheatDisableAutosave');

};

Remtairy.CM.ConfigManager_makeData = ConfigManager.makeData;
ConfigManager.makeData = function() {
	let config = Remtairy.CM.ConfigManager_makeData.call(this);
	config.remBattlelogDuration = this.remBattlelogDuration;
	config.remBattlelogFontSize = this.remBattlelogFontSize;
	config.remMaleDialogueAppear = this.remMaleDialogueAppear;
	config.synchFps = this.synchFps;
	config.voiceVolume = this.voiceVolume;
    config.moanVolume = this.moanVolume;
	config.maleVolume = this.maleVolume;
	return config;
};

ConfigManager.readRemVolume = function(config, name) {
    let value = config[name];
    if (value !== undefined) {
        return Number(value).clamp(0, 100);
    } else {
		switch(name) {
        case 'masterVolume':
			return 100;
		case 'moanVolume':
			return 30;
		case 'voiceVolume':
			return 100;
		case 'seVolume':
			return 50;
		case 'bgmVolume':
			return 50;
		case 'maleVolume':
			return 50;
		}
    }
};

ConfigManager.readRemConfig = function(config, name) {
	let value = config[name];
	if (value !== undefined) {
		return value;
	} else {
		switch(name) {
		case 'remBattlelogDuration':
			return 2;
		case 'remBattlelogFontSize':
			return 2;
		case 'remMaleDialogueAppear':
			return 3;
		case 'pixelMovement':
			return true;
		case 'remMapEffect':
			return true;
		case 'remDisableScreenFlash':
			return false;
		case 'karrynLinesPrompt':
			return true;
		case 'remCutinsSmootherLoading':
			return false;
		case 'remSmootherCGLoading':
			return false;
		case 'remCutinsDisabled':
			return false;
		case 'remShowSexualDamagePopup':
			return true;
		case 'displayPleasureAsPercent':
			return true;
		case 'disableFootjobs':
			return false;
		case 'disableRimjobs':
			return false;
		case 'disableSmegma':
			return false;
		case 'disableFeraMouth':
			return false;

		case 'keepVoicePlayback':
			return false;
		case 'autoContinueAfterVoice':
			return true;
		case 'synchFps':
			return false;

		case 'edictsOutlineColorObtainable':
			return EDICTS_OUTLINE_COLOR_OBTAINABLE_GREEN_ID;
		case 'edictsOutlineColorMeetReq':
			return EDICTS_OUTLINE_COLOR_METREQ_YELLOW_ID;
		case 'edictsOutlineColorNoReq':
			return EDICTS_OUTLINE_COLOR_NOREQ_GRAY_ID;

		case 'cheatEnemyDoublePhysicalDamage':
			return false;
		case 'cheatEnemyTriplePhysicalDamage':
			return false;
		case 'cheatEnemyDoubleSexualDamage':
			return false;
		case 'cheatEnemyTripleSexualDamage':
			return false;
		case 'cheatEnemyDoubleOrgasmPoint':
			return false;

		case 'cheatEnemyAlwaysAct':
			return false;

		case 'cheatActorDoublePassiveGain':
			return false;
		case 'cheatActorHalfStaminaRegen':
			return false;
		case 'cheatActorThirdStaminaRegen':
			return false;
		case 'cheatActorHalfExpRate':
			return false;
		case 'cheatActorNoEvasion':
			return false;
		case 'cheatLessControlFive':
			return false;
		case 'cheatLessControlTen':
			return false;
		case 'cheatInstantRiotsOne':
			return false;
		case 'cheatInstantRiotsTwo':
			return false;
		case 'cheatInstantRiotsThree':
			return false;
		case 'cheatInstantRiotsFour':
			return false;
		case 'cheatWaitressLog':
			return false;
		case 'cheatDisableAutosave':
			return false;

		case 'sortPassivesAscending':
			return false;
		case 'shorterDefeatBattles':
			return false;
		case 'displayPubic':
			return true;

		case 'remLanguage':
			return KARRYN_PRISON_LANGUAGE;
		case 'remVoiceLanguage':
			return KARRYN_PRISON_LANGUAGE;

		default:
			return false;
		}
	}
};

ConfigManager.readConfigMessageSpeed = function(config, name) {
	let value = config[name];
	if(value !== undefined) {
		return value;
	} else {
		return 10;
	}
};

//////////////////
// Window Options
//////////////////

Remtairy.CM.Window_Options_addGeneralOptions = Window_Options.prototype.addGeneralOptions;
Window_Options.prototype.addGeneralOptions = function() {
	Remtairy.CM.Window_Options_addGeneralOptions.call(this);
	if (Imported.YEP_OptionsCore) return;
	this.addRemOptions();
};

Window_Options.prototype.addRemOptions = function() {
	this.addCommand(TextManager.safeMode, 'safeMode');
	this.addCommand(TextManager.replayMode, 'replayMode');
	this.addCommand(TextManager.pixelMovement, 'pixelMovement');
	this.addCommand(TextManager.remLanguage, 'remLanguage');
	this.addCommand(TextManager.remVoiceLanguage, 'remVoiceLanguage');

	this.addCommand(TextManager.yanflyOptionsDisableRimjob, 'disableFootjobs');
	this.addCommand(TextManager.yanflyOptionsDisableRimjob, 'disableRimjobs');
	this.addCommand(TextManager.yanflyOptionsDisableSmegma, 'disableSmegma');
	this.addCommand(TextManager.yanflyOptionsDisableFeraMouth, 'disableFeraMouth');

	this.addCommand(TextManager.yanflyOptionsKeepVoicePlayback, 'keepVoicePlayback');
	this.addCommand(TextManager.yanflyOptionsAutoContinueAfterVoice, 'autoContinueAfterVoice');

	this.addCommand(TextManager.yanflyOptionsDisplayPleasureAsPercent, 'displayPleasureAsPercent');

	this.addCommand(TextManager.yanflyOptionsMapEffects, 'remMapEffect');
	this.addCommand(TextManager.yanflyOptionsDisableFlashing, 'remDisableScreenFlash');

	this.addCommand(TextManager.yanflyOptionsKarrynLinesPrompt, 'karrynLinesPrompt');
	this.addCommand(TextManager.yanflyOptionsFasterBattleDialogue, 'remLinesFast');
	this.addCommand(TextManager.yanflyOptionsFasterBattleCutins, 'remCutinsFast');
	this.addCommand(TextManager.yanflyOptionsSmootherBattleCutinLoading, 'remCutinsSmootherLoading');
	this.addCommand(TextManager.yanflyOptionsSmootherCGLoading, 'remSmootherCGLoading');
	this.addCommand(TextManager.yanflyOptionsDisableBattleCutins, 'remCutinsDisabled');

	this.addCommand(TextManager.yanflyOptionsShowSexualDamagePopup, 'remShowSexualDamagePopup');

	this.addCommand(TextManager.yanflyOptionsBattlelogDuration, 'remBattlelogDuration');
	this.addCommand(TextManager.yanflyOptionsBattlelogFontsize, 'remBattlelogFontSize');

	this.addCommand(TextManager.yanflyOptionsMaleDialogueAppear, 'remMaleDialogueAppear');

	this.addCommand(TextManager.yanflyOptionsSortPassivesAscending, 'sortPassivesAscending');

	this.addCommand(TextManager.yanflyOptionsCancelSkipMentalPhase, 'cancelSkipMentalPhase');
};

Remtairy.CM.Window_Options_statusText = Window_Options.prototype.statusText;
Window_Options.prototype.statusText = function(index) {
	let symbol = this.commandSymbol(index);
	let value = this.getConfigValue(symbol);
	if(symbol === 'remLanguage') {
		if(value == RemLanguageJP)
			return "日本語";
		else if(value == RemLanguageEN)
			return "English";
		else if(value == RemLanguageTCH)
			return "繁體中文";
		else if(value == RemLanguageSCH)
			return "简体中文";
		else if(value == RemLanguageKR)
			return "한국어";
		else if(value == RemLanguageRU)
			return "русский";
		else
			return "error";
	}
	else if(symbol === 'remVoiceLanguage') {
		if(value == RemLanguageJP)
			return "日本語";
		else if(value == RemLanguageEN)
			return "English";
		else
			return "error";
	}
	else if(symbol === 'edictsOutlineColorObtainable' || symbol === 'edictsOutlineColorMeetReq' || symbol === 'edictsOutlineColorNoReq') {
		return TextManager.edictsOutlineColorOption(symbol, value);
	}
	else if(symbol === 'remBattlelogDuration') {
		return TextManager.battlelogDurationOption(value);
	}
	else if(symbol === 'remBattlelogFontSize') {
		return TextManager.battlelogFontSizeOption(value);
	}

	else if(symbol === 'remMaleDialogueAppear') {
		return TextManager.maleDialogueAppearOption(value);
	}
	else {
		return Remtairy.CM.Window_Options_statusText.call(this, index);
	}
};

Window_Options.prototype.changePaintOpacity = function(enabled) {
	this.contents.fontBold = enabled;
    this.contents.paintOpacity = enabled ? 255 : this.translucentOpacity();
};

Window_Options.prototype.drawOptionsFullscreen = function(index) {
	let onText = 'Fullscreen';
	let offText = 'Window';
	var rect = this.itemRectForText(index);
	var statusWidth = this.statusWidth();
	var halfStatusWidth = this.statusWidth() / 2;
	var titleWidth = rect.width - statusWidth;
	this.resetTextColor();
	var symbol = this.commandSymbol(index);
	var value = this.getConfigValue(symbol);
	this.changePaintOpacity(!value);
	this.drawText(offText, titleWidth, rect.y, halfStatusWidth, 'center');
	this.changePaintOpacity(value);
	this.drawText(onText, titleWidth + halfStatusWidth, rect.y, halfStatusWidth, 'center');
};

//Credits to https://github.com/ivan02022000/rpg-maker-files/blob/9607c1c95783d291ae757b22701dec19f50b72b0/FullscreenToggleOption_change
Window_Options.prototype.lastInput = false;

Window_Options_processHandling = Window_Options.prototype.processHandling
Window_Options.prototype.processHandling = function() {
	if (this.isOpenAndActive()) {
			if (this.lastInput){
				this.refresh();
				this.lastInput = false;
		} else if ((this.isOkEnabled() && this.isOkTriggered()) ||
		 (TouchInput.isTriggered() && this.isTouchedInsideFrame())){
			this.lastInput = true;
		}
	}
	Window_Options_processHandling.call(this);
};