/*:ja
 * @plugindesc 戦闘プラグイン
 * @author COBRA
 *
 * @help
 * オルタの戦闘プラグイン
 */

function Window_CBR_BattleResult() {
	this.initialize(...arguments);
}

function Window_BattleSkillType() {
	this.initialize(...arguments);
}

function Window_Battle_Help() {
	this.initialize(...arguments);
}

function Window_Message_Battle() {
	this.initialize(...arguments);
}

(function () {
	//無駄な箇所の削除
	Spriteset_Battle.prototype.createBackground = function () {};
	Spriteset_Battle.prototype.loadSystemImages = function () {
		Spriteset_Base.prototype.loadSystemImages.call(this);
		//ImageManager.loadSystem("Shadow2");
		//ImageManager.loadSystem("Weapons1");
		//ImageManager.loadSystem("Weapons2");
		//ImageManager.loadSystem("Weapons3");
	};

	//画面の装飾
	const _Spriteset_Battle_createBattleback = Spriteset_Battle.prototype.createBattleback;
	Spriteset_Battle.prototype.createBattleback = function () {
		_Spriteset_Battle_createBattleback.call(this);

		this.CBR_createBattleDeco();
	};

	Spriteset_Battle.prototype.CBR_createBattleDeco = function () {
		this._battleDeco = new Sprite();
		this._battleDeco.bitmap = ImageManager.loadSystem("battle_back");
		this._battleDeco.x = 0;
		this._battleDeco.y = 0;
		this._baseSprite.addChild(this._battleDeco);
	};

	//戦闘開始のコマンドウィンドウ
	Scene_Battle.prototype.partyCommandWindowRect = function () {
		const ww = 192;
		const wh = this.windowAreaHeight();
		const wx = 0;
		const wy = 100;
		return new Rectangle(wx, wy, ww, wh);
	};

	//各キャラクターのコマンドウィンドウ
	//位置調整
	Scene_Battle.prototype.actorCommandWindowRect = function () {
		const ww = 192;
		const wh = 480;
		const wx = 0;
		const wy = 100;
		return new Rectangle(wx, wy, ww, wh);
	};
	Scene_Battle.prototype.createActorCommandWindow = function () {
		const rect = this.actorCommandWindowRect();
		const commandWindow = new Window_ActorCommand(rect);
		//commandWindow.y = Graphics.boxHeight - commandWindow.height;//なぜかここでもyを定義してる
		commandWindow.setHandler("attack", this.commandAttack.bind(this));
		commandWindow.setHandler("skill", this.commandSkill.bind(this));
		commandWindow.setHandler("guard", this.commandGuard.bind(this));
		commandWindow.setHandler("item", this.commandItem.bind(this));
		commandWindow.setHandler("escape", this.commandEscape.bind(this));
		commandWindow.setHandler("cancel", this.commandCancel.bind(this));
		commandWindow.setHandler("kigae", this.commandKigae.bind(this));

		commandWindow.setHandler("teiko", this.commandTeiko.bind(this));
		commandWindow.setHandler("akirame", this.commandAkirame.bind(this));

		this.addWindow(commandWindow);
		this._actorCommandWindow = commandWindow;
	};

	Scene_Battle.prototype.commandKigae = function () {
		// this._actorCommandWindow.deactivate();
	};

	Window_ActorCommand.prototype.processOk = function () {
		if (this._actor) {
			if (ConfigManager.commandRemember) {
				if (this.currentSymbol() === "kigae") {
					var idx = this._actor._name == "Shirayuki" ? 1150 : 1151;

					BattleManager._inputting = false;
					const commonEvent = $dataCommonEvents[idx];
					if (commonEvent) {
						const interpreter = new Game_Interpreter();
						interpreter.setup(commonEvent.list);
						interpreter.update();
					}
					return;
				} else {
					this._actor.setLastCommandSymbol(this.currentSymbol());
				}
			} else {
				this._actor.setLastCommandSymbol("");
			}
		}
		Window_Command.prototype.processOk.call(this);
	};

	Scene_Battle.prototype.skillTypeWindowRect = function () {
		const wx = 640;
		const wy = 30;
		const ww = 620;
		const wh = 500;
		return new Rectangle(wx, wy, ww, wh);
	};

	Scene_Battle.prototype.createSkillWindow = function () {
		const rect = this.skillWindowRect();
		this._skillWindow = new Window_BattleSkill(rect);
		this._skillWindow.setHelpWindow(this._helpWindow);
		this._skillWindow.setHandler("ok", this.onSkillOk.bind(this));
		this._skillWindow.setHandler("cancel", this.onSkillCancel.bind(this));

		const rect2 = this.skillTypeWindowRect();
		this._skillTypeWindow = new Window_BattleSkillType(rect2);
		this._skillTypeWindow.setSkillWindow(this._skillWindow);
		this.addWindow(this._skillTypeWindow);
		this.addWindow(this._skillWindow);
	};

	Scene_Battle.prototype.hideSubInputWindows = function () {
		this._actorWindow.deactivate();
		this._enemyWindow.deactivate();
		this._skillWindow.deactivate();
		this._skillTypeWindow.deactivate();
		this._itemWindow.deactivate();
		this._actorWindow.hide();
		this._enemyWindow.hide();
		this._skillWindow.hide();
		this._skillTypeWindow.hide();
		this._itemWindow.hide();
	};
	Scene_Battle.prototype.commandSkill = function () {
		this._skillWindow.setActor(BattleManager.actor());
		this._skillWindow.setStypeId(this._actorCommandWindow.currentExt());

		this._skillTypeWindow.setActor(BattleManager.actor());
		this._skillTypeWindow.show();
		this._skillTypeWindow.activate();
		this._skillTypeWindow.selectLastIndex();

		this._skillWindow.refresh();
		this._skillWindow.selectLastIndex();
		this._skillWindow.show();
		this._skillWindow.activate();
		// this._statusWindow.hide();
		// this._actorCommandWindow.hide();
	};

	Scene_Battle.prototype.commandItem = function () {
		this._itemWindow.refresh();
		this._itemWindow.show();
		this._itemWindow.activate();
		//this._statusWindow.hide();
		//this._actorCommandWindow.hide();
	};

	Scene_Battle.prototype.onSkillCancel = function () {
		this._skillWindow.hide();
		this._skillTypeWindow.hide();
		this._statusWindow.show();
		this._actorCommandWindow.show();
		this._actorCommandWindow.activate();
	};

	Scene_Battle.prototype.commandTeiko = function () {
		const action = BattleManager.inputtingAction();
		action.setTeiko();
		this.onSelectAction();
	};

	Game_Action.prototype.setTeiko = function () {
		// 実行したいスキルID
		this.setSkill(100);
	};

	Scene_Battle.prototype.commandAkirame = function () {
		const action = BattleManager.inputtingAction();
		action.setAkirame();
		this.onSelectAction();
	};
	Game_Action.prototype.setAkirame = function () {
		// 実行したいスキルID
		this.setSkill(101);
	};

	const _Game_Action_apply = Game_Action.prototype.apply;
	Game_Action.prototype.apply = function (target) {
		_Game_Action_apply.call(this, target);

		const result = target.result();
		// 命中したかどうかを記録（true / false）
		BattleManager._lastHitResult = result.isHit();
	};

	//逃げるコマンドの追加
	Window_ActorCommand.prototype.makeCommandList = function () {
		if (this._actor) {
			// このマップ条件はいらん
			//if ($gameMap.mapId() < 174 || 179 < $gameMap.mapId()) {
			// 拘束中の時コマンド変更
			if (this._actor.isStateAffected(88)) {
				this.addCommand("抵抗する", "teiko", true);
				this.addCommand("諦める", "akirame", true);
			} else {
				this.addAttackCommand();
				this.addSkillCommands();
				this.addGuardCommand();
				this.addItemCommand();
				//this._actor._stateSteps.findIndex(e => e.);

				if (this._actor.name() == "Shirayuki") {
					//裸だと強制的に出現
					if ($gameVariables.value(204) == 1 || $gameSwitches.value(121)) {
						this.addCommand("更衣", "kigae", true);
					}
				} else {
					//裸だと強制的に出現
					if ($gameVariables.value(205) == 1 || $gameSwitches.value(122)) {
						this.addCommand("更衣", "kigae", true);
					}
				}
			}

			this.addCommand("撤退", "escape", BattleManager.canEscape());
		}
	};

	Window_ActorCommand.prototype.drawItem = function (index) {
		const rect = this.itemLineRect(index);
		const align = "center";
		this.changeTextColor("#FFFFFF");
		this.contents.fontFace = "serif";
		this.changePaintOpacity(this.isCommandEnabled(index));
		this.drawText(this.commandName(index), rect.x, rect.y + 1, rect.width, align);
	};

	// テキストを左寄せに設定
	Window_ActorCommand.prototype.itemTextAlign = function () {
		return "left";
	};
	//選択コマンドの背景
	ColorManager.loadWindowskin = function () {
		this._windowskin = ImageManager.loadSystem("Window");
		this._battlewindowskin = ImageManager.loadSystem("battle_command");
	};
	Window_ActorCommand.prototype.loadWindowskin = function () {
		this.windowskin = ImageManager.loadSystem("Window");
		this._battlewindowskin = ImageManager.loadSystem("battle_command");
	};

	//無駄な物を削除
	Window_ActorCommand.prototype._refreshAllParts = function () {
		//this._refreshBack();
		//this._refreshFrame();
		//this._refreshCursor();
		//this._refreshArrows();
		//this._refreshPauseSign();
	};

	//56×200にする
	Window_ActorCommand.prototype._refreshCursor = function () {
		const drect = this._cursorRect.clone();
		const srect = { x: 0, y: 0, width: 169, height: 58 };
		const m = 4;
		for (const child of this._cursorSprite.children) {
			child.bitmap = this._battlewindowskin;
		}
		this._setRectPartsGeometry(this._cursorSprite, srect, drect, m);
	};

	//透明度を1に
	Window_ActorCommand.prototype._updateCursor = function () {
		this._cursorSprite.alpha = 1;
		this._cursorSprite.visible = this.isOpen() && this.cursorVisible;
		this._cursorSprite.x = this._cursorRect.x;
		this._cursorSprite.y = this._cursorRect.y;
	};

	//未選択コマンドの背景を画像に
	Window_ActorCommand.prototype.drawItemBackground = function (index) {
		const rect = this.itemRect(index);
		if (this._battlewindowskin) {
			const bitmap = this._battlewindowskin;
			const dx = rect.x;
			const dy = rect.y;
			const dw = rect.width;
			const dh = rect.height;
			this.contentsBack.blt(bitmap, 0, 58, 169, 58, dx, dy, dw, dh);
		}
	};
	Window_ActorCommand.prototype.itemHeight = function () {
		return 58;
	};
	Window_ActorCommand.prototype.colSpacing = function () {
		return 12;
	};

	// ####################################################
	// ################# メッセージウィンドウ ####################
	// ####################################################
	Window_Message_Battle.prototype = Object.create(Window_Message.prototype);
	Window_Message_Battle.prototype.constructor = Window_Message_Battle;

	Scene_Battle.prototype.createMessageWindow = function () {
		const rect = this.messageWindowRect();
		this._messageWindow = new Window_Message_Battle(rect);
		this.addWindow(this._messageWindow);
	};

	// メッセージの位置微調整
	Window_Message_Battle.prototype.newPage = function (textState) {
		this.contents.clear();
		this.resetFontSettings();
		this.clearFlags();
		this.updateSpeakerName();
		this.loadMessageFace();
		if ($gameMessage.background() == 1) {
			textState.x = 20;
			textState.y = 8;
			this.height = 50;
		} else {
			textState.x = textState.startX;
			textState.y = 120;
			this.height = 270;
		}
		textState.height = this.calcTextHeight(textState);
	};

	// 背景の透明度を変更
	Window_Message_Battle.prototype.updateBackgroundDimmer = function () {
		if (this._dimmerSprite) {
			this._dimmerSprite.opacity = this.openness * 0.5;
		}
	};

	// ####################################################
	// ################# スキルの種類 ####################
	// ####################################################
	Window_BattleSkillType.prototype = Object.create(Window_Command.prototype);
	Window_BattleSkillType.prototype.constructor = Window_BattleSkillType;

	Window_BattleSkillType.prototype.maxCols = function () {
		return 5;
	};

	Window_BattleSkillType.prototype.processOk = function () {};

	Window_BattleSkillType.prototype.initialize = function (rect) {
		Window_HorzCommand.prototype.initialize.call(this, rect);
		this._padding = 0;
		this.hide();

		// windowが重なっても透過させる
		this._isWindow = false;
	};

	Window_BattleSkillType.prototype.setActor = function (actor) {
		if (this._actor !== actor) {
			this._actor = actor;
			this.refresh();
		}
	};
	Window_BattleSkillType.prototype.selectLastIndex = function () {
		if (this._actor) {
			if (ConfigManager.commandRemember) {
				this.select(this._actor._lastBattleSkillCateIndex || 0);
			} else {
				this.select(0);
			}
		}
	};

	Window_BattleSkillType.prototype._refreshAllParts = function () {
		this._padding = 0;
		this._refreshBack();
		//this._refreshFrame();
		this._refreshCursor();
		this._refreshArrows();
		this._refreshPauseSign();
	};

	// デザイン関係
	//カーソルの変更
	Window_BattleSkillType.prototype.loadWindowskin = function () {
		this.windowskin = ImageManager.loadSystem("Window");
		this.menu_item_skin = ImageManager.loadSystem("menu_item_categoly_select");
		this.menu_cursor_skin = ImageManager.loadSystem("menu_item_categoly_cursor");
		this.CBR_back = ImageManager.loadSystem("battle_skill_window");

		if (!this.menu_item_skin.isReady()) {
			this.menu_item_skin.addLoadListener(() => {
				this.refresh(); // 画像がロードされたら再描画
			});
			return;
		}
	};

	Window_BattleSkillType.prototype.updateBackOpacity = function () {
		this.backOpacity = 255;
	};

	Window_BattleSkillType.prototype._refreshBack = function () {
		// const m = this._margin;
		// const w = Math.max(0, this._width - m * 2);
		// const h = Math.max(0, this._height - m * 2);
		const sprite = this._backSprite;
		// const tilingSprite = sprite.children[0];
		// [Note] We use 95 instead of 96 here to avoid blurring edges.
		sprite.bitmap = this.CBR_back;
		// sprite.setFrame(0, 0, 95, 95);
		// sprite.move(m, m);
		// sprite.scale.x = w / 95;
		// sprite.scale.y = h / 95;
		// tilingSprite.bitmap = this._windowskin;
		// tilingSprite.setFrame(0, 96, 96, 96);
		// tilingSprite.move(0, 0, w, h);
		// tilingSprite.scale.x = 1 / sprite.scale.x;
		// tilingSprite.scale.y = 1 / sprite.scale.y;
		// sprite.setColorTone(this._colorTone);
	};

	Window_BattleSkillType.prototype.lineHeight = function () {
		return 58;
	};

	Window_BattleSkillType.prototype._refreshCursor = function () {
		const drect = this._cursorRect.clone();
		const srect = { x: 0, y: 0, width: 126, height: 58 };
		const m = 0;
		for (const child of this._cursorSprite.children) {
			child.bitmap = this.menu_cursor_skin;
		}
		this._setRectPartsGeometry(this._cursorSprite, srect, drect, m);
	};
	//カーソルを微調整、あとカーソルを常に不透明に
	Window_BattleSkillType.prototype._updateCursor = function () {
		this._cursorSprite.alpha = 255;
		this._cursorSprite.visible = this.isOpen() && this.cursorVisible;
		this._cursorSprite.x = this._cursorRect.x;
		this._cursorSprite.y = this._cursorRect.y - 4;
	};
	//未選択コマンドの背景を画像に
	Window_BattleSkillType.prototype.drawItemBackground = function (index) {
		const rect = this.itemRect(index);
		if (this.menu_item_skin.isReady()) {
			const bitmap = this.menu_item_skin;
			const dx = rect.x;
			const dy = rect.y;
			const dw = rect.width;
			const dh = rect.height;
			this.contentsBack.blt(bitmap, 0, 0, 126, 58, dx, dy - 4, dw, dh);
		}
	};

	//カーソルが来た時、アイテムの文字名の色を変更する
	Window_BattleSkillType.prototype.drawItem = function (index) {
		const rect = this.itemLineRect(index);
		const align = this.itemTextAlign();
		this.resetTextColor();
		if (index == this._index) {
			this.changeTextColor("#000000");
		}
		this.contents.fontFace = "serif";
		// this.contents.fontSize = 18;
		this.changePaintOpacity(this.isCommandEnabled(index));
		//文字をちょっと下にする
		this.drawTextS(this.commandName(index), rect.x, rect.y + 8, rect.width, align);
	};

	Window_BattleSkillType.prototype.itemWidth = function () {
		return Math.floor((this.innerWidth - 196) / this.maxCols());
	};

	Window_BattleSkillType.prototype.itemRect = function (index) {
		const maxCols = this.maxCols();
		const itemWidth = this.itemWidth();
		const itemHeight = this.itemHeight();
		const colSpacing = this.colSpacing();
		const rowSpacing = this.rowSpacing();
		const col = index % maxCols;
		const row = Math.floor(index / maxCols);
		const x = col * itemWidth + colSpacing / 2 - this.scrollBaseX() + 218;
		const y = row * itemHeight + rowSpacing / 2 - this.scrollBaseY() + 4;
		const width = itemWidth - colSpacing;
		const height = itemHeight - rowSpacing;
		return new Rectangle(x, y, width, height);
	};
	//↑のセレクトでの不具合を出ないようにする
	Window_BattleSkillType.prototype.drawAllItems = function () {
		const topIndex = this.topIndex();
		for (let i = 0; i < this.maxVisibleItems(); i++) {
			const index = topIndex + i;

			if (this._list && index < this.maxItems()) {
				//選択ちゅうだけ背景なくす
				if (i != this._index) {
					this.drawItemBackground(index);
				}
				this.drawItem(index);
			}
		}
	};

	// コマンド関係
	// コマンドの追加、2は必殺技
	Window_BattleSkillType.prototype.makeCommandList = function () {
		//if (this._actor) {
		// const skillTypes = this._actor.skillTypes();
		// for (const stypeId of skillTypes) {
		// 	const name = $dataSystem.skillTypes[stypeId];
		// 	this.addCommand("全スキル", "skill", true, stypeId, "all");
		// }

		this.addCommand("攻撃", "attack", true, 2);
		this.addCommand("回復", "cure", true, 2);
		this.addCommand("補助", "support", true, 2);
		this.addCommand("エッチ", "h", true, 2);
		//}
	};
	// コマンドにCBR_typeって属性作れるようにする
	// Window_BattleSkillType.prototype.addCommand = function (name, symbol, enabled = true, ext = null, CBR_type = null) {
	// 	this._list.push({ name: name, symbol: symbol, enabled: enabled, ext: ext, CBR_type: CBR_type });
	// };
	// // 上の_listからextを引っ張ってくる
	// Window_BattleSkillType.prototype.currentExt = function () {
	// 	return this.currentData() ? this.currentData() : null;
	// };

	// // updateで毎回これが更新されてる

	Window_BattleSkillType.prototype.setSkillWindow = function (skillWindow) {
		this._skillWindow = skillWindow;
		//this.callUpdateHelp();
	};

	Window_BattleSkillType.prototype.select = function (index) {
		this._index = index;

		this.contents.clear();
		this.contentsBack.clear();
		this.drawAllItems();

		this.refreshCursor();
		this.callUpdateHelp();

		if (index >= 0 && this._skillWindow) {
			this._skillWindow.setSkillType(this.commandSymbol(index));
			this._skillWindow.forceSelect(0);
		}
	};

	// カテゴリー記録用
	Window_BattleSkillType.prototype.smoothSelect = function (index) {
		if (this._actor) {
			this._actor.setLastCateIndex(index);
		}
		this.select(index);
		this.ensureCursorVisible(true);
	};
	Game_Actor.prototype.setLastCateIndex = function (index) {
		this._lastBattleSkillCateIndex = index;
	};

	// Window_SkillList.prototype.setStypeId = function (stype) {
	// 	if (stype) {
	// 		if (this._stypeId !== stype.ext || this._CBR_type !== stype.CBR_type) {
	// 			this._stypeId = stype.ext;
	// 			this._CBR_type = stype.CBR_type;
	// 			this.refresh();
	// 			this.scrollTo(0, 0);
	// 		}
	// 	}
	// };
	// //スキル一覧に表示するべきstypeIdを設定する、コメント欄を使用
	// Window_SkillList.prototype.includes = function (item) {
	// 	//return item && item.stypeId === this._stypeId;
	// 	if (!this._CBR_type || this._CBR_type === "all") {
	// 		return item;
	// 	} else {
	// 		return item && item.meta.CBR_type === this._CBR_type;
	// 	}
	// };

	// #############################################################
	// ##################### スキルウィンドウ #######################
	// #############################################################
	Scene_Battle.prototype.skillWindowRect = function () {
		const wx = 640;
		const ww = 620;
		const wh = 347;
		const wy = 83;
		return new Rectangle(wx, wy, ww, wh);
	};
	Scene_Battle.prototype.startEnemySelection = function () {
		this._enemyWindow.refresh();
		this._enemyWindow.show();
		this._enemyWindow.select(0);
		this._enemyWindow.activate();
		this._statusWindow.hide();
		this._skillWindow.hide();
		this._skillTypeWindow.hide();
		this._itemWindow.hide();
	};

	Scene_Battle.prototype.onEnemyCancel = function () {
		this._enemyWindow.hide();
		switch (this._actorCommandWindow.currentSymbol()) {
			case "attack":
				this._statusWindow.show();
				this._actorCommandWindow.activate();
				break;
			case "skill":
				this._skillTypeWindow.show();
				this._skillWindow.show();
				this._skillWindow.activate();
				this._statusWindow.show();
				break;
			case "item":
				this._itemWindow.show();
				this._itemWindow.activate();
				this._statusWindow.show();
				break;
		}
	};

	Scene_Battle.prototype.startActorSelection = function () {
		this._actorWindow.refresh();
		this._actorWindow.show();
		this._actorWindow.activate();
		this._skillWindow.hide();
		this._skillTypeWindow.hide();
	};

	Scene_Battle.prototype.onActorCancel = function () {
		this._actorWindow.hide();
		switch (this._actorCommandWindow.currentSymbol()) {
			case "skill":
				this._skillTypeWindow.show();
				this._skillWindow.show();
				this._skillWindow.activate();
				this._skillTypeWindow.show();
				break;
			case "item":
				this._itemWindow.show();
				this._itemWindow.activate();
				break;
		}
	};

	Window_BattleSkill.prototype.initialize = function (rect) {
		Window_SkillList.prototype.initialize.call(this, rect);
		this.hide();

		// windowが重なっても透過させる
		this._isWindow = false;
		this._stypeId = "attack";
		this.contents.fontFace = "serif";
	};

	Window_BattleSkill.prototype.setSkillType = function (type) {
		this._stypeId = type;
		this.refresh();
	};
	Window_BattleSkill.prototype.includes = function (item) {
		return item && item.meta.CBR_type === this._stypeId;
	};

	Window_BattleSkill.prototype.maxCols = function () {
		return 1;
	};
	Window_BattleSkill.prototype._refreshAllParts = function () {
		//this._refreshBack();
		//this._refreshFrame();
		this._refreshCursor();
		this._refreshArrows();
		this._refreshPauseSign();
	};

	// スキル記録用
	Game_Actor.prototype.setLastSkillIndex = function (index) {
		this._lastBattleSkillIndex = index;
	};

	Window_BattleSkill.prototype.processOk = function () {
		if (this._actor) {
			if (ConfigManager.commandRemember) {
				this._actor.setLastSkillIndex(this.index());
			} else {
				this._actor.setLastSkillIndex(0);
			}
		}
		Window_Selectable.prototype.processOk.call(this);
	};
	Window_BattleSkill.prototype.selectLastIndex = function () {
		if (this._actor) {
			if (ConfigManager.commandRemember) {
				this.forceSelect(this._actor._lastBattleSkillIndex || 0);
			} else {
				this.select(0);
			}
		}
	};

	Window_BattleSkill.prototype.loadWindowskin = function () {
		this.windowskin = ImageManager.loadSystem("Window");
		this.menu_item_skin = ImageManager.loadSystem("battle_skill_cursor2");
		this.menu_cursor_skin = ImageManager.loadSystem("battle_skill_cursor");

		if (!this.menu_item_skin.isReady()) {
			this.menu_item_skin.addLoadListener(() => {
				this.refresh(); // 画像がロードされたら再描画
			});
			return;
		}

		if (!this.menu_cursor_skin.isReady()) {
			this.menu_cursor_skin.addLoadListener(() => {
				this.refresh(); // 画像がロードされたら再描画
			});
			return;
		}
	};

	// カーソルの位置を微調整　タテ28pxを中央にもってくる
	Window_BattleSkill.prototype.setCursorRect = function (x, y, width, height) {
		const cw = Math.floor(width || 0);
		const ch = Math.floor(height || 0);
		this._cursorRect.x = Math.floor(x || 0);
		this._cursorRect.y = Math.floor(y || 0) + (ch - 28) / 2;
		if (this._cursorRect.width !== cw || this._cursorRect.height !== ch) {
			this._cursorRect.width = cw;
			this._cursorRect.height = 28;
			this._refreshCursor();
		}
	};

	Window_BattleSkill.prototype._refreshCursor = function () {
		const drect = this._cursorRect.clone();
		const srect = { x: 0, y: 0, width: 549, height: 28 };
		const m = 0;
		for (const child of this._cursorSprite.children) {
			child.bitmap = this.menu_cursor_skin;
		}
		this._setRectPartsGeometry(this._cursorSprite, srect, drect, m);
	};
	//カーソルを微調整、あとカーソルを常に不透明に
	Window_BattleSkill.prototype._updateCursor = function () {
		this._cursorSprite.alpha = 255;
		this._cursorSprite.visible = this.isOpen() && this.cursorVisible;
		this._cursorSprite.x = this._cursorRect.x;
		this._cursorSprite.y = this._cursorRect.y;
	};
	//未選択コマンドの背景を画像に、あと位置を微調整、タテ28pxを中央にもってくる
	Window_BattleSkill.prototype.drawItemBackground = function (index) {
		const rect = this.itemRect(index);
		if (this.menu_item_skin.isReady()) {
			const bitmap = this.menu_item_skin;
			const dx = rect.x;
			const dy = rect.y + (rect.height - 28) / 2;
			const dw = rect.width;
			const dh = 28;
			this.contentsBack.blt(bitmap, 0, 28, 549, 28, dx, dy, dw, dh);
		}
	};
	Window_BattleSkill.prototype.lineHeight = function () {
		return 38;
	};
	Window_BattleSkill.prototype.drawItem = function (index) {
		const skill = this.itemAt(index);
		if (skill) {
			if (index == this._index) {
				this.changeTextColor("#000000");
			}
			const costWidth = this.costWidth();
			const rect = this.itemLineRect(index);
			this.changePaintOpacity(this.isEnabled(skill));
			this.drawItemName(skill, rect.x, rect.y, rect.width - costWidth);
			this.drawSkillCost(skill, rect.x - 20, rect.y, rect.width);
			this.contents.fillRect(rect.x - 8, rect.y - 4, 2, 1, "#FFFFFF");
			this.contents.fillRect(rect.x - 3, rect.y - 4, 568, 1, "#FFFFFF");
			this.contents.fillRect(rect.x + 568, rect.y - 4, 2, 1, "#FFFFFF");
			this.changePaintOpacity(1);

			if (index == this.maxItems() - 1) {
				this.contents.fillRect(rect.x - 8, rect.y + 38 + 4, 2, 1, "#FFFFFF");
				this.contents.fillRect(rect.x - 3, rect.y + 38 + 4, 568, 1, "#FFFFFF");
				this.contents.fillRect(rect.x + 568, rect.y + 38 + 4, 2, 1, "#FFFFFF");
			}
		}
	};

	Window_BattleSkill.prototype.drawItemName = function (item, x, y, width) {
		if (item) {
			const iconY = y + (this.lineHeight() - ImageManager.iconHeight) / 2;
			const delta = ImageManager.standardIconWidth - ImageManager.iconWidth;
			const textMargin = ImageManager.standardIconWidth + 4;
			const itemWidth = Math.max(0, width - textMargin);
			this.resetTextColor();
			this.drawIcon(item.iconIndex, x + delta / 2, iconY);
			this.drawText(item.name, x + textMargin + 40, y, itemWidth);
		}
	};

	Window_BattleSkill.prototype.itemWidth = function () {
		return 549;
	};

	// #############################################################
	// ################### アイテムウィンドウ #######################
	// #############################################################
	Scene_Battle.prototype.itemWindowRect = function () {
		const wx = 640;
		const wy = 30;
		const ww = 620;
		const wh = 332;
		return new Rectangle(wx, wy, ww, wh);
	};

	// 上からウィンドウ内部の描写をズラす
	var paddingTop = 74;
	Window_BattleItem.prototype.hitTest = function (x, y) {
		if (this.innerRect.contains(x, y)) {
			const cx = this.origin.x + x - this.padding;
			const cy = this.origin.y + y - paddingTop;
			const topIndex = this.topIndex();
			for (let i = 0; i < this.maxVisibleItems(); i++) {
				const index = topIndex + i;
				if (index < this.maxItems()) {
					const rect = this.itemRect(index);
					if (rect.contains(cx, cy)) {
						return index;
					}
				}
			}
		}
		return -1;
	};

	Object.defineProperty(Window_BattleItem.prototype, "innerRect", {
		get: function () {
			return new Rectangle(this._padding, paddingTop, this.innerWidth, this.innerHeight);
		},
		configurable: true
	});
	Window_BattleItem.prototype._createClientArea = function () {
		this._clientArea = new Sprite();
		this._clientArea.filters = [new PIXI.filters.AlphaFilter()];
		this._clientArea.filterArea = new Rectangle();
		this._clientArea.move(this._padding, paddingTop);
		this.addChild(this._clientArea);
	};

	Window_BattleItem.prototype._updateClientArea = function () {
		const pad = this._padding;
		this._clientArea.move(pad, pad);
		this._clientArea.x = pad - this.origin.x;
		this._clientArea.y = -this.origin.y + paddingTop;
		if (this.innerWidth > 0 && this.innerHeight > 0) {
			this._clientArea.visible = this.isOpen();
		} else {
			this._clientArea.visible = false;
		}
	};

	Window_BattleItem.prototype.loadWindowskin = function () {
		this.windowskin = ImageManager.loadSystem("Window");
		this.menu_cursor_skin = ImageManager.loadSystem("menu_item_selected");
		this.menu_item_skin = ImageManager.loadSystem("menu_item_selected_2");
		this.CBR_back = ImageManager.loadSystem("battle_item_window");
	};

	Window_BattleItem.prototype.show = function () {
		this.selectLast();
		this.showHelpWindow();
		Window_ItemList.prototype.show.call(this);
	};

	Window_BattleItem.prototype.updateBackOpacity = function () {
		this.backOpacity = 255;
	};

	Window_BattleItem.prototype._refreshBack = function () {
		const sprite = this._backSprite;
		sprite.bitmap = this.CBR_back;
	};

	Window_BattleItem.prototype._refreshAllParts = function () {
		this._refreshBack();
		//this._refreshFrame();
		this._refreshCursor();
		this._refreshArrows();
		this._refreshPauseSign();
	};

	Window_BattleItem.prototype._refreshArrows = function () {
		const w = this._width;
		const h = this._height;
		const p = 24;
		const q = p / 2;
		const sx = 96 + p;
		const sy = 0 + p;
		this._downArrowSprite.bitmap = this._windowskin;
		this._downArrowSprite.anchor.x = 0.5;
		this._downArrowSprite.anchor.y = 0.5;
		this._downArrowSprite.setFrame(sx + q, sy + q + p, p, q);
		this._downArrowSprite.move(w / 2, h - q + 62);
		this._upArrowSprite.bitmap = this._windowskin;
		this._upArrowSprite.anchor.x = 0.5;
		this._upArrowSprite.anchor.y = 0.5;
		this._upArrowSprite.setFrame(sx + q, sy, p, q);
		this._upArrowSprite.move(w / 2, q + 62);
	};

	// #############################################################
	// ##################### ヘルプウィンドウ #######################
	// #############################################################
	Scene_Battle.prototype.helpWindowRect = function () {
		const wx = 640;
		const wh = 120;
		const wy = 420;
		const ww = 620;
		return new Rectangle(wx, wy, ww, wh);
	};
	Window_Battle_Help.prototype = Object.create(Window_Help.prototype);
	Window_Battle_Help.prototype.constructor = Window_Battle_Help;

	Window_Battle_Help.prototype.loadWindowskin = function () {
		this.windowskin = ImageManager.loadSystem("Window");
		this.CBR_back = ImageManager.loadSystem("battle_skill_help_window");
	};

	Window_Battle_Help.prototype._refreshAllParts = function () {
		this._refreshBack();
		//this._refreshFrame();
		this._refreshCursor();
		this._refreshArrows();
		this._refreshPauseSign();
	};
	Window_Battle_Help.prototype._refreshBack = function () {
		const sprite = this._backSprite;
		sprite.bitmap = this.CBR_back;
	};
	Window_Battle_Help.prototype.updateBackOpacity = function () {
		this.backOpacity = 255;
	};
	Window_Battle_Help.prototype.refresh = function () {
		const rect = this.baseTextRect();
		this.contents.clear();
		this.drawTextEx(this._text, rect.x, rect.y - 2, rect.width);
	};

	Scene_Battle.prototype.createHelpWindow = function () {
		const rect = this.helpWindowRect();
		this._helpWindow = new Window_Battle_Help(rect);
		this._helpWindow._isWindow = false;
		this._helpWindow.hide();
		this.addWindow(this._helpWindow);
	};

	//######################  ステータス画面　#########################
	Scene_Battle.prototype.statusWindowRect = function () {
		const extra = 10;
		const ww = 330 * $gameParty._actors.length;
		const wh = this.windowAreaHeight() + extra;
		const wx = 1280 - ww - 8;
		const wy = Graphics.boxHeight - wh + extra - 4;
		return new Rectangle(wx, wy, ww, wh);
	};
	//特にウィンドウの移動とかないよね
	Scene_Battle.prototype.updateStatusWindowPosition = function () {};

	Window_BattleStatus.prototype.maxCols = function () {
		return $gameParty._actors.length;
	};

	Window_BattleStatus.prototype.createContents = function () {
		const width = this.contentsWidth();
		const height = this.contentsHeight();
		this.destroyContents();
		this.contents = new Bitmap(width, height);
		this.contentsBack = new Bitmap(width, height);
		this.resetFontSettings();
	};
	Window_BattleStatus.prototype.drawActorFace = function (actor, x, y, width, height) {
		if (actor._name == "Shirayuki") {
			this.drawFace("battle_face_sira", actor.faceIndex(), x, y, width, height, actor);
		} else {
			this.drawFace("battle_face_yozu", actor.faceIndex(), x, y, width, height, actor);
		}
	};
	//名前を消してLVを表記
	Window_BattleStatus.prototype.placeActorName = function (actor, x, y) {};
	Window_BattleStatus.prototype.drawFace = function (faceName, faceIndex, x, y, width, height, actor) {
		const bitmap = ImageManager.loadSystem(faceName);
		this.contents.blt(bitmap, 0, 0, 200, 182, x, y);

		const bitmap2 = ImageManager.loadSystem("battle_status");
		this.contents.blt(bitmap2, 0, 0, 300, 180, x - 7, y + 15);

		this.contents.fontFace = "Times New Roman";
		this.contents.fontSize = 24;
		this.changeTextColor("#FFFFFF");
		this.contents.drawText(`LV　${actor._level}`, x + 138, y + 34, 150, 50, "left");
	};
	//めんどいから二人読み込む
	Window_BattleStatus.prototype.loadFaceImages = function () {
		ImageManager.loadSystem("battle_face_sira");
		ImageManager.loadSystem("battle_face_yozu");
		ImageManager.loadSystem("battle_status");
	};

	//################## ゲージ ####################
	//戦闘画面用のゲージスプライトを作る

	Window_BattleStatus.prototype.placeGauge = function (actor, type, x, y) {
		const key = "actor%1-gauge-%2".format(actor.actorId(), type);
		const sprite = this.createInnerSprite(key, Sprite_Gauge_Battle);
		sprite.setup(actor, type);
		sprite.move(x, y);
		sprite.show();
	};

	Window_BattleStatus.prototype.basicGaugesX = function (rect) {
		return rect.x + 124;
	};
	Window_BattleStatus.prototype.basicGaugesY = function (rect) {
		const bottom = rect.y + rect.height - this.extraHeight() - 50;
		const numGauges = $dataSystem.optDisplayTp ? 3 : 2;
		return bottom - this.gaugeLineHeight() * numGauges;
	};

	//hp mpの間隔
	Window_BattleStatus.prototype.placeBasicGauges = function (actor, x, y) {
		this.placeGauge(actor, "hp", x, y);
		this.placeGauge(actor, "mp", x, y + this.gaugeLineHeight() + 29);
		if ($dataSystem.optDisplayTp) {
			this.placeGauge(actor, "tp", x, y + this.gaugeLineHeight() * 2);
		}
	};

	// ############### 味方選択時にカーソルのアイコンを追加 ################
	const Spriteset_Battle_createActors = Spriteset_Battle.prototype.createActors;
	Spriteset_Battle.prototype.createActors = function () {
		Spriteset_Battle_createActors.call(this);

		// TorigoyaMZ_DisplayAnimationInFrontView.jsに対応させるため、あっちでやる

		// for (const e of this._actorSprites) {
		// 	var sp = new Sprite();
		// 	sp.bitmap = ImageManager.loadSystem("battle_select");
		// 	sp.anchor.set(0.5, 1);
		// 	sp.hide();
		// 	sp._CBR_count = 0;
		// 	e._targetSp = sp; // アクターにこのスプライト情報を入れる
		// 	this.addChild(sp); // 入れるけどこの階層にspriteをadd
		// }
	};
	// ############### 敵選択時にカーソルのアイコンを追加 ################
	const Spriteset_Battle_createEnemies = Spriteset_Battle.prototype.createEnemies;
	Spriteset_Battle.prototype.createEnemies = function () {
		Spriteset_Battle_createEnemies.call(this);

		//敵選択した時のカーソルを追加
		for (const e of this._enemySprites) {
			var sp = new Sprite();
			sp.bitmap = ImageManager.loadSystem("battle_select");
			sp.anchor.set(0.5, 1);
			sp.hide();
			sp._CBR_count = 0;
			e._targetSp = sp; // エネミーにこのスプライト情報を入れる
			this.addChild(sp); // 入れるけどこの階層にspriteをadd
		}
	};

	Sprite_Battler.prototype.updateSelectionEffect = function () {
		const target = this.mainSprite();
		if (this._battler.isSelected()) {
			console.log(this);
			this._targetSp.show();
			this._selectionEffectCount++;

			//カーソルの位置を整える
			var flagX = 0;
			var flagY = 0;
			if (this._battler && this._battler._enemyId) {
				var hoge = $dataEnemies[this._battler._enemyId].meta.CBR_CursorX;
				if (hoge) {
					flagX = Number(hoge);
				}

				var hoge = $dataEnemies[this._battler._enemyId].meta.CBR_CursorY;
				if (hoge) {
					flagY = Number(hoge);
				}
			}

			this._targetSp.x = this.x + flagX;
			this._targetSp.y = this.y - this.height - 60 + flagY + Math.sin(this._targetSp._CBR_count / 10) * 10;
			if (this._battler.constructor.name == "Game_Actor") {
				this._targetSp.y -= 50;
			}

			this._targetSp.opacity = 170 + 85 * Math.sin(this._targetSp._CBR_count / 10);
			this._targetSp._CBR_count++;
		} else if (this._selectionEffectCount > 0) {
			this._targetSp.hide();
		}
	};

	//######################## live2d #############################
	//変数を小数点可能に
	Game_Variables.prototype.setValue = function (variableId, value) {
		if (variableId > 0 && variableId < $dataSystem.variables.length) {
			if (typeof value === "number") {
				value = value;
			}
			this._data[variableId] = value;
			this.onChange();
		}
	};

	Window_BattleLog.prototype.showAnimation = function (subject, targets, animationId) {
		if (animationId < 0) {
			this.showAttackAnimation(subject, targets);
		} else {
			this.showNormalAnimation(targets, animationId);
		}
	};

	//いきなり戦闘コマンド　戦う　逃げるは省略
	let battleTurn = 0; // バトルのターン数を管理
	// バトル開始時にターン数をリセット
	const _BattleManager_startBattle = BattleManager.startBattle;
	BattleManager.startBattle = function () {
		battleTurn = 0;
		$gameParty._reservedItems = [];
		_BattleManager_startBattle.call(this);
	};
	// ターン開始時にカウントを増やす
	const _BattleManager_startTurn = BattleManager.startTurn;
	BattleManager.startTurn = function () {
		battleTurn++;
		_BattleManager_startTurn.call(this);
	};
	// 2ターン目以降は戦う・逃げるをスキップ
	Scene_Battle.prototype.startPartyCommandSelection = function () {
		this.selectNextCommand(); // パーティコマンドをスキップ
	};

	//アニメーションのディレイ
	Spriteset_Base.prototype.createAnimation = function (request) {
		const animation = $dataAnimations[request.animationId];
		const targets = request.targets;
		const mirror = request.mirror;

		let delay = this.animationBaseDelay();

		if (BattleManager._action && BattleManager._action._item.object().meta.anime_delay) {
			if (!Input.isLongPressed("ok")) {
				delay += Number(BattleManager._action._item.object().meta.anime_delay);
			}
		}

		const nextDelay = this.animationNextDelay();
		if (this.isAnimationForEach(animation)) {
			for (const target of targets) {
				this.createAnimationSprite([target], animation, mirror, delay);
				delay += nextDelay;
			}
		} else {
			this.createAnimationSprite(targets, animation, mirror, delay);
		}
	};

	//アニメーションの位置変更
	Sprite_Animation.prototype.targetPosition = function (renderer) {
		const pos = new Point();
		this.zIndex = 9999999999;
		if (this._animation.displayType === 2) {
			pos.x = renderer.view.width / 2;
			pos.y = renderer.view.height / 2;
		} else {
			for (const target of this._targets) {
				const tpos = this.targetSpritePosition(target);
				pos.x += tpos.x;
				pos.y += tpos.y;
			}
			pos.x /= this._targets.length;
			pos.y /= this._targets.length;
		}
		if (this._animation.name == "sira_斬撃_物理") {
			//pos.x = 300;
			pos.y = 200;
		} else if (this._animation.name == "sira_爪_炎") {
			pos.x = 300;
			pos.y = 200;
		}
		return pos;
	};

	//戦闘が始まった瞬間コモンイベント実行
	const BattleManager_startBattle = BattleManager.startBattle;
	BattleManager.startBattle = function () {
		BattleManager_startBattle.call(this);

		const commonEvent = $dataCommonEvents[1103];
		if (commonEvent) {
			const interpreter = new Game_Interpreter();
			interpreter.setup(commonEvent.list);
			interpreter.update();
		}

		//$gameTemp.reserveCommonEvent(14);
	};

	//戦闘が終わったらコモンイベント実行
	// const BattleManager_endBattle = BattleManager.endBattle;
	// BattleManager.endBattle = function (result) {
	// 	BattleManager_endBattle.call(this, result);

	// 	$gameTemp.reserveCommonEvent(1121);
	// };

	// ################### キャラクターのコマンドで表示キャラを切り替える ##########################
	Scene_Battle.prototype.startActorCommandSelection = function () {
		this._statusWindow.show();
		this._statusWindow.selectActor(BattleManager.actor());
		this._partyCommandWindow.close();
		this._actorCommandWindow.show();
		this._actorCommandWindow.setup(BattleManager.actor());
		this.CBR_changeLive2d(BattleManager.actor()._name);

		if (BattleManager.actor()._name === "Shirayuki") {
			var commonEventId = 1137;
		} else {
			var commonEventId = 1138;
		}
		const commonEvent = $dataCommonEvents[Number(commonEventId)];
		if (commonEvent) {
			const interpreter = new Game_Interpreter();
			interpreter.setup(commonEvent.list);
			interpreter.update();
		}
	};

	//どの状態からでも待機モーションに変化させる
	Scene_Battle.prototype.CBR_changeLive2d = function (show) {
		Object.keys($gameLive2d._name).forEach(function (key) {
			//見えてる物はhide
			if ($gameLive2d.visible[key]) {
				$gameLive2d.CBR_fadeMode[key] = "hide";
				$gameLive2d.CBR_fadeDuration[key] = $gameLive2d.CBR_getDuration();
			}
		});

		//白雪を表示させたい時
		if (show == "Shirayuki") {
			$gameLive2d.CBR_fadeMode[9] = "show";
			$gameLive2d.CBR_fadeDuration[9] = $gameLive2d.visible[9] ? 0 : $gameLive2d.CBR_getDuration();
		} else {
			$gameLive2d.CBR_fadeMode[5] = "show";
			$gameLive2d.CBR_fadeDuration[5] = $gameLive2d.visible[5] ? 0 : $gameLive2d.CBR_getDuration();
		}
	};

	//攻撃する時、攻撃されるとき
	Window_BattleLog.prototype.startAction = function (subject, action, targets) {
		const item = action.item();
		this.push("performActionStart", subject, action);
		this.push("waitForMovement");
		this.push("performAction", subject, action);
		this.push("showAnimation", subject, targets.clone(), item.animationId);
		this.displayAction(subject, item);

		var liveChange = function (name) {
			var taiki = {
				sira: 9,
				yozu: 5
			};
			var keyName = name == "Shirayuki" ? "sira" : "yozu";
			Object.keys($gameLive2d._name).forEach(function (key) {
				var delName = keyName == "sira" ? "y" : "s";
				//表示されてるのが削除したいキャラ名だったら
				if ($gameLive2d.visible[key] && $gameLive2d._name[key].charAt(0) == delName) {
					$gameLive2d.CBR_fadeMode[key] = "hide";
					$gameLive2d.CBR_fadeDuration[key] = $gameLive2d.CBR_getDuration();
				}

				// スキルにコモンイベント情報があったら即座に実行
				if (item.meta.common_bf) {
					var commonEventId = Number(item.meta.common_bf);

					if (commonEventId) {
						const commonEvent = $dataCommonEvents[Number(commonEventId)];
						if (commonEvent) {
							const interpreter = new Game_Interpreter();
							interpreter.setup(commonEvent.list);
							interpreter.update();
						}
					}
					// 防御とか攻撃を受けるで待機モーションを表示
				} else {
					// 待機モーションが表示されてなかった場合のみ待機表示イベントを実行
					if (!$gameLive2d.visible[taiki[keyName]]) {
						var commonEventId = delName == "y" ? 1109 : 1119;

						if (commonEventId) {
							const commonEvent = $dataCommonEvents[Number(commonEventId)];
							if (commonEvent) {
								const interpreter = new Game_Interpreter();
								interpreter.setup(commonEvent.list);
								interpreter.update();
							}
						}
					}
				}
			});
		};

		if (subject.constructor.name == "Game_Actor") {
			if (subject._name == "Shirayuki" || subject._name == "Yotsuru") {
				liveChange(subject._name);
			}
		} else if (subject.constructor.name == "Game_Enemy") {
			if (targets[0]._name == "Shirayuki" || targets[0]._name == "Yotsuru") {
				liveChange(targets[0]._name);
			}
		}

		if (item.meta.act_common) {
			// if (targets[0]) {
			// 	action.updateLastTarget(targets[0]);
			// }
			// var commonEventId = Number(item.meta.act_common);
			// $gameTemp.reserveCommonEvent(commonEventId);
			// console.log("res");
			// BattleManager.updateEvent();
			// SceneManager._scene;
			// if (commonEventId) {
			// 	const commonEvent = $dataCommonEvents[Number(commonEventId)];
			// 	if (commonEvent) {
			// 		const interpreter = new Game_Interpreter();
			// 		interpreter.setup(commonEvent.list);
			// 		interpreter.update();
			// 	}
			// }
		}
	};

	// スキル直前でact_commonを発動させる
	// var __BManager_startAction = BattleManager.startAction;
	BattleManager.startAction = function () {
		var action = this._subject.currentAction();
		if (this.checkBeforeCommon(action)) {
			return;
		}

		// __BManager_startAction.call(this);
		const subject = this._subject;
		//const action = subject.currentAction();
		const targets = action.makeTargets();
		this._phase = "action";
		this._action = action;
		this._targets = targets;
		subject.cancelMotionRefresh();
		subject.useItem(action.item());
		this._action.applyGlobal();
		this._logWindow.startAction(subject, action, targets);

		var subject_name = subject.constructor.name;
		//スキル敵味方が使った直後にIDを変数124番に入れる
		$gameVariables.setValue(124, subject._actorId);

		if (subject_name == "Game_Actor") {
			//直前の行動したアクター（味方のみ）のIDを変数125
			$gameVariables.setValue(125, subject._actorId);
		} else if (subject_name == "Game_Enemy") {
			if (targets.length === 1 && targets[0].constructor.name == "Game_Actor") {
				//敵が攻撃した時に126に対象になったアクターのID入れる
				//全体攻撃の時は入れない
				$gameVariables.setValue(126, targets[0]._actorId);
			}
		}

		this._execBeforeCommon = false;
	};

	BattleManager.checkBeforeCommon = function (action) {
		// if (action && !this._execBeforeCommon && DataManager.isBeforeCommon(action.item())) {
		if (action && !this._execBeforeCommon) {
			var act_common_id = action.item().meta.act_common;

			if (!act_common_id) {
				return false;
			}

			// 最期のターゲットをココで更新するようにする
			const targets = action.makeTargets();
			if (targets[0]) {
				action.updateLastTarget(targets[0]);
			}

			// 最期の直前情報をココで更新するようにする
			action.updateLastUsed();
			action.updateLastSubject();

			// var beforeCommon = DataManager.beforeCommonEffect(action.item());
			var beforeCommon = act_common_id;
			// if (nullNumberCommonReserve && beforeCommon <= 0) return false;
			this._execBeforeCommon = true;
			$gameTemp.reserveCommonEvent(beforeCommon);
			var sId = this._subject.index();
			var tId = action._targetIndex;
			if (this._subject.isEnemy()) sId += 1000;
			if (this._subject.isActor() && action.isForOpponent() && tId >= 0) tId += 1000;
			if (this._subject.isEnemy() && action.isForFriend() && tId >= 0) tId += 1000;
			if (action.isForUser()) tId = sId;
			// if (indexVariableId) $gameVariables._data[indexVariableId] = sId;
			// if (targetIndexVariableId) $gameVariables._data[targetIndexVariableId] = tId;
			// if (useMz) {
			if (this.isActionForced()) this._actionForcedBattler = this._subject;
			// } else {
			// 	if (this.isForcedTurn()) this._actionForcedBattler = this._subject;
			// }
			this._phase = "turn";
			return true;
		}
		return false;
	};

	var __GBattler_removeCurrentAction = Game_Battler.prototype.removeCurrentAction;
	Game_Battler.prototype.removeCurrentAction = function () {
		if (!BattleManager._execBeforeCommon) {
			__GBattler_removeCurrentAction.call(this);
		}
	};

	const _Scene_Battle_commandFight = Scene_Battle.prototype.commandFight;
	Scene_Battle.prototype.commandFight = function () {
		for (var i = 1; i <= $gameLive2d.MAXNUMBER; i++) {
			$gameLive2d.pos_x[i] += 100;
		}
		// 元の「戦う」コマンドの処理を実行
		_Scene_Battle_commandFight.call(this);
	};

	//live2dを切り替えるヤツ
	var Scene_Battle_update = Scene_Battle.prototype.update;
	Scene_Battle.prototype.update = function () {
		if ($gameSwitches.value(904)) {
			var count = $gameVariables.value(929);
			count--;
			$gameVariables.setValue(929, count);
			if (count <= 0) {
				const next_common = $gameVariables.value(928);
				const commonEvent = $dataCommonEvents[next_common];
				if (commonEvent) {
					const interpreter = new Game_Interpreter();
					interpreter.setup(commonEvent.list);
					interpreter.update();
				}
			}
		}

		//###################### 戦闘開始時のメッセージを消去してロゴに変更する ##################
		//決定キーを押した時
		if (this.CBR_startMotion) {
			if (TouchInput.isTriggered() || Input.isTriggered("ok")) {
				this._battleStartImage_logo.visible = false;
				this._battleStartImage_cursor.visible = false;
				this._battleStartImage_ready.visible = false;
				this.CBR_startMotion = false;
				AudioManager.playSe({ name: "Decision5", volume: 70, pitch: 100, pan: 0 });
			}
		}
		Scene_Battle_update.call(this);

		// マウスクリック検知 & 動画再生中チェック
		if (Input.isTriggered("ok") || TouchInput.isTriggered() || utakata.MessageSkip.isPressedMsgSkipButton()) {
			if (Video.isPlaying()) {
				Video._onEnd();
			}

			// MoviePicture.js
			if ($gameScreen._pictures[11] && $gameScreen._pictures[11].isVideoWait()) {
				$gameScreen.erasePicture(11);
			}
		}
	};

	//###################### 戦闘開始時のメッセージを消去してロゴに変更する ##################
	//開戦時メッセージを消す
	BattleManager.displayStartMessages = function () {};

	//追加する画像を
	class BattleStartImage extends Sprite {
		constructor(name, x, y, type) {
			super();
			this.bitmap = ImageManager.loadSystem(name);
			this.anchor.set(0.5, 0.5);
			this.x = x;
			this.y = y;
			this.visible = true;

			this.CBR_count = 0;

			if (type == "cursor") {
				this.CBR_cursor = true;
			}
		}

		update() {
			this.CBR_count++;

			if (this.CBR_cursor) {
				var cnt = this.CBR_count % 20;
				if (cnt === 0) {
					this.setFrame(0, 17 * Math.floor((this.CBR_count % 80) / 20), 35, 17);
				}
			}
			super.update();
		}
	}

	//戦闘開始時のロゴとステータス隠し
	Scene_Battle.prototype.start = function () {
		Scene_Message.prototype.start.call(this);
		BattleManager.playBattleBgm();
		BattleManager.startBattle();
		this._statusWindow.refresh();
		this.startFadeIn(this.fadeSpeed(), false);

		var sp = new BattleStartImage("battle_encount_logo", Graphics.width / 2, 80);
		this._battleStartImage_logo = sp;
		this.addChild(this._battleStartImage_logo);

		var sp = new BattleStartImage("battle_encount_ready", Graphics.width / 2, 170);
		this._battleStartImage_ready = sp;
		this.addChild(this._battleStartImage_ready);

		var sp = new BattleStartImage("battle_encount_cursor", Graphics.width / 2, 140, "cursor");
		sp.setFrame(0, 0, 35, 17);
		this._battleStartImage_cursor = sp;
		this.addChild(this._battleStartImage_cursor);
		//

		this.CBR_startMotion = true;
		this._statusWindow.visible = false;
	};

	//ロゴがある間は表示させない
	Scene_Battle.prototype.updateBattleProcess = function () {
		if (this.CBR_startMotion) {
			return;
		}
		BattleManager.update(this.isTimeActive());
	};
})();

