//============================================================================= // DynamicActorGraphic.js // ---------------------------------------------------------------------------- // (C) 2016 Triacontane // This software is released under the MIT License. // http://opensource.org/licenses/mit-license.php // ---------------------------------------------------------------------------- // Version // 1.2.3 2020/06/06 必要ない場合はプレイヤーをリフレッシュしないよう修正 // 1.2.2 2020/04/21 NpcFollower.jsと併用したときに発生する循環参照を解消 // 1.2.1 2018/11/18 ヘルプの記述を修正 // 1.2.0 2018/11/18 プレイヤーの残MPに応じてグラフィックを変更する機能を追加 // 1.1.0 2017/05/24 特定のスイッチがONのときにグラフィックを変更する機能を追加 // 1.0.2 2017/02/07 端末依存の記述を削除 // 1.0.1 2017/01/21 ステートアイコンの並び順が逆になっていた不具合を修正 // 1.0.0 2016/12/31 初版 // ---------------------------------------------------------------------------- // [Blog] : https://triacontane.blogspot.jp/ // [Twitter]: https://twitter.com/triacontane/ // [GitHub] : https://github.com/triacontane/ //============================================================================= /*: @url https://triacontane.blogspot.com/ @plugindesc Actor graphics dynamic setting plugin @author Triacontane @license MIT License @help English Help Translator: munokura This is an unofficial English translation of the plugin help, created to support global RPG Maker users. Feedback is welcome to improve translation quality (see: https://github.com/munokura/triacontane-MV-plugins ). Original plugin by Triacontane. Please check the latest official version at: https://triacontane.blogspot.com ----- Dynamically changes the actor's walking, face, and battle graphics. Changes based on remaining HP, when certain states are active, and when a switch is turned on. Switch changes take effect after switching menu screens or moving maps. Enter the following in the actor's Note field. # When HP is below 50%, the second image in test.png will be used as the walking graphic. (Specify in 10% increments.) # When HP is below 10%, the second image in test.png will be used as the face graphic. # When HP is below 30%, the test.png will be used as the battler graphic. # When MP is below 50%, the second image in test.png will be used as the walking graphic. (Specify in 10% increments.) # When MP is below 10%, the second image in test.png will be used as the face graphic. # Sets test.png as the battler graphic when MP is below 30%. # Sets the second image in test.png as the walking graphic when state [5] is active. # Sets the second image in test.png as the face graphic when state [5] is active. # Sets test.png as the battler graphic when state [5] is active. # Sets the second image in test.png as the walking graphic when switch [1] is ON. # Sets the second image in test.png as the face graphic when switch [1] is ON. # When switch [1] is ON, set test.png as the battler graphic. Caution! If you change to an uncached image, the image may flicker or not display correctly due to the asynchronous loading of JS. This plugin does not provide any special countermeasures, so please use a dedicated countermeasure plugin or cache the image beforehand using an event command or similar. This plugin does not have any plugin commands. Terms of Use: You may modify and redistribute this plugin without permission from the author, and there are no restrictions on its use (commercial, 18+, etc.). This plugin is now yours. */ /*:ja @plugindesc アクターグラフィックの動的設定プラグイン @author トリアコンタン @help アクターの歩行、顔、バトルグラフィックを動的に変化させます。 HPの残量、特定のステート有効時、スイッチON時に変化します。 スイッチによる変動はメニュー画面の切り替えもしくはマップ移動後に有効になります。 アクターのメモ欄に以下の通り入力してください。 # HP残量50%以下でtest.pngの2番目の画像を # 歩行グラフィックに指定します。(10%刻みで指定) # HP残量10%以下でtest.pngの2番目の画像を # 顔グラフィックに指定します。 # HP残量30%以下でtest.pngを # バトラーグラフィックに指定します。 # MP残量50%以下でtest.pngの2番目の画像を # 歩行グラフィックに指定します。(10%刻みで指定) # MP残量10%以下でtest.pngの2番目の画像を # 顔グラフィックに指定します。 # MP残量30%以下でtest.pngを # バトラーグラフィックに指定します。 # ステート[5]有効時にtest.pngの2番目の画像を # 歩行グラフィックに指定します。 # ステート[5]有効時にtest.pngの2番目の画像を # 顔グラフィックに指定します。 # ステート[5]有効時にtest.pngを # バトラーグラフィックに指定します。 # スイッチ[1]ON時にtest.pngの2番目の画像を # 歩行グラフィックに指定します。 # スイッチ[1]ON時にtest.pngの2番目の画像を # 顔グラフィックに指定します。 # スイッチ[1]ON時にtest.pngを # バトラーグラフィックに指定します。 注意! キャッシュされていない画像に変更した場合、JSの非同期読み込みの仕様で 画像がチラついたり、ただしく表示されない場合があります。 当プラグインでは特に対策は行っていないので、専用の対策プラグインを使うか 事前にイベントコマンドなどでキャッシュを行っていただくようお願いします。 このプラグインにはプラグインコマンドはありません。 利用規約: 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等) についても制限はありません。 このプラグインはもうあなたのものです。 */ (function () { 'use strict'; var metaTagPrefix = 'DAG_'; //============================================================================= // ローカル関数 // プラグインパラメータやプラグインコマンドパラメータの整形やチェックをします //============================================================================= var getArgNumber = function (arg, min, max) { if (arguments.length < 2) min = -Infinity; if (arguments.length < 3) max = Infinity; return (parseInt(arg) || 0).clamp(min, max); }; var getArgArrayString = function (args) { var values = args.split(','); for (var i = 0; i < values.length; i++) { values[i] = values[i].trim(); } return values; }; var getMetaValue = function (object, name) { var metaTagName = metaTagPrefix + name; return object.meta.hasOwnProperty(metaTagName) ? convertEscapeCharacters(object.meta[metaTagName]) : undefined; }; var convertEscapeCharacters = function (text) { if (text == null) text = ''; text = text.replace(/\\/g, '\x1b'); text = text.replace(/\x1b\x1b/g, '\\'); text = text.replace(/\x1bV\[(\d+)\]/gi, function () { return $gameVariables.value(parseInt(arguments[1], 10)); }.bind(this)); text = text.replace(/\x1bV\[(\d+)\]/gi, function () { return $gameVariables.value(parseInt(arguments[1], 10)); }.bind(this)); text = text.replace(/\x1bN\[(\d+)\]/gi, function () { var actor = parseInt(arguments[1], 10) >= 1 ? $gameActors.actor(parseInt(arguments[1], 10)) : null; return actor ? actor.name() : ''; }.bind(this)); text = text.replace(/\x1bP\[(\d+)\]/gi, function () { var actor = parseInt(arguments[1], 10) >= 1 ? $gameParty.members()[parseInt(arguments[1], 10) - 1] : null; return actor ? actor.name() : ''; }.bind(this)); text = text.replace(/\x1bG/gi, TextManager.currencyUnit); return text; }; //============================================================================= // Game_Actor // アクターグラフィックを動的に差し替えます。 //============================================================================= var _Game_Actor_refresh = Game_Actor.prototype.refresh; Game_Actor.prototype.refresh = function () { _Game_Actor_refresh.apply(this, arguments); this.refreshCustomGraphic(); }; Game_Actor.prototype.recoverAll = function () { Game_BattlerBase.prototype.recoverAll.apply(this, arguments); this.refreshCustomGraphic(); }; Game_Actor.prototype.refreshCustomGraphic = function () { this.initCustomGraphic(); this.refreshCustomGraphicForState(); this.refreshCustomGraphicForHpRate(); this.refreshCustomGraphicForMpRate(); this.refreshCustomGraphicForSwitch(); if (this.isChangeCharacterImage()) { $gamePlayer.requestRefresh(); } }; Game_Actor.prototype.refreshCustomGraphicForState = function () { var actor = this.actor(); this.getSortedStates().forEach(function (stateId) { this.setCharacterCustom(getMetaValue(actor, 'CHARACTER_ST' + String(stateId))); this.setFaceCustom(getMetaValue(actor, 'FACE_ST' + String(stateId))); this.setBattlerCustom(getMetaValue(actor, 'BATTLER_ST' + String(stateId))); }, this); }; Game_Actor.prototype.refreshCustomGraphicForHpRate = function () { var actor = this.actor(); for (var hpRate = 10; hpRate <= 100; hpRate += 10) { if (this.hpRate() > hpRate / 100) continue; this.setCharacterCustom(getMetaValue(actor, 'CHARACTER_HP' + String(hpRate))); this.setFaceCustom(getMetaValue(actor, 'FACE_HP' + String(hpRate))); this.setBattlerCustom(getMetaValue(actor, 'BATTLER_HP' + String(hpRate))); } }; Game_Actor.prototype.refreshCustomGraphicForMpRate = function () { var actor = this.actor(); for (var mpRate = 10; mpRate <= 100; mpRate += 10) { if (this.mpRate() > mpRate / 100) continue; this.setCharacterCustom(getMetaValue(actor, 'CHARACTER_MP' + String(mpRate))); this.setFaceCustom(getMetaValue(actor, 'FACE_MP' + String(mpRate))); this.setBattlerCustom(getMetaValue(actor, 'BATTLER_MP' + String(mpRate))); } }; Game_Actor.prototype.refreshCustomGraphicForSwitch = function () { var actor = this.actor(); Object.keys(actor.meta).forEach(function (metaName) { metaName.replace(/CHARACTER_SWITCH(\d+)/i, function () { if ($gameSwitches.value(getArgNumber(arguments[1]))) { this.setCharacterCustom(getMetaValue(actor, arguments[0])); } }.bind(this)); metaName.replace(/FACE_SWITCH(\d+)/i, function () { if ($gameSwitches.value(getArgNumber(arguments[1]))) { this.setFaceCustom(getMetaValue(actor, arguments[0])); } }.bind(this)); metaName.replace(/BATTLER_SWITCH(\d+)/i, function () { if ($gameSwitches.value(getArgNumber(arguments[1]))) { this.setBattlerCustom(getMetaValue(actor, arguments[0])); } }.bind(this)); }.bind(this)); }; Game_Actor.prototype.getSortedStates = function () { return this._states.clone().sort(this.compareOrderStateIdPriority.bind(this)); }; Game_Actor.prototype.compareOrderStateIdPriority = function (stateIdA, stateIdB) { return $dataStates[stateIdB].priority - $dataStates[stateIdA].priority; }; Game_Actor.prototype.initCustomGraphic = function () { this._characterNameCustom = null; this._characterIndexCustom = null; this._faceNameCustom = null; this._faceIndexCustom = null; this._battlerNameCustom = null; }; Game_Actor.prototype.isChangeCharacterImage = function () { return this._characterNameCustom !== null || this._characterIndexCustom !== null; }; Game_Actor.prototype.setCharacterCustom = function (metaValue) { if (!metaValue || this._characterNameCustom) return; var metaValueArray = getArgArrayString(metaValue); this._characterNameCustom = metaValueArray[0]; this._characterIndexCustom = getArgNumber(metaValueArray[1], 0, 7); }; Game_Actor.prototype.setFaceCustom = function (metaValue) { if (!metaValue || this._faceNameCustom) return; var metaValueArray = getArgArrayString(metaValue); this._faceNameCustom = metaValueArray[0]; this._faceIndexCustom = getArgNumber(metaValueArray[1], 0, 7); }; Game_Actor.prototype.setBattlerCustom = function (metaValue) { if (!metaValue || this._battlerNameCustom) return; this._battlerNameCustom = metaValue; }; var _Game_Actor_characterName = Game_Actor.prototype.characterName; Game_Actor.prototype.characterName = function () { return this._characterNameCustom || _Game_Actor_characterName.apply(this, arguments); }; var _Game_Actor_characterIndex = Game_Actor.prototype.characterIndex; Game_Actor.prototype.characterIndex = function () { return this._characterIndexCustom || _Game_Actor_characterIndex.apply(this, arguments); }; var _Game_Actor_faceName = Game_Actor.prototype.faceName; Game_Actor.prototype.faceName = function () { return this._faceNameCustom || _Game_Actor_faceName.apply(this, arguments); }; var _Game_Actor_faceIndex = Game_Actor.prototype.faceIndex; Game_Actor.prototype.faceIndex = function () { return this._faceIndexCustom || _Game_Actor_faceIndex.apply(this, arguments); }; var _Game_Actor_battlerName = Game_Actor.prototype.battlerName; Game_Actor.prototype.battlerName = function () { return this._battlerNameCustom || _Game_Actor_battlerName.apply(this, arguments); }; //============================================================================= // Game_Player // リフレッシュ要求に応じてリフレッシュします。 //============================================================================= var _Game_Player_update = Game_Player.prototype.update; Game_Player.prototype.update = function () { _Game_Player_update.apply(this, arguments); if (this._needsRefresh) { this._needsRefresh = false; this.refresh(); } }; Game_Player.prototype.requestRefresh = function () { this._needsRefresh = true; }; //============================================================================= // Game_Party // メンバーのグラフィックを動的に差し替えます。 //============================================================================= Game_Party.prototype.refreshMemberCustomGraphic = function () { this.members().forEach(function (actor) { actor.refreshCustomGraphic(); }); }; //============================================================================= // Game_Map // 場所移動時にアクターグラフィックを更新します。 //============================================================================= var _Game_Map_setup = Game_Map.prototype.setup; Game_Map.prototype.setup = function (mapId) { $gameParty.refreshMemberCustomGraphic(); _Game_Map_setup.apply(this, arguments); }; //============================================================================= // Scene_Map // 作成時にアクターグラフィックを更新します。 //============================================================================= var _Scene_Map_create = Scene_Map.prototype.create; Scene_Map.prototype.create = function () { $gameParty.refreshMemberCustomGraphic(); _Scene_Map_create.apply(this, arguments); }; //============================================================================= // Scene_MenuBase // 作成時にアクターグラフィックを更新します。 //============================================================================= var _Scene_MenuBase_create = Scene_MenuBase.prototype.create; Scene_MenuBase.prototype.create = function () { $gameParty.refreshMemberCustomGraphic(); _Scene_MenuBase_create.apply(this, arguments); }; })();