Adding new variables to Game_Party? (SOLVED)

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
After taking a few days to ensure that the necessary objects are working properly, I've run into problems adding a variable to Game_Party to keep a glossary of important information in RPG Maker MV.

The idea is that I should be able to access the new variable via the Script command in events to add new items to it, edit existing items, and check if certain items are present in the list; once I've got the list working properly I'll migrate everything into Plugin commands to streamline everything, but at present the list does not seem to successfully bind to the Game_Party prototype.

I've already verified that the intelList and intelItem object prototypes (defined in a separate file for the moment) are working properly, so I must be doing something wrong/forgetting something with the redefinitions.

Code:
//Attach IntelList to the Party object on initialization.
Game_Party.prototype.initialize = function() {
    Game_Unit.prototype.initialize.call(this);
    this._gold = 0;
    this._steps = 0;
    this._lastItem = new Game_Item();
    this._intelList = new intelList();
    this._menuActorId = 0;
    this._targetActorId = 0;
    this._actors = [];
    this.initAllItems();
};

//Methods for accessing data from intelList
//Returns the categories
Game_Party.prototype.getIntelCategories = function() {
    return this._intelList.intelCategories;
};

//Return all Intel items in the list.
Game_Party.prototype.getAllIntel = function() {
    return this._intelList.intelItems;
};

//Used for event flags.
Game_Party.prototype.hasIntel = function(targetIntel){
    return this._intelList.hasIntel(targetIntel);
};

//Return all Intel items with the specified category.
Game_Party.prototype.getIntelFromCategory = function(category) {
        return this._intelList.getIntelFromCategory(category);
};

//returns a string for an in-game message if the intel was added successfully.
Game_Party.prototype.addIntel = function(targetIntel){
    return(this._intelList.addIntel(targetIntel));
};

Code:
var newIntel = new intelItem("Places", "Chi Bi",
["A small fishing villiage located on the southern cliffs of the Song Empire.  Its name translates roughly to 'red stone', in refference to the dusty redstone cliffs the city was built upon.",
"Chi Bi was once a major waypoint between the Jing providences of the central and Eastern empire, and the various kingdoms to the north.  After the establishment of a more accessable port on Wei Zhou island the city's economic power quickly dwindled.  Today most of its residents are either fisherfolk or subsistance farmers."]);
$gameParty.addIntel(newIntel);

Attempting to run this script causes a game crash on execution (TypeError: undefined is not a function), which I'm assuming means that $gameParty.addIntel is not being successfully applied.

Now, I have two questions:
  1. Why isn't this working as expected, and how do I fix that?
  2. Is there a better place to define/attach intelList?
 
Last edited:

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
Nothing immediately jumps out at me as wrong with the sample code.
 

Kino

EIS Game Dev
Veteran
Joined
Nov 27, 2015
Messages
556
Reaction score
794
First Language
English
Primarily Uses
RMMV
Where is intelList defined? Does it have all those v properties and methods like addIntel, has intel, etc?

Also, when you made that plugin for your intelList class, did you use a closure? If you wrapped your code in a closure IntelList doesn't exist to game_party's prototype.
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
The code defining the IntelList variable is loaded through a separate plugin loaded prior to the one the code sample was taken from; this was mostly done in an effort to determine what was going wrong. I'm not presently using closures on any of my code; this will likely be implemented later once I've actually gotten the code working, although at that point the variables will be joined to the script in the first post.

I've gone ahead and included it in the spoiler below in the event that I'm missing something obvious.
Code:
function intelItem(category,topic,contents) {
    this.category = category;
    this.topic = topic;
    this.contents = contents;
    this.matches = function (intelFromList) {
        var index = 0;
        //isMatch first checks if the topics match; while loop won't even start if they don't.
        var isMatch = (this.topic === intelFromList.topic);       
        while (isMatch && index <  this.contents.length) {
            //Step through the contents of the item executing the function; if the obect from the list does not have one indexed, end the loop and return false.
            isMatch = (intelFromList.contents.indexOf(this.contents[index]) > -1);
            index++;
        };
        return isMatch;
    };
    
    this.helpFindIndex = function(intelFromList) {
        var result = this.topic.localeCompare(intelFromList.topic);
        return (result === -1);
    };
    
    this.addNewContents = function(intelFromList){
        var newContentsAdded = false;
        for (var index = 0; index < this.contents.length; index++) {
            if (intelFromList.contents.indexOf(this.contents[index]) === -1) {
                intelFromList.contents.push("  " + this.contents[index]);
                newContentsAdded = true;
            };
        };
        return newContentsAdded;
    };
}