var px = -200;
var py = -20;

var si = 1;

Spriteset_Battle.prototype.createBackground = function () {};

//なんか"Times New Roman"の読み込みが遅い？
Scene_Boot.prototype.loadGameFonts = function () {
	const advanced = $dataSystem.advanced;
	FontManager.load("rmmz-mainfont", advanced.mainFontFilename);
	FontManager.load("rmmz-numberfont", advanced.numberFontFilename);

	const bitmap = ImageManager.loadSystem("battle_status");
	bitmap.fontFace = "Times New Roman";
};

Sprite_Damage.prototype.fontSize = function () {
	return $gameSystem.mainFontSize() + 20;
};

Sprite_Actor.prototype.createDamageSprite = function () {
	const last = this._damages[this._damages.length - 1];
	const sprite = new Sprite_Damage();
	if (last) {
		sprite.x = last.x + 8;
		sprite.y = last.y - 16;
	} else {
		sprite.x = this.x + this.damageOffsetX() + 50;
		sprite.y = this.y + this.damageOffsetY() + 38;
	}
	sprite.setup(this._battler);
	this._damages.push(sprite);
	this.parent.addChild(sprite);
};

// 戦闘フォントの色を変更
ColorManager.damageColor = function (colorType) {
	switch (colorType) {
		case 0: // HP damage
			return "#ff0000";
		case 1: // HP recover
			return "#b9ffb5";
		case 2: // MP damage
			return "#ffff90";
		case 3: // MP recover
			return "#80b0ff";
		default:
			return "#808080";
	}
};

