//-----------------------------------------------------------------------------
// Game_Actor
//
// The game object class for an actor.
/**
* The game object class for an actor.
*
* @class
* @extends Game_Battler
* @property {number} level - The actor's level
*/
function Game_Actor() {
this.initialize(...arguments);
}
Game_Actor.prototype = Object.create(Game_Battler.prototype);
Game_Actor.prototype.constructor = Game_Actor;
Object.defineProperty(Game_Actor.prototype, "level", {
get: function() {
return this._level;
},
configurable: true
});
/**
* Initialize the actor
*
* @param {number} actorId - The actor's id
*/
Game_Actor.prototype.initialize = function(actorId) {
Game_Battler.prototype.initialize.call(this);
this.setup(actorId);
};
Game_Actor.prototype.initMembers = function() {
Game_Battler.prototype.initMembers.call(this);
this._actorId = 0;
this._name = "";
this._nickname = "";
this._classId = 0;
this._level = 0;
this._characterName = "";
this._characterIndex = 0;
this._faceName = "";
this._faceIndex = 0;
this._battlerName = "";
this._exp = {};
this._skills = [];
this._equips = [];
this._actionInputIndex = 0;
this._lastMenuSkill = new Game_Item();
this._lastBattleSkill = new Game_Item();
this._lastCommandSymbol = "";
};
/**
* Set up the actor
*
* @param {number} actorId - The actor's id
*/
Game_Actor.prototype.setup = function(actorId) {
const actor = $dataActors[actorId];
this._actorId = actorId;
this._name = actor.name;
this._nickname = actor.nickname;
this._profile = actor.profile;
this._classId = actor.classId;
this._level = actor.initialLevel;
this.initImages();
this.initExp();
this.initSkills();
this.initEquips(actor.equips);
this.clearParamPlus();
this.recoverAll();
};
/**
* Get the actor's id
*
* @return {number} The actor's id
*/
Game_Actor.prototype.actorId = function() {
return this._actorId;
};
/**
* Get the actor data object
*
* @return {Object} The actor data object
*/
Game_Actor.prototype.actor = function() {
return $dataActors[this._actorId];
};
/**
* Get the actor's name
*
* @return {string} The actor's name
*/
Game_Actor.prototype.name = function() {
return this._name;
};
/**
* Set the actor's name
*
* @param {string} name - The actor's new name
*/
Game_Actor.prototype.setName = function(name) {
this._name = name;
};
/**
* Get the actor's nickname
*
* @return {string} The actor's nickname
*/
Game_Actor.prototype.nickname = function() {
return this._nickname;
};
/**
* Set the actor's nickname
*
* @param {string} nickname - The actor's new nickname
*/
Game_Actor.prototype.setNickname = function(nickname) {
this._nickname = nickname;
};
/**
* Get the actor's profile
*
* @return {string} The actor's profile
*/
Game_Actor.prototype.profile = function() {
return this._profile;
};
/**
* Set the actor's profile
*
* @param {string} profile - The actor's new profile
*/
Game_Actor.prototype.setProfile = function(profile) {
this._profile = profile;
};
/**
* Get the actor's character name (for their character sheet)
*
* @return {string} The actor's character name
*/
Game_Actor.prototype.characterName = function() {
return this._characterName;
};
/**
* Get the actor's character index (on their character sheet)
*
* @return {number} The actor's character index
*/
Game_Actor.prototype.characterIndex = function() {
return this._characterIndex;
};
/**
* Get the actor's face name (for their face sheet)
*
* @return {string} The actor's face name
*/
Game_Actor.prototype.faceName = function() {
return this._faceName;
};
/**
* Get the actor's face index (on their face sheet)
*
* @return {number} The actor's face index
*/
Game_Actor.prototype.faceIndex = function() {
return this._faceIndex;
};
/**
* Get the actor's battler name (for their battler image)
*
* @return {string} The actor's battler name
*/
Game_Actor.prototype.battlerName = function() {
return this._battlerName;
};
Game_Actor.prototype.clearStates = function() {
Game_Battler.prototype.clearStates.call(this);
this._stateSteps = {};
};
Game_Actor.prototype.eraseState = function(stateId) {
Game_Battler.prototype.eraseState.call(this, stateId);
delete this._stateSteps[stateId];
};
Game_Actor.prototype.resetStateCounts = function(stateId) {
Game_Battler.prototype.resetStateCounts.call(this, stateId);
this._stateSteps[stateId] = $dataStates[stateId].stepsToRemove;
};
/**
* Initialize the actor's image data
*/
Game_Actor.prototype.initImages = function() {
const actor = this.actor();
this._characterName = actor.characterName;
this._characterIndex = actor.characterIndex;
this._faceName = actor.faceName;
this._faceIndex = actor.faceIndex;
this._battlerName = actor.battlerName;
};
/**
* Get the exp needed for a given level
*
* @param {number} level - The level to calculate exp for
* @return {number} The exp needed
*/
Game_Actor.prototype.expForLevel = function(level) {
const c = this.currentClass();
const basis = c.expParams[0];
const extra = c.expParams[1];
const acc_a = c.expParams[2];
const acc_b = c.expParams[3];
return Math.round(
(basis * Math.pow(level - 1, 0.9 + acc_a / 250) * level * (level + 1)) /
(6 + Math.pow(level, 2) / 50 / acc_b) +
(level - 1) * extra
);
};
/**
* Initialize the actor's exp
*/
Game_Actor.prototype.initExp = function() {
this._exp[this._classId] = this.currentLevelExp();
};
/**
* Get the actor's current exp
*
* @return {number} The actor's current exp
*/
Game_Actor.prototype.currentExp = function() {
return this._exp[this._classId];
};
/**
* Get the exp needed for the actor's current level
*
* @return {number} The exp needed for the actor's current level
*/
Game_Actor.prototype.currentLevelExp = function() {
return this.expForLevel(this._level);
};
/**
* Get the exp needed for the actor's next level
*
* @return {number} The exp needed for the actor's next level
*/
Game_Actor.prototype.nextLevelExp = function() {
return this.expForLevel(this._level + 1);
};
/**
* Get the exp needed to level up from the actor's current exp
*
* @return {number} The exp needed to level up
*/
Game_Actor.prototype.nextRequiredExp = function() {
return this.nextLevelExp() - this.currentExp();
};
/**
* Get the actor's max level
*
* @return {number} The actor's max level
*/
Game_Actor.prototype.maxLevel = function() {
return this.actor().maxLevel;
};
/**
* Check if the actor is max level
*
* @return {boolean} True if max level
*/
Game_Actor.prototype.isMaxLevel = function() {
return this._level >= this.maxLevel();
};
/**
* Initialize the actor's skills
*/
Game_Actor.prototype.initSkills = function() {
this._skills = [];
for (const learning of this.currentClass().learnings) {
if (learning.level <= this._level) {
this.learnSkill(learning.skillId);
}
}
};
/**
* Initialize the actor's equipment
*
* @param {Array} equips - Array of equipment ids for each equip slot
*/
Game_Actor.prototype.initEquips = function(equips) {
const slots = this.equipSlots();
const maxSlots = slots.length;
this._equips = [];
for (let i = 0; i < maxSlots; i++) {
this._equips[i] = new Game_Item();
}
for (let j = 0; j < equips.length; j++) {
if (j < maxSlots) {
this._equips[j].setEquip(slots[j] === 1, equips[j]);
}
}
this.releaseUnequippableItems(true);
this.refresh();
};
/**
* Get the actor's equip slots
*
* @return {Array} Array of equipment slots
*/
Game_Actor.prototype.equipSlots = function() {
const slots = [];
for (let i = 1; i < $dataSystem.equipTypes.length; i++) {
slots.push(i);
}
if (slots.length >= 2 && this.isDualWield()) {
slots[1] = 1;
}
return slots;
};
/**
* Get the actor's equips
*
* @return {Array} Array of equipped items
*/
Game_Actor.prototype.equips = function() {
return this._equips.map(item => item.object());
};
/**
* Get the actor's weapons
*
* @return {Array} Array of equipped weapons
*/
Game_Actor.prototype.weapons = function() {
return this.equips().filter(item => item && DataManager.isWeapon(item));
};
/**
* Get the actor's armors
*
* @return {Array} Array of equipped armors
*/
Game_Actor.prototype.armors = function() {
return this.equips().filter(item => item && DataManager.isArmor(item));
};
/**
* Check if the actor has the given weapon
*
* @param {Object} weapon - The weapon data object
* @return {boolean} True if the actor has the weapon
*/
Game_Actor.prototype.hasWeapon = function(weapon) {
return this.weapons().includes(weapon);
};
/**
* Check if the actor has the given armor
*
* @param {Object} armor - The armor data object
* @return {boolean} True if the actor has the armor
*/
Game_Actor.prototype.hasArmor = function(armor) {
return this.armors().includes(armor);
};
/**
* Check if the actor can change equips in the given slot
*
* @param {number} slotId - The equipment slot id
* @return {boolean} True if the actor can change the equip in the slot
*/
Game_Actor.prototype.isEquipChangeOk = function(slotId) {
return (
!this.isEquipTypeLocked(this.equipSlots()[slotId]) &&
!this.isEquipTypeSealed(this.equipSlots()[slotId])
);
};
/**
* Changes the actor's equipment in the given slot to the given item
*
* @param {number} slotId - The equipment slot id to change
* @param {Object} item - The data object to equip
*/
Game_Actor.prototype.changeEquip = function(slotId, item) {
if (
this.tradeItemWithParty(item, this.equips()[slotId]) &&
(!item || this.equipSlots()[slotId] === item.etypeId)
) {
this._equips[slotId].setObject(item);
this.refresh();
}
};
/**
* Forcibly changes the actor's equipment in the given slot to the given item
*
* @param {number} slotId - The equipment slot id to change
* @param {Object} item - The data object to equip
*/
Game_Actor.prototype.forceChangeEquip = function(slotId, item) {
this._equips[slotId].setObject(item);
this.releaseUnequippableItems(true);
this.refresh();
};
/**
* Trades an item the actor has with the party inventory
*
* @param {Object} newItem - The item to trade to the actor
* @param {Object} oldItem - The item to trade to the party inventory
* @return {boolean} True if the trade succeeds
*/
Game_Actor.prototype.tradeItemWithParty = function(newItem, oldItem) {
if (newItem && !$gameParty.hasItem(newItem)) {
return false;
} else {
$gameParty.gainItem(oldItem, 1);
$gameParty.loseItem(newItem, 1);
return true;
}
};
/**
* Change equips by ids
*
* @param {number} etypeId - The equipment type id
* @param {number} itemId - The id of the item to equip
*/
Game_Actor.prototype.changeEquipById = function(etypeId, itemId) {
const slotId = etypeId - 1;
if (this.equipSlots()[slotId] === 1) {
this.changeEquip(slotId, $dataWeapons[itemId]);
} else {
this.changeEquip(slotId, $dataArmors[itemId]);
}
};
/**
* Check if the given item is equipped by the actor
*
* @param {Object} item - The item to check for
* @return {boolean} True if the item is already equipped
*/
Game_Actor.prototype.isEquipped = function(item) {
return this.equips().includes(item);
};
/**
* Discards the item if it is equipped
*
* @param {Object} item - The item to discard
*/
Game_Actor.prototype.discardEquip = function(item) {
const slotId = this.equips().indexOf(item);
if (slotId >= 0) {
this._equips[slotId].setObject(null);
}
};
/**
* Unequips items that are not equippable
*
* @param {boolean} forcing - If uneqippping items forcibly
*/
Game_Actor.prototype.releaseUnequippableItems = function(forcing) {
for (;;) {
const slots = this.equipSlots();
const equips = this.equips();
let changed = false;
for (let i = 0; i < equips.length; i++) {
const item = equips[i];
if (item && (!this.canEquip(item) || item.etypeId !== slots[i])) {
if (!forcing) {
this.tradeItemWithParty(null, item);
}
this._equips[i].setObject(null);
changed = true;
}
}
if (!changed) {
break;
}
}
};
/**
* Clears all equipment slots
*/
Game_Actor.prototype.clearEquipments = function() {
const maxSlots = this.equipSlots().length;
for (let i = 0; i < maxSlots; i++) {
if (this.isEquipChangeOk(i)) {
this.changeEquip(i, null);
}
}
};
/**
* Optimizes equipment
*/
Game_Actor.prototype.optimizeEquipments = function() {
const maxSlots = this.equipSlots().length;
this.clearEquipments();
for (let i = 0; i < maxSlots; i++) {
if (this.isEquipChangeOk(i)) {
this.changeEquip(i, this.bestEquipItem(i));
}
}
};
/**
* Get the best item for a given equip slot id
*
* @param {number} slotId - The id of the equipment slot
* @return {Object} The best item to equip in the given slot
*/
Game_Actor.prototype.bestEquipItem = function(slotId) {
const etypeId = this.equipSlots()[slotId];
const items = $gameParty
.equipItems()
.filter(item => item.etypeId === etypeId && this.canEquip(item));
let bestItem = null;
let bestPerformance = -1000;
for (let i = 0; i < items.length; i++) {
const performance = this.calcEquipItemPerformance(items[i]);
if (performance > bestPerformance) {
bestPerformance = performance;
bestItem = items[i];
}
}
return bestItem;
};
/**
* Calculate an item's performance
*
* @param {Object} item - The item to calculate performance for
* @return {number} The performance rating of the item
*/
Game_Actor.prototype.calcEquipItemPerformance = function(item) {
return item.params.reduce((a, b) => a + b);
};
/**
* Check if actor has required weapon types for the given skill
*
* @param {Object} skill - The skill object
* @return {boolean} True if the actor has the required weapon types equipped
*/
Game_Actor.prototype.isSkillWtypeOk = function(skill) {
const wtypeId1 = skill.requiredWtypeId1;
const wtypeId2 = skill.requiredWtypeId2;
if (
(wtypeId1 === 0 && wtypeId2 === 0) ||
(wtypeId1 > 0 && this.isWtypeEquipped(wtypeId1)) ||
(wtypeId2 > 0 && this.isWtypeEquipped(wtypeId2))
) {
return true;
} else {
return false;
}
};
/**
* Check if actor has a weapon of the given type equipped
*
* @param {number} wtypeId - The weapon type id to check for
* @return {boolean} True if the actor has a weapon of the given type equipped
*/
Game_Actor.prototype.isWtypeEquipped = function(wtypeId) {
return this.weapons().some(weapon => weapon.wtypeId === wtypeId);
};
Game_Actor.prototype.refresh = function() {
this.releaseUnequippableItems(false);
Game_Battler.prototype.refresh.call(this);
};
Game_Actor.prototype.hide = function() {
Game_Battler.prototype.hide.call(this);
$gameTemp.requestBattleRefresh();
};
/**
* Check if this is an actor. When called from Game_Actor, this is always true
*
* @return {boolean} True if this is an actor
*/
Game_Actor.prototype.isActor = function() {
return true;
};
/**
* Get the friendly unit in battle. For Game_Actor, this is Game_Party
*
* @return {Game_Party|Game_Troop} The friendly unit in battle
*/
Game_Actor.prototype.friendsUnit = function() {
return $gameParty;
};
/**
* Get the enemy unit in battle. For Game_Actor, this is Game_Troop
*
* @return {Game_Party|Game_Troop} The enemy unit in battle
*/
Game_Actor.prototype.opponentsUnit = function() {
return $gameTroop;
};
/**
* Get the actor's index in the party
*
* @return {number} The actor's index in the party
*/
Game_Actor.prototype.index = function() {
return $gameParty.members().indexOf(this);
};
/**
* Check if this actor will participate in battle
*
* @return {boolean} True if the actor will participate in battle
*/
Game_Actor.prototype.isBattleMember = function() {
return $gameParty.battleMembers().includes(this);
};
/**
* Check if this actor can change formation. When called from Game_Actor, this is always true
*
* @return {boolean} True if the actor can change formation
*/
Game_Actor.prototype.isFormationChangeOk = function() {
return true;
};
/**
* Get the class data object for the actor's current class
*
* @return {Object} The class data object
*/
Game_Actor.prototype.currentClass = function() {
return $dataClasses[this._classId];
};
/**
* Check if the actor's class matches the given class
*
* @param {Object} gameClass - The class data object
* @return {boolean} True if the given class is the actor's class
*/
Game_Actor.prototype.isClass = function(gameClass) {
return gameClass && this._classId === gameClass.id;
};
/**
* Get the actor's skill types
*
* @return {Array} The actor's skill types
*/
Game_Actor.prototype.skillTypes = function() {
const skillTypes = this.addedSkillTypes().sort((a, b) => a - b);
return skillTypes.filter((x, i, self) => self.indexOf(x) === i);
};
/**
* Get the actor's skills
*
* @return {Array} The actor's skills
*/
Game_Actor.prototype.skills = function() {
const list = [];
for (const id of this._skills.concat(this.addedSkills())) {
if (!list.includes($dataSkills[id])) {
list.push($dataSkills[id]);
}
}
return list;
};
/**
* Get the actor's usable skills
*
* @return {Array} The actor's usable skills
*/
Game_Actor.prototype.usableSkills = function() {
return this.skills().filter(skill => this.canUse(skill));
};
Game_Actor.prototype.traitObjects = function() {
const objects = Game_Battler.prototype.traitObjects.call(this);
objects.push(this.actor(), this.currentClass());
for (const item of this.equips()) {
if (item) {
objects.push(item);
}
}
return objects;
};
Game_Actor.prototype.attackElements = function() {
const set = Game_Battler.prototype.attackElements.call(this);
if (this.hasNoWeapons() && !set.includes(this.bareHandsElementId())) {
set.push(this.bareHandsElementId());
}
return set;
};
/**
* Check if the actor has no weapon
*
* @return {boolean} True if the actor has no weapon
*/
Game_Actor.prototype.hasNoWeapons = function() {
return this.weapons().length === 0;
};
/**
* Get the bare hand element id
*
* @return {number} The bare hand element id
*/
Game_Actor.prototype.bareHandsElementId = function() {
return 1;
};
/**
* Get a base param value
*
* @param {number} paramId - The id of the param to get
* @return {number} The base param value
*/
Game_Actor.prototype.paramBase = function(paramId) {
return this.currentClass().params[paramId][this._level];
};
Game_Actor.prototype.paramPlus = function(paramId) {
let value = Game_Battler.prototype.paramPlus.call(this, paramId);
for (const item of this.equips()) {
if (item) {
value += item.params[paramId];
}
}
return value;
};
/**
* Get the attack animation id1
*
* @return {number} The attack animation id1
*/
Game_Actor.prototype.attackAnimationId1 = function() {
if (this.hasNoWeapons()) {
return this.bareHandsAnimationId();
} else {
const weapons = this.weapons();
return weapons[0] ? weapons[0].animationId : 0;
}
};
/**
* Get the attack animation id2
*
* @return {number} The attack animation id2
*/
Game_Actor.prototype.attackAnimationId2 = function() {
const weapons = this.weapons();
return weapons[1] ? weapons[1].animationId : 0;
};
/**
* Get the bare hand attack animation id
*
* @return {number} The bare hand attack animation id
*/
Game_Actor.prototype.bareHandsAnimationId = function() {
return 1;
};
/**
* Change the actor's exp
*
* @param {number} exp - The new exp amount
* @param {boolean} show - If level up messages show as a result of this operation
*/
Game_Actor.prototype.changeExp = function(exp, show) {
this._exp[this._classId] = Math.max(exp, 0);
const lastLevel = this._level;
const lastSkills = this.skills();
while (!this.isMaxLevel() && this.currentExp() >= this.nextLevelExp()) {
this.levelUp();
}
while (this.currentExp() < this.currentLevelExp()) {
this.levelDown();
}
if (show && this._level > lastLevel) {
this.displayLevelUp(this.findNewSkills(lastSkills));
}
this.refresh();
};
/**
* Handles when the actor levels up
*/
Game_Actor.prototype.levelUp = function() {
this._level++;
for (const learning of this.currentClass().learnings) {
if (learning.level === this._level) {
this.learnSkill(learning.skillId);
}
}
};
/**
* Handles when the actor levels down
*/
Game_Actor.prototype.levelDown = function() {
this._level--;
};
/**
* Gets the actor's new skills after change
*
* @param {Array} lastSkills - Array of the actor's previous skills
* @return {Array} Array of skills the actor knows but were not found in the lastSkills parameter
*/
Game_Actor.prototype.findNewSkills = function(lastSkills) {
const newSkills = this.skills();
for (const lastSkill of lastSkills) {
newSkills.remove(lastSkill);
}
return newSkills;
};
/**
* Displays a level up message
*
* @param {Array} newSkills - Skills the actor learned from leveling up
*/
Game_Actor.prototype.displayLevelUp = function(newSkills) {
const text = TextManager.levelUp.format(
this._name,
TextManager.level,
this._level
);
$gameMessage.newPage();
$gameMessage.add(text);
for (const skill of newSkills) {
$gameMessage.add(TextManager.obtainSkill.format(skill.name));
}
};
/**
* Gain exp
*
* @param {number} exp - Amount of exp to gain
*/
Game_Actor.prototype.gainExp = function(exp) {
const newExp = this.currentExp() + Math.round(exp * this.finalExpRate());
this.changeExp(newExp, this.shouldDisplayLevelUp());
};
/**
* Rate at which exp is gained
*
* @return {number} The rate of exp gain
*/
Game_Actor.prototype.finalExpRate = function() {
return this.exr * (this.isBattleMember() ? 1 : this.benchMembersExpRate());
};
/**
* Rate modifier for exp gain for benched party members
*
* @return {number} The exp gain rate modifier
*/
Game_Actor.prototype.benchMembersExpRate = function() {
return $dataSystem.optExtraExp ? 1 : 0;
};
/**
* Check if level up messages should display. For Game_Actor, this always returns true
*
* @return {boolean} True if level up messages should display
*/
Game_Actor.prototype.shouldDisplayLevelUp = function() {
return true;
};
/**
* Changes the actor's level
*
* @param {number} level - The actor's new level
* @param {boolean} show - If level up messages display as a result of this operation
*/
Game_Actor.prototype.changeLevel = function(level, show) {
level = level.clamp(1, this.maxLevel());
this.changeExp(this.expForLevel(level), show);
};
/**
* Causes the actor to learn a skill by id
*
* @param {number} skillId - The id of the skill to learn
*/
Game_Actor.prototype.learnSkill = function(skillId) {
if (!this.isLearnedSkill(skillId)) {
this._skills.push(skillId);
this._skills.sort((a, b) => a - b);
}
};
/**
* Causes the actor to forget a skill by id
*
* @param {number} skillId - The id of the skill to forget
*/
Game_Actor.prototype.forgetSkill = function(skillId) {
this._skills.remove(skillId);
};
/**
* Check if the actor has already learned a skill by id
*
* @param {number} skillId - The id of the skill to check
* @return {boolean} True if the skill is already learned
*/
Game_Actor.prototype.isLearnedSkill = function(skillId) {
return this._skills.includes(skillId);
};
/**
* Check if the actor has already has a skill by id
*
* @param {number} skillId - The id of the skill to check
* @return {boolean} True if the actor already has the skill
*/
Game_Actor.prototype.hasSkill = function(skillId) {
return this.skills().includes($dataSkills[skillId]);
};
/**
* Changes the actor's class
*
* @param {number} classId - The id of the class to change to
* @param {boolean} keepExp - If the actor's exp in their previous class transfers to the new class
*/
Game_Actor.prototype.changeClass = function(classId, keepExp) {
if (keepExp) {
this._exp[classId] = this.currentExp();
}
this._classId = classId;
this._level = 0;
this.changeExp(this._exp[this._classId] || 0, false);
this.refresh();
};
/**
* Changes the actor's character image
*
* @param {string} characterName - Name of the character sheet
* @param {number} characterIndex - Index on the character sheet
*/
Game_Actor.prototype.setCharacterImage = function(
characterName,
characterIndex
) {
this._characterName = characterName;
this._characterIndex = characterIndex;
};
/**
* Changes the actor's face image
*
* @param {string} faceName - Name of the face sheet
* @param {number} faceIndex - Index on the face sheet
*/
Game_Actor.prototype.setFaceImage = function(faceName, faceIndex) {
this._faceName = faceName;
this._faceIndex = faceIndex;
$gameTemp.requestBattleRefresh();
};
/**
* Changes the actor's battler image
*
* @param {string} battlerName - Name of the battler image
*/
Game_Actor.prototype.setBattlerImage = function(battlerName) {
this._battlerName = battlerName;
};
/**
* Check if the battler sprite should be visible (for side view battles)
*
* @return {boolean} True if the battler sprite should be visible
*/
Game_Actor.prototype.isSpriteVisible = function() {
return $gameSystem.isSideView();
};
Game_Actor.prototype.performActionStart = function(action) {
Game_Battler.prototype.performActionStart.call(this, action);
};
Game_Actor.prototype.performAction = function(action) {
Game_Battler.prototype.performAction.call(this, action);
if (action.isAttack()) {
this.performAttack();
} else if (action.isGuard()) {
this.requestMotion("guard");
} else if (action.isMagicSkill()) {
this.requestMotion("spell");
} else if (action.isSkill()) {
this.requestMotion("skill");
} else if (action.isItem()) {
this.requestMotion("item");
}
};
Game_Actor.prototype.performActionEnd = function() {
Game_Battler.prototype.performActionEnd.call(this);
};
/**
* Performs an attack
*/
Game_Actor.prototype.performAttack = function() {
const weapons = this.weapons();
const wtypeId = weapons[0] ? weapons[0].wtypeId : 0;
const attackMotion = $dataSystem.attackMotions[wtypeId];
if (attackMotion) {
if (attackMotion.type === 0) {
this.requestMotion("thrust");
} else if (attackMotion.type === 1) {
this.requestMotion("swing");
} else if (attackMotion.type === 2) {
this.requestMotion("missile");
}
this.startWeaponAnimation(attackMotion.weaponImageId);
}
};
Game_Actor.prototype.performDamage = function() {
Game_Battler.prototype.performDamage.call(this);
if (this.isSpriteVisible()) {
this.requestMotion("damage");
} else {
$gameScreen.startShake(5, 5, 10);
}
SoundManager.playActorDamage();
};
Game_Actor.prototype.performEvasion = function() {
Game_Battler.prototype.performEvasion.call(this);
this.requestMotion("evade");
};
Game_Actor.prototype.performMagicEvasion = function() {
Game_Battler.prototype.performMagicEvasion.call(this);
this.requestMotion("evade");
};
Game_Actor.prototype.performCounter = function() {
Game_Battler.prototype.performCounter.call(this);
this.performAttack();
};
Game_Actor.prototype.performCollapse = function() {
Game_Battler.prototype.performCollapse.call(this);
if ($gameParty.inBattle()) {
SoundManager.playActorCollapse();
}
};
/**
* Perform a victory
*/
Game_Actor.prototype.performVictory = function() {
this.setActionState("done");
if (this.canMove()) {
this.requestMotion("victory");
}
};
/**
* Perform an escape
*/
Game_Actor.prototype.performEscape = function() {
if (this.canMove()) {
this.requestMotion("escape");
}
};
/**
* Make the action list
*
* @return {Array} A list of actions
*/
Game_Actor.prototype.makeActionList = function() {
const list = [];
const attackAction = new Game_Action(this);
attackAction.setAttack();
list.push(attackAction);
for (const skill of this.usableSkills()) {
const skillAction = new Game_Action(this);
skillAction.setSkill(skill.id);
list.push(skillAction);
}
return list;
};
/**
* Make the auto battle action
*/
Game_Actor.prototype.makeAutoBattleActions = function() {
for (let i = 0; i < this.numActions(); i++) {
const list = this.makeActionList();
let maxValue = -Number.MAX_VALUE;
for (const action of list) {
const value = action.evaluate();
if (value > maxValue) {
maxValue = value;
this.setAction(i, action);
}
}
}
this.setActionState("waiting");
};
/**
* Make actions when confused
*/
Game_Actor.prototype.makeConfusionActions = function() {
for (let i = 0; i < this.numActions(); i++) {
this.action(i).setConfusion();
}
this.setActionState("waiting");
};
Game_Actor.prototype.makeActions = function() {
Game_Battler.prototype.makeActions.call(this);
if (this.numActions() > 0) {
this.setActionState("undecided");
} else {
this.setActionState("waiting");
}
if (this.isAutoBattle()) {
this.makeAutoBattleActions();
} else if (this.isConfused()) {
this.makeConfusionActions();
}
};
/**
* Processing when the player walks on the map
*/
Game_Actor.prototype.onPlayerWalk = function() {
this.clearResult();
this.checkFloorEffect();
if ($gamePlayer.isNormal()) {
this.turnEndOnMap();
for (const state of this.states()) {
this.updateStateSteps(state);
}
this.showAddedStates();
this.showRemovedStates();
}
};
/**
* Update states that can end by walking
*
* @param {Object} state - The state object to update
*/
Game_Actor.prototype.updateStateSteps = function(state) {
if (state.removeByWalking) {
if (this._stateSteps[state.id] > 0) {
if (--this._stateSteps[state.id] === 0) {
this.removeState(state.id);
}
}
}
};
/**
* Displays a message when state is added
*/
Game_Actor.prototype.showAddedStates = function() {
for (const state of this.result().addedStateObjects()) {
if (state.message1) {
$gameMessage.add(state.message1.format(this._name));
}
}
};
/**
* Displays a message when state is removed
*/
Game_Actor.prototype.showRemovedStates = function() {
for (const state of this.result().removedStateObjects()) {
if (state.message4) {
$gameMessage.add(state.message4.format(this._name));
}
}
};
/**
* Get the steps per turn
*
* @return {number} Steps per turn
*/
Game_Actor.prototype.stepsForTurn = function() {
return 20;
};
/**
* Handle a turn end on map scene
*/
Game_Actor.prototype.turnEndOnMap = function() {
if ($gameParty.steps() % this.stepsForTurn() === 0) {
this.onTurnEnd();
if (this.result().hpDamage > 0) {
this.performMapDamage();
}
}
};
/**
* Check if the player is on a floor effect
*/
Game_Actor.prototype.checkFloorEffect = function() {
if ($gamePlayer.isOnDamageFloor()) {
this.executeFloorDamage();
}
};
/**
* Executes a floor damage effect
*/
Game_Actor.prototype.executeFloorDamage = function() {
const floorDamage = Math.floor(this.basicFloorDamage() * this.fdr);
const realDamage = Math.min(floorDamage, this.maxFloorDamage());
this.gainHp(-realDamage);
if (realDamage > 0) {
this.performMapDamage();
}
};
/**
* Get basic damage for floor damage
*
* @return {number} Amount of basic damage for floor damage
*/
Game_Actor.prototype.basicFloorDamage = function() {
return 10;
};
/**
* Get maximum amount of floor damage to inflict
*
* @return {number} Maximum amount of floor damage the player can take
*/
Game_Actor.prototype.maxFloorDamage = function() {
return $dataSystem.optFloorDeath ? this.hp : Math.max(this.hp - 1, 0);
};
/**
* Perform damage on map
*/
Game_Actor.prototype.performMapDamage = function() {
if (!$gameParty.inBattle()) {
$gameScreen.startFlashForDamage();
}
};
Game_Actor.prototype.clearActions = function() {
Game_Battler.prototype.clearActions.call(this);
this._actionInputIndex = 0;
};
/**
* Get inputting action
*
* @return {Game_Action} The inputting action
*/
Game_Actor.prototype.inputtingAction = function() {
return this.action(this._actionInputIndex);
};
/**
* Selects the next command
*
* @return {boolean} True if selected
*/
Game_Actor.prototype.selectNextCommand = function() {
if (this._actionInputIndex < this.numActions() - 1) {
this._actionInputIndex++;
return true;
} else {
return false;
}
};
/**
* Selects the previous command
*
* @return {boolean} True if selected
*/
Game_Actor.prototype.selectPreviousCommand = function() {
if (this._actionInputIndex > 0) {
this._actionInputIndex--;
return true;
} else {
return false;
}
};
/**
* Get the last skill
*
* @return {Object} Last skill object
*/
Game_Actor.prototype.lastSkill = function() {
if ($gameParty.inBattle()) {
return this.lastBattleSkill();
} else {
return this.lastMenuSkill();
}
};
/**
* Get the last skill from menu
*
* @return {Object} Last skill object
*/
Game_Actor.prototype.lastMenuSkill = function() {
return this._lastMenuSkill.object();
};
/**
* Set the last skill from menu
*
* @param {Object} skill - The skill object
*/
Game_Actor.prototype.setLastMenuSkill = function(skill) {
this._lastMenuSkill.setObject(skill);
};
/**
* Get the last skill from battle
*
* @return {Object} Last skill object
*/
Game_Actor.prototype.lastBattleSkill = function() {
return this._lastBattleSkill.object();
};
/**
* Set the last skill from battle
*
* @param {Object} skill - The skill object
*/
Game_Actor.prototype.setLastBattleSkill = function(skill) {
this._lastBattleSkill.setObject(skill);
};
/**
* Get the last command symbol
*
* @return {string} The last command symbol
*/
Game_Actor.prototype.lastCommandSymbol = function() {
return this._lastCommandSymbol;
};
/**
* Set the last command symbol
*
* @param {string} symbol - The command symbol
*/
Game_Actor.prototype.setLastCommandSymbol = function(symbol) {
this._lastCommandSymbol = symbol;
};
/**
* Check if the given item has an escape effect
*
* @param {Object} item - The item object to test
* @return {boolean} True if escape special effect detected
*/
Game_Actor.prototype.testEscape = function(item) {
return item.effects.some(
effect => effect && effect.code === Game_Action.EFFECT_SPECIAL
);
};
Game_Actor.prototype.meetsUsableItemConditions = function(item) {
if ($gameParty.inBattle()) {
if (!BattleManager.canEscape() && this.testEscape(item)) {
return false;
}
}
return Game_BattlerBase.prototype.meetsUsableItemConditions.call(
this,
item
);
};
/**
* Handling when an escape fails
*/
Game_Actor.prototype.onEscapeFailure = function() {
if (BattleManager.isTpb()) {
this.applyTpbPenalty();
}
this.clearActions();
this.requestMotionRefresh();
};