function intelList() {
    this.intelItems = [];
    this.intelCategories = [];
    
    this.getIntelFromCategory = function(categoryName){
        var result = [];
        for (var index = 0; index < this.intelItems.length; index++) {
            if (this.intelItems[index].category === categoryName) {
                result.push(this.intelItems[index]);
            };
        };
        return result;
    };
    
    this.sortingAlgorithm = function(sortingTarget) {
        var x = this.intelItems.length - 1;
        var searching = true;
        while (x >= 0 && searching) {
            searching = sortingTarget.helpFindIndex(this.intelItems[x]);
          
            if (searching) {
                x -= 1;
            };
        };
        return x;
    };
    
    this.addIntel = function(targetIntel) {   
        var result = null;
        var dexVal = this.sortingAlgorithm(targetIntel);
        if (this.intelCategories.indexOf(targetIntel.category) === -1) {
            this.intelCategories.push(targetIntel.category);
            this.intelCategories.sort();
        };
        if (dexVal === -1) {
            this.intelItems.unshift(targetIntel);
            
            result = "New intelligence file: " + targetIntel.topic;
        } else {
            var intelAtIndex = this.intelItems[dexVal];
            
            if (intelAtIndex.topic != targetIntel.topic) {
                this.intelItems.splice(dexVal+ 1, 0, targetIntel);
                result = "New intelligence file: " + targetIntel.topic;
            } else {
                var contentsCheck = targetIntel.addNewContents(intelAtIndex);
                if (contentsCheck){
                    result = "Information updated: " + targetIntel.topic;
                };
            };
        };
        return result;   
    };
    
    this.hasIntel = function(targetIntel) {
        var searchFunction = function(intelFromList){
            return targetIntel.matches(intelFromList);
        };
        
        return this.intelItems.some(searchFunction);
    };
}
 

Kino

EIS Game Dev
Veteran
Joined
Nov 27, 2015
Messages
556
Reaction score
794
First Language
English
Primarily Uses
RMMV
The issue with your code is that you don't have any prototypes in your intelList definition here. That intelList function will not work because it's attached to intelList as a static method.

You need to change it to this:

PHP:
function intelList() {};

intelList.prototype.getIntelFromCategory = function(categoryName) {
  //Code
}
For a lot of your functions. @Camkitsune
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
I switched all of the non-constructor methods to being defined via intelList.prototype.function; same problem with the game crashing due to 'Undefined is not a function' when running $gameParty.addIntel(newIntel) (commenting that out of the script allows it to run fine).
I'm not exactly sure how defining the methods via intelList.prototype outside of the constructor is different from defining them via this.method = function() method, since most of my experience in OOP is in C#;

Strategically commenting out bits of the code has narrowed it down to Game_Party.addIntel being the part that isn't defined; even removing all of the contents results in a crash when called via script.
 

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
I've copied all the code to a single plugin on a new project. Everything seems to work fine on my end. There are no error messages and when I ran the inievent script in the console the string "New intelligence file: Chi Bi" appears.

Code:
function intelItem(category,topic,contents) {
    this.category = category;
    this.topic = topic;
    this.contents = contents;
    this.matches = function (intelFromList) {
        var index = 0;
        //isMatch first checks if the topics match; while loop won't even start if they don't.
        var isMatch = (this.topic === intelFromList.topic);      
        while (isMatch && index <  this.contents.length) {
            //Step through the contents of the item executing the function; if the obect from the list does not have one indexed, end the loop and return false.
            isMatch = (intelFromList.contents.indexOf(this.contents[index]) > -1);
            index++;
        };
        return isMatch;
    };
   
    this.helpFindIndex = function(intelFromList) {
        var result = this.topic.localeCompare(intelFromList.topic);
        return (result === -1);
    };
   
    this.addNewContents = function(intelFromList){
        var newContentsAdded = false;
        for (var index = 0; index < this.contents.length; index++) {
            if (intelFromList.contents.indexOf(this.contents[index]) === -1) {
                intelFromList.contents.push("  " + this.contents[index]);
                newContentsAdded = true;
            };
        };
        return newContentsAdded;
    };
}