// 戦闘フォントの数字を変更
Game_System.prototype.numberFontFace = function () {
	return "fantasy";
};

//逃走率を100に
BattleManager.processEscape = function () {
	$gameParty.performEscape();
	SoundManager.playEscape();
	const success = true;
	if (success) {
		this.onEscapeSuccess();
	} else {
		this.onEscapeFailure();
	}
	return success;
};

//　勝利ウィンドウ
Window_CBR_BattleResult.prototype = Object.create(Window_Base.prototype);
Window_CBR_BattleResult.prototype.constructor = Window_CBR_BattleResult;

//Scene_Base.prototype.createWindowLayer でGraphicsのbox分-4されてるので
Scene_Battle.prototype.CBR_BattleResultWindowRect = function () {
	const wx = 0;
	const wy = -4;
	const ww = Graphics.width;
	const wh = Graphics.height - wy;
	return new Rectangle(wx, wy, ww, wh);
};
Window_CBR_BattleResult.prototype._refreshAllParts = function () {
	//this._refreshBack();
	//this._refreshFrame();
	this._refreshCursor();
	this._refreshArrows();
	this._refreshPauseSign();
};

//開始時隠す
Scene_Battle.prototype.createCBR_BattleResultWindow = function () {
	const rect = this.CBR_BattleResultWindowRect();
	this._resultWindow = new Window_CBR_BattleResult(rect);
	this._resultWindow.hide();
	this.addWindow(this._resultWindow);
};

