//============================================================================= // TRP_ParticleMZ_Editor.js //============================================================================= /*: * @target MZ * @author Thirop * @plugindesc パーティクルデータの編集[開発用] * @base TRP_ParticleMZ * @orderAfter TRP_ParticleMZ * * @help * 【更新履歴】 * 1.32 2022/03/29 グループエディタでエスケープ文字(\)対応(\V[1]など変数使用可) * 1.31 2022/01/22 Ctrl+Shift+Sで別名で一度だけ保存する機能の追加 * 1.24 2022/06/24 アニメーション画像の自動キャッシュクリア * 1.23 2022/06/04 コアスクリプトv1.5.0のタイルサイズ変更対応 * 1.22 2022/05/26 アニメーション画像使用時の不具合修正 * 1.21 2022/05/02 目隠しボタンの位置を調整 * 1.18 2022/02/02 エディタからアツマールにアップロードできない不具合修正 * 1.15 2021/12/06 カラーピッカーの不具合修正 * 1.13 2021/11/03 不具合修正 * 1.09 2021/08/18 プリセットピッカーの操作性修正 * 1.06 2021/06/01 コマンド生成のデフォルト値変更 * 1.03 2021/04/14 表示の微修正 * 1.01 2021/04/12 内部処理の微細な変更 * 1.00 2021/04/10 初版。 * * * @param showGuide * @text 項目ヘルプの表示 * @desc ON/trueにすると編集中の項目の説明が左下に表示されます。 * @type Boolean * @default true * * @param paramFontSize * @text 項目フォントサイズ * @desc 画面右に表示される項目のフォントサイズ。見切れる場合には小さくしてください。(デフォ値18) * @type number * @default 18 * * @param noColorCode * @text 色コード非表示 * @desc colorパラメータのコード(#ffffffなど)の非表示設定。横幅が見切れる場合はON(非表示)推奨 * @type Boolean * @default false * * @param buttonFontSize * @text ボタンフォントサイズ * @desc 画面右下に表示されるボタンのフォントサイズ。見切れる場合には小さくしてください。(デフォ値13) * @type number * @default 13 * * @param buttonWidth * @text ボタンの横幅 * @desc 画面右下に表示されるボタンの横幅。見切れる場合には小さくしてください。(デフォ値120) * @type number * @default 86 * * @param saveAsArray * @text 配列圧縮して保存 * @desc 配列圧縮して保存することでファイル容量を削減します。 * @type boolean * @default false * * @param copyAsArray * @text 配列圧縮してコピー * @desc 配列圧縮してコピーすることでテキスト量を削減します。 * @type boolean * @default true * * @param skipListCommand * @text リストのコマンド削除 * @desc TRP_ParticleMZ_Listプラグインの簡易set/play呼び出しコマンドを削除 * @default false * @type boolean * */ //============================================================================= //PRAGMA_END: editorHeader //PRAGMA: englishHeader //PRAGMA_END: englishHeader // ParticleEditor // ParticleParam // ParticleParam.ValueParam // ParticleParam.NodeParam // ParticleParam.ColorNodeParam // ColorPicker // ImagePicker function ParticleEditor(){ this.initialize.apply(this, arguments); } if (Utils.isNwjs() && Utils.isOptionValid('test')){ //PRAGMA: editorPathSetting ParticleEditor.DATA_DIR_PATH = 'dataEx'; ParticleEditor.FILE_PATH = 'dataEx/TrpParticles.json'; ParticleEditor.HELP_PATH = 'js/plugins/TRP_ParticleMZ_List.js'; ParticleEditor.IMAGE_PATH = 'img/particles/'; ParticleEditor.ANIMATION_PATH = 'img/animations/'; //PRAGMA_END: editorPathSetting //make animation dir var fs = require('fs'); var path = require('path'); var base = path.dirname(process.mainModule.filename); var filePath = path.join(base, ParticleEditor.ANIMATION_PATH); if(!fs.existsSync(filePath)){ fs.mkdirSync(ParticleEditor.ANIMATION_PATH) } if(!fs.existsSync(ParticleEditor.DATA_DIR_PATH)){ fs.mkdirSync(ParticleEditor.DATA_DIR_PATH); } }; (function(){ "use strict"; if (!Utils.isNwjs() || !Utils.isOptionValid('test')){ return; } var fs = require('fs'); var path = require('path'); var base = path.dirname(process.mainModule.filename); var filePath = path.join(base, ParticleEditor.FILE_PATH); if(!fs.existsSync(filePath)){ var defData = JSON.stringify(JsonEx.makeDeepCopy(Game_Particle.DEFAULT_DATA)); var file = '{"test":'+defData+'}'; fs.writeFileSync(filePath,file); } })(); (function(){ "use strict"; if (!Utils.isNwjs() || !Utils.isOptionValid('test')){ return; }; //PRAGMA: editorPluginNames var pluginName = 'TRP_ParticleMZ_Editor'; var basePluginName = 'TRP_ParticleMZ'; var listPluginName = 'TRP_ParticleMZ_List'; //PRAGMA_END: editorPluginNames var LC = TRP_Localize.localize.bind(TRP_Localize,'parEd'); var NLC = TRP_Localize.noLocalize; var parameters = PluginManager.parameters(pluginName); parameters.imageNames = null; parameters.animationNames = null; var showGuide = parameters.showGuide==='true'; var paramFontSize = Number(parameters.paramFontSize)||18; var noColorCode = parameters.noColorCode==='true'; var saveAsArray = parameters.saveAsArray==='true'; var copyAsArray = parameters.copyAsArray==='true'; var noLineBreaks = parameters.noLineBreaks===saveAsArray; var isMac = navigator.userAgent.match(/Macintosh|Mac/); var displayCount = PluginManager.parameters(basePluginName).displayCount==='true'; ParticleEditor.DEFAULT_DATA = Game_Particle.DEFAULT_DATA; (function(){ ParticleEditor.GUIDE_TEXTS = { alpha:[LC('【アルファ/不透明度】',0),LC('値の範囲:0~1',1),null,LC('<中間値設定可能>',2),LC('左端が開始時(時間0)、右端が終了時(時間1)の値',3),LC('@時間(0~1) + Enterで中間値を設定可能',4),LC('delete(Macはfn+delete)で中間値の削除',5),LC('中間値編集中にshift+@時間(0~1)+Enterで時間変更',6),LC('例)@0.5 + Enterで中間地点での値を設定開始',7)], scale:[LC('【スケール/拡大率】',8),LC('1で等倍',9),null,LC('<中間値設定可能>',10),LC('左端が開始時(時間0)、右端が終了時(時間1)の値',11),LC('@時間(0~1) + Enterで中間値を設定可能',12),LC('delete(Macはfn+delete)で中間値の削除',13),LC('中間値編集中にshift+@時間(0~1)+Enterで時間変更',14),LC('例)@0.5 + Enterで中間地点での値を設定開始',15)], minimumScaleMultiplier:[LC('【最小スケール倍率】',16),LC('パーティクル生成時の最小スケール倍率',17),LC('例)0.1として開始時のスケールが0.5の場合は',18),LC('  0.5*0.1=0.05から0.5の間の',19),LC('  ランダムなスケールのパーティクルが発生。',20)], speed:[LC('【スピード/速度】',21),LC('パーティクルの速度。開始値は0にしないこと。',22),null,LC('<中間値設定可能>',23),LC('左端が開始時(時間0)、右端が終了時(時間1)の値',24),LC('@時間(0~1) + Enterで中間値を設定可能',25),LC('delete(Macはfn+delete)で中間値の削除',26),LC('中間値編集中にshift+@時間(0~1)+Enterで時間変更',27),LC('例)@0.5 + Enterで中間地点での値を設定開始',28)], minimumSpeedMultiplier:[LC('【最小スピード倍率】',29),LC('パーティクル生成時の最小スピード倍率',30),LC('例)0.1として開始時のスピードが0.5の場合は',31),LC('  0.5*0.1=0.05から0.5の間の',32),LC('  ランダムなスピードのパーティクルが発生。',33)], color:[LC('【カラー/色】',34),LC('左上のカラーピッカーで設定可能',35),LC('バックスペース(Macはdelete)で白にリセット',36),null,LC('<中間値設定可能>',37),LC('左端が開始時(時間0)、右端が終了時(時間1)の値',38),LC('@時間(0~1) + Enterで中間値を設定可能',39),LC('delete(Macはfn+delete)で中間値の削除',40),LC('中間値編集中にshift+@時間(0~1)+Enterで時間変更',41),LC('例)@0.5 + Enterで中間地点での値を設定開始',42)], colorMode:[LC('【カラーモード】',43),LC('0で時間によって色が変化。',44),LC('0以外で発生時の色の分布を変化(時間変化無し)',45)], acceleration:[LC('【加速度】',46),LC('加速度が有効な場合は画像の向きは移動方向で固定',47)], startRotation:[LC('【発生時の射出角度】',48),LC('パーティクルの飛び出す方向。(画像の向きも連動)',49),LC('0で右,90で下,180で左,270(-90)で上方向。',50)], rotationSpeed:[LC('【画像回転速度】',51),LC('画像の回転速度の最小値と最大値。',52),LC('動きには影響なし。',53)], imageOption:[LC('【画像表示設定】',54),LC('画像の向き/反転の設定。動きには影響なし。',55),LC('angle:0~360で画像のみ回転、-1でランダムな角度。',56),LC('mirror:0で調整なし,1で反転,2でランダム。',57)], lifetime:[LC('【パーティクル寿命】',58),LC('個々のパーティクルの消えるまでの秒数',59)], blendMode:[], frequency:[LC('【フリクエンシー/発生間隔】',60),LC('パーティクルが発生する間隔',61),LC('0.01とすると0.01秒に1回発生し、1秒間に100回',62)], spawnChance:[LC('【発生確率】',63),LC('各発生タイミングに、パーティクルが発生する確率。',64)], particlesPerWave:[LC('【1回での発生個数】',65),LC('各発生タイミングに同時に発生する個数。',66),LC('同時に発生するパーティクルのlifetimeは固定',67)], emitterLifetime:[LC('【エミッター寿命】',68),LC('-1で無限。0より大きくすると、指定時間で発生終了',69)], maxParticles:[LC('【最大表示数の制限】',70),LC('このエミッターから発生する最大数の制限値',71)], fluctuation:[LC('【フラクチュエーション/ゆらぎ】',72),LC('角度のゆらぎ設定。',73),LC('max:各フレームで角度の変化幅の最大値',74),LC('sensitivity:0~1で指定。小さいほどゆるやかに、大きいほど激しくゆらぐ。',75)], pos:[LC('【ポイント(発生方法)】',76),LC('指定の点から発生。',77),LC('<※発生方法はいずれか1つのみ指定が有効>',78)], rect:[LC('【レクト/四角(発生方法)】',79),LC('四角形の中からランダムに発生。',80),LC('左上の点をx,y、幅/高さをwidth,heightで指定',81),LC('<※発生方法はいずれか1つのみ指定が有効>',82)], circle:[LC('【サークル/円(発生方法)】',83),LC('円の中からからランダムに発生',84),LC('中心点をx,y、半径をradiusで指定。',85),LC('<※発生方法はいずれか1つのみ指定が有効>',86)], ring:[LC('【リング(発生方法)】',87),LC('ドーナツ状のリングからランダムに発生。',88),LC('中心点をx,y、外側の半径をradius',89),LC('内側の半径をminRで指定。',90),LC('<※発生方法はいずれか1つのみ指定が有効>',91)], burst:[LC('【バースト(発生方法)】',92),LC('particlesPerWaveで規則的に発生させる',93),LC('ps:射出角度の差(particleSpacing)',94),LC('sa:開始角度。ps*sa=360とすると放射状に射出(startAngle)',95),LC('dt:射出時間の差(deltaTime)',96),LC('rt:0=開始角度(startRotation)無視',97),LC('└1=開始角度優先,2=開始角度を加算(rotationType)',98),LC('r:半径(radius)',99),LC('dr:半径の差。マイナスで1周ごとの差(deltaRadius)',100),LC('dx:xの差(deltaX)',101),LC('dy:yの差(deltaY)',102),LC('<※発生方法はいずれか1つのみ指定が有効>',103)], sub:[LC('【サブエミッター設定】',104),LC('st:射出開始タイミング(0~1)',105),LC('et:射出終了タイミング(0~1。-1で無効)',106),LC('spd:慣性の影響度合い。0=影響なし、1=100%影響。',107),LC('iAngle:1=開始角度は慣性方向基準',108),LC('iScale:1=親パーティクルの拡大率乗数を継承',109)] }; //blend mode guide text var texts = ParticleEditor.GUIDE_TEXTS.blendMode; ParticleEditor.BLEND_MODE_NAMES = Game_Particle.BLEND_MODE_NAMES; texts.push(LC('【ブレンドモード/画像合成方法】',110)); var length = ParticleEditor.BLEND_MODE_NAMES.length; var text = ''; for(var i = 0; i0){ texts.push(text); } text = ''; }else{ text += ','; } text += i + ':' + ParticleEditor.BLEND_MODE_NAMES[i]; if(i===length-1){ texts.push(text); } } })(); function supplement(defaultValue,optionArg){ if(optionArg === undefined){ return defaultValue; } return optionArg; }; function supplementNum(defaultValue,optionArg){ return Number(supplement(defaultValue,optionArg)); }; var _supplementDefWords = ['default','def','d']; function supplementDef(defaultValue, optionArg, otherWords) { var value = supplement(defaultValue,optionArg); var defTargetWords = otherWords || []; if(defTargetWords){ defTargetWords = defTargetWords.concat(_supplementDefWords); }else{ defTargetWords = _supplementDefWords; } var length = defTargetWords.length; for(var i=0; i=0){ this._data.clear = true; } } if(this._subData){ delete this._subData.editing; } this._countHandler = null; this._particle = null; this._data = null; this._subData = null; this._config = null; this.removeEventListeners(); emitter = null; } ParticleEditor.prototype.isTerminated = function(){ return this._terminated; }; ParticleEditor.prototype.trySearchImageNames = function(){ if(parameters.imageNames)return; var fs = require('fs'); var path = require('path'); var base = path.dirname(process.mainModule.filename); var dirPath = path.join(base,ParticleEditor.IMAGE_PATH); var imageNames = []; var animImageNames = []; var files = fs.readdirSync(dirPath) var length = files.length; for(var i = 0; i0){ this.processPickImage(); } }else if(event.keyCode===KEY_CODE.p){ this.processPickPreset(); }else if(event.keyCode===KEY_CODE.a){ if(parameters.animationNames&¶meters.animationNames.length>0){ this.processPickAnimation(); } }else if(event.keyCode===KEY_CODE.w){ this.processQuit(); }else if(event.keyCode===KEY_CODE.e){ this.processComplete(); }else if(event.keyCode===KEY_CODE.t){ this.processPickTile(); }else if(event.keyCode===KEY_CODE.l){ this.processPickLoad(); } } ParticleEditor.prototype.tryProcessAliasSave = function(){ var targetName = this.targetData().name; if(targetName.contains('_auto')||targetName.contains('_sub')){ return null; } if($gameSystem && $gameSystem.isJapanese()){ name = window.prompt('別名で一度だけ保存:設定名を入力\n(元の設定名も保存されます)',targetName); }else{ name = window.prompt('Save once under a different name: Enter a setting name\n(The original configuration name is also saved.)',targetName); } if(!name){ SoundManager.playCancel(); return; } name = name.trim(); return name; }; ParticleEditor.prototype._onKeyUp = function(event){ // this._keyCode = 0; }; /* word inputting ===================================*/ ParticleEditor.prototype.resetInputingWords = function(){ if(this._inputtingWords==='')return; this._inputtingWords = ''; this.prepareInputtingCandidates(); }; ParticleEditor.prototype.prepareInputtingCandidates = function(){ this._inputtingCandidates = this._commands.concat(); this._inputtingCandidates.push('SCREEN'); }; ParticleEditor.prototype.pushInputtingCharacter = function(chara){ this._inputtingWords += chara; var words = this._inputtingWords; var candidates = this._inputtingCandidates; var length = candidates.length; var firstHit = null; for(var i = 0; i0 && !firstHit){ for(var i=0; i=0; i=(i-1)|0){ if(candidates[i].indexOf(words)!==0)continue; candidates.splice(i,1); } } this._inputtingWords = words; } if(firstHit){ this.tryInputtingFirstHit(firstHit) } }; ParticleEditor.prototype.tryInputtingFirstHit = function(firstHit){ var perfectHit = this._inputtingWords===firstHit; if(firstHit==='SCREEN'){ if(perfectHit){ var index = this._commands.indexOf('RECT'); this.targetData().params.rect = [-Graphics.width/2,-Graphics.height/2,Graphics.width,Graphics.height]; this._parts[index].refreshParts(); this.startEditing(index); } }else{ var index = this._commands.indexOf(firstHit); this.startEditing(index); } }; /* update ===================================*/ ParticleEditor.prototype.update = function(){ if(this._terminated)return; if(this.updateParticleCount){ this.updateParticleCount(); } if(this._activePicker){ this._activePicker.update(); this._keyCode = 0; this._key = ''; return; } var children = this.children; var length = children.length; var i=length-1; for(;i>=0;i-=1){ var child = children[i]; if (child && child.update){ child.update(); } } /* input & return ===================================*/ if(TouchInput.isTriggered()||TouchInput.isPressed()){ this.processTouch(); }else if(Input._latestButton || this._keyCode){ this.processInput(); } this._keyCode = 0; this._key = ''; }; ParticleEditor.prototype.processTouch = function(){ var allParts = this._parts; var length = allParts.length; var x = TouchInput.x; var y = TouchInput.y; var margin = ParticleEditor.SELECTOR_MARGIN; for(var i = 0; i=KEY_CODE.alphabet && this._keyCode<=KEY_CODE.alphabetEnd){ this.pushInputtingCharacter(String.fromCharCode(this._keyCode)); }else{ var editing = this._editingIndex>=0 ? this.editingParts() : null; if(editing){ if(!editing.processInput(this._keyCode,this._key)){ this.endEditing(); }else{ this.selectParts(this._editingIndex); if(editing.hasSaveData()){ this.saveEditingParams(); } } }else if(Input.isTriggered('cancel')&&this._keyCode!==96){ if(this._saveButton.opacity<255){ this.processQuit(); }else{ SoundManager.playBuzzer(); } } if(this._keyCode!==0){ this.resetInputingWords(); } } }; ParticleEditor.prototype.saveEditingParams = function(){ var editing = this.editingParts(); if(!editing)return; this.supplyEditingParams(editing); var saveData = editing.handOverSaveData(); if(!saveData)return; this.saveEditingData(saveData); editing.didSaveParams(); }; ParticleEditor.prototype.supplyEditingParams = function(editing){}; ParticleEditor.prototype.saveEditingData = function(saveData){ var editing = this.editingParts(); if(!editing)return; this._saveEditingData(editing._title,saveData); }; ParticleEditor.prototype._saveEditingData = function(title,saveData){ saveData.unshift(title); saveData.unshift(this._id); this._applySaveData(saveData); this._saveButton.opacity = 255; }; ParticleEditor.prototype._applySaveData = function(saveData){ if(this._subData){ var id = saveData.shift(); var key = saveData.shift(); var data = this._subData; this._particle.tryUpdateSpawnType(key,data); data.params[key] = saveData; data.pChanged = true; }else{ this._particle.particleUpdate(saveData); } }; var _ParticleEmitter__updateParam = ParticleEmitter.prototype._updateParam; ParticleEmitter.prototype._updateParam = function(key,args,rate,emitter=this._emitter){ if(key==='sub'){ emitter.timing = Number(args[0])||0; emitter.endTiming = supplementDefNum(-1,args[1]); emitter.speedRate = Number(args[2])||0; emitter.inheritAngle = Number(args[3])||0; emitter.inheritScale = Number(args[4])||0; if(Game_Particle.GROUP_EDITOR){ Game_Particle.GROUP_EDITOR.changeSubEmitterConfig(emitter.timing,emitter.endTiming,emitter.speedRate,emitter.inheritAngle,emitter.inheritScale); } }else{ _ParticleEmitter__updateParam.apply(this,arguments); } }; ParticleEditor.prototype.startEditing = function(index){ if(index<0)return; if(this._editingIndex === index)return; SoundManager.playCursor(); var target = this._parts[index]; if(this._editingIndex>=0){ this._endEditing(); index = this._parts.indexOf(target); if(index<0){ this._editingIndex = -1; this.deselectParts(); return; } } if(!target){ this.refreshPartsHidden(); return; } this._editingIndex = index; target.startEditing(); var title = target.title(); this.showGuideWithTitle(title); if(target.type() === 'color'){ target.setPicker(this._colorPicker); } if(target.isSpawnParam()){ var saveData = target.paramSaveData(); this.saveEditingData(saveData); } this.refreshPartsHidden(); this.selectParts(index); }; ParticleEditor.prototype.spawnType = function(){ var spawnType = this._config.spawnType; var params = this.targetData().params; if(params.rect)spawnType = 'rect'; else if(params.circle)spawnType = 'circle'; else if(params.ring)spawnType = 'ring'; else if(params.burst)spawnType = 'burst'; else if(params.pos||params.point||params.spawnPos)spawnType = 'point'; if(spawnType==='position'||spawnType==='pos')spawnType = 'point'; return spawnType; }; ParticleEditor.prototype.refreshPartsHidden = function(){ var spawnType = this.spawnType(); var allParts = this._parts; var length = allParts.length; for(var i = 0; i