function intelList() {
    this.intelItems = [];
    this.intelCategories = [];
   
    this.getIntelFromCategory = function(categoryName){
        var result = [];
        for (var index = 0; index < this.intelItems.length; index++) {
            if (this.intelItems[index].category === categoryName) {
                result.push(this.intelItems[index]);
            };
        };
        return result;
    };
   
    this.sortingAlgorithm = function(sortingTarget) {
        var x = this.intelItems.length - 1;
        var searching = true;
        while (x >= 0 && searching) {
            searching = sortingTarget.helpFindIndex(this.intelItems[x]);
         
            if (searching) {
                x -= 1;
            };
        };
        return x;
    };
   
    this.addIntel = function(targetIntel) {
        var result = null;
        var dexVal = this.sortingAlgorithm(targetIntel);
        if (this.intelCategories.indexOf(targetIntel.category) === -1) {
            this.intelCategories.push(targetIntel.category);
            this.intelCategories.sort();
        };
        if (dexVal === -1) {
            this.intelItems.unshift(targetIntel);
           
            result = "New intelligence file: " + targetIntel.topic;
        } else {
            var intelAtIndex = this.intelItems[dexVal];
           
            if (intelAtIndex.topic != targetIntel.topic) {
                this.intelItems.splice(dexVal+ 1, 0, targetIntel);
                result = "New intelligence file: " + targetIntel.topic;
            } else {
                var contentsCheck = targetIntel.addNewContents(intelAtIndex);
                if (contentsCheck){
                    result = "Information updated: " + targetIntel.topic;
                };
            };
        };
        return result;  
    };
   
    this.hasIntel = function(targetIntel) {
        var searchFunction = function(intelFromList){
            return targetIntel.matches(intelFromList);
        };
       
        return this.intelItems.some(searchFunction);
    };
}

//Attach IntelList to the Party object on initialization.
Game_Party.prototype.initialize = function() {
    Game_Unit.prototype.initialize.call(this);
    this._gold = 0;
    this._steps = 0;
    this._lastItem = new Game_Item();
    this._intelList = new intelList();
    this._menuActorId = 0;
    this._targetActorId = 0;
    this._actors = [];
    this.initAllItems();
};

//Methods for accessing data from intelList
//Returns the categories
Game_Party.prototype.getIntelCategories = function() {
    return this._intelList.intelCategories;
};

//Return all Intel items in the list.
Game_Party.prototype.getAllIntel = function() {
    return this._intelList.intelItems;
};

//Used for event flags.
Game_Party.prototype.hasIntel = function(targetIntel){
    return this._intelList.hasIntel(targetIntel);
};

//Return all Intel items with the specified category.
Game_Party.prototype.getIntelFromCategory = function(category) {
        return this._intelList.getIntelFromCategory(category);
};

//returns a string for an in-game message if the intel was added successfully.
Game_Party.prototype.addIntel = function(targetIntel){
    return(this._intelList.addIntel(targetIntel));
};
 

Kino

EIS Game Dev
Veteran
Joined
Nov 27, 2015
Messages
556
Reaction score
794
First Language
English
Primarily Uses
RMMV
When you define them like that, they're almost the same but it's not best practices in JS.

The functions in JS are objects and each function has a prototype.constructor property.

What you're doing is attaching the method directly to that instance of the function.

So, if you wanted to make a class that inherited from the original function it wouldn't work, because there'd be no prototype/parent to look up for methods.

Or you could use Object.create to inherit from the original function the way it's setup now, but I don't recommend it.
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
Consolidating everything into one file did the trick; the next step would be to create a menu item to view that data. When I inevitably run into a problem I can't work out the solution to on my own, would it be better to make a new thread concerning getting the data into the window, or should I just use this one?
 

Kino