var Scene_Battle_createAllWindows = Scene_Battle.prototype.createAllWindows;
Scene_Battle.prototype.createAllWindows = function () {
	Scene_Battle_createAllWindows.call(this);

	this.createCBR_BattleResultWindow();
};

var Window_CBR_BattleResult_initialize = Window_CBR_BattleResult.prototype.initialize;
Window_CBR_BattleResult.prototype.initialize = function (rect) {
	Window_CBR_BattleResult_initialize.call(this, rect);

	this._back1 = new Sprite();
	this._back1.bitmap = ImageManager.loadSystem("battle_result_back");
	this._container.addChild(this._back1);
	//this.contents.fontFace = "serif";

	// 一人目
	this._chara_1 = new Sprite();
	this._chara_1.x = 0;
	this._chara_1.y = 260;

	this.contents.fontSize = 32;
	if ($gameParty.members()[0].name() === "Shirayuki") {
		this._chara_1.bitmap = ImageManager.loadSystem("battle_result_sira");
		this.drawTextS("白雪・Lindblum", 134, 255, 400);
	} else {
		this._chara_1.bitmap = ImageManager.loadSystem("battle_result_yozu");
		this.drawTextS("黒羽　夜鶴", 134, 255, 400);
	}
	this.contents.fontSize = 32;
	this._container.addChild(this._chara_1);

	if ($gameParty.members().length == 2) {
		// 2人目
		this._chara_2 = new Sprite();
		this._chara_2.x = 0;
		this._chara_2.y = 370;
		if ($gameParty.members()[1].name() === "Shirayuki") {
			this._chara_2.bitmap = ImageManager.loadSystem("battle_result_sira");
			this.drawTextS("白雪・Lindblum", 134, 365, 400);
		} else {
			this._chara_2.bitmap = ImageManager.loadSystem("battle_result_yozu");
			this.drawTextS("黒羽　夜鶴", 134, 365, 400);
		}
		this.contents.fontSize = 32;
		this._container.addChild(this._chara_2);
	}
	this.drawTextS("獲得金額", 34, 133, 200);
	this.drawTextS("獲得経験値", 34, 191, 200);
	this.drawTextS("獲得アイテム", 34, 478, 200);

	this._chara_3 = new Sprite();
	this._chara_3.x = 530;
	this._container.addChild(this._chara_3);
};

