356 lines
12 KiB
JavaScript
356 lines
12 KiB
JavaScript
//=============================================================================
|
||
// MPP_StateLevel.js
|
||
//=============================================================================
|
||
// Copyright (c) 2024 Mokusei Penguin
|
||
// Released under the MIT license
|
||
// http://opensource.org/licenses/mit-license.php
|
||
//=============================================================================
|
||
|
||
/*:
|
||
* @target MZ
|
||
* @plugindesc ステートを重ね掛け出来るようにします。
|
||
* @author 木星ペンギン
|
||
* @url
|
||
*
|
||
* @help [version 1.0.0]
|
||
* - 本プラグインはRPGツクールMZ用です。
|
||
* - Japanese help only.
|
||
* - 不具合・競合・機能追加等の要望に対処できない場合があります。
|
||
* - これらに対応する場合、有償となります。
|
||
*
|
||
* ▼ 仕様
|
||
* 〇 ステート重ね掛け
|
||
* - ステートを重ね掛けした場合、そのステートが複数個付与されている状態と
|
||
* なります。
|
||
* - 2回重ね掛けした場合、単純に効果が2倍になるとは限りません。
|
||
* (一部の乗算処理に関しては2倍になるように調整しています)
|
||
* - 細かな仕様はツクール側の仕様や他プラグインの仕様に準じます。
|
||
*
|
||
* 〇 他追加機能
|
||
* - ステートに重ねて表示される数値は重ね掛けした回数です。
|
||
* - ステートの下に表示されるゲージは残り効果時間です。
|
||
* - ステートを上書きした場合、効果時間が減らないように修正。
|
||
*
|
||
* ================================
|
||
* Mail : wood_penguin@yahoo.co.jp (@は半角)
|
||
* Blog : http://woodpenguin.blog.fc2.com/
|
||
* License : MIT license
|
||
*
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
(() => {
|
||
const pluginName = 'MPP_StateLevel';
|
||
|
||
// Plugin Parameters
|
||
const parameters = PluginManager.parameters(pluginName);
|
||
|
||
const __base = (obj, prop) => {
|
||
if (obj.hasOwnProperty(prop)) {
|
||
return obj[prop];
|
||
} else {
|
||
const proto = Object.getPrototypeOf(obj);
|
||
return function () { return proto[prop].apply(this, arguments); };
|
||
}
|
||
};
|
||
|
||
let stateUser;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Game_Temp
|
||
|
||
const _Game_Temp_initialize = Game_Temp.prototype.initialize;
|
||
Game_Temp.prototype.initialize = function() {
|
||
_Game_Temp_initialize.apply(this, arguments);
|
||
stateUser = null;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Game_Action
|
||
|
||
const _Game_Action_itemEffectAddAttackState = Game_Action.prototype.itemEffectAddAttackState;
|
||
Game_Action.prototype.itemEffectAddAttackState = function(target, effect) {
|
||
stateUser = this.subject();
|
||
_Game_Action_itemEffectAddAttackState.apply(this, arguments);
|
||
stateUser = null;
|
||
};
|
||
|
||
const _Game_Action_itemEffectAddNormalState = Game_Action.prototype.itemEffectAddNormalState;
|
||
Game_Action.prototype.itemEffectAddNormalState = function(target, effect) {
|
||
stateUser = this.subject();
|
||
_Game_Action_itemEffectAddNormalState.apply(this, arguments);
|
||
stateUser = null;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Game_BattlerBase
|
||
|
||
const _Game_BattlerBase_clearStates = Game_BattlerBase.prototype.clearStates;
|
||
Game_BattlerBase.prototype.clearStates = function() {
|
||
_Game_BattlerBase_clearStates.apply(this, arguments);
|
||
this._stateLevels = {};
|
||
this._stateMaxTurns = {};
|
||
};
|
||
|
||
const _Game_BattlerBase_eraseState = Game_BattlerBase.prototype.eraseState;
|
||
Game_BattlerBase.prototype.eraseState = function(stateId) {
|
||
_Game_BattlerBase_eraseState.apply(this, arguments);
|
||
delete this._stateLevels[stateId];
|
||
delete this._stateMaxTurns[stateId];
|
||
};
|
||
|
||
const _Game_BattlerBase_resetStateCounts = Game_BattlerBase.prototype.resetStateCounts;
|
||
Game_BattlerBase.prototype.resetStateCounts = function(stateId) {
|
||
const stTurns = this._stateTurns;
|
||
const stLevels = this._stateLevels;
|
||
const lastStateTurn = stTurns[stateId] || 0;
|
||
_Game_BattlerBase_resetStateCounts.apply(this, arguments);
|
||
stTurns[stateId] = Math.max(stTurns[stateId], lastStateTurn);
|
||
if (stLevels[stateId]) {
|
||
const maxLevel = this.maxStateLevel(stateId)
|
||
+ (stateUser ? stateUser.stateLevelPlus(stateId) : 0);
|
||
if (stLevels[stateId] < maxLevel)
|
||
stLevels[stateId]++;
|
||
} else {
|
||
stLevels[stateId] = 1;
|
||
}
|
||
};
|
||
|
||
Game_BattlerBase.prototype.maxStateLevel = function(stateId) {
|
||
const state = $dataStates[stateId];
|
||
return state ? 99 : 1;
|
||
};
|
||
|
||
Game_BattlerBase.prototype.displayedStates = function() {
|
||
return this.states().filter(state => state.iconIndex > 0);
|
||
};
|
||
|
||
Game_BattlerBase.prototype.stateTurn = function(stateId) {
|
||
return this._stateTurns[stateId] || 0;
|
||
};
|
||
|
||
Game_BattlerBase.prototype.maxStateTurn = function(stateId) {
|
||
return this._stateMaxTurns[stateId] || 1;
|
||
};
|
||
|
||
Game_BattlerBase.prototype.allLevels = function() {
|
||
const levels = this.displayedStates().map(state => {
|
||
return this.maxStateLevel(state.id) > 1
|
||
? this._stateLevels[state.id]
|
||
: 0;
|
||
});
|
||
// for (let i = 0; i < this._buffs.length; i++) {
|
||
// if (this._buffs[i] !== 0) {
|
||
// levels.push(Math.abs(this._buffs[i]));
|
||
// }
|
||
// }
|
||
return levels;
|
||
};
|
||
|
||
// overwrite
|
||
Game_BattlerBase.prototype.traitObjects = function() {
|
||
return this.levelStates();
|
||
};
|
||
|
||
Game_BattlerBase.prototype.levelStates = function() {
|
||
return this.states().reduce((r, state) => {
|
||
const level = this._stateLevels[state.id] || 1;
|
||
for (let i = 0; i < level; i++)
|
||
r.push(state);
|
||
return r;
|
||
}, []);
|
||
};
|
||
|
||
// overwrite
|
||
Game_BattlerBase.prototype.traitsPi = function(code, id) {
|
||
const traitMap = new Map();
|
||
const stateTraits = this.states().map(state => state.traits).flat();
|
||
let value = this.traitsWithId(code, id).reduce((r, trait) => {
|
||
if (stateTraits.includes(trait)){
|
||
traitMap.set(trait, (traitMap.get(trait) || 0) + 1);
|
||
return r;
|
||
}
|
||
return r * trait.value;
|
||
}, 1);
|
||
for (const [trait, level] of traitMap)
|
||
value *= (trait.value - 1) * level + 1;
|
||
return value;
|
||
};
|
||
|
||
Game_BattlerBase.prototype.allMetadata = function(name) {
|
||
return this.traitObjects().reduce((r, obj) => {
|
||
if (name in obj.meta)
|
||
r.push(obj.meta[name]);
|
||
return r;
|
||
}, []);
|
||
};
|
||
|
||
Game_BattlerBase.prototype.metadataNumbers = function(name) {
|
||
return this.allMetadata(name).map(Number);
|
||
};
|
||
|
||
Game_BattlerBase.prototype.metadataSum = function(name) {
|
||
return this.metadataNumbers(name).reduce((r, n) => r + n, 0);
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Game_Battler
|
||
|
||
const _Game_Battler_addState = Game_Battler.prototype.addState;
|
||
Game_Battler.prototype.addState = function(stateId) {
|
||
_Game_Battler_addState.apply(this, arguments);
|
||
if (this.isStateAffected(stateId))
|
||
this.resetMaxStateTurn(stateId);
|
||
};
|
||
|
||
Game_Battler.prototype.resetMaxStateTurn = function(stateId) {
|
||
this._stateMaxTurns[stateId] = Math.max(
|
||
this._stateMaxTurns[stateId] || 0, this._stateTurns[stateId]
|
||
);
|
||
};
|
||
|
||
Game_Battler.prototype.stateLevelPlus = function(stateId) {
|
||
return this.metadataSum(`stLvPlus ${stateId}`);
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_StateTurnGauge
|
||
|
||
class Sprite_StateTurnGauge extends Sprite_Gauge {
|
||
constructor() {
|
||
super();
|
||
this._stateId = 0;
|
||
this.anchor.set(0.5);
|
||
}
|
||
|
||
bitmapWidth() {
|
||
return ImageManager.iconWidth;
|
||
}
|
||
|
||
bitmapHeight() {
|
||
return 8;
|
||
}
|
||
|
||
textHeight() {
|
||
return this.gaugeHeight();
|
||
}
|
||
|
||
gaugeHeight() {
|
||
return this.bitmapHeight() - 2;
|
||
}
|
||
|
||
gaugeX() {
|
||
return 0;
|
||
}
|
||
|
||
setup(battler) {
|
||
super.setup(battler, 'stTurn');
|
||
}
|
||
|
||
setState(stateId) {
|
||
if (this._stateId !== stateId) {
|
||
this._stateId = stateId;
|
||
this._value = NaN;
|
||
this._maxValue = NaN;
|
||
}
|
||
}
|
||
|
||
currentValue() {
|
||
const state = $dataStates[this._stateId];
|
||
return this._battler && state && state.autoRemovalTiming > 0
|
||
? this._battler.stateTurn(this._stateId)
|
||
: NaN;
|
||
}
|
||
|
||
currentMaxValue() {
|
||
return this._battler
|
||
? this._battler.maxStateTurn(this._stateId)
|
||
: NaN;
|
||
}
|
||
|
||
gaugeColor1() {
|
||
return ColorManager.ctGaugeColor1();
|
||
}
|
||
|
||
gaugeColor2() {
|
||
return ColorManager.ctGaugeColor2();
|
||
}
|
||
|
||
drawLabel() {}
|
||
|
||
drawValue() {}
|
||
|
||
}
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_StateIcon
|
||
|
||
const _Sprite_StateIcon_initialize = Sprite_StateIcon.prototype.initialize;
|
||
Sprite_StateIcon.prototype.initialize = function() {
|
||
_Sprite_StateIcon_initialize.apply(this, arguments);
|
||
this._level = 0;
|
||
this._lastLevel = 0;
|
||
this.createTurnSprite();
|
||
this.createLevelSprite();
|
||
};
|
||
|
||
Sprite_StateIcon.prototype.createTurnSprite = function() {
|
||
this._turnSprite = new Sprite_StateTurnGauge();
|
||
this._turnSprite.move(0, 20);
|
||
this.addChild(this._turnSprite);
|
||
};
|
||
|
||
Sprite_StateIcon.prototype.createLevelSprite = function() {
|
||
const bitmap = new Bitmap(ImageManager.iconWidth, ImageManager.iconHeight);
|
||
bitmap.fontFace = $gameSystem.numberFontFace();
|
||
bitmap.fontSize = ImageManager.iconHeight - 12;
|
||
bitmap.textColor = ColorManager.normalColor();
|
||
bitmap.outlineColor = 'rgba(80, 64, 64, 0.75)';//ColorManager.outlineColor();
|
||
bitmap.outlineWidth = 5;
|
||
this._levelSprite = new Sprite(bitmap);
|
||
this._levelSprite.move(-12, -12);
|
||
this.addChild(this._levelSprite);
|
||
};
|
||
|
||
const _Sprite_StateIcon_destroy = __base(Sprite_StateIcon.prototype, 'destroy');
|
||
Sprite_StateIcon.prototype.destroy = function() {
|
||
this._levelSprite.bitmap.destroy();
|
||
_Sprite_StateIcon_destroy.apply(this, arguments);
|
||
};
|
||
|
||
const _Sprite_StateIcon_setup = Sprite_StateIcon.prototype.setup;
|
||
Sprite_StateIcon.prototype.setup = function(battler) {
|
||
if (this._battler !== battler)
|
||
this._turnSprite.setup(battler);
|
||
_Sprite_StateIcon_setup.apply(this, arguments);
|
||
};
|
||
|
||
const _Sprite_StateIcon_update = Sprite_StateIcon.prototype.update;
|
||
Sprite_StateIcon.prototype.update = function() {
|
||
_Sprite_StateIcon_update.apply(this, arguments);
|
||
if (this._lastLevel !== this._level) {
|
||
this._lastLevel = this._level;
|
||
this.updateLevel();
|
||
}
|
||
};
|
||
|
||
const _Sprite_StateIcon_updateIcon = Sprite_StateIcon.prototype.updateIcon;
|
||
Sprite_StateIcon.prototype.updateIcon = function() {
|
||
_Sprite_StateIcon_updateIcon.apply(this, arguments);
|
||
const levels = this.shouldDisplay() ? this._battler.allLevels() : [];
|
||
const state = this._battler.displayedStates()[this._animationIndex];
|
||
this._level = levels.length ? levels[this._animationIndex] || 0 : 0;
|
||
this._turnSprite.setState(state ? state.id : 0);
|
||
};
|
||
|
||
Sprite_StateIcon.prototype.updateLevel = function() {
|
||
const bitmap = this._levelSprite.bitmap;
|
||
const width = ImageManager.iconWidth;
|
||
const height = ImageManager.iconHeight - 12;
|
||
bitmap.clear();
|
||
if (this._level > 0)
|
||
bitmap.drawText(this._level, 0, 12, width - 2, height, 'right');
|
||
};
|
||
|
||
})();
|