//=============================================================================
// MrTS_Perks.js
//=============================================================================
/*:
* @plugindesc Allows actors to have perks which increase their stats or add something new.
* @author Mr. Trivel
*
* @param Points Per Level
* @desc How many perk points actors gets on level up?
* @default 1
*
* @param Points On Levels
* @desc Get perk points only on specific levels?
* 0 for all levels.
* @default 1 3 5 7 10 13 14 15 18 20 25 30 35 40 45 50 55 65 75 85 90 93 96 98 99
*
* @param Command Name
* @desc Name of Perks Command in menu.
* Default: Perks
* @default Perks
*
* @help
* --------------------------------------------------------------------------------
* Terms of Use
* --------------------------------------------------------------------------------
* Don't remove the header or claim that you wrote this plugin.
* Credit Mr. Trivel if using this plugin in your project.
* Free for commercial and non-commercial projects.
* --------------------------------------------------------------------------------
* Version 1.0
* --------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------
* Actor Tags
* --------------------------------------------------------------------------------
* Creating perks:
*
*
*
* level: [INT]
* atk: [INT]
* def: [INT]
* matk: [INT]
* mdef: [INT]
* agi: [INT]
* luk: [INT]
* perk: [NAME]
* switch: [ID] [ON/OFF]
* variable: [ID] [> >= < <= == !=] [VALUE]
*
*
* state: [ID]
*
*
* [TEXT]
*
*
*
* Notes:
* Don't need to type out requirements you don't use.
* [TEXT] - Each line uses text wrap.
* Perk example:
*
*
*
* matk: 2
*
*
* state: 11
*
*
* You have amazing ability to circulate mana around you. Gaining increase mana regeneration and mana compatibility. The spirits you summon deal more damage.
*
*
* --------------------------------------------------------------------------------
* Plugin Commands
* --------------------------------------------------------------------------------
* AddPerkPoints [POINTS] [ACTOR_ID] - Adds Perk Points to Actor
* E.g. AddPerkPoints 999 5
*
* ChangePerksCommand [TRUE/FALSE] - enable or disable perks command in menu
* E.g. ChangePerksCommand true
*
*
* --------------------------------------------------------------------------------
* Version History
* --------------------------------------------------------------------------------
* 1.0 - Release
*/
(function() {
var parameters = PluginManager.parameters('MrTS_Perks');
var paramPPPL = Number(parameters['Points Per Level'] || 1);
var paramPPOL = String(parameters['Points On Levels'] || "1 3 5 7 10 13 14 15 18 20 25 30 35 40 45 50 55 65 75 85 90 93 96 98 99");
var paramPPOLD = paramPPOL.split(" ");
var paramName = String(parameters['Command Name'] || "Perks");
//--------------------------------------------------------------------------
// Game_Interpreter
//
var _GameInterpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_GameInterpreter_pluginCommand.call(this, command, args);
if (command === 'AddPerkPoints') {
var points = Number(args[0]);
var actorId = Number(args[1]);
$gameActors.actor(actorId)._perkPoints += points;
} else if (command === 'ChangePerksCommand') {
var bool = (args[0].toLowerCase() === "true");
$gameSystem.changePerksCommand(bool);
}
};
//--------------------------------------------------------------------------
// Game_Actor
//
var _GameActor_initMembers = Game_Actor.prototype.initMembers;
Game_Actor.prototype.initMembers = function() {
_GameActor_initMembers.call(this);
this._perkPoints = 0;
this._perks = [];
this._obtainedPerks = [];
};
var _GameActor_setup = Game_Actor.prototype.setup;
Game_Actor.prototype.setup = function(actorId) {
_GameActor_setup.call(this, actorId);
this.initPerkPoints();
this.initPerks();
};
Game_Actor.prototype.initPerkPoints = function() {
for (var i = 0; i < paramPPOLD.length; i++) {
if (Number(paramPPOLD[i]) <= this._level)
this.addPerkPoint();
};
};
Game_Actor.prototype.addPerkPoint = function() {
this._perkPoints += paramPPPL;
};
Game_Actor.prototype.getPerkList = function() {
return this._perks;
};
Game_Actor.prototype.getObtainedPerksList = function() {
return this._obtainedPerks;
};
Game_Actor.prototype.getPerkPoints = function() {
return this._perkPoints;
};
Game_Actor.prototype.isPerkObtained = function(id) {
return this._obtainedPerks.contains(id);
};
Game_Actor.prototype.tryToObtainPerk = function(id) {
if (this._perkPoints <= 0)
return false;
var perk = this._perks[id];
var perkReqs = perk.requirements;
for (var property in perkReqs)
{
if (perkReqs.hasOwnProperty(property))
{
switch (property)
{
case "ATK":
{
if (this.atk < perkReqs.ATK)
return false;
} break;
case "DEF":
{
if (this.def < perkReqs.DEF)
return false;
} break;
case "MATK":
{
if (this.matk < perkReqs.MATK)
return false;
} break;
case "MDEF":
{
if (this.mdef < perkReqs.MDEF)
return false;
} break;
case "AGI":
{
if (this.agi < perkReqs.AGI)
return false;
} break;
case "LUK":
{
if (this.luk < perkReqs.LUK)
return false;
} break;
case "LEVEL":
{
if (this._level < perkReqs.LEVEL)
return false;
} break;
case "PERK":
{
var hasPerk = false;
for (var i = 0; i < this._obtainedPerks.length; i++) {
if (this._perks[this._obtainedPerks[i]].name === perkReqs.PERK)
hasPerk = true;
};
if (!hasPerk)
return false;
} break;
case "SWITCH":
{
var data = perkReqs.SWITCH.split(" ");
var switchId = Number(data[0]);
var switchState = data[1] === "ON" || false;
if ($gameSwitches.value(switchId) !== switchState)
return false;
} break;
case "VARIABLE":
{
var data = perkReqs.VARIABLE.split(" ");
var varId = Number(data[0]);
var sign = String(data[1]);
var value = Number(data[2]);
var varValue = $gameVariables.value(varId);
var success = false;
switch (sign)
{
case ">":
{
if (varValue > value)
success = true;
} break;
case ">=":
{
if (varValue >= value)
success = true;
} break;
case "<":
{
if (varValue < value)
success = true;
} break;
case "<=":
{
if (varValue <= value)
success = true;
} break;
case "==":
{
if (varValue === value)
success = true;
} break;
case "!=":
{
if (varValue !== value)
success = true;
} break;
}
if (!success)
return false;
} break;
}
}
}
this._perkPoints--;
this._obtainedPerks.push(id);
return true;
};
Game_Actor.prototype.initPerks = function() {
var perkStartRegex = //i;
var perkEndRegex = /<\/perk>/i
var nameRegex = //i
var reqStartRegex = //i;
var reqEndRegex = /<\/requirements>/i;
var dataRegex = /[a-zA-Z]*[:][ ]*(.*)/i;
var rewardsStartRegex = //i;
var rewardsEndRegex = /<\/rewards/i;
var descStartRegex = //i;
var descEndRegex = /<\/description/i;
var perkFound = false;
var reqFound = false;
var rewardsFound = false;
var descFound = false;
var perk = {};
var note = this.actor().note.split(/[\r\n]/);
for (var i = 0; i < note.length; i++) {
//
if (!perkFound)
{
var perkMatch = perkStartRegex.exec(note[i]);
if (perkMatch)
{
perk = {};
perk.requirements = {};
perk.rewards = {};
perk.name = "";
perkFound = true;
this._perks.push(perk);
}
}
else if (perkFound)
{
var perkEndMatch = perkEndRegex.exec(note[i]);
if (perkEndMatch)
{
perkFound = false;
reqFound = false;
rewardsFound = false;
descFound = false;
}
}
//
if (!reqFound)
{
var reqMatch = reqStartRegex.exec(note[i]);
if (reqMatch)
reqFound = true;
}
else if (reqFound)
{
var reqEndMatch = reqEndRegex.exec(note[i]);
if (reqEndMatch)
reqFound = false;
}
//
if (!rewardsFound)
{
var rewardsMatch = rewardsStartRegex.exec(note[i]);
if (rewardsMatch)
rewardsFound = true;
}
else if (rewardsFound)
{
var rewardsEndMatch = rewardsEndRegex.exec(note[i]);
if (rewardsEndMatch)
rewardsFound = false;
}
//
if (!descFound)
{
var descMatch = descStartRegex.exec(note[i]);
if (descMatch){
descFound = true;
perk.description = [];
}
}
else if (descFound)
{
var descEndMatch = descEndRegex.exec(note[i]);
if (descEndMatch)
descFound = false;
if (descFound)
perk.description.push(note[i]);
}
//
var nameMatch = nameRegex.exec(note[i]);
if (nameMatch)
perk.name = nameMatch[1];
// Requirements Data
if (reqFound)
{
var reqDataMatch = dataRegex.exec(note[i]);
if (!reqDataMatch) continue;
switch(reqDataMatch[0].toUpperCase().split(":")[0])
{
case "LEVEL":
{
perk.requirements.LEVEL = Number(reqDataMatch[1]);
} break;
case "ATK":
{
perk.requirements.ATK = Number(reqDataMatch[1]);
} break;
case "DEF":
{
perk.requirements.DEF = Number(reqDataMatch[1]);
} break;
case "MATK":
{
perk.requirements.MATK = Number(reqDataMatch[1]);
} break;
case "MDEF":
{
perk.requirements.MDEF = Number(reqDataMatch[1]);
} break;
case "AGI":
{
perk.requirements.AGI = Number(reqDataMatch[1]);
} break;
case "LUK":
{
perk.requirements.LUK = Number(reqDataMatch[1]);
} break;
case "PERK":
{
perk.requirements.PERK = String(reqDataMatch[1]);
} break;
case "SWITCH":
{
perk.requirements.SWITCH = String(reqDataMatch[1]).toUpperCase();
} break;
case "VARIABLE":
{
perk.requirements.VARIABLE = String(reqDataMatch[1]);
} break;
}
}
// Rewards Data
else if (rewardsFound)
{
var rewardsDataMatch = dataRegex.exec(note[i]);
if (!rewardsDataMatch) continue;
switch(rewardsDataMatch[0].toUpperCase().split(":")[0])
{
case "STATE":
{
perk.rewards.STATE = Number(rewardsDataMatch[1]);
} break;
case "COMMONEVENT":
{
perk.rewards.COMMONEVENT = Number(rewardsDataMatch[1]);
} break;
}
}
};
};
var _GameActor_traitObjects = Game_Actor.prototype.traitObjects;
Game_Actor.prototype.traitObjects = function() {
var objects = _GameActor_traitObjects.call(this);
for (var i = 0; i < this._obtainedPerks.length; i++) {
if (this._perks[this._obtainedPerks[i]].rewards.STATE)
objects.push($dataStates[this._perks[this._obtainedPerks[i]].rewards.STATE]);
};
return objects;
};
//--------------------------------------------------------------------------
// Scene_Menu
//
var _SceneMenu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
Scene_Menu.prototype.createCommandWindow = function() {
_SceneMenu_createCommandWindow.call(this);
this._commandWindow.setHandler('perks', this.commandPersonal.bind(this));
};
Window_MenuCommand.prototype.addOriginalCommands = function() {
this.addCommand(paramName, 'perks', $gameSystem.isPerksCommandEnabled());
};
var _SceneMenu_onPersonalOk = Scene_Menu.prototype.onPersonalOk;
Scene_Menu.prototype.onPersonalOk = function() {
_SceneMenu_onPersonalOk.call(this);
if (this._commandWindow.currentSymbol() === 'perks')
SceneManager.push(Scene_Perks);
};
//--------------------------------------------------------------------------
// Scene_Perks
//
// Perks Scene where player can activate perks for perk points.
function Scene_Perks() {
this.initialize.apply(this, arguments);
};
Scene_Perks.prototype = Object.create(Scene_MenuBase.prototype);
Scene_Perks.prototype.constructor = Scene_Perks;
Scene_Perks.prototype.initialize = function() {
Scene_MenuBase.prototype.initialize.call(this);
};
Scene_Perks.prototype.create = function() {
Scene_MenuBase.prototype.create.call(this);
this.createMainWindow();
this.createPerkWindow();
this.createPerkInfoWindow();
this.onActorChange();
};
Scene_Perks.prototype.createMainWindow = function() {
this._windowDummy = new Window_MainPerks();
this.addWindow(this._windowDummy);
};
Scene_Perks.prototype.createPerkWindow = function() {
this._windowCommand = new Window_SelectPerks();
this._windowCommand.setHandler('ok', this.onPerkOk.bind(this));
this._windowCommand.setHandler('cancel', this.popScene.bind(this));
this._windowCommand.setHandler('pagedown', this.nextActor.bind(this));
this._windowCommand.setHandler('pageup', this.previousActor.bind(this));
this.addWindow(this._windowCommand);
};
Scene_Perks.prototype.createPerkInfoWindow = function() {
this._windowInfo = new Window_InfoPerks();
this.addWindow(this._windowInfo);
this._windowCommand.setHelpWindow(this._windowInfo);
};
Scene_Perks.prototype.onActorChange = function() {
this._windowCommand.setActor(this._actor);
this._windowCommand.activate();
this._windowCommand.select(0);
};
Scene_Perks.prototype.onPerkOk = function() {
};
//--------------------------------------------------------------------------
// Window_MainPerks
//
// Just a dummy window to take up space.
function Window_MainPerks() {
this.initialize.apply(this, arguments);
};
Window_MainPerks.prototype = Object.create(Window_Base.prototype);
Window_MainPerks.prototype.constructor = Window_MainPerks;
Window_MainPerks.prototype.initialize = function() {
var ww = Graphics.boxWidth >= 816 ? 816 : Graphics.boxWidth;
var wh = Graphics.boxHeight >= 624 ? 624 : Graphics.boxHeight;
var wx = Graphics.boxWidth/2 - ww/2;
var wy = Graphics.boxHeight/2 - wh/2;
Window_Base.prototype.initialize.call(this, wx, wy, ww, wh);
};
//--------------------------------------------------------------------------
// Window_SelectPerks
//
// Window where player can select and buy perks.
function Window_SelectPerks() {
this.initialize.apply(this, arguments);
};
Window_SelectPerks.prototype = Object.create(Window_Selectable.prototype);
Window_SelectPerks.prototype.constructor = Window_SelectPerks;
Window_SelectPerks.prototype.initialize = function() {
var ww = Graphics.boxWidth >= 816 ? 816 : Graphics.boxWidth;
var wh = Graphics.boxHeight >= 624 ? 624 : Graphics.boxHeight;
var wx = Graphics.boxWidth/2 - ww/2;
var wy = Graphics.boxHeight/2 - wh/2;
Window_Selectable.prototype.initialize.call(this, wx, wy, ww/2.5, wh);
this._actor = null;
this.refresh();
};
Window_SelectPerks.prototype.maxItems = function() {
return this._actor ? this._actor.getPerkList().length : 0;
};
Window_SelectPerks.prototype.item = function() {
var index = this.index();
return this._actor ? this._actor.getPerkList()[index] : null;
};
Window_SelectPerks.prototype.drawItem = function(index) {
var item = this._actor.getPerkList()[index];
if (item) {
var rect = this.itemRectForText(index);
this.changePaintOpacity(this._actor.isPerkObtained(index));
this.drawText(item.name, rect.x+5, rect.y, rect.width);
}
};
Window_SelectPerks.prototype.setActor = function(actor) {
this._actor = actor;
this.refresh();
};
Window_SelectPerks.prototype.updateHelp = function() {
this._helpWindow.setActor(this._actor);
this._helpWindow.setItem(this.item());
};
Window_SelectPerks.prototype.isCurrentItemEnabled = function() {
return !this._actor.isPerkObtained(this.index());
};
Window_SelectPerks.prototype.processOk = function() {
if (this.isCurrentItemEnabled() && this._actor.tryToObtainPerk(this.index())) {
this.playOkSound();
this.updateInputData();
this.redrawCurrentItem();
this.updateHelp();
this.callOkHandler();
} else {
this.playBuzzerSound();
}
};
//--------------------------------------------------------------------------
// Window_InfoPerks
//
// Window that shows perk info.
function Window_InfoPerks() {
this.initialize.apply(this, arguments);
};
Window_InfoPerks.prototype = Object.create(Window_Base.prototype);
Window_InfoPerks.prototype.constructor = Window_InfoPerks;
Window_InfoPerks.prototype.initialize = function() {
var ww = Graphics.boxWidth >= 816 ? 816 : Graphics.boxWidth;
var wh = Graphics.boxHeight >= 624 ? 624 : Graphics.boxHeight;
var wx = Graphics.boxWidth/2 - ww/2;
var wy = Graphics.boxHeight/2 - wh/2;
this._currentPerk = null;
this._actor = null;
Window_Base.prototype.initialize.call(this, wx+ww/2.5, wy, 816-ww/2.5, wh);
};
Window_InfoPerks.prototype.setItem = function(perk) {
this._currentPerk = perk;
this.refresh();
};
Window_InfoPerks.prototype.refresh = function() {
this.contents.clear();
if (!this._currentPerk) return;
this.drawActorInfo();
this.drawPerkInfo();
this.drawPointCount();
};
Window_InfoPerks.prototype.drawPointCount = function() {
var y = this.contentsHeight() - this.lineHeight()*2;
this.drawHorzLine(y);
y += this.lineHeight();
this.drawText("Perk Points: " + this._actor.getPerkPoints(), 0, y);
};
Window_InfoPerks.prototype.drawPerkDescription = function(y) {
var description = this._currentPerk.description;
var tempText = [];
for (var i = 0; i < description.length; i++) {
tempText.push([""]);
var text = tempText[i];
var brokenText = description[i].split(" ");
for (var j = 0; j < brokenText.length; j++) {
var txtWidth = this.textWidth(text[text.length-1] + brokenText[j]);
if (txtWidth >= this.contentsWidth())
text.push([""]);
text[text.length-1] += brokenText[j] + " ";
}
};
for (var i = 0; i < tempText.length; i++) {
for (var j = 0; j < tempText[i].length; j++) {
y += this.lineHeight();
this.drawText(tempText[i][j], 0, y);
};
};
};
Window_InfoPerks.prototype.drawPerkInfo = function() {
var lineHeight = this.lineHeight();
var perk = this._currentPerk;
var y = lineHeight*5;
var reqText = ["Req: "];
var level = 0;
var special = false;
var tempText = [];
for (var property in perk.requirements)
{
if (perk.requirements.hasOwnProperty(property))
{
switch (property)
{
case "LEVEL":
{
level = perk.requirements.LEVEL;
} break;
case "SWITCH":
{
special = true;
} break;
case "VARIABLE":
{
special = true;
} break;
case "PERK":
{
tempText.push(perk.requirements.PERK);
} break;
default:
{
tempText.push(String(property) + " " + perk.requirements[property]);
} break;
}
}
}
if (level > 0)
{
var comma = (tempText.length > 0 || special) ? ", " : "";
reqText[0] += "Level " + level + comma;
}
if (special)
tempText.push("Secret");
for (var i = 0; i < tempText.length; i++) {
var comma = tempText.length-1 !== i ? ", " : "";
var txtWidth = this.textWidth(reqText[reqText.length-1]+tempText[i]+comma);
if (txtWidth >= this.contentsWidth())
reqText.push("");
reqText[reqText.length-1] += tempText[i] + comma;
};
for (var i = 0; i < reqText.length; i++) {
this.drawText(reqText[i], 0, y);
y += lineHeight;
};
this.drawHorzLine(y);
this.drawPerkDescription(y);
};
Window_InfoPerks.prototype.drawActorInfo = function() {
var lineHeight = this.lineHeight();
var actor = this._actor;
this.drawActorFace(actor, 0, 0);
this.drawActorName(actor, 220, 0);
this.drawActorClass(actor, 220, lineHeight);
this.drawActorLevel(actor, 400, 0);
this.drawActorHp(actor, 220, lineHeight*2, this.contentsWidth()-220);
this.drawActorMp(actor, 220, lineHeight*3, this.contentsWidth()-220);
this.drawHorzLine(lineHeight*4);
};
Window_InfoPerks.prototype.setActor = function(actor) {
this._actor = actor;
};
Window_InfoPerks.prototype.drawHorzLine = function(y) {
var lineY = y + this.lineHeight() / 2 - 1;
this.contents.paintOpacity = 48;
this.contents.fillRect(0, lineY, this.contentsWidth(), 2, this.lineColor());
this.contents.paintOpacity = 255;
};
Window_InfoPerks.prototype.lineColor = function() {
return this.normalColor();
};
//--------------------------------------------------------------------------
// Game_System
//
var _GameSystem_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
_GameSystem_initialize.call(this);
this._isPerksCommandEnabled = true;
};
Game_System.prototype.isPerksCommandEnabled = function() {
return this._isPerksCommandEnabled || false;
};
Game_System.prototype.changePerksCommand = function(bool) {
this._isPerksCommandEnabled = bool;
};
})();