// DarkPlasma_BlastScope 1.0.1 // Copyright (c) 2024 DarkPlasma // This software is released under the MIT license. // http://opensource.org/licenses/mit-license.php /** * 2024/11/09 1.0.1 戦闘不能対象の範囲拡散の挙動が正常でない * 2024/11/09 1.0.0 公開 */ /*: @target MZ @url https://github.com/elleonard/DarkPlasma-MZ-Plugins/tree/release @plugindesc Range: "Spread" @author DarkPlasma @license MIT @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/DarkPlasma-MZ-Plugins ). Original plugin by DarkPlasma. Please check the latest official version at: https://github.com/elleonard/DarkPlasma-MZ-Plugins/tree/release ----- version: 1.0.1 Adds "Spread" to the range settings for skills and items. If the range setting is "Enemy" or "Ally" and the number is "Single," enter the following in the memo field of a skill or item to change the range setting to "Spread." The "Spread" range specifies a single enemy and also affects enemies on either side of it. Note that "adjacent" here refers to the order in which the enemy was added to the group, and does not necessarily relate to the display position. @param damageRate @text Damage multiplier (%) @desc Set the damage and recovery amount multiplier for the target's neighbors. @type number @default 50 */ /*:ja @plugindesc 範囲「拡散」 @author DarkPlasma @license MIT @target MZ @url https://github.com/elleonard/DarkPlasma-MZ-Plugins/tree/release @param damageRate @desc 対象の両隣に与えるダメージ、回復量の倍率を設定します。 @text ダメージ倍率(%) @type number @default 50 @help version: 1.0.1 スキルやアイテムの範囲設定に「拡散」を追加します。 範囲設定の陣営が「敵」または「味方」かつ数が「単体」であるような スキルやアイテムのメモ欄に以下のように記述すると、 範囲設定が「拡散」になります。 「拡散」範囲は敵単体を指定し、その両隣にも効果を及ぼします。 ここで言う隣とは、敵グループに追加した順番を基準にしており、 必ずしも表示位置とは関係しないことに注意してください。 */ (() => { 'use strict'; const pluginName = document.currentScript.src.replace(/^.*\/(.*).js$/, function () { return arguments[1]; }); const pluginParametersOf = (pluginName) => PluginManager.parameters(pluginName); const pluginParameters = pluginParametersOf(pluginName); const settings = { damageRate: Number(pluginParameters.damageRate || 50), }; function BattleManager_BlastScopeMixIn(battleManager) { const _endAction = battleManager.endAction; battleManager.endAction = function () { $gameTemp.clearSubTargetOf(this._action); _endAction.call(this); }; } BattleManager_BlastScopeMixIn(BattleManager); function Game_Temp_BlastScopeMixIn(gameTemp) { const _initialize = gameTemp.initialize; gameTemp.initialize = function () { _initialize.call(this); this._actionId = 1; this._actionSubTargets = new Map(); }; gameTemp.allocateActionId = function () { return this._actionId++; }; gameTemp.markAsSubTarget = function (action, target) { const actionId = action.actionId(); if (actionId) { this._actionSubTargets.set(actionId, (this._actionSubTargets.get(actionId) || []).concat([target])); } }; gameTemp.isBattlerSubTargetOf = function (action, target) { const actionId = action.actionId(); if (actionId) { const subTargets = this._actionSubTargets.get(actionId); return !!subTargets && subTargets.includes(target); } return false; }; gameTemp.clearSubTargetOf = function (action) { const actionId = action?.actionId(); if (actionId) { this._actionSubTargets.delete(actionId); } }; } Game_Temp_BlastScopeMixIn(Game_Temp.prototype); function Game_Unit_BlastScopeMixIn(gameUnit) { /** * baseTargetIndexから見てtargetIndexの方向に隣の生きているバトラーを返す */ gameUnit.smoothAliveNextTarget = function (baseTargetIndex, targetIndex) { do { const candidate = this.members()[targetIndex]; if (candidate?.isAlive()) { return candidate; } if (baseTargetIndex < targetIndex) { targetIndex++; } else { targetIndex--; } } while (this.members().length > targetIndex && 0 <= targetIndex); return undefined; }; gameUnit.smoothDeadNextTarget = function (baseTargetIndex, targetIndex) { do { const candidate = this.members()[targetIndex]; if (candidate?.isDead()) { return candidate; } if (baseTargetIndex < targetIndex) { targetIndex++; } else { targetIndex--; } } while (this.members().length > targetIndex && 0 <= targetIndex); return undefined; }; } Game_Unit_BlastScopeMixIn(Game_Unit.prototype); function Game_Action_BlastScopeMixIn(gameAction) { gameAction.actionId = function () { return this._actionId; }; const _setTarget = gameAction.setTarget; gameAction.setTarget = function (targetIndex) { _setTarget.call(this, targetIndex); if (!this._actionId) { this._actionId = $gameTemp.allocateActionId(); } }; gameAction.isBlastScope = function () { return !this.isForUser() && !this.isForEveryone() && !!this.item()?.meta.blastScope; }; const _targetsForDead = gameAction.targetsForDead; gameAction.targetsForDead = function (unit) { const result = _targetsForDead.call(this, unit); if (this.isBlastScope()) { result.push( ...result.flatMap((battler) => this.makeSubTargets(battler, (targetIndex) => unit.smoothDeadNextTarget(this._targetIndex, targetIndex)), ), ); } return result; }; const _targetsForAlive = gameAction.targetsForAlive; gameAction.targetsForAlive = function (unit) { const result = _targetsForAlive.call(this, unit); if (this.isBlastScope()) { result.push( ...result.flatMap((battler) => this.makeSubTargets(battler, (targetIndex) => unit.smoothAliveNextTarget(this._targetIndex, targetIndex)), ), ); } return result; }; const _targetsForDeadAndAlive = gameAction.targetsForDeadAndAlive; gameAction.targetsForDeadAndAlive = function (unit) { const result = _targetsForDeadAndAlive.call(this, unit); if (this.isBlastScope()) { result.push( ...result.flatMap((battler) => this.makeSubTargets(battler, (targetIndex) => unit.members()[targetIndex])), ); } return result; }; gameAction.makeSubTargets = function (mainTarget, findSubTargetFunction) { const candidates = []; if (this._targetIndex > 0) { candidates.push(findSubTargetFunction(this._targetIndex - 1)); } candidates.push(findSubTargetFunction(this._targetIndex + 1)); const subTargets = candidates.filter((candidate) => !!candidate && candidate !== mainTarget); /** * 副作用をもたらすが、冪等なのでとりあえずヨシとする */ subTargets.forEach((subTarget) => this.markAsSubTarget(subTarget)); return subTargets; }; gameAction.markAsSubTarget = function (target) { $gameTemp.markAsSubTarget(this, target); }; const _makeDamageValue = gameAction.makeDamageValue; gameAction.makeDamageValue = function (target, critical) { const value = _makeDamageValue.call(this, target, critical); return $gameTemp.isBattlerSubTargetOf(this, target) ? this.applySubTargetDamageRate(value) : value; }; gameAction.applySubTargetDamageRate = function (value) { return Math.floor((value * settings.damageRate) / 100); }; } Game_Action_BlastScopeMixIn(Game_Action.prototype); })();