sakura-gozen/js/plugins/iii/iiiEnemyInfo.js
2025-01-14 14:06:54 -06:00

619 lines
19 KiB
JavaScript

//=============================================================================
// iiiEnemyInfo.js
//=============================================================================
/*: ja
* @target MZ
* @plugindesc エネミー情報表示プラグイン
* @author iii
* @orderAfter iiiBattleViewCustom
* -----
*/
(() => {
"use strict";
const script = document.currentScript;
const pluginParam = PluginManagerEx.createParameter(script);
const _dpStateId = 41;
const _hpIconW = 74,
_hpIconH = 48;
const _dpIconW = 74,
_dpIconH = 48;
const _largeIconW = _hpIconW > _dpIconW ? _hpIconW : _dpIconW;
const _infoWinRect = new Rectangle(
-3,
20,
300 + _largeIconW + 20,
_hpIconH + _dpIconH + 48 /* lineHeight * 2 */
);
const _gaugeX = _largeIconW + 10;
const _gaugeW = _infoWinRect.width - (_largeIconW + 20 + 10);
const _gaugeH = 24;
//-----------------------------------------------------------------------------
// Scene_Base / Scene_Battle
//
const _Scene_Battle_prototype_createAllWindows =
Scene_Battle.prototype.createAllWindows;
Scene_Battle.prototype.createAllWindows = function () {
_Scene_Battle_prototype_createAllWindows.call(this);
this._currentEnemyInfoWindow = new CurrentEnemyInfoWindow(_infoWinRect);
this._currentEnemyInfoWindow.hide();
this.addWindow(this._currentEnemyInfoWindow, 2); //ステータスウインドウの次
// 雑魚敵用の表示
this._residentEnemyWins = [];
const enemies = $gameTroop.aliveMembers();
enemies.forEach(
function (enemy, index) {
if (enemy.isBigEnemy()) {
return;
}
const enemySprite = this._spriteset.findTargetSprite(enemy);
let rect = new Rectangle(
enemySprite.x,
enemySprite.y,
300,
_infoWinRect.height
);
let win = new ResidentEnemyInfoWindow(rect);
win.anchor.x = 0;
win.anchor.y = 0;
win.setEnemyInfo(enemy);
this._spriteset.addChild(win);
this._residentEnemyWins.push(win);
}.bind(this)
);
};
const _Scene_Battle_prototype_update = Scene_Battle.prototype.update;
Scene_Battle.prototype.update = function () {
_Scene_Battle_prototype_update.call(this);
this.updateCurrentEnemyInfo();
this.updateResidentEnemyInfo();
};
// 現在選択中エネミーの情報更新
Scene_Battle.prototype.updateCurrentEnemyInfo = function () {
if (!this._currentEnemyInfoWindow) return;
if (this._logWindow.opacity) {
this._currentEnemyInfoWindow.hide();
return;
}
let nextTarget = null;
if (this._enemyWindow.active) {
nextTarget = this._enemyWindow.enemy();
} else if (BattleManager._bossTarget) {
nextTarget = BattleManager._bossTarget;
} else if (BattleManager._nextTarget) {
nextTarget = BattleManager._nextTarget;
}
if (!nextTarget) return;
this._currentEnemyInfoWindow.setEnemyInfo(nextTarget);
// 状態異常アイコン群位置調整
const enemySprite = this._spriteset.findTargetSprite(nextTarget);
if (enemySprite) {
const currentWin = this._currentEnemyInfoWindow;
const iconSprite = enemySprite._stateIconSprite;
iconSprite.anchor.x = 0;
iconSprite.anchor.y = 0;
iconSprite.x = -enemySprite.x;
iconSprite.y = -enemySprite.y;
iconSprite.y += currentWin.height + ImageManager.iconHeight + 8;
}
// 敵グループ内にボスがいれば強制表示
if (BattleManager._bossTarget) {
this._currentEnemyInfoWindow.show();
}
};
// 常駐エネミー表示(ザコ用)の更新
Scene_Battle.prototype.updateResidentEnemyInfo = function () {
this._residentEnemyWins.forEach(
function (win, index) {
if (win._gameEnemy.isDead()) {
win.hide();
const enemySprite2 = this._spriteset.findTargetSprite(win._gameEnemy);
enemySprite2._stateIconSprite.hide();
} else {
win.refreshMeta();
win.show();
const enemySprite = this._spriteset.findTargetSprite(win._gameEnemy);
win.x = enemySprite.x - enemySprite.width / 2;
win.y = enemySprite.y - enemySprite.height / 2;
// 状態異常アイコン群位置調整
//enemySprite._stateIconSprite.x = -win.width/2 -ImageManager.iconWidth/2;
//enemySprite._stateIconSprite.y = -win.height/2-ImageManager.iconHeight/2;
enemySprite._stateIconSprite.x = -win.width / 4 - 75;
if (enemySprite.height <= 3000 && enemySprite.height >= 700) {
enemySprite._stateIconSprite.y =
-win.height + ImageManager.iconWidth / 2;
} else {
enemySprite._stateIconSprite.y =
-win.height - enemySprite.height / 6 + ImageManager.iconWidth;
}
}
}.bind(this)
);
};
const _Scene_Battle_prototype_startPartyCommandSelection =
Scene_Battle.prototype.startPartyCommandSelection;
Scene_Battle.prototype.startPartyCommandSelection = function () {
_Scene_Battle_prototype_startPartyCommandSelection.call(this);
this._currentEnemyInfoWindow.hide();
};
// const _Scene_Battle_prototype_startActorCommandSelection = Scene_Battle.prototype.startActorCommandSelection;
// Scene_Battle.prototype.startActorCommandSelection = function()
// {
// _Scene_Battle_prototype_startActorCommandSelection.call(this);
// }
const _Scene_Battle_prototype_commandSkill =
Scene_Battle.prototype.commandSkill;
Scene_Battle.prototype.commandSkill = function () {
_Scene_Battle_prototype_commandSkill.call(this);
// this._currentEnemyInfoWindow.show(); //ボス以外では表示不要とのことなのでコメントアウト
};
const _Scene_Battle_prototype_onSkillCancel =
Scene_Battle.prototype.onSkillCancel;
Scene_Battle.prototype.onSkillCancel = function () {
_Scene_Battle_prototype_onSkillCancel.call(this);
if (!this._skillWindow.active) {
this._currentEnemyInfoWindow.hide();
}
};
//-----------------------------------------------------------------------------
// BattleManager
//
const _BattleManager_startBattle = BattleManager.startBattle;
BattleManager.startBattle = function () {
_BattleManager_startBattle.call(this);
this._nextTarget = null;
this._bossTarget = null;
const enemies = $gameTroop.aliveMembers();
if (enemies.length <= 0) return;
//現在選択的情報はとりあえず先頭の敵を入れておく
this._nextTarget = enemies[0];
//ボスいれば情報保存しとく
enemies.forEach(
function (enemy) {
if (enemy.isBigEnemy()) {
this._bossTarget = enemy;
}
}.bind(this)
);
};
const _BattleManager_startAction = BattleManager.startAction;
BattleManager.startAction = function () {
_BattleManager_startAction.call(this);
//戦闘の対象をとりあえず設定しておく
this._setNextTarget(this._targets[0]);
};
const _BattleManager_invokeAction = BattleManager.invokeAction;
BattleManager.invokeAction = function (subject, target) {
_BattleManager_invokeAction.call(this, subject, target);
this._setNextTarget(target);
};
BattleManager._setNextTarget = function (target) {
if (
target &&
target.constructor &&
target.constructor.name == "Game_Enemy"
) {
this._nextTarget = target;
} else {
this._nextTarget = null;
}
};
//-----------------------------------------------------------------------------
// Original Classes
//
/**
* 敵情報ウインドウ(左上・ボス用)
*/
class CurrentEnemyInfoWindow extends Window_Base {
constructor(rect) {
super(rect);
// ウインドウ枠の描画をOFF
this.frameVisible = false;
this._defaultPadding = this.padding;
this.padding = 0; //オリジナル背景描画に都合悪いのでパディング0に
// オリジナルの背景画像利用する。
{
this._backGroundSprite = new Sprite();
this._backGroundSprite1 = new Sprite();
this._backGroundSprite2 = new Sprite();
this._backGroundSprite.addChild(this._backGroundSprite1);
this._backGroundSprite.addChild(this._backGroundSprite2);
//↓pictureフォルダから画像を読み込み設定している。systemフォルダから読む場合はloadSystemを利用する。
// * ツクールの画像読み込みは基本非同期(遅延読み込み)されるので大きすぎる画像だと注意。
this._backGroundSprite1.bitmap = ImageManager.loadPicture(
"BattlePic/UI_Bossinfo"
);
this._backGroundSprite2.bitmap = ImageManager.loadPicture(
"BattlePic/UI_Bossinfo_ss"
);
//画像読み込み後にウインドウサイズに合わせて拡縮する。不要なら削除して問題ないです。
// this._backGroundSprite.bitmap.addLoadListener(function(bitmap) {
// this._backGroundSprite.scale.x = this.width / bitmap.width;
// this._backGroundSprite.scale.y = this.height / bitmap.height;
// }.bind(this));
Torigoya.FrameTween.create(this._backGroundSprite)
.to({ x: -300 }, 0)
.to({ x: 0 }, 180, Torigoya.FrameTween.Easing.easeOutCircular)
.start();
//_contentsSprite(テキスト類等)より後ろにしたいので描画位置調整
this._backSprite.opacity = 0;
this._clientArea.addChildAt(
this._backGroundSprite,
this._clientArea.children.lenght - 2
);
}
this._enemyHpGauge = new EnemyGaugeContainer(_gaugeW - 128, 32);
this.addChild(this._enemyHpGauge);
this._enemyTikanGauge = new EnemyGaugeContainer(_gaugeW - 128, 32);
this.addChild(this._enemyTikanGauge);
this.updatePerfectSprite();
// ボスに関しては状態異常アイコンもウインドウ内にて表示(立ち絵より前に出したいため)
// Sprite_StateIcon2についてはiiiBattleViewCustom参照
this._stateIconSprite = new Sprite_StateIcon2();
this.addChild(this._stateIconSprite);
}
update() {
super.update();
this.updatePerfectSprite();
}
updatePerfectSprite() {
if ($gameParty.leader().actorId() == 1) {
this._backGroundSprite1.visible = !$gameActors
.actor(1)
.hasArmor($dataArmors[9]);
this._backGroundSprite2.visible = !this._backGroundSprite1.visible;
} else {
this._backGroundSprite1.visible = true;
this._backGroundSprite2.visible = false;
}
}
setWeakInfo(gameEnemy) {
var enemy = this._gameEnemy;
if (!enemy) return;
//++弱点アイコン表示
var weaks = enemy
.enemy()
.traits.filter(
(t) =>
t.code == 11 && [7, 8, 9, 10].indexOf(t.dataId) >= 0 && t.value > 1
);
if (!weaks) return;
const iconIdTbl = {
7: 272,
8: 273,
9: 274,
10: 275,
};
const iix = 230;
const iiw = 32;
const iiy = 55;
weaks.forEach((weak, idx) => {
const iconId = iconIdTbl[weak.dataId];
this.drawIcon(iconId, iix + iiw * idx, iiy);
}, this);
return;
}
setEnemyInfo(gameEnemy) {
this._gameEnemy = gameEnemy;
if (this._gameEnemy && this._gameEnemy.enemy) {
this.drawTextEx(
this._gameEnemy.enemy().name,
this._defaultPadding,
this._defaultPadding,
this.contentsWidth()
);
this._enemyHpGauge.setup(
this._gameEnemy,
"hp",
"BattlePic/UI_enmHP",
_gaugeX
);
this._enemyHpGauge.x = 5;
this._enemyHpGauge.y = (this.lineHeight() + _hpIconH) / 2;
this._enemyHpGauge.gauge.x = _gaugeX - 32;
this._enemyHpGauge.gauge.y = (_hpIconH - _gaugeH) / 2;
this._enemyHpGauge.show();
this._enemyTikanGauge.setup(
this._gameEnemy,
"dp",
"BattlePic/UI_enmDP",
_gaugeX
);
this._enemyTikanGauge.x = 5;
this._enemyTikanGauge.y =
this._enemyHpGauge.y + (_hpIconH + _dpIconH) / 2 + 3;
this._enemyTikanGauge.gauge.x = _gaugeX - 32;
this._enemyTikanGauge.gauge.y = (_dpIconH - _gaugeH) / 2;
this._enemyTikanGauge.show();
this.setWeakInfo(this._gameEnemy);
this._stateIconSprite.x = 5;
this._stateIconSprite.y = this._enemyTikanGauge.y + _dpIconH;
this._stateIconSprite.setup(this._gameEnemy);
} else {
this._enemyHpGauge.hide();
this._enemyTikanGauge.hide();
}
}
}
/**
* 敵情報ウインドウ(常駐・雑魚用 Spriteを継承しているので注意)
*/
class ResidentEnemyInfoWindow extends Sprite {
constructor(rect) {
super();
this.x = rect.x;
this.y = rect.y;
this.width = rect.width;
this.height = rect.height;
//super(rect)
//this.backOpacity = 0;
//this.isWindow = true;
this._enemyHpGauge = new EnemyGaugeContainer(60, 32);
this.addChild(this._enemyHpGauge);
this._enemyTikanGauge = new EnemyGaugeContainer(30, 32);
this.addChild(this._enemyTikanGauge);
}
setEnemyInfo(gameEnemy) {
this._gameEnemy = gameEnemy;
if (this._gameEnemy && this._gameEnemy.enemy) {
//this.bitmap.drawText(this._gameEnemy.enemy().name, 0, 0, 128, 32);
this._enemyHpGauge.setup(
this._gameEnemy,
"hp",
"BattlePic/UI_enmHP_s",
_gaugeX
);
this._enemyHpGauge.x = 55;
this._enemyHpGauge.y = (32 + _hpIconH) / 2;
this._enemyHpGauge.gauge.x = _gaugeX - 58;
this._enemyHpGauge.gauge.y = (_hpIconH - _gaugeH) / 20;
this._enemyHpGauge.show();
this._enemyTikanGauge.setup(
this._gameEnemy,
"dp",
"BattlePic/UI_enmDP_s",
_gaugeX
);
this._enemyTikanGauge.x = this._enemyHpGauge.x + 90;
this._enemyTikanGauge.y = this._enemyHpGauge.y; //this._enemyHpGauge.y + (_hpIconH + _dpIconH) / 2 + 3;
this._enemyTikanGauge.gauge.x = _gaugeX - 58;
this._enemyTikanGauge.gauge.y = (_dpIconH - _gaugeH) / 20;
this._enemyTikanGauge.show();
} else {
this._enemyHpGauge.hide();
this._enemyTikanGauge.hide();
}
}
destroy = function (options) {
for (const child of this.children) {
if (child.bitmap) {
child.bitmap.destroy();
}
}
Sprite.prototype.destroy.call(this, options);
};
createChildSprite = function (width, height) {
const sprite = new Sprite();
sprite.bitmap = this.createBitmap(width, height);
sprite.anchor.x = 0.5;
sprite.anchor.y = 1;
sprite.y = -40;
sprite.ry = sprite.y;
this.addChild(sprite);
return sprite;
};
createBitmap = function (width, height) {
const bitmap = new Bitmap(width, height);
bitmap.fontFace = this.fontFace();
bitmap.fontSize = this.fontSize();
bitmap.textColor = this.damageColor();
bitmap.outlineColor = this.outlineColor();
bitmap.outlineWidth = this.outlineWidth();
return bitmap;
};
refreshMeta() {
var enemy = this._gameEnemy;
if (!enemy) return;
//++弱点アイコン表示(zako)
var weaks = enemy
.enemy()
.traits.filter(
(t) =>
t.code == 11 && [7, 8, 9, 10].indexOf(t.dataId) >= 0 && t.value > 1
);
if (!weaks) return;
const iconIdTbl = {
7: 272,
8: 273,
9: 274,
10: 275,
};
const iix = 55;
const iiw = 32;
const iiy = this._enemyHpGauge.y + _gaugeH + ImageManager.iconHeight / 4;
weaks.forEach((weak, idx) => {
const iconId = iconIdTbl[weak.dataId];
this.drawIcon(iconId, iix + iiw * idx, iiy);
}, this);
return;
}
drawIcon(iconIndex, x, y) {
if (!this.bitmap) {
this.bitmap = new Bitmap(this.width, this.height);
}
//this.bitmap.clear();
const image = ImageManager.loadSystem("IconSet");
const pw = ImageManager.iconWidth;
const ph = ImageManager.iconHeight;
const sx = (iconIndex % 16) * pw;
const sy = Math.floor(iconIndex / 16) * ph;
this.bitmap.blt(image, sx, sy, pw, ph, x, y);
}
}
/**
* ゲージアイコン画像+ゲージのコンテナ
*/
class EnemyGaugeContainer extends Sprite {
constructor(w, h) {
super();
this._icon = new Sprite();
this.addChild(this._icon);
this._gauge = new NotLabelSprite_Gauge(w, h);
this.addChild(this._gauge);
this.hide();
}
get icon() {
return this._icon;
}
get gauge() {
return this._gauge;
}
setup(enemy, type, iconName) {
this._icon.bitmap = ImageManager.loadPicture(iconName);
this._gauge.setup(enemy, type);
}
show() {
this._icon.show();
this._gauge.show();
}
hide() {
this._icon.hide();
this._gauge.hide();
}
}
/**
* Sprite_Gaugeから名称表示を削除したゲージ
*/
class NotLabelSprite_Gauge extends Sprite_Gauge {
constructor(w, h) {
super(...arguments);
}
initialize(w, h) {
this._gaugeW = w;
this._gaugeH = h;
//console.log("w => " + w);
//console.log("h => " + h);
super.initialize();
}
label() {
let txt = super.label();
if (this._battler) {
txt = "";
}
return txt;
}
currentValue() {
let val = super.currentValue();
if (this._battler && this._statusType == "dp") {
//多少の誤差はいったん無視
//https://www.delftstack.com/ja/howto/javascript/javascript-round-to-2-decimal-places/
val =
Math.round(this._battler.getStateAccumulation(_dpStateId) * 100) / 1;
val = val.clamp(0, 100);
}
return val;
}
currentMaxValue() {
let val = super.currentMaxValue();
if (this._battler && this._statusType == "dp") {
val = 100;
}
return val;
}
gaugeColor1() {
let col = super.gaugeColor1();
if (this._statusType == "dp") {
col = ColorManager.tpGaugeColor1();
}
return col;
}
gaugeColor2() {
let col = super.gaugeColor2();
if (this._statusType == "dp") {
col = ColorManager.tpGaugeColor2();
}
return col;
}
valueColor() {
let col = super.valueColor();
if (this._battler && this._statusType == "dp") {
col = ColorManager.tpColor(this._battler);
}
return col;
}
bitmapWidth() {
/* return 128; */ return this._gaugeW;
}
bitmapHeight() {
/* return 32; */ return this._gaugeH;
}
textHeight() {
/* return 24; */ return 24;
}
gaugeHeight() {
/* return 12; */ return 18;
}
gaugeX() {
/* super() */ return 0;
}
}
})();