ravaged-prison-city/js/plugins/ManoUZ_MessageLogOption.js
2024-12-19 16:13:08 -06:00

971 lines
23 KiB
JavaScript

/*:
* @plugindesc Add Option to Message log
* @author siguren
*
* @target MZ
* @base ManoUZ_MessageLog
*
* @command OpenScene
* @text Open Option Screen
*
* @param optionText
* @desc Sets display name on Option Screen.
* @default Message log Setting
*
* @param textON
* @default ON
*
* @param textOFF
* @default OFF
*
* @param logLimitBasicText
* @text Basic number of logs saved:Item Name
* @default Basic number of logs saved
*
* @param logLimitBasicHelp
* @text Basic number of logs saved:Description
* @default Affects the size of saved data.
* @parent logLimitBasicText
*
* @param logLimitBasicItemList
* @text Number of logs saved:List
* @type struct<EnumItem>[]
* @default ["{\"text\":\"Few\",\"value\":\"20\"}","{\"text\":\"Standard\",\"value\":\"40\"}","{\"text\":\"Many\",\"value\":\"60\"}","{\"text\":\"Extreme\",\"value\":\"100\"}"]
* @parent logLimitBasicText
*
* @param logLimitExtendsText
* @text Number of logs saved/added:Item Name
* @default Number of logs saved(Add)
*
* @param logLimitExtendsHelp
* @type multiline_string
* @text Number of logs saved/added:Description
* @default Affects memory consumption.
* @parent logLimitExtendsText
*
* @param logLimitExtendsItemList
* @text Number of logs saved/added:List
* @desc This item is for changing settings.
* @type struct<EnumItem>[]
* @default ["{\"text\":\"Few\",\"value\":\"20\"}","{\"text\":\"Standard\",\"value\":\"50\"}","{\"text\":\"Many\",\"value\":\"80\"}"]
* @parent logLimitExtendsText
*
* @param autoWaitTimeText
* @text Auto Read:Item Name
* @default Auto Read Wait Time
*
* @param autoWaitTimeHelp
* @type multiline_string
* @text Auto Read Wait Time:Description
* @default Waiting time after sentence is displayed.
* @parent autoWaitTimeText
*
* @param autoWaitTimeItemList
* @text Auto Read Wait Time:Item List
* @type struct<EnumItem>[]
* @default ["{\"text\":\"Short\",\"value\":\"180\"}","{\"text\":\"Standard\",\"value\":\"360\"}","{\"text\":\"Long\",\"value\":\"480\"}","{\"text\":\"Very Long\",\"value\":\"600\"}"]
* @parent autoWaitTimeText
*
* @param gaugeColorText
* @text Gauge Color:Item Name
* @type string
* @default Gauge Color
*
* @param gaugeColorHelp
* @type multiline_string
* @text Gauge Color:Description
* @default The color of the gauge
* that appears during the Auto Read Wait Time.
* @parent gaugeColorText
*
* @param gaugeColorItemListOld
* @text Gauge Color List
* @type number[]
* @desc Numeric Value
* Manually convert a hexadecimal number to a decimal number.
* @default ["13181999","12674371","8104783","3050327","45797","20362","16628736"]
* @parent gaugeColorText
*
* @param keepAutoMode
* @text Keep Auto Read Mode:Item Name
* @default Keep Auto Read Mode
*
* @param keepAutoModeHelp
* @type multiline_string
* @text Keep Auto Read Mode:Description
* @default After the conversation has ended, keeps Auto Read Mode on.
* @parent keepAutoMode
*
* @param machinakaMode
* @text NPC convo Mode Line:Item Name
* @default NPC convo Mode Line
*
* @param machinakaModeHelp
* @text NPC convo Mode Line:Description
* @type multiline_string
* @default number for simultaneous displays in NPC convo Mode.
* @parent machinakaMode
*
*
*
* @help
* Attach optional features to ManoUZ_MessageLog.
*
* The main unit has Plugin Commands for changing values directly.
*
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*:ja
* @plugindesc メッセージログにオプションを追加
* @author しぐれん
*
* @target MZ
* @base ManoUZ_MessageLog
*
* @command OpenScene
* @text オプション画面を開く/OpenScene
*
* @param optionText
* @text オプション画面での表示名
* @default メッセージログ設定
*
* @param textON
* @default ON
*
* @param textOFF
* @default OFF
*
*
* @param logLimitBasicText
* @text ログ保存数(基本):項目名
* @default ログ保存数(基本)
*
* @param logLimitBasicHelp
* @text ログの保存数(基本):解説
* @default セーブデータの大きさに影響します。
* @parent logLimitBasicText
*
* @param logLimitBasicItemList
* @text ログ保存数:候補リスト
* @type struct<EnumItem>[]
* @default ["{\"text\":\"少ない\",\"value\":\"20\"}","{\"text\":\"標準\",\"value\":\"40\"}","{\"text\":\"多い\",\"value\":\"60\"}","{\"text\":\"とても多い\",\"value\":\"100\"}"]
* @parent logLimitBasicText
*
* @param logLimitExtendsText
* @text ログ保存数・追加分:項目名
* @default ログ保持数(追加)
*
* @param logLimitExtendsHelp
* @text ログ保存数・追加分:説明文
* @default メモリの消費量に影響します。
* @parent logLimitExtendsText
*
* @param logLimitExtendsItemList
* @text 追加のログ保存数:項目リスト
* @desc 設定変更用の項目です。
* @type struct<EnumItem>[]
* @default ["{\"text\":\"少ない\",\"value\":\"20\"}","{\"text\":\"標準\",\"value\":\"50\"}","{\"text\":\"多い\",\"value\":\"80\"}"]
* @parent logLimitExtendsText
*
* @param autoWaitTimeText
* @text オート待ち時間:項目名
* @default オート待ち時間
*
* @param autoWaitTimeHelp
* @text オート待ち時間:説明文
* @default 文章表示完了後の待機時間です。
* @parent autoWaitTimeText
*
* @param autoWaitTimeItemList
* @text オート待ち時間:項目リスト
* @type struct<EnumItem>[]
* @default ["{\"text\":\"短い\",\"value\":\"180\"}","{\"text\":\"標準\",\"value\":\"360\"}","{\"text\":\"長い\",\"value\":\"480\"}","{\"text\":\"とても長い\",\"value\":\"600\"}"]
* @parent autoWaitTimeText
*
* @param gaugeColorText
* @text ゲージ色:項目名
* @type string
* @default ゲージ色
*
* @param gaugeColorHelp
* @text ゲージ色:説明文
* @type string
* @default オート待ち時間の間に表示するゲージの色。
* @parent gaugeColorText
*
*
* @param gaugeColorItemListOld
* @text ゲージ色一覧
* @type number[]
* @desc 数値指定です。
* 各自で16進数を10進数に変換して設定します。
* @default ["13181999","12674371","8104783","3050327","45797","20362","16628736"]
* @parent gaugeColorText
*
*
* @param keepAutoMode
* @text オートモード保持:項目名
* @default オートモードを保持
*
* @param keepAutoModeHelp
* @text オートモード保持:説明文
* @default 会話終了後もオートモードを維持します。
* @parent keepAutoMode
*
* @param machinakaMode
* @text 街中モード行数:項目名
* @default 街中モード行数
*
* @param machinakaModeHelp
* @text 街中モード行数:説明文
* @type string
* @default 表示する数を増やすと、その分ログを表示する場所が減ります。
* @parent machinakaMode
*
*
*
* @help
* ManoUZ_MessageLogにオプション機能を取り付けます。
*
* 数値を直接変更するプラグインコマンドは本体側にあります。
*
*/
/*~struct~EnumItem:
* @param text
* @type string
*
* @param value
* @type number
* @default 0
*/
(function () {
"use strict";
/**
* @typedef {Object} OptionParametor
* @property {number} logLimitBasic
* @property {number} logLimitExtends
* @property {number} autoWaitTime
* @property {boolean} keepingAutoMode
* @property {number} gaugeColor
* @property {number} machinakaLines
*/
/**
* @type {String}
*/
const PLUGIN_NAME = "ManoUZ_MessageLogOption";
function getParam() {
return PluginManager.parameters(PLUGIN_NAME);
}
/**
* @returns {OptionParametor}
*/
function getOption() {
return ManoUZ_MessageLog.cloneOptionValue();
}
/**
* @param {OptionParametor} option
*/
function setOption(option) {
ManoUZ_MessageLog.setOptionValue(option);
}
class Option_ItemBase {
/**
*
* @param {string} key
* @param {string} name
* @param {string} help
*/
constructor(key, name, help) {
this._key = key;
this._help = help;
this._name = name;
}
helpText() {
return this._help;
}
key() {
return this._key;
}
name() {
return this._name;
}
/**
* @param {number} index
* @returns
*/
text(index) {
return "";
}
/**
*
* @param {number} index
* @returns
*/
textColor(index) {
return ColorManager.normalColor();
}
/**
* @param {number} value
* @returns
*/
indexOf(value) {
const maxItems = this.maxItems();
for (let i = 0; i < maxItems; ++i) {
const vv = this.value(i);
if (vv === value) {
return i;
}
}
return 0;
}
maxItems() {
return 1;
}
/**
* @returns {number}
* @param {number} _index
*/
value(_index) {
return 0;
}
}
/**
* @typedef {object} ValueTextPair
* @property {number} value
* @property {string} text
*/
class OptionItemEnum extends Option_ItemBase {
/**
* @param {string} key
* @param {string} name
* @param {string} help
* @param {ValueTextPair[]} list
*/
constructor(key, name, help, list) {
super(key, name, help);
//this._defaultValue=defaultValue;
this._list = list;
}
/**
* @param {string} key
* @param {string} name
* @param {string} helpText
* @param {string} listText
*/
static create(key, name, helpText, listText) {
/**
* @type {string[]}
*/
const listObj = JSON.parse(listText || "[]");
return new OptionItemEnum(
key,
name,
helpText,
listObj.map((text) => {
const obj = JSON.parse(text);
return {
text: obj.text,
value: Number(obj.value),
};
})
);
}
maxItems() {
return this._list.length;
}
/**
* @param {number} index
* @returns
*/
text(index) {
const item = this._list[index];
if (item) {
return item.text;
}
return "";
}
/**
*
* @param {number} index
*/
value(index) {
const item = this._list[index];
if (item) {
return item.value;
}
return 0;
}
}
/**
* @param {string} key
* @param {string} name
* @param {string} helpText
* @param {string} listText
*/
function createEnumOption(key, name, helpText, listText) {
return OptionItemEnum.create(key, String(name), String(helpText), listText);
}
class OptionItem_Boolean extends Option_ItemBase {
/**
* @param {number} index
* @returns
*/
value(index) {
return index;
}
/**
* @param {number} index
* @returns
*/
text(index) {
return index === 0 ? "OFF" : "ON";
}
maxItems() {
return 2;
}
}
class OptionItem_Number extends Option_ItemBase {
/**
* @param {string} key
* @param {string} name
* @param {string} help
*
* @param {number} min
* @param {number} max
*/
constructor(key, name, help, min, max) {
super(key, name, help);
this._min = min;
this._max = max;
this._name = name;
}
/**
* @param {number} index
* @returns
*/
text(index) {
return this.value(index).toString();
}
maxItems() {
return this._max - this._min;
}
/**
*
* @param {number} index
* @returns
*/
value(index) {
return index + this._min;
}
}
class OptionItemColorSelect extends Option_ItemBase {
/**
* @param {string} name
* @param {string} help
* @param {number[]} colorList
*/
constructor(name, help, colorList) {
super("color", name, help);
this._colorList = colorList;
}
text() {
return "????";
}
/**
* @param {number} index
* @returns
*/
textColor(index) {
const color = this.value(index);
const _0x = color.toString(16);
const zzz = _0x.padStart(6, "0");
return `#${zzz}`;
}
maxItems() {
return this._colorList.length;
}
/**
*
* @param {number} index
* @returns
*/
value(index) {
return this._colorList[index];
}
}
/**
* @template {Option_ItemBase} OptionItemType
*/
class OptionItemCase {
/**
*
* @param {OptionItemType} obj
* @param {(opt:OptionParametor)=>number} optionReadFunc
*
*/
constructor(obj, optionReadFunc) {
this._index = 0;
this._item = obj;
this._readFunc = optionReadFunc;
}
/**
* @param {OptionParametor} option
*/
readIndex(option) {
const value = this._readFunc(option);
this._index = this._item.indexOf(value);
}
helpText() {
return this._item.helpText();
}
name() {
return this._item.name();
}
text() {
return this._item.text(this._index);
}
textColor() {
return this._item.textColor(this._index);
}
changePrev() {
if (this._index > 0) {
this._index -= 1;
return true;
}
this._index = this._item.maxItems() - 1;
return true;
}
changeNext() {
if (this._index + 1 < this._item.maxItems()) {
this._index += 1;
return true;
}
this._index = 0;
return true;
}
/**
* @returns {OptionItemType | Option_ItemBase}
*/
item() {
return this._item;
}
maxItems() {
return this._item.maxItems();
}
value() {
return this._item.value(this._index);
}
/**
* @param {number} value
*/
selectValue(value) {
const index = this._item.indexOf(value);
this._index = index;
}
}
class OptionClass {
/**
*
* @param {Option_ItemBase[]} list
*/
constructor(list) {
/**
* @type {Map<string,OptionItemCase< Option_ItemBase > >}
*/
this._map = new Map();
this.addItem(setting.logLimitBasic, (opt) => opt.logLimitBasic);
this.addItem(setting.logLimitExtends, (opt) => opt.logLimitExtends);
this.addItem(setting.autoSpeed, (opt) => opt.autoWaitTime);
this.addItem(setting.keepAutoMode, (opt) =>
opt.keepingAutoMode ? 1 : 0
);
this.addItem(setting.colorList, (opt) => opt.gaugeColor);
this.addItem(setting.machinaka, (opt) => opt.machinakaLines);
}
/**
*
* @param {string} key
*/
getValue(key) {
const item = this._map.get(key);
if (item) {
return item.value();
}
return 0;
}
/**
* @returns {OptionParametor}
*
*/
createOption() {
const autokeep = this.getValue(setting.keepAutoMode.key()) !== 0;
return {
autoWaitTime: this.getValue(setting.autoSpeed.key()),
logLimitBasic: this.getValue(setting.logLimitBasic.key()),
logLimitExtends: this.getValue(setting.logLimitExtends.key()),
keepingAutoMode: autokeep,
gaugeColor: this.getValue(setting.colorList.key()),
machinakaLines: this.getValue(setting.machinaka.key()),
};
}
/**
* @private
* @param {Option_ItemBase} item
* @param {(option:OptionParametor)=>number} func
*/
addItem(item, func) {
const key = item.key();
this._map.set(key, new OptionItemCase(item, func));
}
/**
*
* @param {OptionParametor} option
*/
setOption(option) {
for (const iterator of this._map.values()) {
iterator.readIndex(option);
}
}
/**
* @returns
*/
createKeyList() {
return Array.from(this._map.keys());
}
/**
* @param {string} key
* @returns {OptionItemCase<Option_ItemBase>}
*/
getItem(key) {
return this._map.get(key);
}
}
const setting = (function () {
const param = getParam();
const logLimitBasic = createEnumOption(
"logbasic",
param.logLimitBasicText,
param.logLimitBasicHelp || "",
param.logLimitBasicItemList || "[]"
);
const logLimitExtends = createEnumOption(
"logextends",
param.logLimitExtendsText,
param.logLimitExtendsHelp || "",
param.logLimitExtendsItemList || "[]"
);
const autoSpeed = createEnumOption(
"autospeed",
param.autoWaitTimeText,
param.autoWaitTimeHelp,
param.autoWaitTimeItemList || "[]"
);
/**
* @type {String[]}
*/
const colorArray = JSON.parse(param.gaugeColorItemListOld);
const colorList = new OptionItemColorSelect(
String(param.gaugeColorText),
String(param.gaugeColorHelp),
colorArray.map((c) => Number(c))
);
const keepAutoMode = new OptionItem_Boolean(
"autokeep",
String(param.keepAutoMode),
String(param.keepAutoModeHelp)
);
const machinaka = new OptionItem_Number(
"machinaka",
String(param.machinkaMode || param.machinakaMode),
String(param.machinakaModeHelp || param.machinkaModeHelp),
1,
9
);
const optionText = String(param.optionText);
const result = {
optionText,
logLimitBasic,
logLimitExtends,
colorList,
autoSpeed,
keepAutoMode,
machinaka,
};
return result;
})();
class Window_LogOption extends Window_Selectable {
/**
* @param {Rectangle} rect
*/
constructor(rect) {
super(rect);
this._optionClass = new OptionClass(setting.itemList);
this._list = this._optionClass.createKeyList();
}
/**
*
* @param {OptionParametor} value
*/
setOption(value) {
this._optionClass.setOption(value);
this.refresh();
}
/**
* @returns {OptionParametor}
*/
createOption() {
return this._optionClass.createOption();
}
maxItems() {
if (this._list) {
return this._list.length;
}
return 0;
}
changeNextValue() {
const index = this.index();
const key = this._list[index];
const item = this._optionClass.getItem(key);
if (item) {
if (item.changeNext()) {
this.playCursorSound();
this.redrawItem(index);
}
}
}
changePrevValue() {
const index = this.index();
const key = this._list[index];
const item = this._optionClass.getItem(key);
if (item) {
if (item.changePrev()) {
this.playCursorSound();
this.redrawItem(index);
}
}
}
cursorLeft() {
this.changePrevValue();
}
playOkSound() {}
cursorRight() {
this.changeNextValue();
}
/**
*
* @param {OptionItemCase<Option_ItemBase>} item
* @param {Rectangle} rect
*/
drawItemText(item, rect) {
const color = item.textColor();
this.changeTextColor(color);
this.drawText(item.text(), rect.x, rect.y, rect.width, "right");
}
/**
* @param {number} index
*/
itemAt(index) {
const key = this._list[index];
if (!key) {
return null;
}
return this._optionClass.getItem(key);
}
/**
* @param {number} index
*/
drawItem(index) {
const item = this.itemAt(index);
if (item) {
const rect = this.itemRectWithPadding(index);
const nameWidth = Math.min(rect.width, 200);
const name = item.name() || "";
this.drawTextEx(name, rect.x, rect.y, nameWidth);
if (item.item() !== setting.colorList) {
this.drawItemText(item, rect);
} else {
const colorRect = new Rectangle(
rect.x + 240,
rect.y + 2,
rect.width - 240,
rect.height - 4
);
const color = item.textColor();
this.drawColorBar(colorRect, color);
}
}
}
/**
* @param {Rectangle} rect
* @param {string} color
*/
drawColorBar(rect, color) {
this.contents.fillRect(rect.x, rect.y, rect.width, rect.height, color);
}
updateHelp() {
const item = this.itemAt(this.index());
if (item) {
this._helpWindow.setText(item.helpText());
}
}
}
/**
*
* @param {string} symbol
* @param {Sprite_Button} other
* @param {number} buttonY
* @param {number} spacing
*/
function createButton(symbol, other, buttonY, spacing) {
const button = new Sprite_Button(symbol);
button.x = other.x - button.width - spacing;
button.y = buttonY;
return button;
}
class Scene_MessageLogOption extends Scene_MenuBase {
constructor() {
super();
this._helpWindow = null;
this._opitonWindow = null;
}
create() {
super.create();
this.createAllWindows();
}
createAllWindows() {
this.createHelpWindow();
this.createLogOpitonWindow();
}
logWindowRect() {
const x = 0;
const y = this.mainAreaTop();
const w = Graphics.boxWidth;
const h = this.mainAreaHeight();
return new Rectangle(x, y, w, h);
}
createButtons() {
super.createButtons();
if (ConfigManager.touchUI) {
this.createCursorButton();
}
}
createCursorButton() {
if (!this._cancelButton) {
return;
}
const spacing = 4;
const buttonY = this.buttonY();
const right = createButton(
"pagedown",
this._cancelButton,
buttonY,
spacing
);
const left = createButton("pageup", right, buttonY, spacing);
this.addWindow(right);
this.addWindow(left);
}
createLogOpitonWindow() {
const low = new Window_LogOption(this.logWindowRect());
low.setOption(getOption());
low.setHandler("ok", this.onOptionOk.bind(this));
low.setHandler("cancel", this.saveOption.bind(this));
low.setHandler("pageup", this.onOptionPageup.bind(this));
low.setHandler("pagedown", this.onOptionPagedown.bind(this));
this._opitonWindow = low;
this.addWindow(low);
low.select(0);
low.setHelpWindow(this._helpWindow);
low.activate();
}
onOptionOk() {
this._opitonWindow.changeNextValue();
this._opitonWindow.activate();
}
onOptionPageup() {
this._opitonWindow.changePrevValue();
this._opitonWindow.activate();
}
onOptionPagedown() {
this._opitonWindow.changeNextValue();
this._opitonWindow.activate();
}
saveOption() {
const value = this._opitonWindow.createOption();
setOption(value);
this.popScene();
}
}
const MESSAGELOG_OPTION = "MSGLOG_OPTION";
const Window_Options_makeCommandList =
Window_Options.prototype.makeCommandList;
Window_Options.prototype.makeCommandList = function () {
Window_Options_makeCommandList.call(this);
this.addCommand(setting.optionText, MESSAGELOG_OPTION);
};
const Window_Options_drawItem = Window_Options.prototype.drawItem;
Window_Options.prototype.drawItem = function (index) {
const symbol = this.commandSymbol(index);
if (symbol === MESSAGELOG_OPTION) {
const rect = this.itemRectWithPadding(index);
this.drawTextEx(setting.optionText, rect.x, rect.y, rect.width);
} else {
Window_Options_drawItem.call(this, index);
}
};
const Window_Options_processOk = Window_Options.prototype.processOk;
Window_Options.prototype.processOk = function () {
Window_Options_processOk.call(this);
if (SceneManager.isSceneChanging()) {
return;
}
const symbol = this.currentSymbol();
if (symbol === MESSAGELOG_OPTION) {
SceneManager.push(Scene_MessageLogOption);
return;
}
};
PluginManager.registerCommand(PLUGIN_NAME, "OpenScene", () => {
SceneManager.push(Scene_MessageLogOption);
});
})();