// リザルト画面でOK押したら消えるようにする
Window_CBR_BattleResult.prototype.update = function () {
	Window_Base.prototype.update.call(this);

	if (BattleManager.CBR_result) {
		if (!this.visible) {
			var commonEventId = Number(1101);
			if (commonEventId) {
				const commonEvent = $dataCommonEvents[Number(commonEventId)];
				if (commonEvent) {
					const interpreter = new Game_Interpreter();
					interpreter.setup(commonEvent.list);
					interpreter.update();
				}
			}
			var commonEventId = Number(1121);
			if (commonEventId) {
				const commonEvent = $dataCommonEvents[Number(commonEventId)];
				if (commonEvent) {
					const interpreter = new Game_Interpreter();
					interpreter.setup(commonEvent.list);
					interpreter.update();
				}
			}

			this.updateResult();
		}
		this.show();
		if (Input.isRepeated("ok") || Input.isTriggered("ok") || TouchInput.isTriggered() || TouchInput.isLongPressed()) {
			BattleManager.CBR_result = false;
		}
	}
};
Window_CBR_BattleResult.prototype.updateResult = function () {
	this.contents.fontSize = 32;
	this.drawTextS(`+${BattleManager._rewards.gold}円`, 400, 133, 200, "right");
	this.drawTextS(`+${BattleManager._rewards.exp}`, 400, 191, 200, "right");

	var ac_1 = $gameParty.members()[0];
	this.drawTextS(`Lv ${ac_1._level}`, 400, 255, 200, "right");

	var now = ac_1.currentExp() - ac_1.expForLevel(ac_1._level);

	if (now - BattleManager._rewards.exp < 0) {
		this.changeTextColor(ColorManager.textColor(2));
		this.drawTextS("LVUP!!", 200, 295, 400, "right");
		this.resetTextColor();
	} else {
		this.contents.fontSize = 24;

		if (99 <= ac_1._level) {
			this.drawTextS(`次のレベルまで${0}`, 200, 295, 400, "right");
		} else {
			this.drawTextS(`次のレベルまで${ac_1.expForLevel(ac_1._level + 1) - ac_1.currentExp()}`, 200, 295, 400, "right");
		}
	}
	this.contents.fontSize = 32;
	var ac_2 = $gameParty.members()[1];
	if (ac_2) {
		this.drawTextS(`Lv ${ac_2._level}`, 400, 365, 200, "right");

		var now = ac_2.currentExp() - ac_2.expForLevel(ac_2._level);
		if (now - BattleManager._rewards.exp < 0) {
			this.changeTextColor(ColorManager.textColor(2));
			this.drawTextS("LVUP!!", 400, 405, 200, "right");
			this.resetTextColor();
		} else {
			this.contents.fontSize = 24;
			if (99 <= ac_2._level) {
				this.drawTextS(`次のレベルまで${0}`, 200, 405, 400, "right");
			} else {
				this.drawTextS(`次のレベルまで${ac_2.expForLevel(ac_2._level + 1) - ac_2.currentExp()}`, 200, 405, 400, "right");
			}
		}
	}

	var counter = [];
	for (var i = 0, len = BattleManager._rewards.items.length; i < len; i++) {
		var name = BattleManager._rewards.items[i].name;
		var idx = counter.findIndex((e) => e.name == name);

		if (idx === -1) {
			counter.push({
				name: name,
				count: 1
			});
		} else {
			counter[idx].count++;
		}
	}

	this.contents.fontSize = 32;
	for (var i = 0, len = counter.length; i < len; i++) {
		this.drawTextS(counter[i].name, 70, 524 + i * 36, 300);
		this.drawTextS(`× ${counter[i].count}`, 400, 524 + i * 36, 200, "right");
	}

	if (!this._chara_3.bitmap) {
		var name = $gameParty.allMembers()[0].name() === "Shirayuki" ? "sira" : "yozu";
		var fuku_var = name == "sira" ? 204 : 205;
		var fuku = $gameVariables.value(fuku_var) ? "nude" : "tyaku";
		var bukka_sw = name == "sira" ? 234 : 235;
		var naka_sw = name == "sira" ? 232 : 233;
		var inra_var = name == "sira" ? 245 : 325;
		var h_sw = name == "sira" ? 230 : 231;
		var num = "0000";
		if ($gameSwitches.value(bukka_sw) && $gameSwitches.value(naka_sw) && $gameSwitches.value(inra_var) >= 2) {
			num = "0009";
		} else if ($gameSwitches.value(bukka_sw) && $gameSwitches.value(naka_sw)) {
			num = "0008";
		} else if ($gameSwitches.value(bukka_sw) && $gameSwitches.value(inra_var) >= 2) {
			num = "0007";
		} else if ($gameSwitches.value(bukka_sw)) {
			num = "0006";
		} else if ($gameSwitches.value(naka_sw) && $gameSwitches.value(inra_var) >= 2) {
			num = "0005";
		} else if ($gameSwitches.value(naka_sw)) {
			num = "0004";
		} else if ($gameSwitches.value(h_sw) && $gameSwitches.value(inra_var) >= 2) {
			num = "0003";
		} else if ($gameSwitches.value(h_sw)) {
			num = "0002";
		} else if ($gameParty.allMembers()[0].hp / $gameParty.allMembers()[0].mhp <= 0.25) {
			num = "0001";
		}
		this._chara_3.bitmap = ImageManager.loadSystem(`battle_result_${name}_${fuku}_${num}`);
	}
};

