//============================================================================= // ScopeExtend.js // ---------------------------------------------------------------------------- // Copyright (c) 2015-2017 Triacontane // This software is released under the MIT License. // http://opensource.org/licenses/mit-license.php // ---------------------------------------------------------------------------- // Version // 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 ScopeExtendPlugin * @author triacontane * * @help データベースのスキルの効果範囲を拡張します。 * スキルのメモ欄に以下の通り入力してください。 * * * 効果範囲が敵味方に拡大されます。詳細は以下の通りです。 * * もともとの効果範囲に合わせて以下の通り拡大されます。 * ・敵単体:生存している味方単体がランダムで一人追加 * ・敵全体:生存している味方全体が追加 * ・敵N体ランダム:敵味方N体ランダムに変更 * ・味方単体:生存している敵単体がランダムで一人追加 * ・味方全体:生存している敵全体が追加 * ・味方単体(戦闘不能):死亡している敵単体がランダムで一人追加 * ・味方全体(戦闘不能):死亡している敵全体が追加 * ・使用者:生存している敵単体がランダムで一人追加 * * * 元々の選択範囲に使用者が追加されます。 * * * 元々の選択範囲から使用者が除外されます。 * * * 元々の選択範囲から重複ターゲットが除外されます。 * * * 元々の選択範囲の中からランダムでn人だけが選択されます。 * 狙われ率の影響しない純粋なランダムです。 * 値を省略するとランダムで一人が選択されます。 * * * 敵グループ内に、指定した敵単体と同じIDの敵キャラがいる場合、全員選択されます。 * 味方の場合は味方全員が無条件で選択されます。 * * * 「敵N体ランダム」を効果範囲にしたスキルに対して、 * もともとの設定上限(4回)を超えて、5回以上実行したい場合に指定します。 * 回数の指定には制御文字\v[n]およびJavaScript計算式が利用できます。 * * さらに「味方全体」を効果範囲にしたスキルに対して設定すると * 「味方N体ランダム」を効果範囲にできます。 * * * もともとの効果範囲が「敵単体」「敵全体」のスキルに対して * 対象を戦闘不能者に限定します。 * 敵を蘇生させる等のスキルが作成できますが、「敵単体(戦闘不能)」は * 敵キャラ専用のスキルになります。 * (アクターが使用しても正しく対象を選択できません) * * このプラグインにはプラグインコマンドはありません。 * * 利用規約: * 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等) * についても制限はありません。 * このプラグインはもうあなたのものです。 */ /*:ja * @plugindesc 効果範囲拡張プラグイン * @author トリアコンタン * * @help データベースのスキルの効果範囲を拡張します。 * スキルのメモ欄に以下の通り入力してください。 * * * 効果範囲が敵味方に拡大されます。詳細は以下の通りです。 * * もともとの効果範囲に合わせて以下の通り拡大されます。 * ・敵単体:生存している味方単体がランダムで一人追加 * ・敵全体:生存している味方全体が追加 * ・敵N体ランダム:敵味方N体ランダムに変更 * ・味方単体:生存している敵単体がランダムで一人追加 * ・味方全体:生存している敵全体が追加 * ・味方単体(戦闘不能):死亡している敵単体がランダムで一人追加 * ・味方全体(戦闘不能):死亡している敵全体が追加 * ・使用者:生存している敵単体がランダムで一人追加 * * * 元々の選択範囲に使用者が追加されます。 * * * 元々の選択範囲から使用者が除外されます。 * * * 元々の選択範囲から重複ターゲットが除外されます。 * * * 元々の選択範囲の中からランダムでn人だけが選択されます。 * 狙われ率の影響しない純粋なランダムです。 * 値を省略するとランダムで一人が選択されます。 * * * 敵グループ内に、指定した敵単体と同じIDの敵キャラがいる場合、全員選択されます。 * 味方の場合は味方全員が無条件で選択されます。 * * * 「敵N体ランダム」を効果範囲にしたスキルに対して、 * もともとの設定上限(4回)を超えて、5回以上実行したい場合に指定します。 * 回数の指定には制御文字\v[n]およびJavaScript計算式が利用できます。 * * さらに「味方全体」を効果範囲にしたスキルに対して設定すると * 「味方N体ランダム」を効果範囲にできます。 * * * もともとの効果範囲が「敵単体」「敵全体」のスキルに対して * 対象を戦闘不能者に限定します。 * 敵を蘇生させる等のスキルが作成できますが、「敵単体(戦闘不能)」は * 敵キャラ専用のスキルになります。 * (アクターが使用しても正しく対象を選択できません) * * このプラグインにはプラグインコマンドはありません。 * * 利用規約: * 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等) * についても制限はありません。 * このプラグインはもうあなたのものです。 */ (function() { 'use strict'; var metaTagPrefix = 'SE'; var getArgNumberWithEval = function(arg, min, max) { if (arguments.length < 2) min = -Infinity; if (arguments.length < 3) max = Infinity; return (parseInt(eval(convertEscapeCharacters(arg)), 10) || 0).clamp(min, max); }; var getMetaValue = function(object, name) { var metaTagName = metaTagPrefix + (name ? name : ''); return object.meta.hasOwnProperty(metaTagName) ? object.meta[metaTagName] : undefined; }; var getMetaValues = function(object, names) { if (!Array.isArray(names)) return getMetaValue(object, names); for (var i = 0, n = names.length; i < n; i++) { var value = getMetaValue(object, names[i]); if (value !== undefined) return value; } return undefined; }; var getArgNumber = function(arg, min, max) { if (arguments.length < 2) min = -Infinity; if (arguments.length < 3) max = Infinity; return (parseInt(convertEscapeCharacters(arg), 10) || 0).clamp(min, max); }; var convertEscapeCharacters = function(text) { if (text == null) text = ''; var windowLayer = SceneManager._scene._windowLayer; return windowLayer ? windowLayer.children[0].convertEscapeCharacters(text) : text; }; //============================================================================= // Game_Unit // 味方キャラをランダム選択します。 //============================================================================= Game_Unit.prototype.randomFriendTarget = function() { var members = this.aliveMembers(); return members[Math.floor(Math.random() * members.length)]; }; //============================================================================= // Game_Action // 効果範囲をメモ欄の記述に基づいて拡張します。 //============================================================================= var _Game_Action_repeatTargets = Game_Action.prototype.repeatTargets; Game_Action.prototype.repeatTargets = function(targets) { if (this.isScopeExtendInfo(['敵味方', 'EnemiesAndAllies'])) { if (!this.subject().isConfused() || this._forcing) { targets = this.targetsForAll(targets); } } if (this.isScopeExtendInfo(['使用者追加', 'AdditionUser'])) { if (!targets.contains(this.subject())) { targets.push(this.subject()); } } if (this.isScopeExtendInfo(['使用者除外', 'RemoveUser', '使用者削除'])) { targets = targets.filter(function(target) { return target !== this.subject(); }.bind(this)); } if (this.isScopeExtendInfo(['重複除外', 'RemoveDuplication', '重複削除'])) { targets = targets.filter(function(target, i) { return targets.indexOf(target) === i; }.bind(this)); } if (this.isScopeExtendInfo(['ランダム', 'Random'])) { var number = this.getScopeExtendInfo(['ランダム', 'Random']); var targetsForRandom = []; while (targetsForRandom.length < number && targets.length > targetsForRandom.length) { var index = Math.floor(Math.random() * targets.length); if (!targetsForRandom.contains(targets[index])) { targetsForRandom.push(targets[index]); } } targets = targetsForRandom; } if (this.isScopeExtendInfo(['グループ', 'Group']) && targets[0]) { var 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; } arguments[0] = targets; return _Game_Action_repeatTargets.apply(this, arguments); }; var _Game_Action_numTargets = Game_Action.prototype.numTargets; Game_Action.prototype.numTargets = function() { var metaValue = getMetaValues(this.item(), ['RandomNum', 'ランダム回数']); return metaValue ? getArgNumberWithEval(metaValue, 1) : _Game_Action_numTargets.apply(this, arguments); }; var _Game_Action_targetsForOpponents = Game_Action.prototype.targetsForOpponents; Game_Action.prototype.targetsForOpponents = function() { var targets = _Game_Action_targetsForOpponents.apply(this, arguments); if (this.isForDeadOpponent()) { var unit = this.opponentsUnit(); if (this.isForOne()) { targets = [unit.smoothDeadTarget(this._targetIndex)]; } else { targets = unit.deadMembers(); } } return targets; }; var _Game_Action_targetsForFriends = Game_Action.prototype.targetsForFriends; Game_Action.prototype.targetsForFriends = function() { var targets = _Game_Action_targetsForFriends.apply(this, arguments); var numTargets = this.numTargets(); if (this.isForAll() && numTargets > 0) { var friendUnit = this.friendsUnit(); targets = []; for (var i = 0; i < numTargets; i++) { targets.push(friendUnit.randomFriendTarget()); } } return targets; }; Game_Action.prototype.targetsForAll = function(targets) { var opponentsUnit = this.opponentsUnit(); var friendsUnit = this.friendsUnit(); var anotherUnit = this.isForFriend() ? opponentsUnit : friendsUnit; if (this.isForUser()) { targets.push(opponentsUnit.randomTarget()); } else if (this.isForRandom()) { targets = []; for (var i = 0; i < this.numTargets(); i++) { var opponentsLength = opponentsUnit.aliveMembers().length; var 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; }; var _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]) && getMetaValues(this.item(), ['Dead', '戦闘不能']); }; Game_Action.prototype.isScopeExtendInfo = function(names) { return !!getMetaValues(this.item(), names); }; Game_Action.prototype.getScopeExtendInfo = function(names) { var result = getArgNumber(getMetaValues(this.item(), names)); return result === true ? 1 : result; }; })();