//============================================================================= // ScopeExtend.js // ---------------------------------------------------------------------------- // (C)2016 Triacontane // This software is released under the MIT License. // http://opensource.org/licenses/mit-license.php // ---------------------------------------------------------------------------- // Version // 1.8.0 2024/02/12 対象が敵グループのスキルで敵キャラを選択するとき、対象者をすべてフラッシュするよう修正 // 1.7.0 2021/07/11 MZ向けに全面的に修正 // 1.6.1 2018/06/09 範囲が「なし」になっているグループ攻撃使用時にエラーになる問題を修正 // 1.6.0 2017/07/09 「敵単体(戦闘不能)」および「敵全体(戦闘不能)」の効果範囲を追加 // 1.5.1 2017/02/21 グループ対象に指定したスキルが「隠れ状態」の敵にも当たってしまう問題を修正 // 1.5.0 2016/12/02 味方に対してN回ランダム選択できる機能を追加 // 1.4.0 2016/12/02 ランダム設定に対象人数を設定できる機能を追加 // 1.3.0 2016/09/15 敵N回ランダムのスキルに対して5回以上の繰り返しを指定できる機能を追加 // 1.2.0 2016/09/06 敵グループ内で同じIDの敵キャラ全員を対象にできるスコープを追加 // 1.1.0 2016/07/20 ターゲットの中から重複を除外できる機能を追加 // 1.0.0 2016/06/20 初版 // ---------------------------------------------------------------------------- // [Blog] : https://triacontane.blogspot.jp/ // [Twitter]: https://twitter.com/triacontane/ // [GitHub] : https://github.com/triacontane/ //============================================================================= /*: * @plugindesc 効果範囲拡張プラグイン * @target MZ * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/ScopeExtend.js * @base PluginCommonBase * @orderAfter PluginCommonBase * @author トリアコンタン * * @help ScopeExtend.js * * スキルやアイテムの効果範囲を拡張します。 * スキルのメモ欄に以下の通り入力してください。 * * * もともとの効果範囲に合わせて以下の通り拡大されます。 * ・敵単体:生存している味方単体がランダムで一人追加 * ・敵全体:生存している味方全体が追加 * ・敵N体ランダム:敵味方N体ランダムに変更 * ・味方単体:生存している敵単体がランダムで一人追加 * ・味方全体:生存している敵全体が追加 * ・味方単体(戦闘不能):死亡している敵単体がランダムで一人追加 * ・味方全体(戦闘不能):死亡している敵全体が追加 * ・使用者:生存している敵単体がランダムで一人追加 * * * 元々の選択範囲に使用者が追加されます。 * * * 元々の選択範囲から使用者が除外されます。 * * * 元々の選択範囲から重複ターゲットが除外されます。 * * * 元々の選択範囲の中からランダムでn人だけが選択されます。 * 狙われ率の影響しない純粋なランダムです。 * 値を省略するとランダムで一人が選択されます。 * * * 敵グループ内に指定した敵単体と同じIDの敵キャラがいる場合、全員選択されます。 * 味方の場合は味方全員が無条件で選択されます。 * * * 「敵N体ランダム」を効果範囲にしたスキルに対して、 * もともとの設定上限(4回)を超えて、5回以上実行したい場合に指定します。 * * さらに「味方全体」を効果範囲にしたスキルに対して設定すると * 「味方N体ランダム」を効果範囲にできます。 * * * もともとの効果範囲が「敵単体」「敵全体」のスキルに対して * 対象を戦闘不能者に限定します。 * 敵を蘇生させる等のスキルが作成できますが、「敵単体(戦闘不能)」は * 敵キャラ専用のスキルになります。 * (アクターが使用しても正しく対象を選択できません) * * このプラグインの利用にはベースプラグイン『PluginCommonBase.js』が必要です。 * 『PluginCommonBase.js』は、RPGツクールMZのインストールフォルダ配下の * 以下のフォルダに格納されています。 * dlc/BasicResources/plugins/official * * 利用規約: * 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等) * についても制限はありません。 * このプラグインはもうあなたのものです。 */ (()=> { 'use strict'; //============================================================================= // Game_Unit // 味方キャラをランダム選択します。 //============================================================================= Game_Unit.prototype.randomFriendTarget = function() { const members = this.aliveMembers(); return members[Math.floor(Math.random() * members.length)]; }; //============================================================================= // Game_Action // 効果範囲をメモ欄の記述に基づいて拡張します。 //============================================================================= const _Game_Action_repeatTargets = Game_Action.prototype.repeatTargets; Game_Action.prototype.repeatTargets = function(targets) { if (this.isScopeExtendInfo(['SE敵味方', 'SEEnemiesAndAllies'])) { if (!this.subject().isConfused() || this._forcing) { targets = this.targetsForAll(targets); } } if (this.isGroupAction() && targets[0]) { let targetsForGroup, prevTarget = targets[0]; if (prevTarget.isActor()) { targetsForGroup = prevTarget.friendsUnit().aliveMembers(); } else { targetsForGroup = prevTarget.friendsUnit().aliveMembers().filter(function(member) { return prevTarget.enemyId() === member.enemyId(); }); } targets = targetsForGroup; } if (this.isScopeExtendInfo(['SE使用者追加', 'SEAdditionUser'])) { if (!targets.contains(this.subject())) { targets.push(this.subject()); } } if (this.isScopeExtendInfo(['SE使用者除外', 'SERemoveUser', 'SE使用者削除'])) { targets = targets.filter(function(target) { return target !== this.subject(); }.bind(this)); } if (this.isScopeExtendInfo(['SE重複除外', 'SERemoveDuplication', 'SE重複削除'])) { targets = targets.filter(function(target, i) { return targets.indexOf(target) === i; }.bind(this)); } if (this.isScopeExtendInfo(['SEランダム', 'SERandom'])) { const number = this.getScopeExtendInfo(['SEランダム', 'SERandom']); const targetsForRandom = []; while (targetsForRandom.length < number && targets.length > targetsForRandom.length) { const index = Math.floor(Math.random() * targets.length); if (!targetsForRandom.contains(targets[index])) { targetsForRandom.push(targets[index]); } } targets = targetsForRandom; } arguments[0] = targets; return _Game_Action_repeatTargets.apply(this, arguments); }; Game_Action.prototype.isGroupAction = function() { return this.isScopeExtendInfo(['SEグループ', 'SEGroup']); } const _Game_Action_numTargets = Game_Action.prototype.numTargets; Game_Action.prototype.numTargets = function() { const metaValue = PluginManagerEx.findMetaValue(this.item(), ['SERandomNum', 'SEランダム回数']); return metaValue ? metaValue : _Game_Action_numTargets.apply(this, arguments); }; const _Game_Action_targetsForOpponents = Game_Action.prototype.targetsForOpponents; Game_Action.prototype.targetsForOpponents = function() { let targets = _Game_Action_targetsForOpponents.apply(this, arguments); if (this.isForDeadOpponent()) { const unit = this.opponentsUnit(); if (this.isForOne()) { targets = [unit.smoothDeadTarget(this._targetIndex)]; } else { targets = unit.deadMembers(); } } return targets; }; const _Game_Action_targetsForFriends = Game_Action.prototype.targetsForFriends; Game_Action.prototype.targetsForFriends = function() { let targets = _Game_Action_targetsForFriends.apply(this, arguments); const numTargets = this.numTargets(); if (this.isForAll() && numTargets > 0) { const friendUnit = this.friendsUnit(); targets = []; for (let i = 0; i < numTargets; i++) { targets.push(friendUnit.randomFriendTarget()); } } return targets; }; Game_Action.prototype.targetsForAll = function(targets) { const opponentsUnit = this.opponentsUnit(); const friendsUnit = this.friendsUnit(); const anotherUnit = this.isForFriend() ? opponentsUnit : friendsUnit; if (this.isForUser()) { targets.push(opponentsUnit.randomTarget()); } else if (this.isForRandom()) { targets = []; for (let i = 0; i < this.numTargets(); i++) { const opponentsLength = opponentsUnit.aliveMembers().length; const friendLength = friendsUnit.aliveMembers().length; if (Math.randomInt(opponentsLength + friendLength) >= opponentsLength) { targets.push(friendsUnit.randomTarget()); } else { targets.push(opponentsUnit.randomTarget()); } } } else if (this.isForDeadFriend()) { if (this.isForOne()) { targets.push(opponentsUnit.randomDeadTarget()); } else { targets = targets.concat(opponentsUnit.deadMembers()); } } else if (this.isForDeadOpponent()) { if (this.isForOne()) { targets.push(friendsUnit.randomDeadTarget()); } else { targets = targets.concat(friendsUnit.deadMembers()); } } else if (this.isForOne()) { targets.push(anotherUnit.randomTarget()); } else { targets = targets.concat(anotherUnit.aliveMembers()); } return targets; }; const _Game_Action_testApply = Game_Action.prototype.testApply; Game_Action.prototype.testApply = function(target) { return _Game_Action_testApply.apply(this, arguments) || (this.isForDeadOpponent() && target.isDead()); }; Game_Action.prototype.isForDeadOpponent = function() { return this.checkItemScope([1, 2]) && PluginManagerEx.findMetaValue(this.item(), ['SEDead', 'SE戦闘不能']); }; Game_Action.prototype.isScopeExtendInfo = function(names) { return !!PluginManagerEx.findMetaValue(this.item(), names); }; Game_Action.prototype.getScopeExtendInfo = function(names) { const result = PluginManagerEx.findMetaValue(this.item(), names); return result === true ? 1 : result; }; Game_Troop.prototype.selectGroup = function(activeMember) { for (const member of this.members()) { if (member?.originalName() === activeMember?.originalName()) { member.select(); } else { member.deselect(); } } }; const _Window_BattleEnemy_select = Window_BattleEnemy.prototype.select; Window_BattleEnemy.prototype.select = function(index) { _Window_BattleEnemy_select.apply(this, arguments); const action = BattleManager.inputtingAction(); if (action && action.item() && action.isGroupAction()) { $gameTroop.selectGroup(this.enemy()); } }; })();