prison-brave/js/plugins/SceneLewdStatus.js
2025-08-28 23:16:35 -05:00

983 lines
35 KiB
JavaScript

//=============================================================================
// RPG Maker MZ - SceneLewdStatus
//
// Copyright 2024 Panzer-IV. All rights reserved.
// This source code or any portion thereof must not be
// reproduced or used without licensed in any manner whatsoever.
//=============================================================================
/*:
* @target MZ
* @plugindesc みんぱぶエロステ画面プラグイン
* @author 四号戦車
* @base PluginCommonBase
* @base DebugSwitch
* @base TextResource
* @base PluginUtils
* @orderAfter PluginCommonBase
* @orderAfter DebugSwitch
* @orderAfter TextResource
* @orderAfter PluginUtils
*
* @param bgm
* @text シーンのBGM
* @desc シーン中再生するBGMを指定します。
* @type file
* @dir audio/bgm
* @default
*
* @param lewdLevel1
* @text 勇者レベル
* @desc エロステ値を管理する変数を指定して下さい。
* @type variable
* @default 0
*
* @param lewdLevel2
* @text 娼婦レベル
* @desc エロステ値を管理する変数を指定して下さい。
* @type variable
* @default 0
*
* @param playerActor
* @text プレイヤー
* @desc レベル表示するプレイヤーを指定します
* @type actor
* @default 0
*
* @param lewdStage
* @text エロステ段階の変数
* @desc エロステ段階を管理する変数を指定してください
* @type variable
* @default 0
*
* @param comment
* @text 備考欄
* @desc プラグイン側では使用しません。
* メモ欄としてお使いください。
* @type multiline_string
* @default
*
* @requiredAssets img/system/lewd_status/background
* @requiredAssets img/system/lewd_status/back_button
* @requiredAssets img/system/lewd_status/frame
* @requiredAssets img/system/lewd_status/body_mask
* @requiredAssets img/system/lewd_status/body/stage_1
* @requiredAssets img/system/lewd_status/body/stage_2
* @requiredAssets img/system/lewd_status/body/stage_3
* @requiredAssets img/system/lewd_status/body/stage_4
* @requiredAssets img/system/lewd_status/body_background
*
* @help SceneLewdStatus.js
*
* Version: 0.0.2
*
* エロステ画面プラグイン
*
* @command startScene
* @text エロステ画面表示
* @desc エロステ画面を表示します
*
*/
(() => {
"use strict";
//========================================================================
// プラグイン定義
//========================================================================
const pluginName = "SceneLewdStatus";
const script = document.currentScript;
const param = PluginUtils.reparseParameter(script);
//========================================================================
// 定数定義
//========================================================================
const UI_AREA_X = 7;
const UI_AREA_Y = 0;
const LEWD_LEVEL_WIDTH = 260;
const LEWD_LEVEL_HEIGHT = 58;
const LEWD_LEVEL_MERGIN = 12;
const TITLE_TEXT = "0900-003-n003-0"; // 画面タイトル
const SYSTEM_LEWD_VALUE1 = "0900-030-n030-0"; // ゲージタイトル(勇者レベル)
const SYSTEM_LEWD_VALUE2 = "0900-031-n031-0"; // ゲージタイトル(娼婦レベル)
const SYSTEM_TOTAL_LEBEL = "0900-033-n033-0"; // ラベル(総合レベル)
const ITEM_WIDTH = 518;
const ITEM_HEIGHT = 60;
const ITEM_MERGIN = 8;
const CONTENT_AREA_WIDTH = 682;
const CONTENT_AREA_HEIHGT = 670;
const DESCRIPTION_LINE_HEIGHT = 40;
const DESCRIPTION_MERGIN = 18;
const CONTENT_LINE_WIDTH = 3;
const CONTENT_TOP = 134;
//========================================================================
// Helpers (word wrapping for English)
//========================================================================
/**
* Wrap text into multiple lines so that each line fits within maxWidth (in pixels)
* using the provided bitmap's current font settings. Preserves existing newlines.
* Falls back to character-level splitting if a single word is too wide.
* @param {string} text
* @param {Bitmap} bitmap
* @param {number} maxWidth
* @returns {string[]}
*/
function wrapTextToWidth(text, bitmap, maxWidth) {
if (!text) return [""];
const lines = [];
const rawLines = String(text).replace(/\r\n?|\u2028/g, "\n").split("\n");
for (const raw of rawLines) {
const words = raw.split(/(\s+)/); // keep whitespace tokens to avoid collapsing spaces
let current = "";
for (let i = 0; i < words.length; i++) {
const token = words[i];
const tentative = current + token;
const w = bitmap.measureTextWidth(tentative);
if (w <= maxWidth) {
current = tentative;
continue;
}
// If current is empty and a single token is too big, split the token by chars
if (!current) {
const split = splitLongTokenByChars(token, bitmap, maxWidth);
// take all but last as full lines, last continues
for (let j = 0; j < split.length - 1; j++) {
lines.push(split[j]);
}
current = split[split.length - 1];
} else {
// push the line and start new with token
if (current.trim().length > 0) lines.push(current.trimEnd());
// token itself might still be too big
const split = splitLongTokenByChars(token, bitmap, maxWidth);
for (let j = 0; j < split.length - 1; j++) {
lines.push(split[j]);
}
current = split[split.length - 1];
}
}
if (current.trim().length > 0 || raw === "") {
lines.push(current.trimEnd());
}
}
// Ensure at least one line
return lines.length > 0 ? lines : [""];
}
function splitLongTokenByChars(token, bitmap, maxWidth) {
const chunks = [];
let buf = "";
for (const ch of token) {
const tentative = buf + ch;
if (bitmap.measureTextWidth(tentative) <= maxWidth) {
buf = tentative;
} else {
if (buf) chunks.push(buf);
buf = ch;
}
}
if (buf) chunks.push(buf);
return chunks.length ? chunks : [token];
}
//========================================================================
// 定数定義(ゲーム固有)
//========================================================================
const State = {
PUSSY: { // おまんこ
name: 'PUSSY',
label: '0900-011-n011-0',
texts: [
"0910-001-n001-0",
"0910-002-n002-0",
"0910-003-n003-0",
"0910-004-n004-0",
],
position: new Point(-415, 434),
},
BREASTS: { // おっぱい
name: 'BREASTS',
label: '0900-012-n012-0',
texts: [
"0920-001-n001-0",
"0920-002-n002-0",
"0920-003-n003-0",
"0920-004-n004-0",
],
position: new Point(-436, 332),
},
BUTT: { // お尻
name: 'BUTT',
label: '0900-013-n013-0',
texts: [
"0930-001-n001-0",
"0930-002-n002-0",
"0930-003-n003-0",
"0930-004-n004-0",
],
position: new Point(-524, 516),
},
MOUTH: { // おクチ
name: 'MOUTH',
label: '0900-014-n014-0',
texts: [
"0940-001-n001-0",
"0940-002-n002-0",
"0940-003-n003-0",
"0940-004-n004-0",
],
position: new Point(-470, 0),
},
WOMB: { // 子宮
name: 'WOMB',
label: '0900-017-n017-0',
texts: [
"0950-001-n001-0",
"0950-002-n002-0",
"0950-003-n003-0",
"0950-004-n004-0",
],
position: new Point(-407, 525),
},
MIND: { // 精神
name: 'MIND',
label: '0900-018-n018-0',
texts: [
"0960-001-n001-0",
"0960-002-n002-0",
"0960-003-n003-0",
"0960-004-n004-0",
],
position: new Point(-440, 320),
},
};
//========================================================================
// クラス定義 (SceneLewdStatus)
//========================================================================
class SceneLewdStatus extends Scene_Base {
constructor() {
super();
this.images = {};
this.isImageLoaded = false;
this.runOnExit = false;
this.interpreter = null;
this._state = null;
this.stateSprite = {};
this.currentStage = null;
}
create() {
super.create();
this.createWindowLayer();
let promises = [
ImageManager.loadSystemAsync("lewd_status/background"),
ImageManager.loadSystemAsync("lewd_status/back_button"),
ImageManager.loadSystemAsync("lewd_status/frame"),
ImageManager.loadSystemAsync("lewd_status/body_mask"),
ImageManager.loadSystemAsync("lewd_status/body/stage_1"),
ImageManager.loadSystemAsync("lewd_status/body/stage_2"),
ImageManager.loadSystemAsync("lewd_status/body/stage_3"),
ImageManager.loadSystemAsync("lewd_status/body/stage_4"),
ImageManager.loadSystemAsync("lewd_status/body_background"),
];
const bgBitmap = new Bitmap(Graphics.width, Graphics.height);
bgBitmap.fillAll('#000000');
this.blackBackground = new Sprite(bgBitmap);
this.blackBackground.setFrame(0, 0, Graphics.width, Graphics.height);
this.blackBackground.zIndex = 0;
this.addChild(this.blackBackground);
Promise.all(promises).then(images => {
this.createDisplayObjects(images);
this.isImageLoaded = true;
});
}
createDisplayObjects(images) {
this.background = new Sprite(images[0]);
this.background.zIndex = 1;
this.addChild(this.background);
this.baseSprites = this.createSprites(images);
this.content = this.createContentSprite(images, images[2].width, images[2].height);
if (!!this.content) {
this.content.move(UI_AREA_X, UI_AREA_Y);
this.content.zIndex = 100;
this.addChild(this.content);
}
this.window = this.createMessageWindow();
this.addWindow(this.window);
this.sortChildren();
}
createSprites(images) {
const sprites = [];
const uiWidth = images[2].width;
const uiHeight = images[2].height;
const frame = new Sprite(new Bitmap(uiWidth, uiHeight));
const frameBitmap = frame.bitmap;
frameBitmap.blt(images[2], 0, 0, uiWidth, uiHeight, 0, 0);
frameBitmap.textColor = '#FFFFFF';
frameBitmap.fontFace = 'genkai-mincho';
frameBitmap.outlineWidth = 0;
frameBitmap.fontSize = 64;
frameBitmap.drawText(TextResource.getText(TITLE_TEXT), 52, 46, 1200, 64, 'left');
frame.move(7, 0);
frame.zIndex = 60;
this.addChild(frame);
sprites.push(frame);
const backButtonArea = new Sprite_InputHandle();
backButtonArea.bitmap = images[1];
backButtonArea.setFrame(0, 0, 72, 72);
backButtonArea.addEnterListener(() => {
if (this.handleBackButtonClicked()) {
if (!this.runOnExit && !this.isBusy()) {
this._exit();
}
}
});
backButtonArea.move(1830, 990);
backButtonArea.zIndex = 3;
this.addChild(backButtonArea);
sprites.push(backButtonArea);
const bar1 = this.createLewdGauge(param.lewdLevel1, SYSTEM_LEWD_VALUE1);
bar1.move(902, 846);
bar1.zIndex = 100;
this.addChild(bar1);
sprites.push(bar1);
const bar2 = this.createLewdGauge(param.lewdLevel2, SYSTEM_LEWD_VALUE2);
bar2.move(902, 918);
bar2.zIndex = 100;
this.addChild(bar2);
sprites.push(bar2);
const level = $gameActors.actor(param.playerActor).level;
const levelTextBitmap = new Bitmap(918, 50);
levelTextBitmap.textColor = '#FFFFFF';
levelTextBitmap.fontFace = 'MPLUS1Code-Regular';
levelTextBitmap.outlineWidth = 0;
levelTextBitmap.fontSize = 40;
levelTextBitmap.drawText(TextResource.getText(SYSTEM_TOTAL_LEBEL), 0, 0, 230, levelTextBitmap.height, 'left');
levelTextBitmap.drawText(level, 818, 0, 100, levelTextBitmap.height, 'right');
const levelText = new Sprite(levelTextBitmap);
levelText.move(902, 986);
levelText.zIndex = 100;
this.addChild(levelText);
sprites.push(levelText);
return sprites;
}
createContentSprite(images, width, height) {
const content = new Sprite(new Bitmap(width, height));
const charaBackGround = new Sprite(images[8]);
charaBackGround.move(1265, 33);
charaBackGround.zIndex = 1;
content.addChild(charaBackGround);
const chMask = new Sprite(images[3]);
this.character = new Sprite_Scrollable(images[3].width, images[2].height, chMask);
this.leveledCharacters = [ 0, 1, 2, 3 ].map(index => {
const chImageSprite = new Sprite(images[index + 4]);
chImageSprite.zIndex = 1;
chImageSprite.hide();
this.character.addChild(chImageSprite);
return chImageSprite;
});
this.character.enableLimit(false);
this.character.enableInput(false);
this.character.zIndex = 3;
this.character.move(1265, 33);
content.addChild(this.character);
this.stateMenuArea = new Sprite_Scrollable(ITEM_WIDTH, CONTENT_AREA_HEIHGT);
this.stateMenuArea.enableScroll(false);
this.stateMenus = this.createMenuSprite(Object.values(State)).map(sprite => {
this.stateMenuArea.addChild(sprite);
return sprite;
});
this.stateMenuArea.move(39, CONTENT_TOP);
this.stateMenuArea.zIndex = 2;
content.addChild(this.stateMenuArea);
this.descriptionArea = this.createDescriptionFrame();
const descriptionEntries = Object.values(State).map(state => {
return [ state.name, {
state: state.name,
sprites: [ 1, 2, 3, 4 ].map(level => {
const sprite = this.createDescriptionText(state, level);
sprite.hide();
this.descriptionArea.addChild(sprite);
return sprite;
}),
}
];
});
this.descriptions = Object.fromEntries(descriptionEntries);
this.descriptionArea.move(574, CONTENT_TOP);
this.descriptionArea.zIndex = 2;
content.addChild(this.descriptionArea);
this.setState(State.PUSSY.name);
return content;
}
createMenuSprite(itemNames) {
return itemNames.map((item, index) => {
const sprite = new Sprite_StatusItem(item.name, item.label, ITEM_WIDTH, ITEM_HEIGHT);
sprite.move(0, (ITEM_HEIGHT + ITEM_MERGIN) * index);
return sprite;
});
}
createDescriptionFrame() {
const areaSprite = new Sprite_Scrollable(CONTENT_AREA_WIDTH, CONTENT_AREA_HEIHGT);
const frameSprite = new Sprite(new Bitmap(CONTENT_AREA_WIDTH, CONTENT_AREA_HEIHGT));
const frameBitmap = frameSprite.bitmap;
const lw = CONTENT_LINE_WIDTH;
frameBitmap.fillAll('#FFFFFF');
frameBitmap.clearRect(lw, lw, CONTENT_AREA_WIDTH - (lw * 2), CONTENT_AREA_HEIHGT - (lw * 2));
frameSprite.zIndex = 2;
areaSprite.addChild(frameSprite);
return areaSprite;
}
createDescriptionText(state, level) {
const index = level - 1;
const text = TextResource.getText(state.texts[index]);
// Switch to an English-friendly font and wrap by pixel width; shrink if too tall
const width = CONTENT_AREA_WIDTH - (DESCRIPTION_MERGIN * 2);
const maxHeight = CONTENT_AREA_HEIHGT - DESCRIPTION_MERGIN;
const tmp = new Bitmap(1, 1);
tmp.textColor = '#FFFFFF';
tmp.fontFace = 'NotoSerifCJKjp-Bold'; // English-friendly, narrower than CJK fonts
tmp.outlineWidth = 0;
let fontSize = 26; // start a bit smaller than JP
let lines = [];
let lineHeight = 0;
let height = 0;
for (let tries = 0; tries < 12; tries++) {
tmp.fontSize = fontSize;
lines = wrapTextToWidth(text, tmp, width);
lineHeight = Math.max(24, Math.round(tmp.fontSize * 1.3));
height = lines.length * lineHeight;
if (height <= maxHeight || fontSize <= 18) break;
fontSize -= 1; // shrink until it fits or min size reached
}
const bitmap = new Bitmap(width, height);
bitmap.textColor = tmp.textColor;
bitmap.fontFace = tmp.fontFace;
bitmap.outlineWidth = tmp.outlineWidth;
bitmap.fontSize = tmp.fontSize;
lines.forEach((line, index) => {
const y = (lineHeight * index);
bitmap.drawText(line, 0, y, width, lineHeight, 'left');
})
const sprite = new Sprite(bitmap);
sprite.move(DESCRIPTION_MERGIN, (DESCRIPTION_MERGIN / 2));
sprite.zIndex = 1;
return sprite;
}
createMessageWindow() {
const rect = new Rectangle(0, 0, 840, 248);
const window = new Window_LewdLevel(rect);
window.setLewdLevelListener(this.setLewdStage.bind(this));
const currentLewdStage = Math.max(PluginUtils.getVariables(param.lewdStage) || 1, 1);
this.setLewdStage(currentLewdStage);
return window;
}
createWindowLayer() {
this._windowLayer = new WindowLayer();
this._windowLayer.x = 7;
this._windowLayer.y = 826;
this._windowLayer.zIndex = 500;
this.addChild(this._windowLayer);
}
createLewdGauge(bindingVariable, label) {
const sprite = new Sprite(new Bitmap(1000, 54));
const bitmap = sprite.bitmap;
bitmap.textColor = '#FFFFFF';
bitmap.fontFace = 'MPLUS1Code-Regular';
bitmap.fontSize = 40;
bitmap.outlineWidth = 0;
const labelWidth = 230;
const countWidth = 68;
const textHeight = 50;
const labelY = (bitmap.height - textHeight) / 2;
const barWidth = 620;
const mergin = 10;
bitmap.drawText(TextResource.getText(label), 0, labelY, labelWidth, textHeight, 'left');
const lewdCount = PluginUtils.getVariables(bindingVariable) || 0;
bitmap.drawText(lewdCount, labelWidth + barWidth, labelY, countWidth, textHeight, 'right');
const bar = new Sprite_ProgressBar(barWidth, 54, 99);
bar.lineWidth = 6;
bar.bind(bindingVariable);
bar.setProgressGradation([
new GradientPoint(0, '#CACACA'),
new GradientPoint(100, '#CACACA'),
]);
bar.zIndex = 3;
bar.move(labelWidth + mergin, 0);
sprite.addChild(bar);
return sprite;
}
setBloking(enable) {
if (enable !== this.isTouchBlocking) {
if (enable) {
this.onStartBlocking();
} else {
this.onEndBlocking();
}
this.isTouchBlocking = enable;
}
}
setState(value) {
if (State.hasOwnProperty(value)) {
if (value !== this._state) {
const point = State[value].position;
this.character.smoothScrollTo(point.x, point.y, 6);
Object.values(this.descriptions).forEach(description => {
description.sprites.forEach((sprite, index) => {
sprite.visible = (description.state === value && this.currentStage === (index + 1));
});
});
this.stateMenus.forEach((sprite, index) => {
if (sprite.getName() === value) {
sprite.setFocus(true);
this.stateindex = index;
} else {
sprite.setFocus(false);
}
});
this._state = value;
}
} else {
Logger.w(`[SceneLewdStatus] invalid state: state = ${value}`);
}
}
setLewdStage(value) {
const stage = Number(value).clamp(1, 4);
if (this.currentStage !== stage) {
Object.values(this.descriptions).forEach(description => {
description.sprites.forEach((sprite, index) => {
sprite.visible = (description.state === this._state && stage === (index + 1));
});
});
this.leveledCharacters.forEach((sprite, index) => {
sprite.visible = (stage === (index + 1));
});
this.currentStage = stage;
}
}
onExit() {
// for overload
}
onStartBlocking() {
// for overload
}
onEndBlocking() {
// for overload
}
handleBackButtonClicked() {
// for overload
return true;
}
start() {
super.start();
if (!!this.bgm && this.bgm !== '') {
AudioManager.playBgm({
name: this.bgm,
volume: 100,
pitch: 100,
pan: 0,
pos: 0,
});
}
}
stop() {
super.stop();
if (!!this.bgm && this.bgm !== '') {
AudioManager.stopBgm();
}
}
update() {
super.update();
if (!this.isActive()) {
return;
}
if (!this.runOnExit && !this.isBusy()) {
this.processInput();
}
}
processInput() {
if ((Input.isRepeated("cancel") || TouchInput.isCancelled()) && !this.runOnExit) {
this._exit();
} else if (Input.isRepeated(InputClass.INPUT_CLASS_UP)) {
this.moveStateFocus((this.stateindex < 0) ? 0 : -1);
} else if (Input.isRepeated(InputClass.INPUT_CLASS_DOWN)) {
this.moveStateFocus((this.stateindex < 0) ? 0 : 1);
} else if (TouchInput.isHovered()) {
this.processStatus();
}
}
processStatus() {
if (this.stateMenuArea.isTouchedInsideFrame()) {
const focusedIndex = this.stateMenus.findIndex(sprite => sprite.isHovered());
if (focusedIndex >= 0) {
this.updateStateFocusIndex(focusedIndex, true);
}
}
}
moveStateFocus(moveIndex) {
const index = Number((this.stateindex >= 0) ? this.stateindex + moveIndex : 0);
if (index >= 0 && index < this.stateMenus.length) {
this.updateStateFocusIndex(index, false);
}
}
updateStateFocusIndex(index, fromTouch) {
if (index >= 0 && this.stateindex !== index) {
this.stateMenus.forEach((s, i) => s.setFocus(i === index));
this.stateindex = index;
this.setState(this.stateMenus[index].getName());
SoundManager.playCursor();
return true;
}
return false;
}
_exit() {
this.runOnExit = true;
SoundManager.playCancel();
this.onExit();
// this.fadeOutAll();
this._updateInput();
this._exitScene();
}
_exitScene() {
SceneManager.pop();
}
_updateInput() {
Input.update();
TouchInput.update();
}
}
window.SceneLewdStatus = SceneLewdStatus;
//========================================================================
// クラス定義 (Window_LewdLevel)
//========================================================================
class Window_LewdLevel extends Window_Base {
constructor(rect) {
super(rect);
this.move(rect.x, rect.y, rect.width, rect.height);
this._frame
this._modeListener = null;
this._lewdLevelListener = null;
}
createContents() {
super.createContents();
const bitmap = this.contents;
bitmap.textColor = '#FFFFFF';
bitmap.fontFace = 'NotoSerifCJKjp-Black';
bitmap.fontSize = 40;
bitmap.outlineWidth = 0;
const textWidth = 804;
const x = (bitmap.width - textWidth) / 2;
bitmap.drawText(TextResource.getText('0900-005-n005-0'), x, 6, textWidth, 50, 'center');
const labels = [
'0900-006-n006-0',
'0900-007-n007-0',
'0900-008-n008-0',
'0900-009-n009-0',
];
const maxLewdStage = Math.max(PluginUtils.getVariables(param.lewdStage) || 1, 1) - 1;
const areaSprite = new Sprite();
this.stages = labels.map((label, index) => {
const sprite = new Sprite_LewdLevel(label, index + 1);
const x = (index % 3) * (LEWD_LEVEL_WIDTH + LEWD_LEVEL_MERGIN);
const y = Math.trunc(index / 3) * (LEWD_LEVEL_HEIGHT + LEWD_LEVEL_MERGIN);
sprite.setActive(index <= maxLewdStage);
sprite.move(x, y);
areaSprite.addChild(sprite);
return sprite;
});
const bounds = areaSprite.getBounds();
areaSprite.move((this.width - bounds.width) / 2, 84);
this.addChild(areaSprite);
this.updateFocusIndex(maxLewdStage, false);
}
setDrugAcitive(active) {
this.stages[this.stages.length - 1].setActive(active);
}
setModeListener(listener) {
if (!!listener && typeof listener === 'function') {
this._modeListener = listener;
}
}
setLewdLevelListener(listener) {
if (!!listener && typeof listener === 'function') {
this._lewdLevelListener = listener;
}
}
update() {
super.update();
this.processInput();
}
processInput() {
if (Input.isTriggered(InputClass.INPUT_CLASS_LEFT)) {
for (let i = 1; (this.index - i) >= 0; i++) {
const index = Number(this.index - i).clamp(0, this.stages.length);
if (this.stages[index].isActive()) {
this.updateFocusIndex(index, false);
break;
}
}
} else if (Input.isTriggered(InputClass.INPUT_CLASS_RIGHT)) {
for (let i = 1; (this.index + i) < this.stages.length; i++) {
const index = Number(this.index + i).clamp(0, this.stages.length);
if (this.stages[index].isActive()) {
this.updateFocusIndex(index, false);
break;
}
}
} else if (TouchInput.isHovered()) {
const focusedIndex = this.stages.findIndex(sprite => {
return sprite.isHovered() && sprite.isActive();
});
if (focusedIndex >= 0) {
this.updateFocusIndex(focusedIndex, true);
}
}
}
updateFocusIndex(index, fromTouch) {
if (index >= 0 && this.index !== index) {
this.stages.forEach((s, i) => {
if (i === index) {
s.setFocus(true);
const level = s.getLevel();
if (level < 0) {
this._fireModeChange(Mode.DRAG);
} else {
if (this.index >= 0 && this.stages[this.index].getLevel() < 0) {
this._fireModeChange(Mode.STATUS);
}
this._fireLewdLevelChanged(level);
}
} else {
s.setFocus(false);
}
});
this.index = index;
SoundManager.playCursor();
return true;
}
return false;
}
_fireModeChange(newMode) {
if (!!this._modeListener && typeof this._modeListener === 'function') {
this._modeListener(newMode);
}
}
_fireLewdLevelChanged(newLevel) {
if (!!this._lewdLevelListener && typeof this._lewdLevelListener === 'function') {
this._lewdLevelListener(newLevel);
}
}
}
//========================================================================
// クラス定義 (Sprite_StatusItem)
//========================================================================
class Sprite_StatusItem extends Sprite_InputHandle {
constructor(name, label, width, height) {
super();
this.setFrame(0, 0, width, height);
this._name = name;
this._focus = false;
this.bg = new Sprite(new Bitmap(width, height));
const bgBitmap = this.bg.bitmap;
bgBitmap.fillAll('#FFFFFF');
this.bg.zIndex = 0;
this.bg.opacity = PluginUtils.percent(255, 70);
this.addChild(this.bg);
const textSprite = this.createLabelSprite(label);
textSprite.move((this.width - textSprite.width) / 2, (this.height - textSprite.height) / 2);
textSprite.zIndex = 1;
this.addChild(textSprite);
this.setFocus(false);
}
createLabelSprite(label) {
const title = new Bitmap(494, 40);
title.textColor = '#FFFFFF';
title.fontFace = 'NotoSerifCJKjp-Bold';
title.outlineWidth = 0;
title.fontSize = 28;
title.drawText(TextResource.getText(label), 0, 0, 494, 40, 'left');
return new Sprite(title);
}
getName() {
return this._name;
}
normalColor() {
return 0x000000;
}
focusedColor() {
return 0xCACACA;
}
setFocus(focus) {
this.bg.tint = focus ? this.focusedColor() : this.normalColor();
this._focus = focus;
}
isFocused() {
return this._focus;
}
}
//========================================================================
// クラス定義 (Sprite_LewdLevel)
//========================================================================
class Sprite_LewdLevel extends Sprite_StatusItem {
constructor(label, level) {
super(String(level), label, LEWD_LEVEL_WIDTH, LEWD_LEVEL_HEIGHT);
this._level = level;
this._active = true;
}
getLevel() {
return Number(this.getName());
}
normalColor() {
return 0x444444;
}
setActive(value) {
this.opacity = value ? 255 : 40;
this._active = value;
}
isActive() {
return this._active;
}
createLabelSprite(label) {
const title = new Bitmap(LEWD_LEVEL_WIDTH, LEWD_LEVEL_HEIGHT);
title.textColor = '#FFFFFF';
title.fontFace = 'NotoSerifCJKjp-Bold';
title.outlineWidth = 0;
title.fontSize = 36;
title.drawText(TextResource.getText(label), 0, 0, LEWD_LEVEL_WIDTH, LEWD_LEVEL_HEIGHT, 'center');
return new Sprite(title);
}
}
//========================================================================
// プラグインコマンド
//========================================================================
PluginManagerEx.registerCommand(script, 'startScene', args => {
SceneManager._scene.fadeOutAll();
SceneManager.push(SceneLewdStatus);
});
})();