Files
2019-11-05 20:14:51 +01:00

1909 lines
66 KiB
JavaScript

//=============================================================================
// Yanfly Engine Plugins - Target Extension - Selection Control
// YEP_X_SelectionControl.js
//=============================================================================
var Imported = Imported || {};
Imported.YEP_X_SelectionControl = true;
var Yanfly = Yanfly || {};
Yanfly.Sel = Yanfly.Sel || {};
Yanfly.Sel.version = 1.15;
//=============================================================================
/*:
* @plugindesc v1.15 (Requires YEP_BattleEngineCore & YEP_TargetCore.js)
* Control what targets can and can't be selected for actions.
* @author Yanfly Engine Plugins
*
* @param ---Default---
* @default
*
* @param Single Multiple
* @parent ---Default---
* @type boolean
* @on YES
* @off NO
* @desc Single target magical skills to be able to select all units
* of a battler group. NO - false YES - true
* @default true
*
* @param Disperse Damage
* @parent ---Default---
* @type boolean
* @on YES
* @off NO
* @desc Automatically disperse damage if multiple targets are
* selected instead of single targets? NO - false YES - true
* @default true
*
* @param Actor or Enemy
* @parent ---Default---
* @type boolean
* @on YES
* @off NO
* @desc Single target skills can target either actors or enemies
* by default? NO - false YES - true
* @default true
*
* @param Physical Front Row
* @parent ---Default---
* @type boolean
* @on YES
* @off NO
* @desc Req. YEP_RowFormation, set physical single-target skills
* to target only the front row? NO - false YES - true
* @default false
*
* @param Physical Weapon Range
* @parent ---Default---
* @type boolean
* @on YES
* @off NO
* @desc Req. YEP_RowFormation & if the above is false, set physical
* single-target skills to be weapon ranged? true/false
* @default true
*
* @param Default Weapon Range
* @parent ---Default---
* @type boolean
* @on Ranged
* @off Melee
* @desc Req. YEP_RowFormation, the default range for weapons.
* MELEE - false RANGED - true
* @default false
*
* @param ---Text Display---
* @default
*
* @param All Enemies
* @parent ---Text Display---
* @desc Selection text for all enemies.
* @default All Enemies
*
* @param All Allies
* @parent ---Text Display---
* @desc Selection text for all allies.
* @default All Allies
*
* @param ---Visual All Window Select---
* @default
*
* @param Enable Visual All
* @parent ---Visual All Window Select---
* @type boolean
* @on YES
* @off NO
* @desc Enables a window the player can click to toggle between
* select all for allies/enemies. YES - true NO - false
* @default true
*
* @param Visual Enemy X
* @parent ---Visual All Window Select---
* @desc X coordinate of the All Enemies window.
* This is a formula.
* @default 0
*
* @param Visual Enemy Y
* @parent ---Visual All Window Select---
* @desc Y coordinate of the All Enemies window.
* This is a formula.
* @default this.fittingHeight(2)
*
* @param Visual Enemy Width
* @parent ---Visual All Window Select---
* @desc Width of the All Enemies window.
* This is a formula.
* @default 240
*
* @param Visual Enemy Height
* @parent ---Visual All Window Select---
* @desc Width of the All Enemies window.
* This is a formula.
* @default this.fittingHeight(1)
*
* @param Visual Ally X
* @parent ---Visual All Window Select---
* @desc X coordinate of the All Allies window.
* This is a formula.
* @default Graphics.boxWidth - 240
*
* @param Visual Ally Y
* @parent ---Visual All Window Select---
* @desc Y coordinate of the All Allies window.
* This is a formula.
* @default this.fittingHeight(2)
*
* @param Visual Ally Width
* @parent ---Visual All Window Select---
* @desc Width of the All Allies window.
* This is a formula.
* @default 240
*
* @param Visual Ally Height
* @parent ---Visual All Window Select---
* @desc Width of the All Allies window.
* This is a formula.
* @default this.fittingHeight(1)
*
* @help
* ============================================================================
* Introduction
* ============================================================================
*
* This plugin requires YEP_BattleEngineCore and YEP_TargetCore. Make sure this
* plugin is located under both of those plugins in the plugin list.
*
* When selecting targets, RPG Maker MV has it set by default that the list of
* valid targets is always either alive enemies, alive allies, or only dead
* allies. Actions would not be able to target either actors or enemies or
* change from single target to multiple targets. This extension plugin for the
* Target Core will allow you to break free of that restriction for better
* selection control of targets as well as insert customized conditions.
*
* If you are using the YEP_X_BattleSysCTB plugin, place this plugin under that
* plugin in the plugin list for the best compatibility.
*
* ============================================================================
* Notetags - General
* ============================================================================
*
* To make skills and items select only certain types of battlers, you can use
* the following notetag setup to do so:
*
* Skill and Item Notetags:
*
* <Single or Multiple Select>
* This will allow the skill or item to be able to select either single
* targets or all targets at once. This will automatically make a skill
* default to single target selecting. You MUST change your scope in the
* database to work with this effect.
* *Note: Having this option will cancel out AoE Circles and AoE Rectangles
* to avoid conflicting issues.
* *Note: If there is an enemy with taunt, the option to switch between a
* group target and a single target will not be available.
* *Note: Enemy AI will NOT make use of the ability to toggle between single
* target and multi-target scopes.
*
* <Disperse Damage>
* Used in conjunction with the above notetag, this will cause damage to be
* split evenly amongst the number of targets the skill is dispersed into.
* The damage dispersion effect will only occur if multiple targets are being
* selected after toggling.
*
* <Enemy or Actor Select>
* <Actor or Enemy Select>
* This will allow the player to toggle between selecting an enemy or actor
* for the action's target scope. When using <Enemy or Actor Select>, it will
* first target enemies by default. Using <Actor or Enemy Select> will target
* actors by default. Using either notetag will change the action's target
* scope to single target.
* *Note: Enemy AI will NOT make use of the ability to toggle between actors
* or enemies for skill selection.
*
* <Weapon Range>
* <Weapon Ranged>
* Requires YEP_RowFormation.js. This will make the selection of targets vary
* based on the battler's weapon range. If the weapon is 'melee', then it
* will target the front row only. If the weapon is 'ranged', then it can
* target any row the battler wants.
*
* *Note: If you use any <Select Condition> effects, all selection options
* provided by default with the plugin parameters will be reset under the
* assumption that it will no longer be an action of default nature. If this is
* the case, you will need to use the above notetags to specify how you wish to
* make your skill's selection methods.
*
* Actor, Class, Enemy, Weapon, Armor, State Notetags:
*
* <Cannot Select: All>
* All actions cannot select this battler unless it's an action whose scope
* is a user scope.
*
* <Cannot Select: Physical Hit>
* <Cannot Select: Magical Hit>
* <Cannot Select: Certain Hit>
* This will prevent physical, magical, or certain hit actions from being
* able to select the battler. They will be excluded out of multi-hit skills,
* as well unless it's an action whose scope targets the user itself.
* targets the user itself.
*
* <Cannot Select: Skills>
* <Cannot Select: Items>
* This will prevent skills/items from being able to target the battler
* unless it's an action whose scope targets the user itself.
*
* <Cannot Select: Item x>
* <Cannot Select: Item name>
* This will prevent item 'x' (or the named item) from being able to target
* the battler unless the item's scope targets the user itself. If you have
* multiple items in your database with the same name, priority will be given
* to the item with the highest ID.
*
* <Cannot Select: Skill x>
* <Cannot Select: Skill name>
* This will prevent skill 'x' (or the named skill) from being able to target
* the battler unless the skill's scope targets the user itself. If you have
* multiple skills in your database with the same name, priority will be
* given to the skill with the highest ID.
*
* <Cannot Select: SType x>
* <Cannot Select: SType name>
* This will prevent skills of skill type 'x' (or named) from being able to
* target the battler unless the skill's scope targets the user itself. If
* you have multiple skill types in your database with the same name, then
* priority will be given to the skill type with the highest ID.
*
* <Cannot Select: Element x>
* <Cannot Select: Element name>
* This will prevent actions with an elemental ID of 'x' (or named) from
* being able to target the battler unless the action's scope targets the
* user itself. If you have multiple elements in your database with the same
* name, then priority will be given to the element with the highest ID.
*
* Weapon and Enemy Notetags:
*
* <Melee>
* This will designate the weapon/enemy as being melee and will affect any
* skill or item selection range that uses the 'Weapon Range' condition.
* Weapons/Enemies of this nature will target only the front row for those
* selection conditions.
*
* <Range>
* <Ranged>
* This will designate the weapon/enemy as being ranged and will affect any
* skill or item selection range that uses the 'Weapon Range' condition.
* Weapons/Enemies of this nature will be able to target any row for those
* selection conditions.
*
* ============================================================================
* Notetags - Select Conditions
* ============================================================================
*
* To impose specific conditions on which targets are valid targets, use the
* following notetag setup:
*
* ---
*
* Skill and Item Notetags:
*
* <Select Conditions>
* condition
* condition
* </Select Conditions>
* Replace 'condition' with the desired condition setup. Insert multiple
* conditions to make an action require more conditions for viable targets.
* Using this will overwrite the default settings imposed by the plugin
* parameters so if you wish to use those settings, you'll have to use the
* associated condition with it.
*
* ---
*
* Conditions:
*
* ---
*
* Any Row
* - Requires YEP_RowFormation.js. The battler can be targeted from any row it
* is in as a valid target. This will conflict with the other 'Row Only' select
* conditions.
*
* ---
*
* Back Row Only
* - Requires YEP_RowFormation.js. This will make only the back row battlers
* be selectable for target. The back row will refer to whatever row is in the
* back that has living members. If row 3's enemies are all dead, but row 2
* has living members, then row 2 will be considered the back row. This will
* conflict with the other 'Row Only' select conditions.
*
* ---
*
* Front Row Only
* - Requires YEP_RowFormation.js. This will make only the front row battlers
* be selectable for target. The front row will refer to whatever row is in
* front that has living members. If row 1's enemies are all dead, but row 2
* has living members, then row 2 will be considered the front row. This will
* conflict with the other 'Row Only' select conditions.
*
* ---
*
* Weapon Range
* - Requires YEP_RowFormation.js. This will make the selection of targets vary
* based on the battler's weapon range. If the weapon is 'melee', then it will
* target the front row only. If the weapon is 'ranged', then it can target any
* row the battler wants.
*
* ---
*
* Row x Only
* - Requires YEP_RowFormation.js. This will make only battlers in row x be
* selectable for target. Any battlers not in row x will be excluded from
* target selection. This will conflict with the other 'Row Only' select
* conditions.
*
* ---
*
* Row x Max
* - Requires YEP_RowFormation.js. This will make all battlers who are located
* in a lower number row up to row x be selectable for target. Any battlers in
* a row number larger than x will be excluded from target selection.
*
* ---
*
* Row x Min
* - Requires YEP_RowFormation.js. This will make all battlers who are located
* in a row from row x onward selectable for target. Any battlers in a row
* number smaller than x will be excluded from target selection.
*
* ---
*
* Param stat eval
* ie: Param MaxHP >= 500
* ie: Param HP% <= 0.30
* ie: Param Level === 25
* - This makes the selection have a check on the target's parameter values
* before deciding if the target is a valid target for selection. You can
* replace 'stat' with 'MaxHP', 'MaxMP', 'MaxTP', 'HP', 'MP', 'TP', 'HP%',
* 'MP%', 'TP%', 'ATK', 'DEF', 'MAT', 'MDF', 'AGI', 'LUK', or 'LEVEL'. This
* run an eval check against that parameter owned by the target.
*
* ---
*
* State: x
* State: name
* - The target must have state 'x' in order to be selected as a valid target.
* If you're using the named version of the condition and you have multiple
* states with the same name in your database, priority will be given to the
* state with the highest ID. If the target doesn't have state 'x', then the
* target is not a valid target for selection.
*
* ---
*
* Not State: x
* Not State: name
* - The target must not have state 'x' in order to be selected as a valid
* target. If you're using the named version of the condition and you have
* multiple states with the same name in your database, priority will be given
* to the state with the highest ID. If the target does have state 'x', then
* the target is not a valid target for selection.
*
* ---
*
* Not User
* - This will remove the user from the possible selection pool making the user
* unable to be selected as a valid target.
*
* ============================================================================
* Lunatic Mode - Custom Select Condition
* ============================================================================
*
* For those with JavaScript experience, you can use the following notetags to
* make custom selection conditions for skills and items.
*
* Skill and Item Notetags:
*
* <Custom Select Condition>
* if (target.name() === 'Harold') {
* condition = true;
* } else {
* condition = false;
* }
* </Custom Select Condition>
* The 'condition' variable determines if the condition will pass or not. If
* the variable returns 'true', the condition will pass. If the variable is
* 'false', the condition will fail and the target will not be a valid target
* for the action. Even if the <Custom Select Condition> notetag passes, all
* other selection conditions must pass, too.
*
* ============================================================================
* Changelog
* ============================================================================
*
* Version 1.15:
* - Bypass the isDevToolsOpen() error when bad code is inserted into a script
* call or custom Lunatic Mode code segment due to updating to MV 1.6.1.
*
* Version 1.14:
* - Updated for RPG Maker MV version 1.6.1.
*
* Version 1.13:
* - Fixed a bug for the cached items.
*
* Version 1.12:
* - Updated for RPG Maker MV version 1.5.0.
*
* Version 1.11:
* - Optimization update. Lag that occurred during menu scrolling in the middle
* of battle is now reduced/removed.
*
* Version 1.10:
* - Lunatic Mode fail safes added.
*
* Version 1.09:
* - Fixed an exploit with skills that gain TP across Disperse Damage.
*
* Version 1.08:
* - New Feature: Clicking upon the Party Status Window to select actors works.
* This requires Battle Engine Core v1.38 or else it will not work.
* - New Feature: Visual Enemy and Visual Ally select for touch input.
* This requires Battle Engine Core v1.38 or else it will not work.
*
* Verison 1.07a:
* - Fixed a bug that caused the all dead check to not check the actors that
* were unselectable.
* - Compatibility update with Battle System CTB to prevent taunt effects and
* unselectable from making the CTB Turn Order bug out.
*
* Version 1.06a:
* - Added 'Physical Weapon Range' and 'Default Weapon Range' parameters. These
* parameters are used for the new Select Condition: 'Weapon Range', which will
* determine the range of a skill based on the weapon's range (melee or ranged)
* and allow which enemies the battler can select.
* - Added <Weapon Ranged> for Skills and Items. This will make the skill/item
* be range dependent on the weapon equipped (or if the enemy is ranged).
* - <Melee> and <Ranged> notetags added for weapons and enemies. This will
* give weapons and enemies melee or ranged attributes.
* - Changed sorting algorithm to better fit actors based on their visual
* position on the screen.
*
* Version 1.05:
* - Compatibility update with Damage Core to fix Damage Dispersion if damage
* caps are being used.
*
* Version 1.04:
* - Fixed a bug with the <Cannot Select> notetags that made them only work
* with states.
*
* Version 1.03:
* - Fixed a bug that made <Bypass Taunt> and <Ignore Taunt> notetags not work
* for the YEP_Taunt.js plugin.
*
* Version 1.02a:
* - Fixed a bug that caused a crash when multiple targets are present.
* - Fixed an error with getting the wrong eval variable.
*
* Version 1.01:
* - Fixed a bug with the 'Not User' select condition not working properly.
*
* Version 1.00:
* - Finished Plugin!
*/
//=============================================================================
if (Imported.YEP_BattleEngineCore && Imported.YEP_TargetCore) {
//=============================================================================
// Parameter Variables
//=============================================================================
Yanfly.Parameters = PluginManager.parameters('YEP_X_SelectionControl');
Yanfly.Param = Yanfly.Param || {};
Yanfly.Param.SelectSoleMulti = String(Yanfly.Parameters['Single Multiple']);
Yanfly.Param.SelectSoleMulti = eval(Yanfly.Param.SelectSoleMulti);
Yanfly.Param.SelectDisperse = String(Yanfly.Parameters['Disperse Damage']);
Yanfly.Param.SelectDisperse = eval(Yanfly.Param.SelectDisperse);
Yanfly.Param.SelectActorEnemy = String(Yanfly.Parameters['Actor or Enemy']);
Yanfly.Param.SelectActorEnemy = eval(Yanfly.Param.SelectActorEnemy);
Yanfly.Param.SelectMelee = String(Yanfly.Parameters['Physical Front Row']);
Yanfly.Param.SelectMelee = eval(Yanfly.Param.SelectMelee);
Yanfly.Param.SelectWpn = String(Yanfly.Parameters['Physical Weapon Range']);
Yanfly.Param.SelectWpn = eval(Yanfly.Param.SelectWpn);
Yanfly.Param.SelectWpnRng = String(Yanfly.Parameters['Default Weapon Range']);
Yanfly.Param.SelectWpnRng = eval(Yanfly.Param.SelectWpnRng);
Yanfly.Param.SelectAllFoes = String(Yanfly.Parameters['All Enemies']);
Yanfly.Param.SelectAllAllies = String(Yanfly.Parameters['All Allies']);
Yanfly.Param.BECEnemySelect = true;
Yanfly.Param.BECActorSelect = true;
Yanfly.Param.SelectVisualAll = String(Yanfly.Parameters['Enable Visual All']);
Yanfly.Param.SelectVisualAll = eval(Yanfly.Param.SelectVisualAll);
Yanfly.Param.SelectVisualEnemy = {
x: String(Yanfly.Parameters['Visual Enemy X']),
y: String(Yanfly.Parameters['Visual Enemy Y']),
width: String(Yanfly.Parameters['Visual Enemy Width']),
height: String(Yanfly.Parameters['Visual Enemy Height'])
}
Yanfly.Param.SelectVisualAlly = {
x: String(Yanfly.Parameters['Visual Ally X']),
y: String(Yanfly.Parameters['Visual Ally Y']),
width: String(Yanfly.Parameters['Visual Ally Width']),
height: String(Yanfly.Parameters['Visual Ally Height'])
}
//=============================================================================
// DataManager
//=============================================================================
Yanfly.Sel.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
if (!Yanfly.Sel.DataManager_isDatabaseLoaded.call(this)) return false;
if (!Yanfly._loaded_YEP_X_SelectionControl) {
this.processSelectNotetagsI($dataItems);
this.processSelectNotetagsS($dataSkills);
this.processSelectNotetagsT($dataStates);
this.processSelectNotetagsSys($dataSystem);
this.processSelectNotetags1($dataSkills, true);
this.processSelectNotetags1($dataItems, false);
this.processSelectNotetags2($dataActors);
this.processSelectNotetags2($dataClasses);
this.processSelectNotetags2($dataEnemies);
this.processSelectNotetags2($dataWeapons);
this.processSelectNotetags2($dataArmors);
this.processSelectNotetags2($dataStates);
this.processSelectNotetags3($dataWeapons);
this.processSelectNotetags3($dataEnemies);
Yanfly._loaded_YEP_X_SelectionControl = true;
}
return true;
};
DataManager.processSelectNotetagsI = function(group) {
if (Yanfly.ItemIdRef) return;
Yanfly.ItemIdRef = {};
for (var n = 1; n < group.length; n++) {
var obj = group[n];
if (obj.name.length <= 0) continue;
Yanfly.ItemIdRef[obj.name.toUpperCase()] = n;
}
};
DataManager.processSelectNotetagsS = function(group) {
if (Yanfly.SkillIdRef) return;
Yanfly.SkillIdRef = {};
for (var n = 1; n < group.length; n++) {
var obj = group[n];
if (obj.name.length <= 0) continue;
Yanfly.SkillIdRef[obj.name.toUpperCase()] = n;
}
};
DataManager.processSelectNotetagsT = function(group) {
if (Yanfly.StateIdRef) return;
Yanfly.StateIdRef = {};
for (var n = 1; n < group.length; n++) {
var obj = group[n];
if (obj.name.length <= 0) continue;
Yanfly.StateIdRef[obj.name.toUpperCase()] = n;
}
};
DataManager.processSelectNotetagsSys = function(group) {
Yanfly.STypeIdRef = {};
for (var i = 1; i < group.skillTypes.length; ++i) {
var name = group.skillTypes[i].toUpperCase();
name = name.replace(/\\I\[(\d+)\]/gi, '');
Yanfly.STypeIdRef[name] = i;
}
Yanfly.ElementIdRef = {};
for (var i = 1; i < group.elements.length; ++i) {
var name = group.elements[i].toUpperCase();
name = name.replace(/\\I\[(\d+)\]/gi, '');
Yanfly.ElementIdRef[name] = i;
}
};
DataManager.processSelectNotetags1 = function(group, isSkill) {
for (var n = 1; n < group.length; n++) {
var obj = group[n];
var notedata = obj.note.split(/[\r\n]+/);
obj.selectConditions = [];
var changed = false;
var evalMode = 'none';
obj.selectConditionEval = '';
for (var i = 0; i < notedata.length; i++) {
var line = notedata[i];
if (line.match(/<(?:SELECT CONDITION|SELECT CONDITIONS)>/i)) {
evalMode = 'select conditions';
obj.selectConditions = [];
changed = true;
} else if (line.match(/<\/(?:SELECT CONDITION|SELECT CONDITIONS)>/i)) {
evalMode = 'none';
} else if (evalMode === 'select conditions') {
obj.selectConditions.push(line.trim());
} else if (line.match(/<CUSTOM SELECT CONDITION>/i)) {
evalMode = 'custom select condition';
} else if (line.match(/<\/CUSTOM SELECT CONDITION>/i)) {
evalMode = 'none';
} else if (evalMode === 'custom select condition') {
obj.selectConditionEval += line + '\n';
}
}
for (var i = 0; i < notedata.length; i++) {
var line = notedata[i];
if (line.match(/<SINGLE OR MULTIPLE SELECT>/i)) {
obj.selectConditions.push('SINGLE OR MULTIPLE SELECT');
changed = true;
} else if (line.match(/<DISPERSE DAMAGE>/i)) {
obj.selectConditions.push('DISPERSE DAMAGE SELECT');
changed = true;
} else if (line.match(/<ENEMY OR ACTOR SELECT>/i)) {
obj.selectConditions.push('ENEMY OR ACTOR SELECT');
obj.scope = 1;
changed = true;
} else if (line.match(/<ACTOR OR ENEMY SELECT>/i)) {
obj.selectConditions.push('ACTOR OR ENEMY SELECT');
obj.scope = 7;
changed = true;
} else if (line.match(/<(?:WEAPON RANGE|WEAPON RANGED)>/i)) {
obj.selectConditions.push('WEAPON RANGE');
changed = true;
}
}
if (!changed) {
if (isSkill && obj.hitType === Game_Action.HITTYPE_MAGICAL) {
if (Yanfly.Param.SelectSoleMulti && [1, 7].contains(obj.scope)) {
obj.selectConditions.push('SINGLE OR MULTIPLE SELECT');
}
} else if (isSkill && obj.hitType === Game_Action.HITTYPE_PHYSICAL) {
if (Yanfly.Param.SelectMelee && [1].contains(obj.scope)) {
obj.selectConditions.push('FRONT ROW ONLY');
} else if (Yanfly.Param.SelectWpn && [1].contains(obj.scope)) {
obj.selectConditions.push('WEAPON RANGE');
}
}
if (Yanfly.Param.SelectActorEnemy) {
if (obj.scope === 1) obj.selectConditions.push('ENEMY OR ACTOR SELECT');
if (obj.scope === 7) obj.selectConditions.push('ACTOR OR ENEMY SELECT');
}
if (Yanfly.Param.SelectDisperse) {
obj.selectConditions.push('DISPERSE DAMAGE SELECT');
}
}
this.removeAoeEffects(obj);
}
};
DataManager.removeAoeEffects = function(obj) {
if (obj.selectConditions.contains('SINGLE OR MULTIPLE SELECT')) {
obj.aoeCircleRadius = 0;
obj.aoeRectColumn = 0;
obj.aoeRectRow = 0;
obj.aoeRectAll = false;
}
};
DataManager.processSelectNotetags2 = function(group) {
for (var n = 1; n < group.length; n++) {
var obj = group[n];
var notedata = obj.note.split(/[\r\n]+/);
obj.cannotSelect = [];
for (var i = 0; i < notedata.length; i++) {
var line = notedata[i];
if (line.match(/<CANNOT SELECT:[ ](.*)>/i)) {
var text = String(RegExp.$1).trim();
obj.cannotSelect.push(text);
}
}
}
};
DataManager.processSelectNotetags3 = function(group) {
for (var n = 1; n < group.length; n++) {
var obj = group[n];
var notedata = obj.note.split(/[\r\n]+/);
obj.weaponRanged = Yanfly.Param.SelectWpnRng;
for (var i = 0; i < notedata.length; i++) {
var line = notedata[i];
if (line.match(/<MELEE>/i)) {
obj.weaponRanged = false;
} else if (line.match(/<(?:RANGE|RANGED)>/i)) {
obj.weaponRanged = true;
}
}
}
};
//=============================================================================
// BattleManager
//=============================================================================
Yanfly.Sel.BattleManager_makeActionTargets = BattleManager.makeActionTargets;
BattleManager.makeActionTargets = function(string) {
this._action.bypassForceSelectedUnit(true);
var targets = Yanfly.Sel.BattleManager_makeActionTargets.call(this, string);
this._action.bypassForceSelectedUnit(false);
return targets;
};
if (Imported.YEP_X_BattleSysCTB) {
Yanfly.Sel.BattleManager_ctbTurnOrder = BattleManager.ctbTurnOrder;
BattleManager.ctbTurnOrder = function() {
$gameTemp._checkAllAliveMembers = true;
var battlers = Yanfly.Sel.BattleManager_ctbTurnOrder.call(this);
$gameTemp._checkAllAliveMembers = undefined;
return battlers;
};
}; // Imported.YEP_X_BattleSysCTB
//=============================================================================
// Game_Temp
//=============================================================================
Game_Temp.prototype.clearSelectionControlCache = function() {
this._selectionControlItemCache = undefined;
this._selectionControlSkillCache = undefined;
};
Game_Temp.prototype.isSelectionControlCached = function(item) {
var id = item.id;
if (DataManager.isItem) {
if (this._selectionControlItemCache === undefined) return false;
return this._selectionControlItemCache[id] !== undefined;
} else {
if (this._selectionControlSkillCache === undefined) return false;
return this._selectionControlSkillCache[id] !== undefined;
}
};
Game_Temp.prototype.getSelectionControlCache = function(item) {
var id = item.id;
if (DataManager.isItem) {
this._selectionControlItemCache = this._selectionControlItemCache || {};
return this._selectionControlItemCache[id];
} else {
this._selectionControlSkillCache = this._selectionControlSkillCache || {};
return this._selectionControlSkillCache[id];
}
};
Game_Temp.prototype.setSelectionControlCache = function(item, value) {
var id = item.id;
if (DataManager.isItem) {
this._selectionControlItemCache = this._selectionControlItemCache || {};
this._selectionControlItemCache[id] = value;
} else {
this._selectionControlSkillCache = this._selectionControlSkillCache || {};
this._selectionControlSkillCache[id] = value;
}
};
//=============================================================================
// Game_BattlerBase
//=============================================================================
Yanfly.Sel.Game_BattlerBase_refresh = Game_BattlerBase.prototype.refresh;
Game_BattlerBase.prototype.refresh = function() {
$gameTemp.clearSelectionControlCache();
Yanfly.Sel.Game_BattlerBase_refresh.call(this);
};
Yanfly.Sel.Game_BattlerBase_canUse = Game_BattlerBase.prototype.canUse;
Game_BattlerBase.prototype.canUse = function(item) {
var value = Yanfly.Sel.Game_BattlerBase_canUse.call(this, item);
if (!value) return false;
if (!$gameParty.inBattle()) return true;
return this.hasValidTargets(item);
};
Game_BattlerBase.prototype.hasValidTargets = function(item) {
if ($gameTemp.isSelectionControlCached(item)) {
return $gameTemp.getSelectionControlCache(item);
}
var action = new Game_Action(this);
action.setItemObject(item);
var targets = []
if (action.isSpanBothParties()) {
targets = targets.concat(this.friendsUnit().aliveMembers());
targets = targets.concat(this.opponentsUnit().aliveMembers());
} else if (action.isForOpponent()) {
targets = targets.concat(this.opponentsUnit().aliveMembers());
} else if (action.isForFriend()) {
targets = targets.concat(this.friendsUnit().members());
} else {
$gameTemp.setSelectionControlCache(item, true);
return true;
}
var length = targets.length;
for (var i = 0; i < length; ++i) {
var target = targets[i];
if (!target) continue;
if (action.checkAllSelectionConditions(this, target)) {
$gameTemp.setSelectionControlCache(item, true);
return true;
}
}
$gameTemp.setSelectionControlCache(item, false);
return false;
};
//=============================================================================
// Game_Battler
//=============================================================================
Yanfly.Sel.Game_Battler_isSelected = Game_Battler.prototype.isSelected;
Game_Battler.prototype.isSelected = function() {
if ($gameParty.inBattle()) {
var action = BattleManager.inputtingAction();
if (action && action.item()) {
if (!this.isSelectable(action)) return false;
};
}
return Yanfly.Sel.Game_Battler_isSelected.call(this);
};
Game_Battler.prototype.isSelectable = function(action) {
if (!action) return true;
var length = this.states().length;
for (var i = 0; i < length; ++i) {
var obj = this.states()[i];
if (!obj) continue;
if (!this.isSelectableObj(obj, action)) return false;
}
return true;
};
Game_Battler.prototype.isSelectableObj = function(obj, action) {
var array = obj.cannotSelect;
var length = array.length;
for (var i = 0; i < length; ++i) {
var line = array[i];
if (!this.checkActionSelectable(line, action)) return false;
}
return true;
};
Game_Battler.prototype.checkActionSelectable = function(line, action) {
if (action.isForUser()) return true;
// ALL
if (line.toUpperCase() === 'ALL') return false;
// PHYSICAL HIT
if (line.toUpperCase() === 'PHYSICAL HIT') return !action.isPhysical();
// MAGICAL HIT
if (line.toUpperCase() === 'MAGICAL HIT') return !action.isMagical();
// CERTAIN HIT
if (line.toUpperCase() === 'CERTAIN HIT') return !action.isCertainHit();
// SKILLS
if (line.toUpperCase() === 'SKILLS') return !action.isSkill();
// ITEMS
if (line.toUpperCase() === 'ITEMS') return !action.isItem();
// ITEM X
if (line.match(/ITEM[ ](.*)/i)) {
if (action.isItem()) {
var text = String(RegExp.$1).toUpperCase().trim();
if (text.match(/(\d+)/i)) {
var id = parseInt(RegExp.$1);
return action.item().id !== id;
} else if (Yanfly.ItemIdRef[text]) {
var id = Yanfly.ItemIdRef[text];
return action.item().id !== id;
} else {
return true;
}
}
}
// SKILL X
if (line.match(/SKILL[ ](.*)/i)) {
if (action.isSkill()) {
var text = String(RegExp.$1).toUpperCase().trim();
if (text.match(/(\d+)/i)) {
var id = parseInt(RegExp.$1);
return action.item().id !== id;
} else if (Yanfly.SkillIdRef[text]) {
var id = Yanfly.SkillIdRef[text];
return action.item().id !== id;
} else {
return true;
}
}
}
// STYPE X
if (line.match(/STYPE[ ](.*)/i)) {
if (action.isSkill()) {
var text = String(RegExp.$1).toUpperCase().trim();
if (text.match(/(\d+)/i)) {
var id = parseInt(RegExp.$1);
return action.item().stypeId !== id;
} else if (Yanfly.STypeIdRef[text]) {
var id = Yanfly.STypeIdRef[text];
return action.item().stypeId !== id;
} else {
return true;
}
}
}
// ELEMENT X
if (line.match(/ELEMENT[ ](.*)/i)) {
var text = String(RegExp.$1).toUpperCase().trim();
if (text.match(/(\d+)/i)) {
var id = parseInt(RegExp.$1);
return action.item().damage.elementId !== id;
} else if (Yanfly.STypeIdRef[text]) {
var id = Yanfly.STypeIdRef[text];
return action.item().damage.elementId !== id;
} else {
return true;
}
}
// ALL CLEARED
return true;
};
Game_Battler.prototype.isWeaponRanged = function() {
return false;
};
Yanfly.Sel.Game_Battler_gainSilentTp = Game_Battler.prototype.gainSilentTp;
Game_Battler.prototype.gainSilentTp = function(value) {
if ($gameParty.inBattle() && $gameTemp._selectedDmgMod !== undefined) {
value = Math.floor(value * $gameTemp._selectedDmgMod);
}
Yanfly.Sel.Game_Battler_gainSilentTp.call(this, value);
};
//=============================================================================
// Game_Actor
//=============================================================================
Game_Actor.prototype.isSelectable = function(action) {
if (!Game_Battler.prototype.isSelectable.call(this, action)) return false;
var length = this.equips().length;
for (var i = 0; i < length; ++i) {
var obj = this.equips()[i];
if (!obj) continue;
if (!this.isSelectableObj(obj, action)) return false;
}
if (!this.isSelectableObj(this.actor(), action)) return false;
if (!this.isSelectableObj(this.currentClass(), action)) return false;
return true;
};
Game_Actor.prototype.isWeaponRanged = function() {
var weapons = this.weapons();
for (var i = 0; i < weapons.length; ++i) {
var weapon = weapons[i];
if (!weapon) continue;
if (weapon.weaponRanged === undefined && weapon.baseItemId) {
weapon.weaponRanged = DataManager.getBaseItem(weapon).weaponRanged;
}
if (weapon.weaponRanged) return true;
}
return false;
};
//=============================================================================
// Game_Enemy
//=============================================================================
Game_Enemy.prototype.isSelectable = function(action) {
if (!Game_Battler.prototype.isSelectable.call(this, action)) return false;
if (!this.isSelectableObj(this.enemy(), action)) return false;
return true;
};
Game_Enemy.prototype.isWeaponRanged = function() {
return this.enemy().weaponRanged;
};
//=============================================================================
// Game_Unit
//=============================================================================
Yanfly.Sel.Game_Unit_aliveMembers = Game_Unit.prototype.aliveMembers;
Game_Unit.prototype.aliveMembers = function() {
var members = Yanfly.Sel.Game_Unit_aliveMembers.call(this);
if ($gameTemp._checkAllAliveMembers) return members;
if ($gameTemp._selectionFilterInProgress) return members;
if ($gameTemp._selectionFilter) return this.filterSelection(members);
return members;
};
Yanfly.Sel.Game_Unit_deadMembers = Game_Unit.prototype.deadMembers;
Game_Unit.prototype.deadMembers = function() {
var members = Yanfly.Sel.Game_Unit_deadMembers.call(this);
if ($gameTemp._selectionFilterInProgress) return members;
if ($gameTemp._selectionFilter) return this.filterSelection(members);
return members;
};
if (!Imported.YEP_X_StateCategories) {
Yanfly.Sel.Game_Unit_isAllDead = Game_Unit.prototype.isAllDead;
Game_Unit.prototype.isAllDead = function() {
$gameTemp._checkAllAliveMembers = true;
var value = Yanfly.Sel.Game_Unit_isAllDead.call(this);
$gameTemp._checkAllAliveMembers = undefined;
return value;
};
}; // Imported.YEP_X_StateCategories
Game_Unit.prototype.filterSelection = function(members) {
$gameTemp._selectionFilterInProgress = true;
var user = $gameTemp._selectionSubject;
var action = $gameTemp._selectionAction;
var length = members.length;
var targets = [];
for (var i = 0; i < length; ++i) {
var target = members[i];
if (!target) continue;
if (action.checkAllSelectionConditions(user, target)) {
targets.push(target);
}
}
$gameTemp._selectionFilterInProgress = false;
targets = this.filterTauntMembers(user, action, targets);
return targets;
};
Game_Unit.prototype.filterTauntMembers = function(user, action, targets) {
if (!Imported.YEP_Taunt) return targets;
if (!action.isForOne()) return targets;
if (action.item().bypassTaunt) return targets;
if (user.opponentsUnit() !== this) return targets;
$gameTemp._tauntAction = action;
var tauntMembers = [];
if (action.isPhysical() && this.physicalTauntMembers().length > 0) {
if (user.ignoreTauntPhysical()) return targets;
tauntMembers = this.physicalTauntMembers();
} else if (action.isMagical() && this.magicalTauntMembers().length > 0) {
if (user.ignoreTauntMagical()) return targets;
tauntMembers = this.magicalTauntMembers();
} else if (action.isCertainHit() && this.certainTauntMembers().length > 0) {
if (user.ignoreTauntCertain()) return targets;
tauntMembers = this.certainTauntMembers();
}
var common = Yanfly.Util.getCommonElements(targets, tauntMembers);
if (common.length > 0) targets = common;
return targets;
};
//=============================================================================
// Game_Action
//=============================================================================
Yanfly.Sel.Game_Action_clear = Game_Action.prototype.clear;
Game_Action.prototype.clear = function() {
Yanfly.Sel.Game_Action_clear.call(this);
this._selectedTargetType = '';
this._selectedDmgMod = 1;
this._forcedSelectedUnit = false;
this._bypassForceSelectedUnit = false;
};
Yanfly.Sel.Game_Action_mDV = Game_Action.prototype.makeDamageValue;
Game_Action.prototype.makeDamageValue = function(target, critical) {
var value = Yanfly.Sel.Game_Action_mDV.call(this, target, critical);
if (!Imported.YEP_DamageCore) value *= this._selectedDmgMod;
return Math.round(value);
};
if (Imported.YEP_DamageCore) {
Yanfly.Sel.Game_Action_modifyBaseDamage =
Game_Action.prototype.modifyBaseDamage;
Game_Action.prototype.modifyBaseDamage = function(value, baseDamage, target) {
baseDamage = Yanfly.Sel.Game_Action_modifyBaseDamage.call(this, value,
baseDamage, target);
baseDamage *= this._selectedDmgMod;
return baseDamage;
};
}; // Imported.YEP_DamageCore
Game_Action.prototype.selectConditions = function() {
if (!this.item()) return [];
return this.item().selectConditions;
};
Game_Action.prototype.matchSelectConditions = function(line) {
var conditions = this.selectConditions().slice();
var length = conditions.length;
for (var i = 0; i < length; ++i) {
var condition = conditions[i];
if (condition.match(line)) return true;
}
return false;
};
Game_Action.prototype.isSingleOrMultiple = function() {
return this.matchSelectConditions(/SINGLE OR MULTIPLE SELECT/i);
};
Game_Action.prototype.isDisperseDamage = function() {
return this.matchSelectConditions(/DISPERSE DAMAGE SELECT/i);
};
Game_Action.prototype.isForEnemyOrActor = function() {
return this.matchSelectConditions(/ENEMY OR ACTOR SELECT/i);
};
Game_Action.prototype.isForActorOrEnemy = function() {
return this.matchSelectConditions(/ACTOR OR ENEMY SELECT/i);
};
Game_Action.prototype.isWeaponRanged = function() {
return this.matchSelectConditions(/WEAPON RANGE/i);
};
Game_Action.prototype.isNotForUser = function() {
return this.matchSelectConditions(/NOT USER/i);
};
Game_Action.prototype.isSpanBothParties = function() {
if (this.isForEnemyOrActor()) return true;
if (this.isForActorOrEnemy()) return true;
return false;
};
Yanfly.Sel.Game_Action_needsSelection = Game_Action.prototype.needsSelection;
Game_Action.prototype.needsSelection = function() {
if (this.isSingleOrMultiple()) return true;
return Yanfly.Sel.Game_Action_needsSelection.call(this);
};
Yanfly.Sel.Game_Action_setTarget = Game_Action.prototype.setTarget;
Game_Action.prototype.setTarget = function(targetIndex) {
if (typeof targetIndex === 'string') {
if (targetIndex.match(/ACTOR[ ](\d+)[ ]SELECT/i)) {
targetIndex = parseInt(RegExp.$1);
this.chooseSelectionUnit('party');
} else if (targetIndex.match(/ENEMY[ ](\d+)[ ]SELECT/i)) {
targetIndex = parseInt(RegExp.$1);
this.chooseSelectionUnit('troop');
} else {
this._selectedTargetType = targetIndex;
targetIndex = -1;
}
}
Yanfly.Sel.Game_Action_setTarget.call(this, targetIndex);
};
Game_Action.prototype.chooseSelectionUnit = function(unit) {
if (this.isForEverybody()) return;
this._forcedSelectedUnit = unit;
};
Game_Action.prototype.isForceSelectedUnit = function() {
if (this._bypassForceSelectedUnit) return false;
return this._forcedSelectedUnit;
};
Game_Action.prototype.bypassForceSelectedUnit = function(value) {
this._bypassForceSelectedUnit = value;
};
Yanfly.Sel.Game_Action_friendsUnit = Game_Action.prototype.friendsUnit;
Game_Action.prototype.friendsUnit = function() {
if (this.isForceSelectedUnit()) return this.forcedSelectedUnit();
return Yanfly.Sel.Game_Action_friendsUnit.call(this);
};
Yanfly.Sel.Game_Action_opponentsUnit = Game_Action.prototype.opponentsUnit;
Game_Action.prototype.opponentsUnit = function() {
if (this.isForceSelectedUnit()) return this.forcedSelectedUnit();
return Yanfly.Sel.Game_Action_opponentsUnit.call(this);
};
Game_Action.prototype.forcedSelectedUnit = function() {
if (this._forcedSelectedUnit === 'party') {
return $gameParty;
} else if (this._forcedSelectedUnit === 'troop') {
return $gameTroop;
} else {
return false;
}
};
Game_Action.prototype.setSelectionFilter = function(enabled) {
$gameTemp._taunt = false;
$gameTemp._selectionFilter = enabled ? true : undefined;
$gameTemp._selectionSubject = enabled ? this.subject() : undefined;
$gameTemp._selectionAction = enabled ? this : undefined;
};
Yanfly.Sel.Game_Action_makeTargets = Game_Action.prototype.makeTargets;
Game_Action.prototype.makeTargets = function() {
if ($gameParty.inBattle()) this.setSelectionFilter(true);
var targets = this.makeTargetChoices();
if ($gameParty.inBattle()) {
this.setSelectionFilter(false);
var group = this.filterSelection(this.subject(), targets);
if (group.length <= 0 && this._targetIndex >= 0) {
group = this.fallbackFilter();
}
return group;
} else {
return targets;
}
};
Yanfly.Sel.Game_Action_applyItemUserEffect =
Game_Action.prototype.applyItemUserEffect;
Game_Action.prototype.applyItemUserEffect = function(target) {
$gameTemp._selectedDmgMod = this._selectedDmgMod || 1;
Yanfly.Sel.Game_Action_applyItemUserEffect.call(this, target);
$gameTemp._selectedDmgMod = undefined;
};
Game_Action.prototype.fallbackFilter = function() {
this._targetIndex = -1;
return this.makeTargets();
};
Game_Action.prototype.makeTargetChoices = function() {
if (this._selectedTargetType === 'ALL ENEMIES') {
var targets = this.opponentsUnit().aliveMembers();
var mod = Math.max(1, targets.length);
if (this.isDisperseDamage()) this._selectedDmgMod = 1 / mod;
} else if (this._selectedTargetType === 'ALL ALLIES') {
var targets = this.friendsUnit().aliveMembers();
var mod = Math.max(1, targets.length);
if (this.isDisperseDamage()) this._selectedDmgMod = 1 / mod;
} else {
var targets = Yanfly.Sel.Game_Action_makeTargets.call(this);
}
return targets;
};
Game_Action.prototype.filterSelection = function(user, group) {
if (!$gameParty.inBattle()) return group;
var targets = [];
var length = group.length;
for (var i = 0; i < length; ++i) {
var target = group[i];
if (!target) continue;
if (this.checkAllSelectionConditions(user, target)) targets.push(target);
}
return targets;
}
Game_Action.prototype.checkAllSelectionConditions = function(user, target) {
if (!target.isSelectable(this)) return false;
var conditions = this.item().selectConditions;
var length = conditions.length;
for (var i = 0; i < length; ++i) {
var line = conditions[i];
if (!line) continue;
if (!this.meetSelectionCondition(line, user, target)) {
return false;
}
}
if (!this.meetSelectionConditionEval(user, target)) return false;
return true;
};
Game_Action.prototype.meetSelectionCondition = function(line, user, target) {
// Not User
if (line.match(/NOT USER/i)) {
return this.subject() !== target;
}
// Weapon Range - Requires YEP_RowFormation.js
if (line.match(/WEAPON RANGE/i)) {
return this.selectConditionWeaponRange(target);
}
// Back Row Only - Requires YEP_RowFormation.js
if (line.match(/BACK ROW ONLY/i)) {
return this.selectConditionBackRow(target);
}
// Front Row Only - Requires YEP_RowFormation.js
if (line.match(/FRONT ROW ONLY/i)) {
return this.selectConditionFrontRow(target);
}
// Row x Only - Requires YEP_RowFormation.js
if (line.match(/ROW[ ](\d+)[ ]ONLY/i)) {
var id = parseInt(RegExp.$1);
return this.selectConditionSpecificRow(target, id);
}
// Row x Max - Requires YEP_RowFormation.js
if (line.match(/ROW[ ](\d+)[ ]MAX/i)) {
var id = parseInt(RegExp.$1);
return this.selectConditionRowMax(target, id);
}
// Row x Min - Requires YEP_RowFormation.js
if (line.match(/ROW[ ](\d+)[ ]MIN/i)) {
var id = parseInt(RegExp.$1);
return this.selectConditionRowMin(target, id);
}
// Parameter Eval
if (line.match(/PARAM[ ](.*?)[ ](.*)/i)) {
var param = String(RegExp.$1).toUpperCase().trim();
var code = String(RegExp.$2).trim();
return this.selectConditionParam(user, target, param, code);
}
// Not State
if (line.match(/NOT STATE:[ ](.*)/i)) {
var text = String(RegExp.$1).toUpperCase().trim();
return this.selectConditionNotState(target, text);
}
// State
if (line.match(/STATE:[ ](.*)/i)) {
var text = String(RegExp.$1).toUpperCase().trim();
return this.selectConditionState(target, text);
}
return true;
};
Game_Action.prototype.meetSelectionConditionEval = function(user, target) {
if (this.item().selectConditionEval === '') return true;
var condition = true;
var item = this.item();
var skill = this.item();
var a = user;
var subject = user;
var b = target;
var s = $gameSwitches._data;
var v = $gameVariables._data;
var code = this.item().selectConditionEval;
try {
eval(code);
} catch (e) {
Yanfly.Util.displayError(e, code, 'SELECTION CONDITION EVAL');
}
return condition;
};
Game_Action.prototype.selectConditionWeaponRange = function(target) {
if (!Imported.YEP_RowFormation) return true;
if (this.subject().isWeaponRanged()) {
return true;
} else {
return this.selectConditionFrontRow(target);
}
};
Game_Action.prototype.selectConditionBackRow = function(target) {
if (!Imported.YEP_RowFormation) return true;
if (target.isActor() === this.subject().isActor()) return true;
var unit = target.friendsUnit();
for (var i = Yanfly.Param.RowMaximum; i > 0; --i) {
if (unit.rowAliveSize(i) <= 0) continue;
return unit.rowMembers(i).contains(target);
}
return true;
};
Game_Action.prototype.selectConditionFrontRow = function(target) {
if (!Imported.YEP_RowFormation) return true;
if (target.isActor() === this.subject().isActor()) return true;
var length = Yanfly.Param.RowMaximum + 1;
var unit = target.friendsUnit();
for (var i = 1; i < length; ++i) {
if (unit.rowAliveSize(i) <= 0) continue;
return unit.rowMembers(i).contains(target);
}
return true;
};
Game_Action.prototype.selectConditionSpecificRow = function(target, rowId) {
if (!Imported.YEP_RowFormation) return true;
if (target.isActor() === this.subject().isActor()) return true;
return target.row() === rowId;
};
Game_Action.prototype.selectConditionRowMax = function(target, rowId) {
if (!Imported.YEP_RowFormation) return true;
if (target.isActor() === this.subject().isActor()) return true;
return target.row() <= rowId;
};
Game_Action.prototype.selectConditionRowMin = function(target, rowId) {
if (!Imported.YEP_RowFormation) return true;
if (target.isActor() === this.subject().isActor()) return true;
return target.row() >= rowId;
};
Game_Action.prototype.selectConditionParam = function(user, target, param, code) {
if (['MAXHP', 'MHP'].contains(param)) {
code = 'target.mhp ' + code;
} else if (['MAXMP', 'MMP'].contains(param)) {
code = 'target.mmp ' + code;
} else if (['MAXTP', 'MTP'].contains(param)) {
code = 'target.maxTp() ' + code;
} else if (['HP'].contains(param)) {
code = 'target.hp ' + code;
} else if (['MP'].contains(param)) {
code = 'target.mp ' + code;
} else if (['TP'].contains(param)) {
code = 'target.tp ' + code;
} else if (['ATK', 'STR'].contains(param)) {
code = 'target.atk ' + code;
} else if (['DEF'].contains(param)) {
code = 'target.def ' + code;
} else if (['MAT', 'INT', 'SPI'].contains(param)) {
code = 'target.mat ' + code;
} else if (['MDF', 'RES'].contains(param)) {
code = 'target.mdf ' + code;
} else if (['AGI'].contains(param)) {
code = 'target.agi ' + code;
} else if (['LUK'].contains(param)) {
code = 'target.luk ' + code;
} else if (['LEVEL'].contains(param)) {
code = 'target.level ' + code;
} else if (['HP%'].contains(param)) {
code = 'target.hpRate() ' + code;
} else if (['MP%'].contains(param)) {
code = 'target.mpRate() ' + code;
} else if (['TP%'].contains(param)) {
code = 'target.tpRate() ' + code;
} else {
return;
}
var item = this.item();
var skill = this.item();
var a = user;
var subject = user;
var b = target;
var s = $gameSwitches._data;
var v = $gameVariables._data;
try {
eval(code);
} catch (e) {
Yanfly.Util.displayError(e, code, 'SELECTION PARAM CONDITION ERROR');
return false;
}
};
Game_Action.prototype.selectConditionNotState = function(target, text) {
if (text.match(/(\d+)/i)) {
var id = parseInt(RegExp.$1);
} else if (Yanfly.StateIdRef[text]) {
var id = Yanfly.StateIdRef[text];
} else {
return false;
}
var state = $dataStates[id];
if (!state) return false;
return !target.states().contains(state);
};
Game_Action.prototype.selectConditionState = function(target, text) {
if (text.match(/(\d+)/i)) {
var id = parseInt(RegExp.$1);
} else if (Yanfly.StateIdRef[text]) {
var id = Yanfly.StateIdRef[text];
} else {
return false;
}
var state = $dataStates[id];
if (!state) return false;
return target.states().contains(state);
};
//=============================================================================
// Window_Help
//=============================================================================
Yanfly.Sel.Window_Help_setBattler = Window_Help.prototype.setBattler;
Window_Help.prototype.setBattler = function(battler) {
if (typeof battler === 'string') return this.drawSelectionControl(battler);
Yanfly.Sel.Window_Help_setBattler.call(this, battler);
};
Window_Help.prototype.drawSelectionControl = function(battler) {
this.contents.clear();
this.clear();
var wx = 0;
var wy = (this.contents.height - this.lineHeight()) / 2;
var text = '';
if (battler === 'ALL ENEMIES') text = Yanfly.Param.SelectAllFoes;
if (battler === 'ALL ALLIES') text = Yanfly.Param.SelectAllAllies;
this.drawText(text, wx, wy, this.contents.width, 'center');
};
//=============================================================================
// Window_BattleEnemy
//=============================================================================
Window_BattleEnemy.prototype.action = function() {
return BattleManager.inputtingAction();
};
Window_BattleEnemy.prototype.actorWindow = function() {
return SceneManager._scene._statusWindow;
};
Yanfly.Sel.Window_BattleEnemy_allowedTargets =
Window_BattleEnemy.prototype.allowedTargets;
Window_BattleEnemy.prototype.allowedTargets = function() {
this._inputLock = false;
this._selectDead = false;
if (!this.action()) return [];
if (!this.action().item()) return [];
var targets = [];
this.action().setSelectionFilter(true);
if (this.action().isSpanBothParties()) {
targets = targets.concat($gameTroop.aliveMembers());
targets = targets.concat($gameParty.members());
} else if (this.action().isForOpponent()) {
targets = targets.concat($gameTroop.aliveMembers());
} else {
targets = targets.concat($gameParty.members());
}
this.action().setSelectionFilter(false);
targets = this.action().filterSelection(this.action().subject(), targets);
return targets;
};
Window_BattleEnemy.prototype.sortTargets = function() {
this._enemies.sort(function(a, b) {
if (a.spritePosX() === b.spritePosX()) {
return a.spritePosY() - b.spritePosY();
}
return a.spritePosX() - b.spritePosX();
});
if (this.action()) this.addExtraSelectTargets();
};
Yanfly.Sel.Window_BattleEnemy_autoSelect =
Window_BattleEnemy.prototype.autoSelect;
Window_BattleEnemy.prototype.autoSelect = function() {
if (this.action().isForOpponent()) {
Yanfly.Sel.Window_BattleEnemy_autoSelect.call(this);
} else {
this.actorAutoSelect();
}
};
Window_BattleEnemy.prototype.actorAutoSelect = function() {
if (!this.action()) return this.select(0);
var index = 0;
this._inputLock = false;
this._selectDead = false;
if (this.action().isForUser()) {
index = this._enemies.indexOf(BattleManager.actor());
this._inputLock = true;
} else if (this.action().isForDeadFriend()) {
this._selectDead = true;
index = this.autoSelectFirstDeadActor();
if (this.action().isForAll()) this._inputLock = true;
} else {
var length = this._enemies.length;
for (var i = 0; i < length; ++i) {
var member = this._enemies[i];
if (typeof member === 'string') continue;
if (member && member.isActor()) {
index = i;
break;
}
}
}
this.select(index);
};
Window_BattleEnemy.prototype.autoSelectFirstDeadActor = function() {
var length = this._enemies.length;
for (var i = 0; i < length; ++i) {
var member = this._enemies[i];
if (member && member.isActor() && member.isDead()) return i;
}
return 0;
};
Window_BattleEnemy.prototype.furthestRight = function() {
var index = -1;
var length = this._enemies.length;
for (var i = 0; i < length; ++i) {
var target = this._enemies[i];
if (!target) continue;
if (typeof target === 'string') {
continue;
} else if (target && target.isEnemy()) {
index = i;
}
}
return Math.max(0, index);
};
Window_BattleEnemy.prototype.isOkEnabled = function() {
if (this._selectDead) return this.enemy().isDead();
return Window_Selectable.prototype.isOkEnabled.call(this);
};
Window_BattleEnemy.prototype.addExtraSelectTargets = function() {
var action = this.action();
if (action.isSingleOrMultiple()) {
var enemyCount = 0;
var allyCount = 0;
var length = this._enemies.length;
for (var i = 0; i < length; ++i) {
var target = this._enemies[i];
if (!target) continue;
if (target.isEnemy()) enemyCount += 1;
if (target.isActor()) allyCount += 1;
}
if (enemyCount > 1) {
var add = true;
if (Imported.YEP_Taunt) {
var unit = $gameTroop;
if (action.isPhysical() &&
unit.physicalTauntMembers().length > 1) {
add = false;
} else if (action.isMagical() &&
unit.magicalTauntMembers().length > 1) {
add = false;
} else if (action.isCertainHit() &&
unit.certainTauntMembers().length > 1) {
add = false;
}
}
if (add) this._enemies.unshift('ALL ENEMIES');
}
if (allyCount > 1) {
this._enemies.push('ALL ALLIES');
}
}
};
Yanfly.Sel.Window_BattleEnemy_isMouseOverEnemy =
Window_BattleEnemy.prototype.isMouseOverEnemy;
Window_BattleEnemy.prototype.isMouseOverEnemy = function(enemy) {
if (typeof enemy === 'string') return false;
return Yanfly.Sel.Window_BattleEnemy_isMouseOverEnemy.call(this, enemy);
};
Yanfly.Sel.Window_BattleEnemy_isClickedEnemy =
Window_BattleEnemy.prototype.isClickedEnemy;
Window_BattleEnemy.prototype.isClickedEnemy = function(enemy) {
if (typeof enemy === 'string') return false;
return Yanfly.Sel.Window_BattleEnemy_isClickedEnemy.call(this, enemy);
};
Yanfly.Sel.Window_BattleEnemy_hide = Window_BattleEnemy.prototype.hide;
Window_BattleEnemy.prototype.hide = function() {
Yanfly.Sel.Window_BattleEnemy_hide.call(this);
$gameParty.select(null);
if (BattleManager.actor()) {
this.actorWindow().select(BattleManager.actor().index());
}
};
Yanfly.Sel.Window_BattleEnemy_select =
Window_BattleEnemy.prototype.select;
Window_BattleEnemy.prototype.select = function(index) {
$gameTroop.select(null);
$gameParty.select(null);
Yanfly.Sel.Window_BattleEnemy_select.call(this, index);
if (this.enemy() === 'ALL ENEMIES') {
var length = this._enemies.length;
for (var i = 0; i < length; ++i) {
var target = this._enemies[i];
if (!target) continue;
if (typeof target === 'string') continue;
if (target.isEnemy()) target.select();
}
} else if (this.enemy() === 'ALL ALLIES') {
var length = this._enemies.length;
for (var i = 0; i < length; ++i) {
var target = this._enemies[i];
if (!target) continue;
if (typeof target === 'string') continue;
if (target.isActor()) target.select();
}
} else if (this.enemy() && this.enemy().isActor()) {
$gameParty.select(this.enemy());
this.actorWindow().select(this.enemy().index());
}
};
Yanfly.Sel.Window_BattleEnemy_enemyIndex =
Window_BattleEnemy.prototype.enemyIndex;
Window_BattleEnemy.prototype.enemyIndex = function() {
if (typeof this.enemy() === 'string') return this.enemy();
if (this.action().isSpanBothParties()) {
var index = this.enemy().index();
if (this.enemy().isActor()) return 'ACTOR ' + index + ' SELECT';
if (this.enemy().isEnemy()) return 'ENEMY ' + index + ' SELECT';
}
return Yanfly.Sel.Window_BattleEnemy_enemyIndex.call(this);
};
//=============================================================================
// Window_BattleStatus
//=============================================================================
Window_BattleStatus.prototype.setEnemySelectionWindow = function(win) {
this._enemySelectWindow = win;
};
Yanfly.Sel.Window_BattleStatus_update = Window_BattleStatus.prototype.update;
Window_BattleStatus.prototype.update = function() {
Yanfly.Sel.Window_BattleStatus_update.call(this);
this.processInactiveSelectTouch();
};
Window_BattleStatus.prototype.processInactiveSelectTouch = function() {
if (!this._enemySelectWindow) return;
if (!this._enemySelectWindow.active) return;
if (TouchInput.isTriggered() && this.isTouchedInsideFrame()) {
this.onInactiveSelectTouch();
}
};
Window_BattleStatus.prototype.onInactiveSelectTouch = function() {
var lastIndex = this.index();
var x = this.canvasToLocalX(TouchInput.x);
var y = this.canvasToLocalY(TouchInput.y);
var hitIndex = this.hitTest(x, y);
if (hitIndex >= 0) {
var actor = $gameParty.battleMembers()[hitIndex];
var win = this._enemySelectWindow;
if (actor && win) {
var winIndex = win._enemies.indexOf(actor);
if (winIndex >= 0) {
if (winIndex !== win.index()) {
win.select(winIndex);
SoundManager.playCursor();
} else {
win.processOk();
}
}
}
}
};
//=============================================================================
// Window_VisualSelectAll
//=============================================================================
function Window_VisualSelectAll() {
this.initialize.apply(this, arguments);
}
Window_VisualSelectAll.prototype = Object.create(Window_Base.prototype);
Window_VisualSelectAll.prototype.constructor = Window_VisualSelectAll;
Window_VisualSelectAll.prototype.initialize = function(actor) {
this._isActorSelect = actor;
if (this._isActorSelect) {
this._text = Yanfly.Param.SelectAllAllies;
var settings = Yanfly.Param.SelectVisualAlly;
} else {
this._text = Yanfly.Param.SelectAllFoes;
var settings = Yanfly.Param.SelectVisualEnemy;
}
var width = eval(settings.width);
var height = eval(settings.height);
var x = eval(settings.x);
var y = eval(settings.y);
Window_Base.prototype.initialize.call(this, x, y, width, height);
this.hide();
this.refresh();
};
Window_VisualSelectAll.prototype.refresh = function() {
this.contents.clear();
this.drawText(this._text, 0, 0, this.contents.width, 'center');
};
Window_VisualSelectAll.prototype.setEnemySelectionWindow = function(win) {
this._enemySelectWindow = win;
};
Window_VisualSelectAll.prototype.update = function() {
Window_Base.prototype.update.call(this);
this.updateVisible();
this.processMouseOver();
this.processTouch();
};
Window_VisualSelectAll.prototype.updateVisible = function() {
if (!this._enemySelectWindow) return this.visible = false;
if (!this._enemySelectWindow.active) return this.visible = false;
if (this._isActorSelect) {
var index = this._enemySelectWindow._enemies.indexOf('ALL ALLIES');
} else {
var index = this._enemySelectWindow._enemies.indexOf('ALL ENEMIES');
}
this.visible = index >= 0;
};
Window_VisualSelectAll.prototype.processMouseOver = function() {
if (!this.visible) return $gameTemp._disableMouseOverSelect = false;;
var x = this.canvasToLocalX(TouchInput._mouseOverX);
var y = this.canvasToLocalY(TouchInput._mouseOverY);
var inside = x >= 0 && y >= 0 && x < this.width && y < this.height;
if (inside) {
if (this._isActorSelect) {
var index = this._enemySelectWindow._enemies.indexOf('ALL ALLIES');
} else {
var index = this._enemySelectWindow._enemies.indexOf('ALL ENEMIES');
}
if (index !== this._enemySelectWindow.index()) SoundManager.playCursor();
this._enemySelectWindow.select(index);
$gameTemp._disableMouseOverSelect = true;
} else {
$gameTemp._disableMouseOverSelect = false;
}
};
Window_VisualSelectAll.prototype.processTouch = function() {
if (!this.visible) return;
if (!TouchInput.isTriggered()) return;
var x = this.canvasToLocalX(TouchInput._mouseOverX);
var y = this.canvasToLocalY(TouchInput._mouseOverY);
var inside = x >= 0 && y >= 0 && x < this.width && y < this.height;
if (inside) {
this._enemySelectWindow.processOk();
}
};
//=============================================================================
// Scene_Battle
//=============================================================================
Scene_Battle.prototype.selectActorSelection = function() {
this.selectEnemySelection();
};
Yanfly.Sel.Scene_Battle_createEnemyWindow =
Scene_Battle.prototype.createEnemyWindow;
Scene_Battle.prototype.createEnemyWindow = function() {
Yanfly.Sel.Scene_Battle_createEnemyWindow.call(this);
this._statusWindow.setEnemySelectionWindow(this._enemyWindow);
if (!Yanfly.Param.SelectVisualAll) return;
this._visualSelectAllyWindow = new Window_VisualSelectAll(true);
this._visualSelectAllyWindow.setEnemySelectionWindow(this._enemyWindow);
this.addChild(this._visualSelectAllyWindow);
this._visualSelectEnemyWindow = new Window_VisualSelectAll(false);
this._visualSelectEnemyWindow.setEnemySelectionWindow(this._enemyWindow);
this.addChild(this._visualSelectEnemyWindow);
};
//=============================================================================
// Utilities
//=============================================================================
Yanfly.Util = Yanfly.Util || {};
Yanfly.Util.getCommonElements = function(array1, array2) {
var elements = [];
var length = array1.length;
for (var i = 0; i < length; ++i) {
var element = array1[i];
if (array2.contains(element)) elements.push(element);
}
return elements;
};
Yanfly.Util.displayError = function(e, code, message) {
console.log(message);
console.log(code || 'NON-EXISTENT');
console.error(e);
if (Utils.isNwjs() && Utils.isOptionValid('test')) {
if (!require('nw.gui').Window.get().isDevToolsOpen()) {
require('nw.gui').Window.get().showDevTools();
}
}
};
//=============================================================================
// End of File
//=============================================================================
}; // Imported.YEP_BattleEngineCore && Imported.YEP_TargetCore