EIS Game Dev
Veteran
Joined
Nov 27, 2015
Messages
556
Reaction score
794
First Language
English
Primarily Uses
RMMV
Just use this one I'd say and that's strange. I think someone said MV does each plugin included as its own closure.
 

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
I did a quick test and separated the intelItem and intelList functions and Game_Party stuff into their own files and everything still worked as expected. The help documents suggest creating closures for each plugin but RMMV doesn't enforce it.
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
I've subsequently moved on to trying to transform the base code into a proper plugin. However, there are a couple of things I'm still unsure about:

1) I've put all of the code inside of a closure; this is done with the understanding that I can write a Plugin Command to perform the required functions without having to individually scripting them. However, I can't find the documentation on how to actually write these. Could someone point me in the correct direction?

2) I've opted to create static definitions for the intel items rather than individually write them out every time I need to check/add them, for the sake of avoiding typos crippling the entire game. Instead of filling the plugins with hundreds of parameters I've opted to write all of the necessary data into a single json file. Can I add a reference to the new json file via DataManager._databaseFiles.push, or do I need to essentially copy the functionality for loading the file into the plugin?
 

Kino

EIS Game Dev
Veteran
Joined
Nov 27, 2015
Messages
556
Reaction score
794
First Language
English
Primarily Uses
RMMV
2) You could add it manually to the DataManager._databaseFiles, but you should probably hard code it. Pushing it might work, but the Database only loads the files once.

Or you could do this inside of your plugin:

Code:
DataManager.loadDataFile('$dataMyVariables', "mydata.json");
That will send an XMLHTTP request to the server and will work on browsers too, and create a global variable with that name based on your json file.
 

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
1) Monkey patch/alias Game_Interpreter.prototype.pluginCommand(). Monkey patching/aliasing is saving a reference to the original function to invoke later then replacing it with a new function. The replacement can do its new thing and invoke the original via the reference. Here's one example and the RMMV help document shows another.
Code:
// Monkey patch/alias pluginCommand

Game_Interpreter.prototype.pluginCommand = (function (original) {
    "use strict";

    // Define the function that will replace the original.

    function pluginCommand(command, args) {

        // Invoke the original pluginCommand function.
    
        original.call(this, command, args);

        // Deal with arguments command and args.
        // command is a string, the command name.
        // args is an array of strings.

        // Say we had the plugin command:
        // myCommand valuA valuB valuC

        // The value of the command argument will be "myCommand"
        // The value of the args argument will be ["valuA", "valuB", "valuC"]

        // Maybe you want to return if your command wasn't passed in.

        if (command !== "myCommand") {
            return;
        }

        // Still executing? Great! Evaluate the args array next.

        // if (args[0] === ...
    }

    return pluginCommand;

    // The line below is where we pass in a reference to the original
    // function for use in the replacement.
}(Game_Interpreter.prototype.pluginCommand));
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
So I've rewritten everything as shown below:
Code:
/*:
* @plugindesc Adds Intel-Gathering funcionality: itemized intel, checks for
* event handling, and a menu for viewing collected Intel.
* @author Camkitsune
*
* @param JsonFileName
* @desc Filename for the JSON file containing the intel data.
* @default 'Intel.json'
*
* @param ShowAlerts
* @desc Boolean toggles whether or not alert messages appear on intel gain/
* update; functionality currently not implemeneted.
* @default false;
*
* @help
* BETA VERSION
* ------------ABOUT------------------------------------------------------------
* This plugin adds an Intel-gathering feature to RPG Maker MV: it keeps a
* list of user-defined itemized information on specific topics that can be
* viewed via an option in the Menu. 
* Individual items can have multiple notes added at different times according
* to the arguments given.  The presence of certain Intel items can be checked
*
* For flexibility and maintainability, the actual data for intelItems is to be
* saved in a separate JSON file in the data folder.
*
* ------------COMMANDS---------------------------------------------------------
* Plugin commands take the format below:
* IntelPlugin("command", ["id", "contents# contents#"])
*
* "command" should be either "add" to insert a new intel item (or update one
* the player already has), or "check" to determine whether the player has the
* intel required to activate an event switch.
*
* "id" is a string form of the id number of the intel file you want to use for
* the command.
*
* the second string is used to determine which items from the contents array
* you want to use for the command.  These arrays start at zero; negatives and
* numbers greater than the number of contents will be ignored.  For "check"
* commands an empty string can be used to simply check for the topic.
*
* ------------ITEM PARAMETERS--------------------------------------------------
* Each Itel item has three parameters:
* Category = the Category the item will belong to.  Items can currently only
* have one category.
* Topic = What the Contents will appear under when looked up in the menu.  Two
* items cannot have the same topic; using identical topics for multiple items
* will result in their contents being merged.
* Contents = all text that will appear under the specified topic, arranged into
* an array.  Individual lines are intended to serve as seperate bits that will
* be added similarly. 
*
*
* --------------WRITING JSON---------------------------------------------------
* The json file needs to be layed out as follows:
* [
*    null,
*    {"id":1, "topic":"topic1 name", "category":"topic1 category", "contents":["topic1 contents 1", "topic1 contents 2", ...]},
*    {"id":2, "topic":"topic2 name", "category":"topic2 category", "contents":["topic2 contents 1", "topic2 contents 2", ...]},
*    {"id":3, "topic":"topic3 name", ...
*        ... "topic# contents#]}
* ]
* Items will be added in the order they are written; their position in the
order doubles as the item's ID number.
*
* --------------PLUGIN PARAMETERS----------------------------------------------
* INTELJSON = filename for JSON file; file MUST be located in the data folder
* with the other JSON objects.  Defaults to Intel.json
* SHOWALERTS = toggles whether or not the game will display alert messages when
* items are added/updated.
*
*
* ------------COMPATABILITY----------------------------------------------------
* The current version overwrites the functions that populate the Main Menu's
* Command list; any other plugins that do this will most likely not work. 
* Compatability with YanflyEngine's Main Menu Manager pending.
*/

