//=============================================================================
// WeaponProficiency.js
//=============================================================================
/*:
* @plugindesc Allows per-Actor or per-Class weapon or armor bonuses or penalties.
* @author whitesphere
*
* @param Default Type
* @desc Specifies the type of item (weapon or armor) if none specified
* @default weapon
*
* @param Default Attribute
* @desc Specifies the attribute modified if none specified
* @default ATK
*
* @param Default Operation
* @desc How are multiple proficiencies stacked? Set to MULT or ADD.
* @default MULT
*
* @help This modifies parameters such as ATK, MAT, DEF, MDF, AGI or LUK based on
* the weapon or armor equipped. This allows you to have, say, an Archer who is
* more skilled with a Bow than a Knight. Or to have, say, a Wrestler who can use
* a Club but poorly.
*
* If the notetag is set for an Actor and a Class, the values both apply. Multiple
* percentage values will stack by multiplication (for MULT) or by addition (for ADD)
*
* ============================================================================
* Notetags
* ============================================================================
*
* This note-tag will work in Actor, Class or in a State:
* <proficiency: type=(weapon or armor), operation=(mult or add), modify=(ATK, MAT, etc), id=percent, ...>
* Example:
* <proficiency: type=weapon, operation=mult, modify=atk, 1=150, 2=80, 3=110>
* This example modifies WEAPON abilities. In particular, it modifies the ATK skill
* Weapon Type #1 does 150% normal, 2 does 80% normal and so on.
*
* <proficiency: type=weapon, operation=add, modify=atk, 1=3, 2=-1, 3=7>
* This example modifies WEAPON abilities. In particular, it modifies the ATK skill
* Weapon Type #1 has +3 to ATK, 2 does -1 to ATK and so on.
*
* Valid types are: weapon, armor
*
* Valid modify values are: ATK, MAT, DEF, MDF, AGI, LUK
*/
(function() {
WS_WeaponProficiency = {};
WS_WeaponProficiency.Parameters = PluginManager.parameters(\'WeaponProficiency\');
WS_WeaponProficiency.Param = {};
//=============================================================================
// The plug-in parameters
//=============================================================================
WS_WeaponProficiency.Param.defaultType = WS_WeaponProficiency.Parameters[\'Default Type\'].toLowerCase().trim();
WS_WeaponProficiency.Param.defaultAttribute = WS_WeaponProficiency.Parameters[\'Default Attribute\'].toLowerCase().trim();
WS_WeaponProficiency.Param.defaultOperation = WS_WeaponProficiency.Parameters[\'Default Operation\'].toLowerCase().trim();
//=============================================================================
// Class which manages a single weapon skill entry
// entry = the string from the meta-data:
// type=weapon, modify=atk, operation=mult, 1=150, 2=80, 3=110
//=============================================================================
Weapon_skill = function(entry) {
valueSet=entry.split(",");
// Set the defaults
this.type = WS_WeaponProficiency.Param.defaultType;
this.attribute = WS_WeaponProficiency.Param.defaultAttribute;
this.operation=WS_WeaponProficiency.Param.defaultOperation;
for (weapon_index=0; weapon_index<valueSet.length; weapon_index++) {
current_entry=valueSet[weapon_index];
nv_pair=current_entry.split("=");
if (nv_pair.length != 2)
continue;
current_name=nv_pair[0];
current_value=nv_pair[1];
current_name=current_name.toLowerCase().trim();
current_value=current_value.toLowerCase().trim();
if (current_name == "type") {
if (current_value == "weapon" || current_value == "armor")
this.type=current_value;
continue;
}
if (current_name == "modify") {
if (this.findParam(current_value) != -1)
this.attribute=current_value;
continue;
}
if (current_name == "operation") {
if (current_value == "mult" || current_value == "add")
this.operation=current_value;
continue;
}
current_name_int = parseInt(current_name);
current_value_as_number = parseInt(current_value);
if (this.operation == "mult")
current_value_as_number /= 100.0;
// Don\'t store NaN (which results if current_value isn\'t a number)
if (current_value_as_number !== current_value_as_number)
continue;
this[current_name_int]=current_value_as_number;
}
this.param_id=this.findParam(this.attribute);
}
//=============================================================================
// Returns an int representing the parameter, -1 if not found
//=============================================================================
Weapon_skill.prototype.findParam = function(param_name) {
if (!Weapon_skill.prototype._attributes) {
/* The order comes from Game_BattlerBase, so the array offset is the .param() */
Weapon_skill.prototype._attributes=["mhp", "mmp", "atk", "def", "mat", "mdf", "agi", "luk"];
}
for (weap_search=0; weap_search<Weapon_skill.prototype._attributes.length; weap_search++) {
if (Weapon_skill.prototype._attributes[weap_search] == param_name) {
return weap_search;
}
}
return -1;
}
//=============================================================================
// Returns true if this skill would affect the passed in param_id, false if not
//=============================================================================
Weapon_skill.prototype.affectsParam = function(param_id) {
if (this.param_id == param_id)
return true;
return false;
}
//=============================================================================
// Returns a modifier if this skill would affect the passed in weapon, undefined if not
//=============================================================================
Weapon_skill.prototype.getWeaponModifier = function(weapon) {
if (this.type != "weapon")
return undefined;
return this[weapon.wtypeId];
}
//=============================================================================
// Returns a modifier if this skill would affect the passed in armor, undefined if not
//=============================================================================
Weapon_skill.prototype.getArmorModifier = function(armor) {
if (this.type != "armor")
return undefined;
return this[armor.etypeId];
}
//=============================================================================
// Game_Actor
//=============================================================================
//=============================================================================
// Returns the modifier percent being used from 0.0 and up if active, or
// undefined if this skill does not affect the passed-in item
//=============================================================================
Game_Actor.prototype.getItemModifier = function(skill_to_check, item) {
if (DataManager.isWeapon(item)) {
result=skill_to_check.getWeaponModifier(current);
return result;
}
if (DataManager.isArmor(item)) {
result=skill_to_check.getArmorModifier(current);
return result;
}
return undefined;
}
//=============================================================================
// Function that returns a modifier for the current parameter or 1.0 if there
// are no modifiers (for multiplication) or 0 for addition
//=============================================================================
Game_Actor.prototype.getOverallSkillsModifier = function(param_id, operation) {
var ws_result=1.0;
var ws_active=[];
if (operation == "add")
ws_result=0;
/* Check for the actor\'s skills modifier */
var actor_id=this.actorId();
var actors_meta=$dataActors[actor_id].meta;
var current_skill_mod=null;
if (actors_meta && actors_meta.proficiency) {
$gameTemp.actorWSCache = $gameTemp.actorWSCache || [];
if (!$gameTemp.actorWSCache[actor_id]) {
$gameTemp.actorWSCache[actor_id]=new Weapon_skill(actors_meta.proficiency);
}
current_skill_mod=$gameTemp.actorWSCache[actor_id];
if (current_skill_mod.operation == operation) {
if ($gameTemp.actorWSCache[actor_id].affectsParam(param_id)) {
ws_active.push($gameTemp.actorWSCache[actor_id]);
}
}
}
/* Check for the class skills modifier */
if (this._classId)
{
actors_meta=$dataClasses[this._classId].meta;
if (actors_meta && actors_meta.proficiency) {
$gameTemp.actorCCache = $gameTemp.actorCCache || [];
if (!$gameTemp.actorCCache[actor_id]) {
$gameTemp.actorCCache[actor_id]=new Weapon_skill(actors_meta.proficiency);
}
current_skill_mod=$gameTemp.actorCCache[actor_id];
if (current_skill_mod.operation == operation) {
if ($gameTemp.actorCCache[actor_id].affectsParam(param_id))
{
ws_active.push($gameTemp.actorCCache[this._classId]);
}
}
}
}
/* And check for the states modifiers */
var states=this.states();
for (mod=0; mod<states.length; mod++)
{
current=states[mod];
if (current === null)
continue;
if ($dataStates[current.id].meta.proficiency) {
$gameTemp.actorCCache = $gameTemp.stateCache || [];
if (!$gameTemp.stateCache[current.id]) {
$gameTemp.stateCache[current.id]=new Weapon_skill($dataStates[current.id].meta.proficiency);
}
current_skill_mod=$gameTemp.stateCache[actor_id];
if (current_skill_mod.operation == operation) {
if ($gameTemp.stateCache[current.id].affectsParam(param_id))
{
ws_active.push($gameTemp.stateCache[current.id]);
}
}
}
}
/* Now, get the weapon and equipment modifiers which are relevant */
for (var mod=0; mod<ws_active.length; mod++) {
var current_skill_mod=ws_active[mod];
/* Check the weapons */
weapons=this.weapons();
for (index=0; index<weapons.length; index++) {
current_weapon=weapons[index];
new_modifier=this.getItemModifier(current_skill_mod, current_weapon);
if (new_modifier !== undefined) {
if (operation == "add") {
ws_result += new_modifier;
}
else
{
ws_result *= new_modifier;
}
}
}
/* And check the equipment */
items=this.equips();
for (mod=0; mod<items.length; mod++)
{
current_equip=items[mod];
if (current_equip === null || DataManager.isWeapon(current_equip))
continue;
meta={};
if (DataManager.isArmor(current_equip))
{
new_modifier=this.getItemModifier(current_skill_mod, current_equip);
if (new_modifier !== undefined) {
if (operation == "add") {
ws_result += new_modifier;
}
else
{
ws_result *= new_modifier;
}
}
}
}
}
return ws_result;
}
var WS_WP_Game_Actor_paramPlus=Game_Actor.prototype.paramPlus;
//=============================================================================
// Enhance or penalize any relevant stats here
//=============================================================================
Game_Actor.prototype.paramPlus = function(paramId) {
var param_result=WS_WP_Game_Actor_paramPlus.call(this,paramId);
var ws_mult_result=this.getOverallSkillsModifier(paramId, "mult");
var ws_add_result=this.getOverallSkillsModifier(paramId, "add");
if (ws_mult_result == 1.0 && ws_add_result == 0)
return param_result;
return (param_result + ws_add_result) * ws_mult_result;
}
})();
//=============================================================================
// End of File
//=============================================================================