357 lines
15 KiB
JavaScript
357 lines
15 KiB
JavaScript
//=============================================================================
|
||
// 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 データベースのスキルの効果範囲を拡張します。
|
||
* スキルのメモ欄に以下の通り入力してください。
|
||
*
|
||
* <SE敵味方> <SEEnemiesAndAllies>
|
||
* 効果範囲が敵味方に拡大されます。詳細は以下の通りです。
|
||
*
|
||
* もともとの効果範囲に合わせて以下の通り拡大されます。
|
||
* ・敵単体:生存している味方単体がランダムで一人追加
|
||
* ・敵全体:生存している味方全体が追加
|
||
* ・敵N体ランダム:敵味方N体ランダムに変更
|
||
* ・味方単体:生存している敵単体がランダムで一人追加
|
||
* ・味方全体:生存している敵全体が追加
|
||
* ・味方単体(戦闘不能):死亡している敵単体がランダムで一人追加
|
||
* ・味方全体(戦闘不能):死亡している敵全体が追加
|
||
* ・使用者:生存している敵単体がランダムで一人追加
|
||
*
|
||
* <SE使用者追加> <SEAdditionUser>
|
||
* 元々の選択範囲に使用者が追加されます。
|
||
*
|
||
* <SE使用者除外> <SERemoveUser>
|
||
* 元々の選択範囲から使用者が除外されます。
|
||
*
|
||
* <SE重複除外> <SERemoveDuplication>
|
||
* 元々の選択範囲から重複ターゲットが除外されます。
|
||
*
|
||
* <SEランダム:n> <SERandom:n>
|
||
* 元々の選択範囲の中からランダムでn人だけが選択されます。
|
||
* 狙われ率の影響しない純粋なランダムです。
|
||
* 値を省略するとランダムで一人が選択されます。
|
||
*
|
||
* <SEグループ> <SEGroup>
|
||
* 敵グループ内に、指定した敵単体と同じIDの敵キャラがいる場合、全員選択されます。
|
||
* 味方の場合は味方全員が無条件で選択されます。
|
||
*
|
||
* <SEランダム回数:5> <SERandomNum:5>
|
||
* 「敵N体ランダム」を効果範囲にしたスキルに対して、
|
||
* もともとの設定上限(4回)を超えて、5回以上実行したい場合に指定します。
|
||
* 回数の指定には制御文字\v[n]およびJavaScript計算式が利用できます。
|
||
*
|
||
* さらに「味方全体」を効果範囲にしたスキルに対して設定すると
|
||
* 「味方N体ランダム」を効果範囲にできます。
|
||
*
|
||
* <SE戦闘不能> <SEDead>
|
||
* もともとの効果範囲が「敵単体」「敵全体」のスキルに対して
|
||
* 対象を戦闘不能者に限定します。
|
||
* 敵を蘇生させる等のスキルが作成できますが、「敵単体(戦闘不能)」は
|
||
* 敵キャラ専用のスキルになります。
|
||
* (アクターが使用しても正しく対象を選択できません)
|
||
*
|
||
* このプラグインにはプラグインコマンドはありません。
|
||
*
|
||
* 利用規約:
|
||
* 作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等)
|
||
* についても制限はありません。
|
||
* このプラグインはもうあなたのものです。
|
||
*/
|
||
/*:ja
|
||
* @plugindesc 効果範囲拡張プラグイン
|
||
* @author トリアコンタン
|
||
*
|
||
* @help データベースのスキルの効果範囲を拡張します。
|
||
* スキルのメモ欄に以下の通り入力してください。
|
||
*
|
||
* <SE敵味方> <SEEnemiesAndAllies>
|
||
* 効果範囲が敵味方に拡大されます。詳細は以下の通りです。
|
||
*
|
||
* もともとの効果範囲に合わせて以下の通り拡大されます。
|
||
* ・敵単体:生存している味方単体がランダムで一人追加
|
||
* ・敵全体:生存している味方全体が追加
|
||
* ・敵N体ランダム:敵味方N体ランダムに変更
|
||
* ・味方単体:生存している敵単体がランダムで一人追加
|
||
* ・味方全体:生存している敵全体が追加
|
||
* ・味方単体(戦闘不能):死亡している敵単体がランダムで一人追加
|
||
* ・味方全体(戦闘不能):死亡している敵全体が追加
|
||
* ・使用者:生存している敵単体がランダムで一人追加
|
||
*
|
||
* <SE使用者追加> <SEAdditionUser>
|
||
* 元々の選択範囲に使用者が追加されます。
|
||
*
|
||
* <SE使用者除外> <SERemoveUser>
|
||
* 元々の選択範囲から使用者が除外されます。
|
||
*
|
||
* <SE重複除外> <SERemoveDuplication>
|
||
* 元々の選択範囲から重複ターゲットが除外されます。
|
||
*
|
||
* <SEランダム:n> <SERandom:n>
|
||
* 元々の選択範囲の中からランダムでn人だけが選択されます。
|
||
* 狙われ率の影響しない純粋なランダムです。
|
||
* 値を省略するとランダムで一人が選択されます。
|
||
*
|
||
* <SEグループ> <SEGroup>
|
||
* 敵グループ内に、指定した敵単体と同じIDの敵キャラがいる場合、全員選択されます。
|
||
* 味方の場合は味方全員が無条件で選択されます。
|
||
*
|
||
* <SEランダム回数:5> <SERandomNum:5>
|
||
* 「敵N体ランダム」を効果範囲にしたスキルに対して、
|
||
* もともとの設定上限(4回)を超えて、5回以上実行したい場合に指定します。
|
||
* 回数の指定には制御文字\v[n]およびJavaScript計算式が利用できます。
|
||
*
|
||
* さらに「味方全体」を効果範囲にしたスキルに対して設定すると
|
||
* 「味方N体ランダム」を効果範囲にできます。
|
||
*
|
||
* <SE戦闘不能> <SEDead>
|
||
* もともとの効果範囲が「敵単体」「敵全体」のスキルに対して
|
||
* 対象を戦闘不能者に限定します。
|
||
* 敵を蘇生させる等のスキルが作成できますが、「敵単体(戦闘不能)」は
|
||
* 敵キャラ専用のスキルになります。
|
||
* (アクターが使用しても正しく対象を選択できません)
|
||
*
|
||
* このプラグインにはプラグインコマンドはありません。
|
||
*
|
||
* 利用規約:
|
||
* 作者に無断で改変、再配布が可能で、利用形態(商用、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;
|
||
};
|
||
})();
|