// CRB_resultがある場合は進まないようにする
BattleManager.update = function (timeActive) {
	if (!this.isBusy() && !this.updateEvent() && !this.CBR_result) {
		this.updatePhase(timeActive);
	}
	if (this.isTpb()) {
		this.updateTpbInput();
	}
};

const _BattleManager_startBattle = BattleManager.startBattle;
BattleManager.startBattle = function () {
	this.CBR_result = false;
	_BattleManager_startBattle.call(this);
};

BattleManager.processVictory = function () {
	this.CBR_result = true;
	$gameParty.removeBattleStates();
	$gameParty.performVictory();
	this.playVictoryMe();
	this.replayBgmAndBgs();
	this.makeRewards();
	//this.displayVictoryMessage();
	//this.displayRewards();
	this.gainRewards();
	this.endBattle(0);
};

// 行動実行する時に変数をセットする
BattleManager.setup = function (troopId, canEscape, canLose) {
	this.initMembers();
	this._canEscape = canEscape;
	this._canLose = canLose;
	$gameTroop.setup(troopId);
	$gameScreen.onBattleStart();
	this.makeEscapeRatio();

	$gameVariables.setValue(124, 0);
	$gameVariables.setValue(125, 0);
	$gameVariables.setValue(126, 0);
};

// BattleManager.startAction = function () {
// 	const subject = this._subject;
// 	const action = subject.currentAction();
// 	const targets = action.makeTargets();
// 	this._phase = "action";
// 	this._action = action;
// 	this._targets = targets;
// 	subject.cancelMotionRefresh();
// 	subject.useItem(action.item());
// 	this._action.applyGlobal();
// 	this._logWindow.startAction(subject, action, targets);