Game_Interpreter.prototype.IntelPlugin(function(original){
"use strict";
/*----------------------------------------------------------------------------*
 *        PLUGIN SETUP                                                          *
 *----------------------------------------------------------------------------*/
//Get the plugin parameters.
 var intelParameters = PluginManager.paramters('IntelSystem');

 //Get the intel data.
DataManager.loadDataFile('$dataIntel', String(intelParameters.JsonFileName));

DataManager.getIntelData = function(id) {
    return this._dataIntel[id];
};   

//Define core plugin command.
function IntelPlugin(command, args) {
    original.call(this, command, args);
    
    //Get the intel item from the database.
    var intelArg = GetIntelData(args);
    //Determine which of the two core functions to use.
    if (intelArg && command == "add") {
        $gameParty.addIntel(intelArg);
        //TODO: Add popup window announcing whether intel was added/updated.
    } else if (intelArg && command == "check") {
        return $gameParty.hasIntel(intelArg);
    } else {
        return;
    }
}
//Function fetches an intelItem for use by the command.
function GetIntelData(args) {
    try {
        var idNum = Number(args[0]);
        var intelFromData = DataManager.getIntelData(idNum);
        var contentIds = args[1].split(" ");
        var contents = [];
        while (contentIds.length > 0) {
            var contentsIndex = Number(contentIds.shift);
            //If contentsIndex is a valid number, AND the number is within the contents array, AND the item hasn't already been added...
            if (!NaN(contentsIndex) && contentsIndex < intelFromData.contents.length    && contents.indexOf(intelFromData.contents[contentsIndex]) === -1) {
                    //...Add the contents item
                    contents.push(intelFromData.contents[contentsIndex]);
                }
        }
    return new IntelItem(idNum, intelFromData.topic, intelFromData.category, contents);
        
    } catch (err) {
        console.log("Intel plugin ran into problems getting the following data:  " + args);
        return null;
    }
}

/*----------------------------------------------------------------------------*
 *        CORE FUNCTIONS                                                          *
 *----------------------------------------------------------------------------*/

//Object constructor for IntelItem.
function IntelItem(idnum, topic, category, contents) {
    //ID is used to simplify the lookup process.
    this.id = idnum;
    //Topics are what the specific informatoin will appear on: IE, the subject of the intel.
    this.topic = topic;
    //Categories are used for in-game filtering.
    this.category = category;
    //Array representing specific lines of information.
    this.contents = contents;
}

 //Function is used as part of evaluation of whether a new intel item's contents are already in the player's Intel inventory.
IntelItem.prototype.matches = function (intelFromList) {
    var index = 0;
    //isMatch first checks if the topics match; while loop won't even start if they don't.
    var isMatch = (this.id === intelFromList.id);     
    while (isMatch && index <  this.contents.length) {
        //Step through the contents of the calling IntelItem; if the IntelItem from the list is missing any of them, return false.
        isMatch = (intelFromList.contents.indexOf(this.contents[index]) > -1);
        index++;
    }
    return isMatch;
};

//Function adds contents FROM the calling function TO the item given as an argument; the intent is that the item passed as an argument accesses the info from intelList. 
IntelItem.prototype.addNewContents = function(intelFromList){
    var newContentsAdded = false;
    for (var index = 0; index < this.contents.length; index++) {
        if (intelFromList.contents.indexOf(this.contents[index]) === -1) {
            intelFromList.contents.push(this.contents[index]);
            newContentsAdded = true;
        }
    }
    return newContentsAdded;
};

//Function returns the IntelItem.contents array as a single formated string, ready to be written into the menu.
IntelItem.prototype.getContents = function(){
    var result = "";
    for (var x = 0; x < this.contents.length; x++) {
        result += "  " + this.contents[x];
    }
    return result;
};

//IntelList handles in-game inventory of IntelItems, provides sorting functionality.
function intelList() {
    this.IntelItems = [];
    this.intelCategories = [];
}

//Function updates the intel listing with new items, new categories, and new contents for extant items.
//Returns a string for use with alerts.   
intelList.prototype.addIntel = function(targetIntel) {
    //Insert category if it isn't in the categories list.
    if (this.intelCategories.indexOf(targetIntel.category) === -1) {
        this.intelCategories.push(targetIntel.category);
        this.intelCategories.sort();
    }
    
    var result = null;
    var dexVal = this.findIndex(targetIntel);
    if (dexVal === this.IntelItems.length) {
        this.IntelItems.push(targetIntel);
        result = "New intelligence file: " + targetIntel.topic;
    } else {
        var intelAtIndex = this.IntelItems[dexVal];
        if (intelAtIndex.id != targetIntel.id) {
            this.IntelItems.splice(dexVal+ 1, 0, targetIntel);
            result = "New intelligence file: " + targetIntel.topic;
        } else {
            var contentsCheck = targetIntel.addNewContents(intelAtIndex);
            if (contentsCheck){
                result = "Information updated: " + targetIntel.topic;
            }
        }
    }
    if (intelParameters.ShowAlerts) {
        return result;
    } else {
        return null;
    }
};

//Helper function for addIntel function; makes sure new intel is inserted alphabetically.
intelList.prototype.findIndex = function (targetIntel) {
    var index = 0;
    var resultVal = 1;
    while (index < this.IntelItems.length && resultVal < 0) {
        resultVal = targetIntel.topic.localeCompare(this.IntelItems[index].topic);
        if (resultVal > 0) { index++; }
    }
    return index;
};
    
intelList.prototype.hasIntel = function(targetIntel) {
    //searchFunction must be defined this way due to how Array.some handles the function.
    var searchFunction = function(intelFromList){
        //The IntelItem.matches function checks to see if the intel item taken from the list has the same ID as well as all of the contents it has.
        return targetIntel.matches(intelFromList);
    };
    return this.IntelItems.some(searchFunction);
};

//Returns an array of IntelItems with the specified topic.
intelList.prototype.getIntelFromCategory = function(categoryName){
    var result = [];
    for (var index = 0; index < this.IntelItems.length; index++) {
        if (this.IntelItems[index].category === categoryName) {
            result.push(this.IntelItems[index]);
        }
    }
    return result;
};

//Attach IntelList to the Party object on initialization.
Game_Party.prototype.initialize = function() {
    Game_Unit.prototype.initialize.call(this);
    this._gold = 0;
    this._steps = 0;
    this._lastItem = new Game_Item();
    this._intelList = new intelList();
    this._menuActorId = 0;
    this._targetActorId = 0;
    this._actors = [];
    this.initAllItems();
};

//Methods for accessing data from intelList

//Return all Intel items in the list.
Game_Party.prototype.getAllIntel = function() {
    return this._intelList.IntelItems;
};

//Returns the categories
Game_Party.prototype.getIntelCategories = function() {
    return this._intelList.intelCategories;
};

//returns a string for an in-game message if the intel was added successfully.
Game_Party.prototype.addIntel = function(targetIntel){
    return this._intelList.addIntel(targetIntel);
};

//Used for event flags.
Game_Party.prototype.hasIntel = function(targetIntel){
    return this._intelList.hasIntel(targetIntel);
};

//Return all Intel items with the specified category.
Game_Party.prototype.getIntelFromCategory = function(category) {
        return this._intelList.getIntelFromCategory(category);
};

}(Game_Interpreter.prototype.IntelPlugin));

