pure-full-lily/js/plugins/ManoUZ_MessageLogOption.js
2025-09-16 10:12:44 -05:00

969 lines
24 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);
})
}());