//============================================================================== // PictureSpineExtension_UpperCompatible.js //============================================================================== /*: * @plugindesc PictureSpine拡張プラグイン(上位互換機能) * @author 奏ねこま(おとぶきねこま) * * @help * 本プラグインはPictureSpine.jsの下に配置してください。 * * -------------------------------------------------------------------------------- * 本プラグインの利用はRPGツクールMV/RPGMakerMVの正規ユーザーに限られます。 * 商用、非商用、有償、無償、一般向け、成人向けを問わず利用可能です。 * ご利用の際に連絡や報告は必要ありません。また、製作者名の記載等も不要です。 * プラグインを導入した作品に同梱する形以外での再配布、転載はご遠慮ください。 * 本プラグインにより生じたいかなる問題についても一切の責任を負いかねます。 * -------------------------------------------------------------------------------- * Copylight (c) 2020 Nekoma Otobuki * http://makonet.sakura.ne.jp/rpg_tkool/ * https://twitter.com/maconetto_labo */ (()=>{ 'use strict'; if (!PluginManager._scripts.includes('PictureSpine')) { return; } function convars(text = '') { do { RegExp.$_ = ''; text = text.replace(/\\v\[(\d+)\]/i, () => { return $gameVariables.value(Number(RegExp.$1)); }); } while (RegExp.$_); return text; } //============================================================================== // DataManager //============================================================================== (__extractSaveContents => { DataManager.extractSaveContents = function(contents) { __extractSaveContents.apply(this, arguments); let pictures = $gameScreen._pictures.filter(picture => { return picture && picture._MSS_IsSpine && !picture._spine; }); for (let picture of pictures) { let spine = picture._spine = new Game_Spine(); let skeleton = picture._MSS_SpineName; let animationList = picture._MSS_SpineAnimationList; let skin = picture._MSS_SpineSkin; let timeScale = picture._MSS_SpineTimeScale; let mixList = picture._MSS_SpineMixList || {}; let color = picture._MSS_SpineColor; let mosaicList = picture._MSS_SpineMosaicList || {}; let randomList = picture._MSS_SpineRandomAnimationList; let endTime = (picture._MSS_SpinePause - picture._MSS_SpineStart) / 1000; spine.setSkeleton(skeleton).setTimeScale(timeScale); if (skin != null) { spine.setSkin(skin); } else { let skins = Game_Spine.spineData()[skeleton].skins; if (skins.length > 1) { spine.setSkin(skins[1].name); } } for (let mix of Object.values(mixList)) { spine.setMix(mix.from, mix.to, mix.duration); } if (color) { spine.setColor(color.red, color.green, color.blue, color.alpha); } for (let key in mosaicList) { spine.setMosaic(key, mosaicList[key]); } let animation = []; let order = 'sequential'; let continuance; let interrupt = true; if (randomList) { let border = 0; for (let data of randomList) { if (data.border - border > 1) { animation.push(`${data.name}/times=${data.border - border}`); } else { animation.push(data.name); } border = data.border; } order = 'random'; continuance = 'reset'; } else { for (let data of animationList) { animation.push(data.animation); continuance = data.loop ? 'continue' : 'none'; } } spine.setAnimation(0, animation, order, continuance, interrupt); let entries = []; for (let i of animationList.keys()) { let previousData = animationList[i - 1]; let currentData = animationList[i]; let nextData = animationList[i + 1]; let mixDuration = 0; let trackTime = Game_Spine.spineData()[skeleton].animations.find(data => data.name == currentData.animation).duration; if (previousData) { mixDuration = (mixList[[previousData.animation, currentData.animation]] || { duration: 0 }).duration; } if (nextData) { trackTime -= (mixList[[currentData.animation, nextData.animation]] || { duration: 0 }).duration; } let entry = { trackIndex: 0, animation: { name: animationList[i].animation }, loop: animationList[i].loop, mixDuration: mixDuration, timeScale: 1.0, alpha: 1.0, trackTime: trackTime }; spine.setPlayData(entry); entries.push(entry); } for (let i of entries.keys()) { spine.updatePlayData(entries[i], 'start'); endTime -= entries[i].trackTime; if (endTime <= 0) { entries[i].trackTime += endTime; spine.updatePlayData(entries[i], 'update'); break; } if (entries[i + 1]) { spine.updatePlayData(entries[i], 'interrupt'); } else { while (endTime >= entries[i].trackTime) { spine.updatePlayData(entries[i], 'complete'); endTime -= entries[i].trackTime; } if (endTime > 0) { entries[i].trackTime = endTime; spine.updatePlayData(entries[i], 'update'); } } } let lastPlayData = [...spine.playData[0]].reverse()[0]; if (randomList && lastPlayData.state == 'play') { let index = Math.floor(Math.random() * randomList.length); let mixDuration = (mixList[[lastPlayData.name, randomList[index].name]] || { duration: 0 }).duration; let entry = { trackIndex: 0, animation: { name: randomList[index].name }, loop: false, mixDuration: mixDuration, timeScale: 1.0, alpha: 1.0, trackTime: 0 }; spine.setPlayData(entry); } delete picture._MSS_IsSpine; delete picture._MSS_SpineName; delete picture._MSS_SpineAnimationList; delete picture._MSS_SpineSkin; delete picture._MSS_SpineTimeScale; delete picture._MSS_SpineMixList; delete picture._MSS_SpineColor; delete picture._MSS_SpineMosaicList; delete picture._MSS_SpineRandomAnimationList; delete picture._MSS_SpinePause; delete picture._MSS_SpineStart; } }; })(DataManager.extractSaveContents); //============================================================================== // Game_Interpreter //============================================================================== (__pluginCommand => { Game_Interpreter.prototype.pluginCommand = function(command, args) { __pluginCommand.apply(this, arguments); let _command = command.toLowerCase(); let _args = [...args]; switch (_command) { case 'showspine': _args[0] = convars(_args[0]); _args[1] = convars(_args[1]); _args[2] = (convars(_args[2]) || 'true').toLowerCase() == 'true'; $gameTemp['PictureSpineEUC'] = { spine: { skeleton: _args[0], animation: _args[1], continuance: _args[2] ? 'continue' : 'none' }, wait: false }; break; case 'setspineanimation': case 'addspineanimation': _args[0] = Number(convars(_args[0])); _args[1] = convars(_args[1]); _args[2] = (convars(_args[2]) || 'true').toLowerCase() === 'true'; if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setAnimation(0, _args[1], _args[2] ? 'continue' : 'none', _command[0] == 's'); } this.wait(1); break; case 'setspinerandomanimation': case 'addspinerandomanimation': case 'setspinerandomanimationex': case 'addspinerandomanimationex': _args[0] = Number(convars(_args[0])); _args[1] = convars(_args[1]).replace(/\((\d+)\)/g, '/times=$1').split(','); _args[2] = (convars(_args[2]) || 'true').toLowerCase() === 'true'; if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setAnimation(0, _args[1], 'random', _command.match(/ex$/) ? 'reset' : _args[2] ? 'continue' : 'none', _command[0] == 's'); } this.wait(1); break; case 'setspinemix': _args[0] = Number(convars(_args[0])); _args[1] = convars(_args[1]); _args[2] = convars(_args[2]); _args[3] = Number(convars(_args[3])); if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setMix(_args[1], _args[2], _args[3]); } break; case 'setspineskin': _args[0] = Number(convars(_args[0])); _args[1] = convars(_args[1]); if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setSkin(_args[1]); } break; case 'setspinetimescale': _args[0] = Number(convars(_args[0])); _args[1] = Number(convars(_args[1])); if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setTimeScale(_args[1]); } break; case 'setspinecolor': _args[0] = Number(convars(_args[0])); _args[1] = Number(convars(_args[1])); _args[2] = Number(convars(_args[2])); _args[3] = Number(convars(_args[3])); _args[4] = Number(convars(_args[4])); if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setColor(_args[1], _args[2], _args[3], _args[4]); } break; case 'setspinemosaic': _args[0] = Number(convars(_args[0])); _args[1] = convars(_args[1]); _args[2] = Number(convars(_args[2])) || 1; if ($gameScreen.picture(_args[0])) { $gameScreen.spine(_args[0]).setMosaic(_args[1], _args[2]); } break; } }; })(Game_Interpreter.prototype.pluginCommand); (__updateWaitCount => { Game_Interpreter.prototype.updateWaitCount = function() { if ($gameTemp['PictureSpineEUC'] && $gameTemp['PictureSpineEUC'].wait) { this._waitCount = Math.max(this._waitCount, 1); delete $gameTemp['PictureSpineEUC']; } return __updateWaitCount.apply(this, arguments); }; })(Game_Interpreter.prototype.updateWaitCount); //============================================================================== // Game_Screen //============================================================================== (__showPicture => { Game_Screen.prototype.showPicture = function(pictureId, name, origin, x, y, scaleX, scaleY, opacity, blendMode) { let isShowSpine = !!$gameTemp['PictureSpineEUC'] && !!$gameTemp['PictureSpineEUC'].spine; if (isShowSpine) { arguments[1] = ''; } __showPicture.apply(this, arguments); if (isShowSpine) { let spine = $gameTemp['PictureSpineEUC'].spine; let skins = Game_Spine.spineData()[spine.skeleton].skins; this.spine(pictureId).setSkeleton(spine.skeleton) .setSkin(skins.length > 1 ? skins[1].name : null) .setAnimation(0, spine.animation, spine.continuance); $gameTemp['PictureSpineEUC'].spine = null; $gameTemp['PictureSpineEUC'].wait = true; } }; })(Game_Screen.prototype.showPicture); })();