And I've attempted to use it via the command IntelPlugin("add", ["1", "0 1"]); .
Since the next step would be the bit that would let me check all of this in-game, I just wanted to confirm that all of this is written correctly, and I've been clear enough with the comments.
 

Kino

EIS Game Dev
Veteran
Joined
Nov 27, 2015
Messages
556
Reaction score
794
First Language
English
Primarily Uses
RMMV
Looks right to me.

Your loop could be simplified near the end of the main plugin command, you could use the same kind of if statement, except with forEach or map.


I think your plugin command won't work, because the game provides a function for creating plugin commands that it executes inside the Game_Interprerer.prototype

Aliasing that one and processing your arguments that way should work.


But if you want to add those variables to Game_Party.

Just use assignment via: $gameParty

Unless you want to bake the variables into the game party class and modify them.
 

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
The JsonFileName parameter has a set of single quotes around the file name which will cause an error because there is no file 'Intel.json' to be found. Removing the quotes will fix the problem.
Code:
DataManager.loadDataFile('$dataIntel', String(intelParameters.JsonFileName));
Parameter values are strings so there's no reason to pass a parameter to the String function. Removing it improves the code by making it less noisy. I've seen a lot plugins do the same thing and I've always wondered what the programmer was thinking.

The showAlerts parameter has an unnecessary semicolon in the default entry.