// 	var subject_name = subject.constructor.name;
// 	//スキル敵味方が使った直後にIDを変数124番に入れる
// 	$gameVariables.setValue(124, subject._actorId);

// 	if (subject_name == "Game_Actor") {
// 		//直前の行動したアクター（味方のみ）のIDを変数125
// 		$gameVariables.setValue(125, subject._actorId);
// 	} else if (subject_name == "Game_Enemy") {
// 		if (targets.length === 1 && targets[0].constructor.name == "Game_Actor") {
// 			//敵が攻撃した時に126に対象になったアクターのID入れる
// 			//全体攻撃の時は入れない
// 			$gameVariables.setValue(126, targets[0]._actorId);
// 		}
// 	}
// };

(() => {
	// act_common内にある動画の再生が終わってからスキルエフェクトが始まるようにする
	const _showAnimation = Window_BattleLog.prototype.showAnimation;
	Window_BattleLog.prototype.showAnimation = function (subject, targets, animationId) {
		if (!Video.isPlaying()) {
			_showAnimation.call(this, subject, targets, animationId);
		} else {
			this._pendingAnimationData = [subject, targets, animationId];
			this._waitingForVideo = true;
		}
	};

	const _update = Window_BattleLog.prototype.update;
	Window_BattleLog.prototype.update = function () {
		_update.call(this);

		if (this._waitingForVideo && this._pendingAnimationData) {
			if (!Video.isPlaying()) {
				const [subject, targets, animationId] = this._pendingAnimationData;
				this._waitingForVideo = false;
				this._pendingAnimationData = null;
				this.showAnimation(subject, targets, animationId);
			} else {
				this._waitCount = 1;
			}
		}
	};
})();

