//=============================================================================// Aria Framework// Version 0.0.1//=============================================================================/*: * @plugindesc A game development framework to extend and encapsulate core RPG * Maker functionality. * @author Jake Finley * * @help * This plugin is intended to enable game developers to create better games * faster than they could on their own using the built in components of RPG * Maker. For developers already comfortable with JavaScript it aims to use * a similar style and API to the popular jQuery library (commonly used for * for websites and apps). For new developers, or those just new to JS it * aims to provide a simplified interface, debugging tools, and powerful * shortcuts that can be easily integrated into your game. * * There are no known conflicts with other plugins, but the framework is * inherently invasive (it is intended to hijack nearly all built-in classes), * and this is currently a very early alpha stage of development. * * Aria is open source and licensed under the MIT license (which permits you * to sell and make money off of things created with Aria, among other things). * The full license text is included below. Contributions to the project are * welcome, and anyone wishing to do so can find the repository on Github: * https://github.com/jakefinley/Aria.js * * ------------------------------------------------------------------------------- * The MIT License (MIT) * * Copyright (c) 2015 Jake Finley * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * ------------------------------------------------------------------------------- *//** * Provides access to the Aria API, the functions returned by calling Aria() are those intended * to be used outside the framework itself. Further API functions have a target that can be acted * upon, and this can be passed in as a parameter Aria(), which will then pass it along to the API * function being called. You can access the API directly via Aria.api but it should not normally * be necessary to do so. * @param target {*} * @returns {{before: Function, after: Function, note: Function}} * @TODO: More API functions, possibly automate how this works? */var Aria = function(target) { return { before: function (callback) { Aria.api.registerHook('before', target, callback); return this; }, after: function (callback) { Aria.api.registerHook('after', target, callback); return this; }, note: function (name) { return Aria.api.GetNoteVal(target, name); } }};//-----------------------------------------------// Properties -//-----------------------------------------------Aria.isInstalled = true;Aria.actions = Aria.actions || {before: [], after: []};Aria.builtin = Aria.builtin || {};Aria.api = Aria.api || {};Aria.private = Aria.private || {};Aria.hooks = [];//-----------------------------------------------// Private Functions -//-----------------------------------------------/** * Initialize Aria and create hooks for most RPG Maker core classes. * * TODO: Determine if more classes need to be added or if some of these should be removed * TODO: Add in method of customizing what classes are monitored by Aria (possibly plugin parameter?) */Aria.private.init = function() { var classes = [ "Game_Temp", "Game_System", "Game_Screen", "Game_Timer", "Game_Message", "Game_Switches", "Game_Variables", "Game_SelfSwitches", "Game_Actors", "Game_Party", "Game_Troop", "Game_Map", "Game_Player" ]; // Loop through classes setting up hooks, window global used to retrieve classes from their names for(var i in classes) { if(classes.hasOwnProperty(i)) { var className = classes; var coreClass = window[className]; Aria.builtin[className] = {}; for (var prop in coreClass.prototype) { var hook = Aria.private.slugify([className, prop]); Aria.hooks.push(hook); Aria.private.setupCallback(coreClass, className, prop, hook); } } }};/** * Uses the "Official" method of overriding built in class methods to set up before and after hooks. * The hooks can modify the execution and results of the core function in several ways, including * directly manipulating its input and output, or cause the core code (AND any plugin code) to not * execute by returning false on the before hook. * * The value of 'this' in the callback is whatever 'this' would have been in the original core function, * and that is passed along to hooks as well as the core function when they are called. Likewise 'arguments' * is whatever arguments the core function would normally be called with, and these too are passed along to * the hooked in functions. * @param coreClass {object} The RPG Maker built in class 'prop' belongs to * @param className {string} The string name of the core RPG Maker class * @param prop {string} The class method to be hook-enabled * @param hook {string} The name/slug of the hook that will be used to inject code into this function * @TODO: Add additional features beyond just code injection * @TODO: Consider revising how data is passed to hooks and back to the core class * @TODO: Consider removing ability to cancel core function call (its a little dangerous) */Aria.private.setupCallback = function(coreClass, className, prop, hook) { Aria.builtin[className][prop] = coreClass.prototype[prop]; coreClass.prototype[prop] = function() { arguments._result = null; arguments._cancel = false; Aria.private.trigger('before', hook, this, arguments); if(arguments._cancel !== true) { arguments._result = Aria.builtin[className][prop].apply(this, arguments); } Aria.private.trigger('after', hook, this, arguments); return arguments._result; };};/** * Joins a string array with '.' separators and strips out underscores, then returns the final product in * all lower case. * @param text_list {array} An array of strings to be joined and processed * @returns {string} */Aria.private.slugify = function(text_list) { return text_list.join('.').replace('_', '').toLowerCase();};/** * Triggers hooks - any function registered to a particular hook will be called when that hook is triggered. * @param timing {string} "before" or "after" * @param name {string} The name of the hook to be triggered * @param context {object} The value of "this" that should be passed to the hook * @param args {object} The arguments to be passed to the callback function, ._result and ._cancel are added to the * other arguments and can be manipulated by the callback to either change the results of both other hooks and the * core function, or cancel the execution of the core function. * @TODO: Consider changing this to use .call() instead of .apply(), might be more consistent */Aria.private.trigger = function(timing, name, context, args) { //console.log(prefix + ": " + name); var rtnval; for(var i in Aria.actions[timing][name]) { if(Aria.actions[timing][name].hasOwnProperty(i)) { rtnval = null; rtnval = Aria.actions[timing][name].apply(context, args); if(rtnval === false) args._cancel = true; } }};//-----------------------------------------------// API Functions -//-----------------------------------------------/** * A variation of the metadata parser built into RPG Maker, returns an array of values. If the note contains * a comma separated list, ie "<name: abc, def, hij>" then you will get an array in the format ["abc", "def", "jij"]. * Unlike the built in version a space after the colon is required, likewise after each comma. * @param obj {object} The object (actor, item, etc) that you want to fetch a note value for * @param tag {string} The name of the note tag, ie in <example: value> "example" would be the tag name * @returns {Array} * @TODO: Greatly improve this, possibly replace it entirely. At minimum enable optional use of spaces */Aria.api.GetNoteVal = function(obj, tag) { var notes = obj.note.split(/[\r\n]+/); try { for(var i in notes) { var note = notes; var regex = new RegExp("<(?:" + tag + "):[ ]([^<>]+)>", "i"); return note.match(regex)[1].split(', '); } } catch (e) { return null; } return null;};/** * Registers a callback function to be ran when the given hook is triggered, either before or after the * core function call. * @param timing {string} Either "before" or "after" * @param hook {string} The hook slug that the callback should be associated with * @param callback {function} A function to be executed at the given hook and timing * @TODO: Add plugin param to control debug output */Aria.api.registerHook = function(timing, hook, callback) { Aria.actions[timing][hook] = Aria.actions[timing][hook] || []; Aria.actions[timing][hook].push(callback); console.log('registered hook: ['+timing+']['+hook+']', callback);};Aria.private.init();