brainwashing-school/js/plugins/NRP_DamageEffect.js
2025-05-30 08:36:40 -05:00

638 lines
23 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//=============================================================================
// NRP_DamageEffect.js
//=============================================================================
/*:
* @target MV MZ
* @plugindesc v1.04 ダメージ処理の演出を変更し、特定のステートの場合に追加アニメーションを重ねて表示します。
* @author 砂川赳
* @url http://newrpg.seesaa.net/article/475586753.html
*
* @help ダメージ処理の演出を変更します。
*
* ■できること
* ・敵味方の点滅演出の有効・無効化
* ・クリティカル、弱点、耐性時にアニメーションで演出
* ・ダメージポップアップの表示位置変更
* ・対象が特定のステートの場合に追加アニメーションを表示
*
* ※各アニメーションはMV/MZ両対応
*
* ■利用規約
* 特に制約はありません。改変、再配布自由、商用可、権利表示も任意です。
* 作者は責任を負いませんが、不具合については可能な範囲で対応します。
*
* @param enemyBlink
* @type boolean
* @default true
* @desc ダメージ時に敵を点滅させます。(初期値: true
*
* @param actorBlink
* @type boolean
* @default false
* @desc ダメージ時にアクターを点滅させます。(初期値: false
*
* @param blinkDuration
* @type number
* @default 20
* @desc 点滅時間です。(初期値: 20
*
* @param criticalAnimation
* @type animation
* @desc クリティカル時に再生するアニメーションです。(数式可)
*
* @param criticalBlinkOff
* @type boolean
* @default false
* @desc クリティカル時に対象を点滅させません。
*
* @param weakAnimation
* @type animation
* @desc 弱点時に再生するアニメーションです。(数式可)
*
* @param weakBlinkOff
* @type boolean
* @default false
* @desc 弱点時に対象を点滅させません。
*
* @param weakCondition
* @type string
* @default 150 <= action.calcElementRate(target) * 100
* @desc 弱点演出を行う条件です。有効度150%以上)
*
* @param resistAnimation1
* @type animation
* @desc 耐性時に再生するアニメーション(タイプ1)です。(数式可)
*
* @param resistBlinkOff1
* @type boolean
* @default false
* @desc 耐性時に対象の点滅を無効にします。(アニメーションのみの場合)
*
* @param resistCondition1
* @type string
* @default 50 >= action.calcElementRate(target) * 100
* @desc 耐性演出を行う条件です。有効度50%以下)
*
* @param resistAnimation2
* @type animation
* @desc 耐性時に再生するアニメーション(タイプ2)です。(数式可)
*
* @param resistBlinkOff2
* @type boolean
* @default false
* @desc 耐性時に対象の点滅を無効にします。(アニメーションのみの場合)
*
* @param resistCondition2
* @type string
* @default 0 == action.calcElementRate(target) * 100
* @desc 耐性演出を行う条件です。有効度0%
*
* @param effectPrioritity
* @type select
* @option critical
* @option weak
* @option both
* @default critical
* @desc クリティカル/弱点演出の優先度です。(同時発生時の優先順位)
*
* @param enemyDamageOffsetX
* @type string
* @default 0
* @desc 敵のダメージ表示位置Xの調整値です。
*
* @param enemyDamageOffsetY
* @type string
* @default -8
* @desc 敵のダメージ表示位置Yの調整値です。
*
* @param actorDamageOffsetX
* @type string
* @default -32
* @desc アクターのダメージ表示位置Xの調整値です。
*
* @param actorDamageOffsetY
* @type string
* @default 0
* @desc アクターのダメージ表示位置Yの調整値です。
*
* @param extraStateID
* @type number
* @default 5
* @desc 追加アニメーションを表示する対象のステートIDです。5
*
* @param extraAnimationID
* @type number
* @default 10
* @desc 対象が上記ステートのときに再生する追加アニメーションのIDです。10
*/
/*:ja
* @target MV MZ
* @plugindesc v1.04 ダメージ処理の演出を変更し、特定のステートの場合に追加アニメーションを重ねて表示します。
* @author 砂川赳
* @url http://newrpg.seesaa.net/article/475586753.html
*
* @help ダメージ処理の演出を変更します。
*
* ■できること
* ・敵味方の点滅演出の有効・無効化
* ・クリティカル、弱点、耐性時にアニメーションで演出
* ・ダメージポップアップの表示位置変更
* ・対象が特定のステートの場合に追加アニメーションを表示
*
* ※各アニメーションはMV/MZ両対応
*
* ■利用規約
* 特に制約はありません。改変、再配布自由、商用可、権利表示も任意です。
* 作者は責任を負いませんが、不具合については可能な範囲で対応します。
*
* @param enemyBlink
* @text 敵の点滅
* @type boolean
* @default true
* @desc ダメージ時に敵を点滅させます。(初期値: true
*
* @param actorBlink
* @text アクターの点滅
* @type boolean
* @default false
* @desc ダメージ時にアクターを点滅させます。(初期値: false
*
* @param blinkDuration
* @text 点滅時間
* @type number
* @default 20
* @desc 点滅時間です。(初期値: 20
*
* @param criticalAnimation
* @text クリティカル時のアニメ
* @type animation
* @desc クリティカル時に再生するアニメーションです。(数式可)
*
* @param criticalBlinkOff
* @text クリティカル時の点滅オフ
* @type boolean
* @default false
* @desc クリティカル時に対象を点滅させません。
*
* @param weakAnimation
* @text 弱点時のアニメ
* @type animation
* @desc 弱点時に再生するアニメーションです。(数式可)
*
* @param weakBlinkOff
* @text 弱点時の点滅オフ
* @type boolean
* @default false
* @desc 弱点時に対象を点滅させません。
*
* @param weakCondition
* @text 弱点演出条件
* @type string
* @default 150 <= action.calcElementRate(target) * 100
* @desc 弱点演出を行う条件です。有効度150%以上)
*
* @param resistAnimation1
* @text 耐性時アニメ1
* @type animation
* @desc 耐性時に再生するアニメーション(タイプ1)です。(数式可)
*
* @param resistBlinkOff1
* @text 耐性時点滅オフ1
* @type boolean
* @default false
* @desc 耐性時に対象の点滅を無効にします。(初期値: false
*
* @param resistCondition1
* @text 耐性演出条件1
* @type string
* @default 50 >= action.calcElementRate(target) * 100
* @desc 耐性演出を行う条件です。有効度50%以下)
*
* @param resistAnimation2
* @text 耐性時アニメ2
* @type animation
* @desc 耐性時に再生するアニメーション(タイプ2)です。(数式可)
*
* @param resistBlinkOff2
* @text 耐性時点滅オフ2
* @type boolean
* @default false
* @desc 耐性時に対象の点滅を無効にします。(初期値: false
*
* @param resistCondition2
* @text 耐性演出条件2
* @type string
* @default 0 == action.calcElementRate(target) * 100
* @desc 耐性演出を行う条件です。有効度0%
*
* @param effectPrioritity
* @text クリティカル/弱点優先度
* @type select
* @option critical
* @option weak
* @option both
* @default critical
* @desc クリティカル/弱点演出の優先度です。(同時発生時の優先順位)
*
* @param enemyDamageOffsetX
* @text 敵ダメージ表示X調整
* @type string
* @default 0
* @desc 敵のダメージ表示位置Xの調整値です。
*
* @param enemyDamageOffsetY
* @text 敵ダメージ表示Y調整
* @type string
* @default -8
* @desc 敵のダメージ表示位置Yの調整値です。
*
* @param actorDamageOffsetX
* @text アクターダメージ表示X調整
* @type string
* @default -32
* @desc アクターのダメージ表示位置Xの調整値です。
*
* @param actorDamageOffsetY
* @text アクターダメージ表示Y調整
* @type string
* @default 0
* @desc アクターのダメージ表示位置Yの調整値です。
*
* @param extraStateID
* @text 追加ステートID
* @type number
* @default 5
* @desc 追加アニメーションを表示する対象のステートIDです。5
*
* @param extraAnimationID
* @text 追加アニメーションID
* @type number
* @default 10
* @desc 対象が上記ステートの場合に再生する追加アニメーションのIDです。10
*/
(function() {
"use strict";
function toBoolean(str) {
if (str === true) return true;
return (str === "true");
}
function toNumber(str, def) {
return isNaN(str) ? def : +(str || def);
}
function setDefault(str, def) {
return (str !== undefined && str.length > 0) ? str : def;
}
const parameters = PluginManager.parameters("NRP_DamageEffect");
// 点滅設定
const pEnemyBlink = toBoolean(parameters["enemyBlink"]);
const pActorBlink = toBoolean(parameters["actorBlink"]);
const pBlinkDuration = toNumber(parameters["blinkDuration"]);
// クリティカル設定
const pCriticalAnimation = parameters["criticalAnimation"];
const pCriticalBlinkOff = toBoolean(parameters["criticalBlinkOff"]);
// 弱点設定
const pWeakAnimation = parameters["weakAnimation"];
const pWeakBlinkOff = toBoolean(parameters["weakBlinkOff"]);
const pWeakCondition = parameters["weakCondition"];
// 耐性1設定
const pResistAnimation1 = parameters["resistAnimation1"];
const pResistBlinkOff1 = toBoolean(parameters["resistBlinkOff1"]);
const pResistCondition1 = parameters["resistCondition1"];
// 耐性2設定
const pResistAnimation2 = parameters["resistAnimation2"];
const pResistBlinkOff2 = toBoolean(parameters["resistBlinkOff2"]);
const pResistCondition2 = parameters["resistCondition2"];
// クリティカル/弱点共通
const pEffectPrioritity = setDefault(parameters["effectPrioritity"], "critical");
// ダメージ表示位置設定
const pEnemyDamageOffsetX = setDefault(parameters["enemyDamageOffsetX"]);
const pEnemyDamageOffsetY = setDefault(parameters["enemyDamageOffsetY"]);
const pActorDamageOffsetX = setDefault(parameters["actorDamageOffsetX"]);
const pActorDamageOffsetY = setDefault(parameters["actorDamageOffsetY"]);
// 追加アニメーション設定
const pExtraStateID = Number(parameters["extraStateID"] || 5);
const pExtraAnimationID = Number(parameters["extraAnimationID"] || 10);
// 重複防止用フラグ
var noBlink = false;
var noDamageSound = false;
/***********************************************************
* ■敵のダメージ演出
***********************************************************/
var _Game_Enemy_performDamage = Game_Enemy.prototype.performDamage;
Game_Enemy.prototype.performDamage = function() {
if (!pEnemyBlink) {
noBlink = true;
}
if (isEffectTarget(this)) {
noDamageSound = true;
}
_Game_Enemy_performDamage.apply(this, arguments);
noBlink = false;
noDamageSound = false;
};
var _SoundManager_playEnemyDamage = SoundManager.playEnemyDamage;
SoundManager.playEnemyDamage = function() {
if (noDamageSound) return;
_SoundManager_playEnemyDamage.apply(this, arguments);
};
var _Sprite_Enemy_startBlink = Sprite_Enemy.prototype.startBlink;
Sprite_Enemy.prototype.startBlink = function() {
if (pBlinkDuration) {
this._effectDuration = pBlinkDuration;
return;
}
_Sprite_Enemy_startBlink.apply(this, arguments);
};
/***********************************************************
* ■アクターのダメージ演出
***********************************************************/
var _Sprite_Actor_initMembers = Sprite_Actor.prototype.initMembers;
Sprite_Actor.prototype.initMembers = function() {
_Sprite_Actor_initMembers.apply(this, arguments);
this._effectType = null;
this._effectDuration = 0;
};
var _Sprite_Actor_update = Sprite_Actor.prototype.update;
Sprite_Actor.prototype.update = function() {
_Sprite_Actor_update.apply(this, arguments);
if (this._actor) {
this.updateEffect();
}
};
var _Game_Actor_performDamage = Game_Actor.prototype.performDamage;
Game_Actor.prototype.performDamage = function() {
if (isEffectTarget(this)) {
noDamageSound = true;
}
_Game_Actor_performDamage.apply(this, arguments);
noDamageSound = false;
if (pActorBlink) {
this.requestEffect('blink');
}
};
var _SoundManager_playActorDamage = SoundManager.playActorDamage;
SoundManager.playActorDamage = function() {
if (noDamageSound) return;
_SoundManager_playActorDamage.apply(this, arguments);
};
Sprite_Actor.prototype.startBlink = function() {
if (pBlinkDuration) {
this._effectDuration = pBlinkDuration;
return;
}
this._effectDuration = 20;
};
Sprite_Actor.prototype.setupEffect = function() {
if (this._actor.isEffectRequested()) {
this.startEffect(this._actor.effectType());
this._actor.clearEffect();
}
};
Sprite_Actor.prototype.startEffect = function(effectType) {
this._effectType = effectType;
switch (this._effectType) {
case 'blink':
this.startBlink();
break;
}
};
Sprite_Actor.prototype.updateEffect = function() {
this.setupEffect();
if (this._effectDuration > 0) {
this._effectDuration--;
switch (this._effectType) {
case 'blink':
this.updateBlink();
break;
}
if (this._effectDuration === 0) {
this._effectType = null;
}
}
};
Sprite_Actor.prototype.isEffecting = function() {
return this._effectType !== null;
};
Sprite_Actor.prototype.updateBlink = function() {
this.opacity = (this._effectDuration % 10 < 5) ? 255 : 0;
};
/***********************************************************
* ■共通:エフェクトリクエスト(点滅)
***********************************************************/
var _Game_Battler_requestEffect = Game_Battler.prototype.requestEffect;
Game_Battler.prototype.requestEffect = function(effectType) {
if (effectType === "blink") {
if (noBlink) {
return;
} else if (isCriticalEffect(this) && pCriticalBlinkOff) {
return;
} else if (isWeakEffect(this) && pWeakBlinkOff) {
return;
} else if (isResistEffect1(this) && pResistBlinkOff1) {
return;
} else if (isResistEffect2(this) && pResistBlinkOff2) {
return;
}
}
_Game_Battler_requestEffect.apply(this, arguments);
};
/***********************************************************
* ■クリティカル/弱点/耐性演出
***********************************************************/
var _Window_BattleLog_displayCritical = Window_BattleLog.prototype.displayCritical;
Window_BattleLog.prototype.displayCritical = function(target) {
const isCriticalFlg = isCriticalEffect(target);
const isWeakFlg = isWeakEffect(target);
const isResistFlg1 = isResistEffect1(target);
const isResistFlg2 = isResistEffect2(target);
// クリティカルと弱点(または耐性)が同時発生した場合
if (isCriticalFlg && (isWeakFlg || isResistFlg1 || isResistFlg2)) {
if (pEffectPrioritity === "critical") {
callAnimation(target, eval(pCriticalAnimation), this);
// 追加:対象が指定ステートを保持している場合、追加アニメーションを表示
if (target.isStateAffected(pExtraStateID)) {
callAnimation(target, pExtraAnimationID, this);
}
_Window_BattleLog_displayCritical.apply(this, arguments);
return;
} else if (pEffectPrioritity === "weak") {
if (isWeakFlg) {
callAnimation(target, eval(pWeakAnimation), this);
} else if (isResistFlg2) {
callAnimation(target, eval(pResistAnimation2), this);
} else if (isResistFlg1) {
callAnimation(target, eval(pResistAnimation1), this);
}
_Window_BattleLog_displayCritical.apply(this, arguments);
return;
}
}
if (isCriticalFlg) {
callAnimation(target, eval(pCriticalAnimation), this);
// 追加:対象が指定ステートの場合、追加アニメーションを表示
if (target.isStateAffected(pExtraStateID)) {
callAnimation(target, pExtraAnimationID, this);
}
}
if (isWeakFlg) {
callAnimation(target, eval(pWeakAnimation), this);
} else if (isResistFlg2) {
callAnimation(target, eval(pResistAnimation2), this);
} else if (isResistFlg1) {
callAnimation(target, eval(pResistAnimation1), this);
}
_Window_BattleLog_displayCritical.apply(this, arguments);
};
function isEffectTarget(target) {
return isCriticalEffect(target) ||
isWeakEffect(target) ||
isResistEffect1(target) ||
isResistEffect2(target);
}
function isCriticalEffect(target) {
const action = BattleManager._action;
return (target.result().critical && pCriticalAnimation);
}
function isWeakEffect(target) {
const action = BattleManager._action;
if (target.result().missed || target.result().evaded || !pWeakAnimation) {
return false;
} else if (target.result().hpAffected && target.result().hpDamage <= 0) {
return false;
}
return eval(pWeakCondition);
}
function isResistEffect1(target) {
const action = BattleManager._action;
if (target.result().missed || target.result().evaded || !pResistAnimation1) {
return false;
}
return eval(pResistCondition1);
}
function isResistEffect2(target) {
const action = BattleManager._action;
if (target.result().missed || target.result().evaded || !pResistAnimation2) {
return false;
}
return eval(pResistCondition2);
}
function callAnimation(target, animationId, win) {
if (!animationId) return;
if (Utils.RPGMAKER_NAME === "MV") {
target.startAnimation(animationId, target.isActor(), 0);
} else {
let animation = $dataAnimations[animationId];
if (!isMVAnimation(animation) && isEmptyAnimation(animation) &&
typeof $dataMvAnimations !== 'undefined') {
animation = $dataMvAnimations[animationId];
}
createAnimationSprite([target], animation, false, 0);
}
}
function isEmptyAnimation(animation) {
return animation &&
!animation.effectName &&
animation.flashTimings.length === 0 &&
animation.soundTimings.length === 0;
}
function isMVAnimation(animation) {
return animation && !!animation.frames;
}
function createAnimationSprite(targets, animation, mirror, delay) {
var spriteSet = BattleManager._spriteset;
const mv = spriteSet.isMVAnimation(animation);
const sprite = new (mv ? Sprite_AnimationMV : Sprite_Animation)();
const targetSprites = spriteSet.makeTargetSprites(targets);
const baseDelay = spriteSet.animationBaseDelay();
const previous = delay > baseDelay ? spriteSet.lastAnimationSprite() : null;
if (spriteSet.animationShouldMirror(targets[0])) {
mirror = !mirror;
}
sprite.targetObjects = targets;
sprite.setup(targetSprites, animation, mirror, delay, previous);
spriteSet._effectsContainer.addChild(sprite);
spriteSet._animationSprites.push(sprite);
sprite._noWait = true;
}
if (Utils.RPGMAKER_NAME !== "MV") {
const _Spriteset_Base_isAnimationPlaying = Spriteset_Base.prototype.isAnimationPlaying;
Spriteset_Base.prototype.isAnimationPlaying = function() {
if (this._animationSprites.length > 0 &&
this._animationSprites.every(sprite => sprite._noWait)) {
return false;
}
return _Spriteset_Base_isAnimationPlaying.apply(this, arguments);
};
}
/***********************************************************
* ■ダメージ表示位置の調整
***********************************************************/
if (pEnemyDamageOffsetX !== undefined) {
Sprite_Enemy.prototype.damageOffsetX = function() {
const offset = eval(pEnemyDamageOffsetX);
return offset ? Number(offset) : 0;
};
}
if (pEnemyDamageOffsetY !== undefined) {
Sprite_Enemy.prototype.damageOffsetY = function() {
const offset = eval(pEnemyDamageOffsetY);
return offset ? Number(offset) : 0;
};
}
if (pActorDamageOffsetX !== undefined) {
Sprite_Actor.prototype.damageOffsetX = function() {
const offset = eval(pActorDamageOffsetX);
return offset ? Number(offset) : 0;
};
}
if (pActorDamageOffsetY !== undefined) {
Sprite_Actor.prototype.damageOffsetY = function() {
const offset = eval(pActorDamageOffsetY);
return offset ? Number(offset) : 0;
};
}
})();