Is the code supposed to be invoking IntelPlugin or is this a typo and you meant to assign a function? It seems like a bug and I wouldn't recommend assigning your entire plugin to a function anyway.
Code:
Game_Interpreter.prototype.IntelPlugin(function (original) {
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
It's written as-shown because I wasn't sure whether it was supposed to be handled inside of the closure or to replace it. I'm guessing since the latter isn't right it should be the former.

Is the below closer to what is expected?
Code:
Game_Interpreter.prototype.pluginCommand = (function (original) {
    "use strict";

    // Define the function that will replace the original.

    function pluginCommand(command, args) {
        original.call(this, command, args);

        if (command == "IntelAdd") {
            //Define an intelList for the party if one doesn't already exist.
            if (!$gameParty.intelList) {
                $gameParty.intelList = new intelList();
            }          
            var result = $gameParty.intelList.addIntel(GetIntelData(args));
            //TODO: Add pop-up message giving info.
        } else if (command == "IntelCheck") {
            if (!$gameParty.intelList) {
                $gameParty.intelList = new intelList();
                return false;
            } else {
                return $gameParty.intelList.hasIntel(GetIntelData(args));
            }
        } else {
            return;
        }
    }

    return pluginCommand;

    // The line below is where we pass in a reference to the original
    // function for use in the replacement.
}(Game_Interpreter.prototype.pluginCommand));

I've removed the Game_Party.prototype commands from the plugin; will $gameParty.intelList persist across saving and loading the game, given how it's been attached to the party as above?

EDIT: Corrected a typo (left off a $ on one of the '$gameParty's), clarified persistence concerns.
 

Clock Out

Veteran
Veteran
Joined
Jun 14, 2016
Messages
92
Reaction score
45
First Language
English
Primarily Uses
RMMV
Looks good. Might be OK to pull out the check for $gameParty.intelList into a single if statement before the checking the command argument. Just so it's only in one place instead of two.
 

Camkitsune

Veteran
Veteran
Joined
Mar 9, 2017
Messages
34
Reaction score
4
First Language
English
Primarily Uses
RMMV
I've been working on trying to get the collected Intel to display under a custom menu item; currently I'm having trouble even getting the option to show up.

This block of code is from the same file as the above stuff:
//Add intel command to createCommandWindow
Scene_Menu.prototype.createCommandWindow = function() {
this._commandWindow = new Window_MenuCommand(0, 0);
this._commandWindow.setHandler('item', this.commandItem.bind(this));
this._commandWindow.setHandler('skill', this.commandPersonal.bind(this));
this._commandWindow.setHandler('equip', this.commandPersonal.bind(this));
this._commandWindow.setHandler('status', this.commandPersonal.bind(this));
this._commandWindow.setHandler('formation', this.commandFormation.bind(this));
this._commandWindow.setHandler('intel', this.commandIntel.bind(this));
this._commandWindow.setHandler('options', this.commandOptions.bind(this));
this._commandWindow.setHandler('save', this.commandSave.bind(this));
this._commandWindow.setHandler('gameEnd', this.commandGameEnd.bind(this));
this._commandWindow.setHandler('cancel', this.popScene.bind(this));
this.addWindow(this._commandWindow);
};

//Add binding for setHandler above.
Scene_Menu.prototype.commandIntel = function() {
SceneManager.push(Scene_Intel);
};

//Define initialization, prototype, and constructor.
function Scene_Intel() {this.initialize.apply(this, arguments);}
Scene_Intel.prototype = Object.create(Scene_MenuBase.prototype);
Scene_Intel.prototype.constructor = Scene_Intel;
Scene_Intel.prototype.initialize = function() {Scene_MenuBase.prototype.initialize.call(this);};

//Define creation and termination events.
Scene_Intel.prototype.create = function() {
Scene_MenuBase.prototype.create.call(this);
//TODO: Add Help Window.
//TODO: Add Categories Window.
this.createIntelWindow();
};

Scene_Intel.prototype.terminate = function() {
Scene_MenuBase.prototype.terminate.call(this);
};

//Creates the windows that form the .
Scene_Intel.prototype.createIntelWindow = function() {
this._intelWindow = new Window_IntelList();
this._intelWindow.setHandler('cancel', this.popScene.bind(this));
this.addWindow(this._intelWindow);
};

/*----------------------------------------------------------------------------*
* WINDOW FUNCTIONS *
*----------------------------------------------------------------------------*/
function Window_IntelList() {this.initialize.apply(this, arguments);}
Window_IntelList.prototype = Object.create(Window_Selectable.prototype);
Window_IntelList.prototype.constructor = Window_IntelList;

Window_IntelList.prototype.initialize = function(x, y, width, height) {
Window_Selectable.prototype.initialize.call(this, x, y, width, height);
this._category = 'none';
this._data = [];
};

Window_IntelList.prototype.setCategory = function(category) {
if (this._category !== category) {
this._category = category;
this.refresh();
this.resetScroll();
}
};

Window_IntelList.prototype.maxCols = function() {
return 1;
};

Window_IntelList.prototype.maxItems = function() {
return this._data ? this._data.length : 1;
};

Window_IntelList.prototype.item = function() {
var index = this.index();
return this._data && index >= 0 ? this._data[index] : null;
};

Window_IntelList.prototype.makeIntelList = function() {
if ($gameParty.intelList.categories.indexOf(this._category) > -1) {
this._data = $gameParty.intelList.getIntelFromCategory(this._category);
} else {
this._data = $gameParty.intelList.intelItems;
}
};

Window_IntelList.prototype.refresh = function() {
this.makeIntelList();
this.createContents();
this.drawAllIntel();
};

Window_IntelList.prototype.drawIntel = function(index) {
var intel = this._data[index];
if (intel) {
var rect = this.itemRect(index);
rect.width -= this.textPadding();
this.drawText(intel.topic, rect.x, rect.y, rect.width);
}
};

I'm guessing that part of the problem is that 'intel' isn't included in Window_Base._handlers, but I'm not sure what I need to attach to the symbol. Is it a function, or a reference to the Scene_Intel.constructor?
I'm also pretty sure I'm missing something else in here... Any help would be greatly appreciated.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,862
Messages
1,017,049
Members
137,569
Latest member
Shtelsky
Top