// ステータスウィンドウをアニメーションウィンドウより下に配置する
Scene_Battle.prototype.createStatusWindow = function () {
	const rect = this.statusWindowRect();
	const statusWindow = new Window_BattleStatus(rect);
	//this.addWindow(statusWindow);
	this._spriteset.addChild(statusWindow);
	this._statusWindow = statusWindow;
};

// ステートIDが7の時にtrue
// var bindCheck = function (name) {
// 	return $gameParty.members().some((actor) => {
// 		return actor.name() === name && actor.isStateAffected(7);
// 	});
// };

var SDN_ShowRestraintImg = function (name) {
	//ベース設定
	if (name == "Shirayuki") {
		var evChara = "eva_d";
		var cosChara = $gameVariables.value(204);
		var kousokuState = $gameVariables.value(136);
		var idx = 9;
	} else {
		var evChara = "evb_d";
		var cosChara = $gameVariables.value(205);
		var kousokuState = $gameVariables.value(137);
		var idx = 5;
	}
	//拘束している敵の種類（変数138番）
	var Enemy = $gameVariables.value(138);
	var list = [
		{ type: "人間", id: "001" },
		{ type: "ゴブリン", id: "002" },
		{ type: "オーク", id: "003" },
		{ type: "魔犬", id: "004" },
		{ type: "魔豚", id: "005" },
		{ type: "妖馬", id: "006" },
		{ type: "スライム", id: "007" },
		{ type: "触手", id: "008" }
	];
	var evEnemy = list.find((e) => e.type === Enemy).id;

	//服装
	if (cosChara == 0) {
		var evCos = "00";
	} else {
		var evCos = "01";
	}
	//部位
	if ($gameVariables.value(134) == 1) {
		var evPos = "00";
	} else {
		var evPos = "01";
	}
	//拘束状態
	if (kousokuState < 2) {
		var evKousoku = "01";
	} else {
		var evKousoku = "02";
	}
	var dataName = evChara + evEnemy + "_" + evCos + "_" + evPos + "_" + evKousoku;
	// 万が一の為
	if (SceneManager._scene.live2dSprite[idx]) {
		SceneManager._scene.live2dSprite[idx].showImg(dataName);
	}
};

var SDN_HideRestraintImg = function (name) {
	var idx = name === "Shirayuki" ? 9 : 5;
	if (SceneManager._scene.live2dSprite[idx]) {
		SceneManager._scene.live2dSprite[idx].hideImg();
	}
};

(() => {
	// アイテムが選択できるかどうかを判定する処理を上書き
	const _Window_BattleItem_isEnabled = Window_BattleItem.prototype.isEnabled;
	Window_BattleItem.prototype.isEnabled = function (item) {
		if (!item) return false;
		// 元の判定
		if (!_Window_BattleItem_isEnabled.call(this, item)) {
			return false;
		}
		// 戦闘中で残りが1個なら、誰かが既にそのアイテムを予約しているかチェック
		if ($gameParty.numItems(item) <= 1) {
			if ($gameParty._reservedItems && $gameParty._reservedItems.includes(item)) {
				return false;
			}
		}
		return true;
	};

	// アクション確定時に予約登録
	const _Scene_Battle_onItemOk = Scene_Battle.prototype.onItemOk;
	Scene_Battle.prototype.onItemOk = function () {
		const action = BattleManager.inputtingAction();
		const item = this._itemWindow.item();
		if (item) {
			$gameParty._reservedItems = $gameParty._reservedItems || [];
			if (!$gameParty._reservedItems.includes(item)) {
				$gameParty._reservedItems.push(item);
			}
		}
		_Scene_Battle_onItemOk.call(this);
	};

	const _Scene_Battle_onActorCancel = Scene_Battle.prototype.onActorCancel;
	Scene_Battle.prototype.onActorCancel = function () {
		_Scene_Battle_onActorCancel.call(this);

		if (this._actorCommandWindow.currentSymbol() == "item") {
			if ($gameParty._reservedItems && $gameParty._reservedItems.length) {
				$gameParty._reservedItems.pop();
			}
		}
	};

	// キャンセル時に予約解除
	Scene_Battle.prototype.selectPreviousCommand = function () {
		$gameParty._reservedItems = [];

		BattleManager.selectPreviousCommand();
		this.changeInputWindow();
	};

	// ターン終了時に予約解除
	const _BattleManager_endTurn = BattleManager.endTurn;
	BattleManager.endTurn = function () {
		$gameParty._reservedItems = [];
		_BattleManager_endTurn.call(this);
	};
})();
