// ============================================================================= // ABMZ_EnemyHate.js // Version: 1.18 // ----------------------------------------------------------------------------- // Copyright (c) 2015 ヱビ // Released under the MIT license // http://opensource.org/licenses/mit-license.php // ----------------------------------------------------------------------------- // [Homepage]: ヱビのノート // http://www.zf.em-net.ne.jp/~ebi-games/ // ============================================================================= /*: * @target MZ * @plugindesc v1.18 敵が最もヘイトの高いアクターを狙います。 * ヘイトはバトル中の行動で変化します。 * @author ヱビ * @url http://www.zf.em-net.ne.jp/~ebi-games/ * * @requiredAssets img/system/hateline * * @param DisplayHateLine * @text ヘイトライン表示 * @type boolean * @on 表示 * @off 非表示 * @desc ヘイトラインを表示するかどうかを決めます。 * @default false * * @param DebugMode * @text デバッグモード * @type boolean * @on 表示 * @off 非表示 * @desc ONにするとヘイトが何ポイント増加したかをコンソールに出力します。 * @default false * * @param DamageHateFormula * @text ダメージヘイト式 * @desc ダメージを与えたとき増加するヘイトの式です。 * デフォルト: damage * @default damage * * @param MPDamageHateFormula * @text MPダメージヘイト式 * @desc MPダメージを与えたとき増加するヘイトの式です。 * デフォルト: MPDamage * 5 * @default MPDamage * 5 * * @param HealHateFormula * @text 回復ヘイト式 * @desc 味方を回復したとき増加するヘイトの式です。 * デフォルト: healPoint * 2 * @default healPoint * 2 * * @param BuffHateFormula * @text バフヘイト式 * @desc 味方にバフを付加したとき増加するヘイトの式です。 * デフォルト: enemy.atk * 4 * @default enemy.atk * 4 * * @param DebuffHateFormula * @text デバフヘイト式 * @desc 敵にデバフを付加したとき増加するヘイトの式です。 * デフォルト: enemy.atk * 4 * @default enemy.atk * 4 * * @param StateToEnemyHateFormula * @text 敵ステート付加ヘイト式 * @desc 敵にステートを付加した時増加するヘイトの式です。 * デフォルト: enemy.atk * 4 * @default enemy.atk * 4 * * @param StateToActorHateFormula * @text 味方ステート付加ヘイト式 * @desc 味方にステートを付加した時増加するヘイトの式です。 * デフォルト: enemy.atk * 4 * @default enemy.atk * 4 * * @param RemoveStateHateFormula * @text 味方ステート解除ヘイト式 * @desc 味方からステートを取り除いたとき増加するヘイトの式です。 * デフォルト: enemy.atk * 4 * @default enemy.atk * 4 * * @param ReduceOthersHate * @text ヘイト減少モード * @type boolean * @on 減らす * @off 減らさない * @desc ヘイトが増える行動をしたとき、味方のヘイトを減らしますか? * @default false * * @param OthersHateRateFormula * @text 味方ヘイト減少式 * @type string * @desc 味方のヘイトを減らすときの割合の式です。 * デフォルト: (100 - (point / enemy.atk)) / 100 * @default (100 - (point / enemy.atk)) / 100 * * @param ---EnemyList--- * @text ---敵リスト--- * * @param ShowEnemyList * @text 敵リスト表示 * @parent ---EnemyList--- * @type boolean * @on はい * @off いいえ * @desc 敵リストを表示しますか? * @default false * * @param EnemyListX * @text 敵リスト位置X * @parent ---EnemyList--- * @type number * @desc 敵リストのX座標です。 * @default 0 * * @param EnemyListY * @text 敵リスト位置Y * @parent ---EnemyList--- * @type number * @desc 敵リストのY座標です。 * @default 0 * * @param HateIconList * @text ヘイトアイコンリスト * @parent ---EnemyList--- * @type string * @desc ヘイト順位のアイコンリストです。左に行くほど高順位です。半角スペースで区切って並べてください。デフォルト:64 5 4 16 * @default 64 5 4 16 * * @param EnemyListFontSize * @text 敵リストフォントサイズ * @parent ---EnemyList--- * @type number * @desc 敵リストのフォントサイズです。 * @default 24 * * @param EnemyListLineHeight * @text 敵リスト行の高さ * @parent ---EnemyList--- * @type number * @desc 敵リストの行の高さです。 * @default 32 * * @param EnemyListWidth * @text 敵リスト幅 * @parent ---EnemyList--- * @type number * @desc 敵リストの幅です。 * @default 240 * * * * @param HateGaugeColor1 * @text ヘイトゲージ色1 * @parent ---EnemyList--- * @type number * @desc ヘイトゲージの色1色目です。 * @default 2 * * @param HateGaugeColor2 * @text ヘイトゲージ色2 * @parent ---EnemyList--- * @type number * @desc ヘイトゲージの色2色目です。 * @default 10 * * * * @param ---HateGauge--- * @text ヘイトゲージ * * @param ShowHateGauge * @text ヘイトゲージ表示 * @parent ---HateGauge--- * @type boolean * @on はい * @off いいえ * @desc パーティリストを表示しますか? * @default false * * @param HateGaugeWidth * @text ヘイトゲージの幅 * @parent ---HateGauge--- * @type number * @desc ヘイトゲージの幅です。 * @default 180 * * @param HateGaugeX * @text ヘイトゲージのX位置 * @parent ---HateGauge--- * @type text * @desc ヘイトゲージのメンバーごとのX座標の位置です。 * index:メンバーの番号、length:メンバーの人数 * @default Graphics.boxWidth /6 * (index +1) * * @param HateGaugeY * @text ヘイトゲージのY位置 * @parent ---HateGauge--- * @type text * @desc ヘイトゲージのメンバーごとのY座標の位置です。 * index:メンバーの番号、length:メンバーの人数 * @default 320 * * @param ShowEnemyNameOnHateGauge * @text 敵キャラ名表示(ヘイトゲージ) * @parent ---HateGauge--- * @type boolean * @on はい * @off いいえ * @desc ヘイトゲージで敵キャラ名を表示しますか? * @default true * * @help * ============================================================================ * どんなプラグイン? * ============================================================================ * * 敵がアクターに対しヘイトを持ち、最もヘイトの高いアクターを狙うようになります。 * ヘイトはバトル中の行動で変化します。 * * ============================================================================ * プラグインコマンド * ============================================================================ * - v1.10 * ShowHateLine * ヘイトラインを表示します。 * HideHateLine * ヘイトラインを非表示にします。 * - v1.13 * ShowEnemyHateList * エネミーリストを表示します。 * HideEnemyHateList * エネミーリストを非表示にします。 * ShowHateGauge * ヘイトゲージを表示します。 * HideHateGauge * ヘイトゲージを非表示にします。 * * ============================================================================ * 自動的にたまるヘイト * ============================================================================ * * アクターが敵を対象とするスキルやアイテムを使うと、対象から使用者へのヘイトが * 増加します。 * 敵を対象としたヘイトが増加する行動: * HP・MPダメージ、デバフ付加、バフ解除、ステート付加 * * アクターが味方を対象とするスキルやアイテムを使うと、その味方を狙っている敵か * ら使用者へのヘイトが増加します。 * 味方を対象としたヘイトが増加する行動: * HP回復、ステート付加、ステートの解除、バフ付加 * * プラグインパラメータでどれだけヘイトが増加するか計算式を設定できます。 * 計算式では、 * ---------------------------------------------------------------------------- * HPダメージ (対象が敵のときのみ) : damage * MPダメージ (対象が敵のときのみ) : MPDamage * 回復ポイント(対象が味方のときのみ): healPoint * スキルの使用者 : a, user * スキルのターゲット : b, target * ヘイトが増加する敵 : enemy * 変数 : v * ---------------------------------------------------------------------------- * を使えます。 * * スキルの使用者、ターゲット、敵、変数はスキルのダメージ計算式と同じように * 扱うことができます。 * 例1:使用者の最大HP * user.mhp * 例2:12番目の変数 * v[12] * * HP・MP吸収攻撃はダメージで増加するヘイトが2倍になります。 * * ============================================================================ * 「狙われ率」の性質の変化 * ============================================================================ * * 「特殊能力値 狙われ率」がヘイトの増加のしやすさになり、増加するヘイトに掛けら * れます。これにより、自分へのヘイトが増加しやすい装備を作ったり、ステートを作っ * たりすることができます。 * * ============================================================================ * ヘイトライン * ============================================================================ * * サイドビューでプラグインパラメータDisplayHateLineを1にするとヘイトラインを * 表示することができます。表示する場合、img/systemフォルダに * "hateline.png" を入れてください。この画像が縦に引き伸ばされて表示されます。 * * ============================================================================ * ステートごとのヘイト増加式 * ============================================================================ * * ステートのメモ: * * このタグで味方や敵にステートを付加したとき、解除したときのヘイト増加式を * 設定できます。 * * 例えば、デフォルトでは防御しただけで、自分を狙う敵からプラグインパラメー * タで設定した分だけヘイトされますが、防御のステートのメモに * * と記述するとヘイトが増加しないようにできます。 * * * このタグで味方からこのステートを解除したときのヘイト増加式を設定できます。 * 付加したときと解除したときでヘイト増加式を変えたいときに使ってください。 * * * デフォルトでは、敵にいいステートをかけたときや、味方に悪いステートをかけ * た時もヘイトが増加しますが、このタグでステートの性質を設定するとスキルの * 対象によって増加させないこともできるようになります。 * * ======================================================================== * 性質の部分に置き換えられるもの: * ------------------------------------------------------------------------ * good : 味方にこのステートを付加したときだけヘイトが増加します。 * neutral : ヘイトは増加しません。 * bad : 敵にこのステートを付加したときと、 * 味方のこのステートを解除したときだけヘイトが増加します。 * ======================================================================== * * ============================================================================ * ヘイトをコントロールするスキル、アイテム * ============================================================================ * * ヘイトを増減するスキルやアイテムを作ることができます。 * * スキル、アイテムのメモ: * * ======================================================================== * 「誰が」の部分に設定できる文字列: * ------------------------------------------------------------------------ * user : スキルの使用者が敵の場合、使用者がヘイトします。 * target : スキルの対象が敵の場合、対象がヘイトします。 * whoHateUser : スキルの使用者がアクターの場合、使用者を狙う敵がヘイトし * ます。 * whoHateTarget : スキルの対象がアクターの場合、そのアクターを狙う敵がヘイ * トします。 * all : 敵全員がヘイトします。 * 範囲が敵全員のスキルには上記targetを指定してください。 * ヘイト計算はスキルの効果が発動するたびに行われるためです。 * exceptUser : スキルの使用者が敵の場合、使用者以外がヘイトします。 * exceptTarget : スキルの対象が敵の場合、対象以外がヘイトします。 * ======================================================================== * * ======================================================================== * 「誰を」の部分に設定できる文字列 * ------------------------------------------------------------------------ * user : スキルの使用者がアクターの場合、使用者がヘイトされます。 * target : スキルの対象がアクターの場合、対象がヘイトされます。 * exceptUser : スキルの使用者がアクターの場合、使用者以外がヘイトされま * す。 * targetsTarget : スキルの対象が敵の場合、その敵が狙っているアクターがヘイ * トされます。 * ======================================================================== * * 計算式では、上記のプラグインパラメータで使えるもののほかに * ------------------------------------------------------------------------ * ヘイトされるアクター : actor * ------------------------------------------------------------------------ * を使えます。 * 計算の結果負の数になるとヘイトが減少します。 * このタグは同じスキルに複数設定できます。 * 1回目のタグで敵が狙うアクターが変わると2回目のwhoHateUser, whoHateTarget * の結果が変わるので、注意が必要です。 * * --- 例 --- * 「挑発」 * 範囲が敵単体のスキルで、対象から自分へのヘイトを敵の攻撃力 × 12 増加させる * * * 「隠れる」 * 範囲が使用者のスキルで、敵全員の自分へのヘイトを自分の敏捷性 × 4 減少させる * * * 「かばう」 * 範囲が味方単体のスキルで、 * 味方を狙う敵から使用者へのヘイトを使用者の最大HPの半分増加させ、 * 敵全員から味方へのヘイトを使用者の最大HPの4分の1減少させる * * * * 「集中攻撃の号令」(敵専用) * 範囲が敵単体のスキルで、敵全員の対象へのヘイトを50増加させる * * * 「注目の笛」(アイテム) * 範囲が味方単体のアイテムで、敵全員の味方へのヘイトを使用者の魔法攻撃力 × 8 * 増加させる * * * ============================================================================ * ヘイトが溜まらないスキル、アイテム * ============================================================================ * * スキル、アイテムのメモ: * * このタグをつけるとダメージなどでヘイトが増加しないスキルが作れます。 * 前述のヘイトを増減させるタグは無効化しません。 * * ============================================================================ * ヘイトが溜まらなくなるエネミーのステート - v1.03 * ============================================================================ * * 例えば、「睡眠」など、状況が把握できなくなるステートにかかったとき、状況が * 把握できないはずなのにヘイトが溜まってしまうのはおかしく感じられます。 * * ステートのメモ: * * このタグをつけると、このステートにかかったエネミーのヘイトが変動しなく * なります。 * * ============================================================================ * ヘイトの確認方法 * ============================================================================ * * プラグインパラメータ DebugMode を ON にするとどれだけヘイトが増加したか、 * F8キーで起動する Developer Tools の Console に出力されます。 * * また、 DebugMode を ON にするとプラグインパラメータのヘイト増加式にエラーが * あった場合も Console に出力されます。 * * 増加したヘイトはこれで確認できますが、溜まっているヘイトを確認するには * 少し難しい操作が必要です。 * * 溜まっているヘイトはGame_Enemyの_hatesという配列に入っていて、添え字は * アクターのIDになっています。 * * 現在溜まっているヘイトを確認するには * Developer Toolsの Sources タブを開き、右上の Watch Expressions の+を押して * $gameTroopと打ちます。 * $gameTroopの左の右向き三角を押すと中身が見れるので、_enemiesを探します。 * (たぶん1番上にあると思います) * _enemiesの中身を開くと敵の数だけ番号がありますがこれがエネミーのオブジェクト * です。これを開き_hatesを探し、開いてみてください。左の紫色の数字が、アクター * のIDで、右の青の文字が現在溜まっているヘイトです。 * * ============================================================================ * 攻撃者以外へのヘイト減少 - v1.06 * ============================================================================ * * 長期戦になると、ヘイトの差が開き、追いつけないものになってしまうことがありま * す。そこで、アクターがヘイトを稼いだとき、他のアクターへのヘイトが減少する * 機能を追加しました。以下のプラグインパラメータで設定ができます。 * * ReduceOthersHate * この機能を使うかどうかを設定します。デフォルトではOFFになっています。 * * OthersHateRateFormula * この式の計算結果が現在のヘイトに掛けられます。 * 計算式では、 * -------------------------------------------------------------------------- * 増加したヘイト : point * 敵キャラ : enemy * ヘイトが減少するアクター : actor * -------------------------------------------------------------------------- * を使えます。 * * ---例--- * デフォルトの場合 * (100 - (point / enemy.atk)) / 100 * * 攻撃者が敵キャラの攻撃力の4倍のヘイトを稼いだとき、 * (100 - 4) / 100 = 0.96 * 攻撃者以外へのヘイトの現在値が0.96倍になる。 * * 攻撃者が敵キャラの攻撃力の15倍のヘイトを稼いだとき、 * (100 - 15) / 100 = 0.85 * 攻撃者以外へのヘイトの現在値が0.85倍になる。 * * DebugMode を ON にしていれば、攻撃者以外のヘイトの現在値が表示されます。 * * ============================================================================ * ヘイト2番目以下のキャラへの攻撃 - v1.09 * ============================================================================ * * スキルのメモ欄: * * ヘイトがx番目のキャラクターに攻撃します。 * 例: * * ヘイトが3番目に高いキャラクターに攻撃します。2人しかいなかった場合2番目 * のキャラクターが攻撃されます。 * * * ============================================================================ * 敵リスト、パーティリスト - v1.13 * ============================================================================ * * ○敵リスト * 選択中のアクターに対する敵全員のヘイトを見られるウィンドウ。 * * ◆表示されるもの * ・選択中アクターの名前 * ・敵全員の * ・名前 * ・選択中アクターのヘイト順位(ヘイトアイコン) * ・選択中アクターのゲージ * * ○ヘイトゲージ * 選択中、行動中の敵キャラのアクター全員へのヘイトを見られるウィンドウ。 * * ◆表示されるもの * ・選択中敵キャラの名前 * ・アクター全員の * ・名前 * ・そのアクターのヘイト順位(ヘイトアイコン) * ・そのアクターのゲージ * * プラグインパラメータで各種設定ができます。 * プラグインコマンドでONとOFFの切り替えができます。 * (上記プラグインコマンド参照) * * ============================================================================ * YEP_BattleAICore.jsの機能拡張 * ============================================================================ * * YEP_BattleAICore.jsはYanfly氏が作成した、敵に賢い行動パターンを設定できるプラ * グインです。AB_EnemyHate.jsはヘイト関係の機能を追加しました。 * この機能を利用するにはプラグインマネージャでYEP_BattleAICore.jsの下に * AB_EnemyHate.jsを置いてください。 * * 追加したCondition: * HATE ELEMENT X case * HATE stat PARAM eval * HATE STATE === state name * HATE STATE !== state name * * もともとYEP_BattleAICore.jsにあったものの先頭に"HATE "を足しただけです。 * 先頭に"HATE "をつけると最もヘイトの高いアクターの状態を見るようになります。 * これらのConditionはターゲットを絞り込みません。 * * 追加したTargeting: * HATE * * Conditionで絞り込まれたアクターの中で最もヘイトが高いアクターを狙います。 * * --- 例 --- * 最もヘイトの高いアクターがPoison状態ならそのアクターにAttackをし、 * そうでなければそのアクターにPoisonをする * * HATE State === Poison: Attack, HATE * Always: Poison, HATE * * * 最もヘイトの高いアクターがHP70%以下ならDual Attackをし、 * そうでなければそのアクターにAttackをする * * HATE HP% param <= 70%: Dual Attack, HATE * Always: Attack, HATE * * * ============================================================================ * 更新履歴 * ============================================================================ * * Version 1.18 * 敵リストを表示しておらず、ヘイトがマイナスになったとき、エラーが出て止まっ * てしまうバグを修正しました。 * * Version 1.17 * ヘイトゲージと敵リストを戦闘中にON、OFFにできるように修正しました。 * 敗北時、逃走時もヘイトゲージを非表示にするように変更しました。 * * Version 1.16 * ツクールMZに対応 * * Version 1.15 * 攻撃時、エラーが出てゲームが停止してしまう不具合を修正しました。 * * Version 1.14 * ヘイトラインをONにしてもヘイトラインが表示されない不具合を修正しました。 * 戦闘中に敵キャラを攻撃対象にした時に対象にした敵のヘイトゲージが表示されるよ * うにしました。 * 戦闘終了時、ヘイトゲージが非表示になるようにしました。 * ヘイトゲージの敵キャラ名を非表示にできるようにしました。 * 敵キャラクターを選択した時以外非表示にしました。 * * Version 1.13 * パーティリストと敵リストを作りました。 * * * Version 1.12 * ヘイトがマイナスの値のとき、ゲームが止まってしまうことがあるバグを修正しま * した。 * * Version 1.11 * フロントビューでYEP_BattleStatusWindowを使っているとき、ステータス画面に向 * けてラインを伸ばすようにしました。 * * Version 1.10 * ヘイトラインを表示・非表示するプラグインコマンドを実装しました。 * * Version 1.09 * ヘイトがX番目に高いアクターを狙うスキルのタグを追加しまし * た。 * * Version 1.08 * ヘイト値が同じとき、先頭に近いアクターが狙われるようにしました。 * ヘイトコントロールの「誰が」に「exceptUser」「exceptTarget」、 * 「誰を」に「exceptUser」「targetsTarget」を追加しました。 * * Version 1.07 * ヘイトラインの表示がおかしくなることがあったので修正しました。 * フロントビューでもDisplayHatelineがONになっていればヘイトラインを表示する * ようにしました。 * * Version 1.06 * 攻撃者以外へのヘイト減少機能を追加しました。 * エラー表示を見やすくしました。 * * Version 1.05 * RPGツクールMVのバージョン 1.1.0 で追加された「未使用ファイルを含まない」 * でデプロイメントしたとき、hateline.png が含まれるように変更しました。 * * Version 1.04 * 復活したエネミーのヘイトラインも表示されるように変更しました。 * * Version 1.03 * ステートのメモタグを追加しました。 * * Version 1.02 * YEP_BattleEnginCore.js と一緒に動作させたときヘイトラインがチカチカする * 問題を修正 * * Version 1.01 * パーティにいないメンバーを後から加えた時にうまく動作しないバグを修正 * ※この修正後も、パーティにいないメンバーを加えるときはあらかじめそのメンバ * ーを全回復するなどして$gameActorsに登録する必要があります。 * * Version 1.00 * 公開 * * ============================================================================ * 利用規約 * ============================================================================ * * ・クレジット表記は不要 * ・営利目的で使用可 * ・改変可 * ただし、ソースコードのヘッダのライセンス表示は残してください。 * ・素材だけの再配布も可 * ・アダルトゲーム、残酷なゲームでの使用も可 * * * @command ShowHateLine * @text ヘイトラインを表示 * @desc 戦闘中、ヘイトラインを表示します。 * * @command HideHateLine * @text ヘイトラインを非表示 * @desc 戦闘中、ヘイトラインを非表示にします。 * * @command ShowEnemyHateList * @text 敵リスト表示 * @desc 戦闘中、選択中のアクターがどの敵から狙われているかを表示します。 * * @command HideEnemyHateList * @text 敵リスト非表示 * @desc 戦闘中、選択中のアクターがどの敵から狙われているかを非表示にします。 * * @command ShowHateGauge * @text ヘイトゲージ表示 * @desc 戦闘中、選択中の敵キャラがどのアクターをどれだけヘイトしているかを表示します。 * * @command HideHateGauge * @text ヘイトゲージ非表示 * @desc 戦闘中、選択中の敵キャラがどのアクターをどれだけヘイトしているかを非表示にします。 * */ (function() { 'use strict'; const pluginName = "ABMZ_EnemyHate"; var parameters = PluginManager.parameters('ABMZ_EnemyHate'); var displayHateLine = eval(parameters['DisplayHateLine']); var HateDebugMode = eval(parameters['DebugMode']); var DamageHateFormula = (parameters['DamageHateFormula'] || 0); var MPDamageHateFormula = (parameters['MPDamageHateFormula'] || 0); var HealHateFormula = (parameters['HealHateFormula'] || 0); var BuffHateFormula = (parameters['BuffHateFormula'] || 0); var DebuffHateFormula = (parameters['DebuffHateFormula'] || 0); var StateToEnemyHateFormula = (parameters['StateToEnemyHateFormula'] || 0); var StateToActorHateFormula = (parameters['StateToActorHateFormula'] || 0); var RemoveStateHateFormula = (parameters['RemoveStateHateFormula'] || 0); var ReduceOthersHate = eval(parameters['ReduceOthersHate'] == 1); var OthersHateRateFormula = (parameters['OthersHateRateFormula'] || 0); var ShowEnemyList = eval(parameters['ShowEnemyList']); var EnemyListX = Number(parameters['EnemyListX']); var EnemyListY = Number(parameters['EnemyListY']); var HateIconList =parameters['HateIconList'].split(' '); var EnemyListFontSize = Number(parameters['EnemyListFontSize']); var EnemyListLineHeight = Number(parameters['EnemyListLineHeight']); var EnemyListWidth = Number(parameters['EnemyListWidth']); var HateGaugeColor1 = Number(parameters['HateGaugeColor1']); var HateGaugeColor2 = Number(parameters['HateGaugeColor2']); var ShowHateGauge = eval(parameters['ShowHateGauge']); var HateGaugeWidth = Number(parameters['HateGaugeWidth']); var HateGaugeX = String(parameters['HateGaugeX']); var HateGaugeY = String(parameters['HateGaugeY']); var ShowEnemyNameOnHateGauge = eval(parameters['ShowEnemyNameOnHateGauge']); //============================================================================= // Game_Interpreter //============================================================================= // const pluginName = "ABMZ_EnemyHate"; PluginManager.registerCommand(pluginName, "ShowHateLine", args => { $gameSystem.setDispHateLine(true); }); PluginManager.registerCommand(pluginName, "HideHateLine", args => { $gameSystem.setDispHateLine(false); }); PluginManager.registerCommand(pluginName, "ShowEnemyHateList", args => { $gameSystem.setDispEnemyHateList(true); if ($gameParty.inBattle()) { SceneManager._scene._ABEnemyListWindow.show(); } }); PluginManager.registerCommand(pluginName, "HideEnemyHateList", args => { $gameSystem.setDispEnemyHateList(false); if ($gameParty.inBattle()) { SceneManager._scene._ABEnemyListWindow.hide(); } }); PluginManager.registerCommand(pluginName, "ShowHateGauge", args => { $gameSystem.setDispHateGauge(true); }); PluginManager.registerCommand(pluginName, "HideHateGauge", args => { $gameSystem.setDispHateGauge(false); if ($gameParty.inBattle()) { SceneManager._scene.hideHateWindow(); } }); var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand; Game_Interpreter.prototype.pluginCommand = function(command, args) { _Game_Interpreter_pluginCommand.call(this, command, args); if (command === 'ShowHateLine') { $gameSystem.setDispHateLine(true); } else if (command === 'HideHateLine') { $gameSystem.setDispHateLine(false); } else if (command === 'ShowEnemyHateList') { $gameSystem.setDispEnemyHateList(true); if ($gameParty.inBattle()) { SceneManager._scene._ABEnemyListWindow.show(); } } else if (command === 'HideEnemyHateList') { $gameSystem.setDispEnemyHateList(false); if ($gameParty.inBattle()) { SceneManager._scene._ABEnemyListWindow.hide(); } } else if (command === 'ShowHateGauge') { $gameSystem.setDispHateGauge(true); } else if (command === 'HideHateGauge') { $gameSystem.setDispHateGauge(false); if ($gameParty.inBattle()) { SceneManager._scene.hideHateWindow(); } } }; // v1.10 //============================================================================= // Game_System //============================================================================= Game_System.prototype.initDispHateLine = function() { this._dispHateLine = displayHateLine; }; Game_System.prototype.setDispHateLine = function(value) { this._dispHateLine = value; }; Game_System.prototype.isDispHateLine = function() { if (this._dispHateLine === undefined) this.initDispHateLine(); return this._dispHateLine; }; Game_System.prototype.initDispEnemyHateList = function() { this._dispEnemyHateList = ShowEnemyList; }; Game_System.prototype.setDispEnemyHateList = function(value) { this._dispEnemyHateList = value; }; Game_System.prototype.isDispEnemyHateList = function() { if (this._dispEnemyHateList === undefined) this.initDispEnemyHateList(); return this._dispEnemyHateList; }; Game_System.prototype.initDispHateGauge = function() { this._dispHateGauge = ShowHateGauge; }; Game_System.prototype.setDispHateGauge = function(value) { this._dispHateGauge = value; }; Game_System.prototype.isDispHateGauge = function() { if (this._dispHateGauge === undefined) this.initDispHateGauge(); return this._dispHateGauge; }; //============================================================================= // Game_Enemy //============================================================================= var Game_Enemy_prototype_setup = Game_Enemy.prototype.setup; Game_Enemy.prototype.setup = function(enemyId, x, y) { Game_Enemy_prototype_setup.call(this, enemyId, x, y); this._hates = []; var allActors = $gameActors._data; var enemy = this; allActors.forEach(function(actor) { if (!actor) return; enemy._hates[actor.actorId()] = Math.randomInt(10); }); }; Game_Enemy.prototype.hates = function() { return this._hates; }; Game_Enemy.prototype.hate = function(index, point) { this._hates[index] += point; if (this._hates[index] < 0) this._hates[index] = 0; if (HateDebugMode) { console.log(this.name() + "の" + $gameActors.actor(index).name() + "へのヘイトが" + point + "ポイント増加"); } if (point > 0) this.reduceOthersHates(index, point); }; Game_Enemy.prototype.reduceOthersHates = function(index, point) { if (!ReduceOthersHate) return; var enemy = this; var actors = $gameParty.battleMembers(); actors.forEach(function(actor) { if (actor.actorId() == index) return; var rate = 1; try { rate = eval(OthersHateRateFormula); if (isNaN(rate)) { throw new Error("「" + OthersHateRateFormula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); } rate = 1; } enemy.multiplyHate(actor.actorId(), rate); }); }; Game_Enemy.prototype.hateOrder = function(actorId) { var hatesArray = []; if (typeof this._hates === "undefined") { return false; } var hates = this._hates; var max = -99999999999999999999; $gameParty.aliveMembers().forEach(function(member) { if (!member.isBattleMember()) return; var i = member.actorId(); var hateObj = {}; hateObj.i = i; hateObj.hate = hates[i]; hatesArray.push(hateObj); }); // 降順ソート hatesArray.sort(function(a,b){ if (a.hate > b.hate) return -1; if (a.hate < b.hate) return 1; return 0; }); var hateOrder = null; hatesArray.forEach(function(hateObj, i) { if (hateObj.i == actorId) { hateOrder = i; return; } }); return hateOrder; }; Game_Enemy.prototype.multiplyHate = function(index, rate) { if (rate < 0) return; var hate = this._hates[index] * rate; hate = Math.round(hate); this._hates[index] = hate; if (HateDebugMode) { console.log(this.name() + "の" + $gameActors.actor(index).name() + "へのヘイトが" + hate + "になった"); } }; Game_Enemy.prototype.hateTarget = function() { return $gameParty.hateTarget(this._hates); } Game_Enemy.prototype.hateTargetNumber = function(no) { return $gameParty.hateTargetNumber(this._hates, no); } Game_Enemy.prototype.hateTargetOf = function(group) { if (typeof this._hates === "undefined") { return false; } var hates = this._hates; var max = -99999999999999999999; var mainTarget; group.forEach(function(member) { if (!member.isActor()) return false; if (!member.isBattleMember()) return false; var i = member.actorId(); if (max < hates[i]) { max = hates[i]; mainTarget = member; } }); return mainTarget; } Game_Enemy.prototype.canHate = function() { return !this._states.some(function(stateId){ var state = $dataStates[stateId]; if (!state) return false; if (state.meta.HATE_cantHate) return true; return false; }); }; //============================================================================= // Game_Party //============================================================================= Game_Party.prototype.hateTarget = function(hates) { // var max = -1; var mainTarget; this.aliveMembers().forEach(function(member) { if (!member.isBattleMember()) return; var i = member.actorId(); if (max < hates[i]) { max = hates[i]; mainTarget = member; } }); return mainTarget; }; Game_Party.prototype.hateTargetNumber = function(hates, no) { var hatesArray = []; var targetIndex = 0; var mainTarget; this.aliveMembers().forEach(function(member) { if (!member.isBattleMember()) return; var i = member.actorId(); var hateObj = {}; hateObj.i = i; hateObj.hate = hates[i]; hatesArray.push(hateObj); }); // 降順ソート hatesArray.sort(function(a,b){ if (a.hate > b.hate) return -1; if (a.hate < b.hate) return 1; return 0; }); // hatesArrayの(no-1)番目のiを選択。 // (no-1)番目がない場合最後のインデックスを選択。 if ((no-1) < hatesArray.length) { targetIndex = hatesArray[no - 1].i; } else { targetIndex = hatesArray[hatesArray.length - 1].i; } mainTarget = $gameActors.actor(targetIndex); return mainTarget; }; var _Game_Party_prototype_refresh = Game_Party.prototype.refresh; Game_Party.prototype.refresh = function() { // _Game_Party_prototype_refresh.call(this); if (this.inBattle()) { SceneManager._scene.initHateGaugeWindows(); } }; var _Game_Party_prototype_addActor = Game_Party.prototype.addActor; Game_Party.prototype.addActor = function(actorId) { _Game_Party_prototype_addActor.call(this, actorId); if (this.inBattle()) { SceneManager._scene.initHateGaugeWindows(); } }; var _Game_Party_prototype_removeActor = Game_Party.prototype.removeActor; Game_Party.prototype.removeActor = function(actorId) { _Game_Party_prototype_removeActor.call(this, actorId); if (this.inBattle()) { SceneManager._scene.initHateGaugeWindows(); } }; //============================================================================= // Game_Actor //============================================================================= Game_Actor.prototype.whoHateMe = function() { var who = []; var enemies = $gameTroop.aliveMembers(); for (var i=0,l=enemies.length; i < l; i++) { if (enemies[i].hateTarget() == this) { who.push(enemies[i]); } } return who; } //============================================================================= // Sprite_Battler //============================================================================= var _Sprite_Battler_prototype_updatePosition = Sprite_Battler.prototype.updatePosition; Sprite_Actor.prototype.updatePosition = function() { if ($gameSystem.isSideView()) { _Sprite_Battler_prototype_updatePosition.call(this); return; } if (SceneManager._scene._statusWindow) { var statusWindow = SceneManager._scene._statusWindow; this.x = this._homeX - SceneManager._scene._partyCommandWindow.width + 80 + statusWindow.x; this.y = this._homeY; } }; //============================================================================= // Game_Action //===== // 上書き Game_Action.prototype.targetsForOpponents = function() { var targets = []; var unit = this.opponentsUnit(); if (this.isForRandom()) { for (var i = 0; i < this.numTargets(); i++) { targets.push(unit.randomTarget()); } } else if (this.isForOne()) { if (this._targetIndex < 0) { // 使用者がアクターだった場合 if (this._subjectActorId > 0) { targets.push(unit.randomTarget()); // 使用者が敵キャラだった場合 } else { // v1.09 if (this._item.object().meta.HATE_target) { var no = Number(this._item.object().meta.HATE_target); targets.push(unit.hateTargetNumber(this.subject().hates(), no)); } else { targets.push(unit.hateTarget(this.subject().hates())); } } } else { targets.push(unit.smoothTarget(this._targetIndex)); } } else { targets = unit.aliveMembers(); } return targets; }; Game_Action.prototype.confusionTarget = function() { switch (this.subject().confusionLevel()) { case 1: if (this._subjectActorId > 0) return this.opponentsUnit().randomTarget(); return this.opponentsUnit().hateTarget(this.subject().hates()); case 2: if (Math.randomInt(2) === 0) { return this.opponentsUnit().randomTarget(); } return this.friendsUnit().randomTarget(); default: return this.friendsUnit().randomTarget(); } }; var Game_Action_prototype_apply = Game_Action.prototype.apply; Game_Action.prototype.apply = function(target) { Game_Action_prototype_apply.call(this, target); this.varyHate(target); }; Game_Action.prototype.varyHate = function(target) { if (this._subjectActorId > 0) { if (target.isActor()) { if (!this._item.object().meta.HATE_no) { this.actorToActorVaryHate(target); } } else { if (!this._item.object().meta.HATE_no) { this.actorToEnemyVaryHate(target); } } } this.controlHate(target); }; Game_Action.prototype.actorToEnemyVaryHate = function(target) { var result = target.result(); var user = this.subject(); var a = user; var b = target; var enemy = target; var v = $gameVariables._data; var hate = 0; var damage = Math.max(result.hpDamage, 0); var MPDamage = Math.max(result.mpDamage, 0); if (!enemy.canHate()) return; if (damage) { var add = 0; try { add = eval(DamageHateFormula); if (isNaN(add)) { throw new Error("「" + DamageHateFormula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); } add = 0; } hate += add; } if (MPDamage) { var add = 0; try { add = eval(MPDamageHateFormula); if (isNaN(add)) { throw new Error("「" + MPDamageHateFormula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); } add = 0; } hate += add; } if (result.drain) hate = Math.floor(hate * 2); var addedStateObjects = result.addedStateObjects(); addedStateObjects.forEach(function(state) { var property = state.meta.HATE_property; if (property && (property.match(/good/) || property.match(/neutral/))) return; var HATE_formula = state.meta.HATE_formula; var add = 0; if (HATE_formula) { try { add = eval(HATE_formula); if (isNaN(add)) { throw new Error("「" + HATE_formula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); } add = 0; } } else { try { add = eval(StateToEnemyHateFormula); if (isNaN(add)) { throw new Error("「" + StateToEnemyHateFormula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); } add = 0; } } hate += add; }); if (result.addedDebuffs.length + result.removedBuffs.length > 0) { var add = 0; try { add = eval(DebuffHateFormula); if (isNaN(add)) { throw new Error("「" + DebuffHateFormula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); add = 0; } } add = (result.addedDebuffs.length + result.removedBuffs.length) * add; hate += add; } hate = Math.ceil(hate * user.tgr); target.hate(user.actorId(), hate); /*if (HateDebugMode) { console.log(target.name() + "の" + user.name() + "へのヘイトが" + hate + "ポイント増加"); }*/ }; Game_Action.prototype.actorToActorVaryHate = function(target) { var result = target.result(); var user = this.subject(); var a = user; var b = target; var enemies = target.whoHateMe(); var v = $gameVariables._data; var healPoint = Math.max(-result.hpDamage, 0); for (var i=0, l=enemies.length; i 0) { var add = 0; try { add = eval(BuffHateFormula); if (isNaN(add)) { throw new Error("「" + BuffHateFormula + "」の計算結果は数値ではありません。"); } } catch (e) { if (HateDebugMode) { console.log(e.toString()); } add = 0; } add = result.addedBuffs.length * add; hate += add; } hate = Math.ceil(hate * user.tgr); enemy.hate(user.actorId(), hate); /*if (HateDebugMode) { console.log(enemy.name() + "の" + user.name() + "へのヘイトが" + hate + "ポイント増加"); }*/ } }; Game_Action.prototype.controlHate = function(target) { var result = target.result(); var user = this.subject(); var a = user; var b = target; var v = $gameVariables._data; var enemies = []; var actors = []; var hate; var action = this; var damage = Math.max(result.hpDamage, 0); var MPDamage = Math.max(result.mpDamage, 0); var hateControls = this._item.object().hateControls; for (var i = 0; i < hateControls.length; i++) { var HATE_enemy = hateControls[i].enemy; var HATE_actor = hateControls[i].actor; var HATE_formula = hateControls[i].formula; var enemies = this.haterEnemies(target, HATE_enemy); var actors = this.hatedActors(target, HATE_actor); enemies.forEach(function(enemy) { if (!enemy.canHate()) return; actors.forEach(function(actor) { try { hate = eval(HATE_formula); if (isNaN(hate)) { throw new Error("「" + HATE_formula + "」の計算結果は数値ではありません。"); } } catch(e) { if (HateDebugMode) { console.log(e.toString()); } hate = 0; } hate = Math.ceil(hate * actor.tgr); if (hate != 0) action.makeSuccess(target); enemy.hate(actor.actorId(), hate); }); }); } }; Game_Action.prototype.haterEnemies = function(target, HATE_enemy) { if (HATE_enemy.match(/^user$/i)) { return this.enemiesUser(target); } else if (HATE_enemy.match(/^target$/i)) { return this.enemiesTarget(target); } else if (HATE_enemy.match(/^whoHateUser$/i)) { return this.enemiesWhoHateUser(target); } else if (HATE_enemy.match(/^whoHateTarget$/i)) { return this.enemiesWhoHateTarget(target); } else if (HATE_enemy.match(/^all$/i)) { return $gameTroop.aliveMembers(); } else if (HATE_enemy.match(/^exceptUser$/i)) { return this.enemiesExceptUser(target); } else if (HATE_enemy.match(/^exceptTarget$/i)) { return this.enemiesExceptTarget(target); } return []; }; Game_Action.prototype.enemiesUser = function(target) { var enemies = []; var user = this.subject(); if (user.isEnemy()) enemies.push(user); return enemies; }; Game_Action.prototype.enemiesTarget = function(target) { var enemies = []; if (target.isEnemy()) enemies.push(target); return enemies; }; Game_Action.prototype.enemiesWhoHateUser = function(target) { var enemies = []; var user = this.subject(); if (user.isActor()) { enemies = user.whoHateMe(); } return enemies; }; Game_Action.prototype.enemiesWhoHateTarget = function(target) { var enemies = []; if (target.isActor()) { enemies = target.whoHateMe(); } return enemies; }; Game_Action.prototype.enemiesExceptUser = function(target) { var enemies = []; var user = this.subject(); if (user.isEnemy()) { enemies = $gameTroop.aliveMembers().filter(function(enemy) { return enemy != user; }); } return enemies; }; Game_Action.prototype.enemiesExceptTarget = function(target) { var enemies = []; if (target.isEnemy()) { enemies = $gameTroop.aliveMembers().filter(function(enemy) { return enemy != target; }); } return enemies; }; Game_Action.prototype.hatedActors = function (target, HATE_actor) { if (HATE_actor.match(/^user$/i)) { return this.actorsUser(target); } else if (HATE_actor.match(/^target$/i)) { return this.actorsTarget(target); } else if (HATE_actor.match(/^exceptUser$/i)) { return this.actorsExceptUser(target); } else if (HATE_actor.match(/^targetsTarget$/i)) { return this.actorsTargetsTarget(target); } return []; }; Game_Action.prototype.actorsUser = function(target) { var actors = []; var user = this.subject(); if (user.isActor()) { actors.push(user); } return actors; }; Game_Action.prototype.actorsTarget = function(target) { var actors = []; if (target.isActor()) { actors.push(target); } return actors; }; Game_Action.prototype.actorsExceptUser = function(target) { var actors = []; var user = this.subject(); if (user.isActor()) { actors = $gameParty.aliveMembers().filter(function(actor) { return actor != user; }); } return actors; }; Game_Action.prototype.actorsTargetsTarget = function(target) { var actors = []; if (target.isEnemy()) { actors.push(target.hateTarget()); } return actors; }; //============================================================================= // DataManager //============================================================================= var DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded; DataManager.isDatabaseLoaded = function() { if (!DataManager_isDatabaseLoaded.call(this)) return false; this.processHateNotetags($dataSkills); this.processHateNotetags($dataItems); return true; }; DataManager.processHateNotetags = function(group) { var note1 = //i; for (var n = 1; n < group.length; n++) { var obj = group[n]; var notedata = obj.note.split(/[\r\n]+/); obj.hateControls = []; for (var i = 0; i < notedata.length; i++) { var line = notedata[i]; if (line.match(note1)) { var control = {}; control.enemy = RegExp.$1; control.actor = RegExp.$2; control.formula = RegExp.$3; obj.hateControls.push(control); } } } }; //============================================================================= // displayHateLine //============================================================================= // v1.10からコメントアウト // if(displayHateLine) { //============================================================================= // HateLine //============================================================================= var HateLine = function() { this.initialize.apply(this, arguments); }; HateLine.prototype = Object.create(Sprite.prototype); HateLine.prototype.constructer = HateLine; HateLine.prototype.initialize = function(enemy, spriteset) { Sprite.prototype.initialize.call(this); this._enemy = enemy; this._spriteset = spriteset; this._enemySprite = null; this._actorNo = -1; this.bitmap = ImageManager.loadSystem("hateline"); this._ex = 0; this._ey = 0; this._ax = 0; this._ay = 0; this.z = 0; this.findEnemySprite(); }; HateLine.prototype.findEnemySprite = function() { var enemy = this._enemy; var enemySprites = this._spriteset._enemySprites; for (var i=0,l=enemySprites.length; i < l; i++){ if (enemySprites[i]._enemy == enemy) { this._enemySprite = enemySprites[i]; break; } } }; HateLine.prototype.updateBindSprites = function() { this.updateBindEnemySprite(); this.updateBindActorSprite(); }; HateLine.prototype.updateBindEnemySprite = function() { var sprite = this._enemySprite; this._ex = sprite.x; this._ey = sprite.y; }; HateLine.prototype.updateBindActorSprite = function() { var actor = this._enemy.hateTarget(); if (actor) { if ($gameSystem.isSideView()) { var sprite = this._spriteset._actorSprites[actor.index()]; this._ax = sprite.x; this._ay = sprite.y; } else { this._actorNo = actor.index(); const rect = SceneManager._scene._statusWindow.itemRectWithPadding(this._actorNo); this._ax = rect.x + rect.width/2 + SceneManager._scene._statusWindow.x; this._ay = 450; } } }; HateLine.prototype.updatePosition = function() { var dx = this._ex - this._ax; var dy = this._ey - this._ay; var distance = Math.floor(Math.pow(dx*dx+dy*dy,0.5)); this.x = this._ax; this.y = this._ay; this.scale.y = distance / this.height; //this.rotation = Math.PI * 3 / 2 + Math.atan(dy/dx); this.rotation = Math.atan2(dy,dx) - Math.PI / 2; }; HateLine.prototype.update = function() { Sprite.prototype.update.call(this); if (this._enemy.isHidden() || this._enemy.isDead()) { this.hide(); return; } this.show(); this.updateBindSprites(); this.updatePosition(); // v1.10 this.updateVisible(); }; // v1.10 HateLine.prototype.updateVisible = function() { this.visible = $gameSystem.isDispHateLine(); }; //============================================================================= // Spriteset_Battle //============================================================================= Spriteset_Battle.prototype.createHateLines = function() { if (!$gameSystem.isDispHateLine()) return; var enemies = $gameTroop.members(); var hateLines = []; var index = this._battleField.getChildIndex(this._enemySprites[0]); for (var i = 0,l = enemies.length; i < l; i++) { hateLines[i] = new HateLine(enemies[i], this); this._battleField.addChildAt(hateLines[i], index); } this._hateLines = hateLines; }; var Spriteset_Battle_prototype_createLowerLayer = Spriteset_Battle.prototype.createLowerLayer; Spriteset_Battle.prototype.createLowerLayer = function() { Spriteset_Battle_prototype_createLowerLayer.call(this); /*if ($gameSystem.isSideView())*/ this.createHateLines(); } // } //============================================================================= // Window_ABEnemyList //============================================================================= var Window_ABEnemyList = function() { this.initialize.apply(this, arguments); }; Window_ABEnemyList.prototype = Object.create(Window_Base.prototype); Window_ABEnemyList.prototype.constructor = Window_ABEnemyList; Window_ABEnemyList.prototype.initialize = function(x, y, width, height) { height = 9*EnemyListLineHeight + 18*2; var rect = new Rectangle(x, y, width, height); Window_Base.prototype.initialize.call(this, rect); this._actor = null; this._enemy = null; this._flag = ""; this.contents.fontSize = EnemyListFontSize; }; Window_ABEnemyList.prototype.lineHeight = function() { return EnemyListLineHeight; }; var _Window_ABEnemyList_prototype_show = Window_ABEnemyList.prototype.show; Window_ABEnemyList.prototype.show = function() { if (!$gameSystem.isDispEnemyHateList()) return; _Window_ABEnemyList_prototype_show.call(this); }; Window_ABEnemyList.prototype.setActorAndShow = function(actor) { this._actor = actor; this._flag = "actor"; this.refresh(); this.show(); }; Window_ABEnemyList.prototype.setEnemyAndShow = function(enemy) { //this._enemy = enemy; //this._flag = "enemy"; //this.refresh(); //this.show(); }; Window_ABEnemyList.prototype.refresh = function() { if (this._flag == "actor") { this.showEnemyList(); } else if (this._flag == "enemy") { this.ShowHateGauge(); } else { this.contents.clear(); } }; Window_ABEnemyList.prototype.showEnemyList = function() { this.contents.clear(); var actor = this._actor; if (!actor) return; var cw = this.contents.width; if (!$gameSystem.isDispEnemyHateList()) return; this.drawText(actor.name(), 0, 0, cw); var y = this.lineHeight(); var enemies = $gameTroop.aliveMembers(); for (var i=0, l=enemies.length; i b.hate) return -1; if (a.hate < b.hate) return 1; return 0; }); for (var i=0, l=hatesArray.length; i= 0 && paramId <= 7) { condition = 'target.param(paramId) ' + condition; } else if (paramId === 8) { condition = 'target.hp ' + condition; } else if (paramId === 9) { condition = 'target.mp ' + condition; } else if (paramId === 10) { condition = 'target.hp / target.mhp ' + condition; } else if (paramId === 11) { condition = 'target.hp / target.mmp ' + condition; } else if (paramId === 12) { condition = 'target.level ' + condition; } var target = user.hateTarget(); var flag = eval(condition); if (flag) { var group = this.getActionGroup(); this.setProperTarget(group); } return flag; }; AIManager.conditionHateStateHas = function(condition) { if (condition.match(/HATE[ ]STATE[ ](\d+)/i)) { var stateId = parseInt(RegExp.$1); } else { var stateId = Yanfly.StateIdRef[condition.toUpperCase()]; if (!stateId) return false; } if (!$dataStates[stateId]) return false; var user = this.battler(); var target = user.hateTarget(); var flag = target.hasState(stateId); if (flag) { var group = this.getActionGroup(); this.setProperTarget(group); } return flag; }; AIManager.conditionHateStateNot = function(condition) { if (condition.match(/HATE[ ]STATE[ ](\d+)/i)) { var stateId = parseInt(RegExp.$1); } else { var stateId = Yanfly.StateIdRef[condition.toUpperCase()]; if (!stateId) return false; } if (!$dataStates[stateId]) return false; var user = this.battler(); var target = user.hateTarget(); var flag = target.notState(stateId); if (flag) { var group = this.getActionGroup(); this.setProperTarget(group); } return flag; }; var AIManager_setProperTarget = AIManager.setProperTarget; AIManager.setProperTarget = function(group) { var action = this.action(); var user = this.battler(); var randomTarget = group[Math.floor(Math.random() * group.length)]; if (group.length <= 0) return action.setTarget(randomTarget.index()); var line = this._aiTarget.toUpperCase(); if (line.match(/HATE/i)) { if (action.isForOpponent()) { var target = user.hateTargetOf(group); if (target) { return action.setTarget(target.index()); } } return action.setTarget(randomTarget.index()); } return AIManager_setProperTarget.call(this, group); } }