Piyan Glupak

Veteran
Veteran
Joined
Nov 14, 2016
Messages
125
Reaction score
63
First Language
English
PG_Gender.js (Version 1)

Version 1.1 - Corrected an error in the 'Help' section. Code 3 for plugin commands etc is for female, and 2 for male.

Authors are Piyan Glupak, Trihan and Mr. Bubbles

Terms and Conditions: Free for use in commercial and non-commercial games. No liability accepted. Credit Piyan Glupak, Trihan and Mr. Bubbles.

About
I cannot claim to be the sole author of this plugin. Any bugs or errors are mine though. Mr. Bubbles made a script for RPG Maker VX Ace. Trihan ported the script into a plugin for RPG Maker MV "GenderFunctions.js". That plugin inspired this one. Much of the code for script calls, for instance, was taken from Trihan's plugin.

For some games, it is useful to have actors and enemies defined by gender. This could be for NPC reaction to the party leader, restricted party composition ("Sorry, only ladies to visit the unpopular town governor after dark"), use of gender specific equipment, party friendship systems, adjusting traits by gender. As well as recording gender, it will be useful to check the gender of individual party members, actors and enemies. It might also be useful to check whether the party or enemy troop is composed of all one gender, or to be able to count the numbers of each gender.

This plugin is written with games that have a lot of potential party members in mind.

Features
  • 4 "genders" - female, male, neuter, unknown
  • Set genders of actors either by notetag or by plugin command
  • Set genders of enemies by notetag
  • May assign a separate state by parameter to female actors, male actors, female enemies, male enemies. (It is suggested that Yami's YED_RetainStateOnDeath is used for the states used for actors)
  • Script calls for conditional branches to check whether individual party members, actors or members of enemy troops are female, male, neuter or unknown
  • Script calls for conditional branches to check whether the party is all female, male, neuter or unknown
  • Script calls for control variables to return the number of female, male, neuter or unknown members of the party or enemy troop

JavaScript:
//=============================================================================
// PG_Gender.js
//=============================================================================
/*:
 * @plugindesc Allows you to assign gender to actors and enemies, and apply states
 *
 * @author Piyan Glupak, Trihan, Mr. Bubbles, see "Help" for details
 *
 * @param Female Actor State
 * @desc Database number of state to be applied to female actors
 * @default
 *
 * @param Male Actor State
 * @desc Database number of state to be applied to male actors
 * @default
 *
 * @param Female Enemy State
 * @desc Database number of state to be applied to female enemies
 * @default
 *
 * @param Male Enemy State
 * @desc Database number of state to be applied to male enemies
 * @default
 *
 * @help
 * Parameters are used to apply a state to male and female actors, male and
 * female enemies, if required. States are set whether notetags set gender
 * in the database, or whether gender is  set during the game. Use of a
 * plugin to such as Yami's YED_RetainStateOnDeath is suggested for states
 * for actors.
 **************************************************************************
 * Notetags
 **************************************************************************
 * Notetags for actors and enemies to set gender - don't include spaces!
 *
 * For male any of: <gender:m>, <gender:male>, <gender:M>, <gender:Male>     
 * For female any of: <gender:f>, <gender:female>, <gender:F>, <gender:Female>
 * For neuter any of: <gender:n>, <gender:neuter>, <gender:N>, <gender:Neuter>
 * Gender is unknown (undefined) if there is no valid notetag.
 **************************************************************************
 * Plugin Commands to assign or change an actor's gender
 **************************************************************************
 * To set or change an actor's gender during play, use either of:
 *
 * changegender ID CODE
 *
 * vargender VAR CODE
 *
 *   ID is actor ID in database
 *   VAR is the number of the variable the actor's ID is stored in.
 *   CODE is one of: 0 for unknown, 1 for neuter, 2 for male, 3 for female
 **************************************************************************
 * Script Calls
 **************************************************************************
 * Calls for script boxes of conditional branches:
 *
 * this.memberIsUnknown(X)     true if party member X is of unknown gender
 * this.memberIsNeuter(X)      true if party member X is neuter
 * this.memberIsMale(X)        true if party member X is male
 * this.memberIsFemale(X)      true if party member X is female
 *
 * NOTE that 'X' starts at 0 for the party leader.
 *
 * this.actorIsUnknown(ID)     true if actor number ID is of unknown gender
 * this.actorIsNeuter(ID)      true if actor number ID is neuter
 * this.actorIsMale(ID)        true if actor number ID is male
 * this.actorIsFemale(ID)      true if actor number ID is female
 *
 * 'ID' is the actor's position in the database.  The first actor's ID is 1
 *
 * this.partyIsUnknown()       true if all party members are unknown
 * this.partyIsNeuter()        true if all party members are neuter
 * this.partyIsMale()          true if all party members are male
 * this.partyIsFemale()        true if all party members are female
 *
 * this.troopMemberIsUnknown(INX)
 * this.troopMemberIsNeuter(INX)
 * this.troopMemberIsMale(INX)
 * this.troopMemberIsFemale(INX)
 * The troop calls are for battles only. They check the gender of an enemy in
 * the troop the party is facing. 'INX' is the enemy's position in the troop.
 * 0 is the first enemy, 1 the 2nd and so on. They don't check whether the
 * troop member is still alive.
 *************************************************************************
 * Calls for the script boxes of "control variables":
 *
 * this.partyUnknownCount()    returns number of unknown gender party members
 * this.partyNeuterCount()     returns number of neuter party members
 * this.partyMaleCount()       returns number of male party members
 * this.partyFemaleCount()     returns number of female party members
 *
 * this.troopUnknownCount()    returns number of unknown gender troop members
 * this.troopNeuterCount()     returns number of neuter troop members
 * this.troopMaleCount()       returns number of male troop members
 * this.troopFemaleCount()     returns number of female troop members
 * The troop calls are for battle only. They check numbers in the troop that
 * are still alive.
 *************************************************************************
 * Confident scripters may read or set gender by using:
 *
 * $gameParty.allMembers()[INDEX].gender
 * $gameParty.allMembers()[$gameVariables.value(VAR)].gender
 * $gameActors.actor(ID).gender
 * $gameActors.actor($gameVariables.value(VAR)).gender
 *     
 *   INDEX is position in party, starting with 0 for the leader
 *   ID is the actor position in the database (starts at 1)
 *   VAR is the number of the variable 'INDEX' or 'ID' is stored in
 *   Codes used are 3 for female, 2 for male, 1 for neuter, 0 for unknown.
 **************************************************************************
 * Plugin History
 * Mr. Bubbles made a script for RPG Maker VX Ace. Trihan ported the script
 * into a plugin for RPG Maker MV "GenderFunctions.js". That plugin helped to
 * inspire this one. Much of the code for script calls was taken from
 * Trihan's plugin. This plugin adds the abilities to set or change gender in
 * game and assign states to males and females, distinguishes unknown gender
 * from neuter, and changed a few script calls.
 * Version 1.1
 * Corrected Help section - Code 2 is used for male, 3 for female.
 **************************************************************************
 * TERMS OF USE
 * Free for use in commercial and non-commercial games. No liability accepted.
 * Credit Piyan Glupak, Trihan and Mr. Bubbles.
 **************************************************************************
 * COMPATIBILITY
 * No issues known yet.
 */
 // Retain a reference to the original function
 {
const Game_Actor_setup = Game_Actor.prototype.setup;
const  parameters = PluginManager.parameters('PG_Gender');
var  femaleActorState = Number(parameters['Female Actor State']);
var  maleActorState = Number(parameters['Male Actor State']);
var  femaleEnemyState = Number(parameters['Female Enemy State']);
var  maleEnemyState = Number(parameters['Male Enemy State']);

Game_Actor.prototype.setup = function (actorId) {

   // Call the original function
   Game_Actor_setup.call(this, actorId);
   this.gender = $dataActors[actorId].meta.gender || null;
   switch (this.gender) {
                        case 'n':
                        case 'N':
                        case 'neuter':
                        case 'Neuter':
                            this.gender = 1;
                            break;
                        case 'm':
                        case 'M':
                        case 'male':
                        case 'Male':
                            this.gender = 2;
                            this.addState(maleActorState);
                            break;
                        case 'f':
                        case 'F':
                        case 'female':
                        case 'Female':
                            this.gender = 3;
                            this.addState(femaleActorState);
                            break;
                       default :
                            this.gender = 0;
                    }
};

const Game_Enemy_setup = Game_Enemy.prototype.setup;

Game_Enemy.prototype.setup = function (enemyId, x, y) {
   // Call the original function
   Game_Enemy_setup.call(this, enemyId, x, y);
   this.gender = $dataEnemies[enemyId].meta.gender || null;
   switch (this.gender) {
                        case 'n':
                        case 'N':
                        case 'neuter':
                        case 'Neuter':
                            this.gender = 1;
                            break;
                        case 'm':
                        case 'M':
                        case 'male':
                        case 'Male':
                            this.gender = 2;
                            this.addState(maleEnemyState);
                            break;
                        case 'f':
                        case 'F':
                        case 'female':
                        case 'Female':
                            this.gender = 3;
                            this.addState(femaleEnemyState);
                            break;
                       default :
                            this.gender = 0;
                    }
};

Game_Actor.prototype.changeGender = function (newGender) {
   this.gender = newGender;
   if (this.gender == 1) {
      if (this.isStateAffected(femaleActorState))
         this.removeState(femaleActorState);
      if (this.isStateAffected(maleActorState))
         this.removeState(maleActorState);
         }
   if (this.gender == 2) {
      if (this.isStateAffected(femaleActorState))
         this.removeState(femaleActorState);
      this.addState(maleActorState);
      };
   if (this.gender == 3) {
      if (this.isStateAffected(maleActorState))
         this.removeState(maleActorState); 
      this.addState(femaleActorState);
      };
      this.clearResult();
};

// Retain a reference to the original function
const Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
   Game_Interpreter_pluginCommand.call(this, command, args);
};
Game_Interpreter.prototype.pluginCommand = function (command, args) {
   Game_Interpreter_pluginCommand.call(this, command, args);
   // If the plugin command is ours
   if (command.toLowerCase() === "changegender") {
      // Grab the arguments
      const id = parseInt(args[0]);
      const newGender = parseInt(args[1]);
      // Change the actor's gender
      $gameActors.actor(id).changeGender(newGender);
   }
  //Game_Interpreter_pluginCommand.call(this, command, args);
  if (command.toLowerCase() === "vargender") {
// Grab the arguments
      const holder = $gameVariables.value(parseInt(args[0]));
      const newGender = parseInt(args[1]);
 // Change the actor's gender
      $gameActors.actor(holder).changeGender(newGender);
   }
};
//Output
    Game_BattlerBase.prototype.isUnknown = function() {
        return this.gender === 0;
    };
 
    Game_BattlerBase.prototype.isNeuter = function() {
        return this.gender === 1;
    };
 
    Game_BattlerBase.prototype.isMale = function() {
        return this.gender === 2;
    };
    
    Game_BattlerBase.prototype.isFemale = function() {
        return this.gender === 3;
    };
 
     _Game_Actor_setup = Game_Actor.prototype.setup;
    Game_Actor.prototype.setup = function(actorId) {
        this._gender = $dataActors[actorId].gender;
        _Game_Actor_setup.call(this, actorId);
    };

    _Game_Enemy_setup = Game_Enemy.prototype.setup;
    Game_Enemy.prototype.setup = function(enemyId, x, y) {
        this._gender = $dataEnemies[enemyId].gender;
        _Game_Enemy_setup.call(this, enemyId, x, y);
    };
 
    Game_Interpreter.prototype.memberIsUnknown = function(index) {
        var member = $gameParty.allMembers()[index];
        if (member) { return member.isUnknown(); }
        return false;
    };
    
    Game_Interpreter.prototype.memberIsNeuter = function(index) {
        var member = $gameParty.allMembers()[index];
        if (member) { return member.isNeuter(); }
        return false;
    };
 
    Game_Interpreter.prototype.memberIsMale = function(index) {
        var member = $gameParty.allMembers()[index];
        if (member) { return member.isMale(); }
        return false;
    };
 
    Game_Interpreter.prototype.memberIsFemale = function(index) {
        var member = $gameParty.allMembers()[index];
        if (member) { return member.isFemale(); }
        return false;
    };

    Game_Interpreter.prototype.actorIsUnknown = function(id) {
        var actor = $gameActors.actor(id);
        if (actor) { return actor.isUnknown(); }
        return false;
    };
 
    Game_Interpreter.prototype.actorIsNeuter = function(id) {
        var actor = $gameActors.actor(id);
        if (actor) { return actor.isNeuter(); }
        return false;
    };
 
    Game_Interpreter.prototype.actorIsMale = function(id) {
        var actor = $gameActors.actor(id);
        if (actor) { return actor.isMale(); }
        return false;
    };
 
    Game_Interpreter.prototype.actorIsFemale = function(id) {
        var actor = $gameActors.actor(id);
        if (actor) { return actor.isFemale(); }
        return false;
    };
 
    Game_Interpreter.prototype.partyIsUnknown = function() {
        return $gameParty.allMembers().every(function(member) {
            return member.isUnknown();
        });
    };
 
    Game_Interpreter.prototype.partyIsNeuter = function() {
        return $gameParty.allMembers().every(function(member) {
            return member.isNeuter();
        });
    };
 
    Game_Interpreter.prototype.partyIsMale = function() {
        return $gameParty.allMembers().every(function(member) {
            return member.isMale();
        });
    };
 
    Game_Interpreter.prototype.partyIsFemale = function() {
        return $gameParty.allMembers().every(function(member) {
            return member.isFemale();
        });
    };
 
    Game_Interpreter.prototype.unknownCount = function(group) {
        return group.reduce(function(total, member) {
            return member.isUnknown() ? total + 1 : total;
        }, 0);
    };
  
    Game_Interpreter.prototype.neuterCount = function(group) {
        return group.reduce(function(total, member) {
            return member.isNeuter() ? total + 1 : total;
        }, 0);
    };
 
    Game_Interpreter.prototype.maleCount = function(group) {
        return group.reduce(function(total, member) {
            return member.isMale() ? total + 1 : total;
        }, 0);
    };
 
    Game_Interpreter.prototype.femaleCount = function(group) {
        return group.reduce(function(total, member) {
            return member.isFemale() ? total + 1 : total;
        }, 0);
    };
 
    Game_Interpreter.prototype.partyUnknownCount = function() {
        return this.unknownCount($gameParty.allMembers());
    };
 
    Game_Interpreter.prototype.partyNeuterCount = function() {
        return this.neuterCount($gameParty.allMembers());
    };
 
    Game_Interpreter.prototype.partyMaleCount = function() {
        return this.maleCount($gameParty.allMembers());
    };
 
    Game_Interpreter.prototype.partyFemaleCount = function() {
        return this.femaleCount($gameParty.allMembers());
    };   
    
    Game_Interpreter.prototype.troopMemberIsUnknown = function(index) {
        if ($gameParty.inBattle()) {
            var enemy = $gameTroop.members()[index];
            if (enemy) { return enemy.isUnknown(); }
        }
        return false;
    };
      
    Game_Interpreter.prototype.troopMemberIsNeuter = function(index) {
        if ($gameParty.inBattle()) {
            var enemy = $gameTroop.members()[index];
            if (enemy) { return enemy.isNeuter(); }
        }
        return false;
    };
 
    Game_Interpreter.prototype.troopMemberIsMale = function(index) {
        if ($gameParty.inBattle()) {
            var enemy = $gameTroop.members()[index];
            if (enemy) { return enemy.isMale(); }
        }
        return false;
    };
 
    Game_Interpreter.prototype.troopMemberIsFemale = function(index) {
        if ($gameParty.inBattle()) {
            var enemy = $gameTroop.members()[index];
            if (enemy) { return enemy.isFemale(); }
        }
        return false;
    };   

    Game_Interpreter.prototype.troopUnknownCount = function() {
        return this.unknownCount($gameTroop.aliveMembers());
    };
 
    Game_Interpreter.prototype.troopNeuterCount = function() {
        return this.neuterCount($gameTroop.aliveMembers());
    };
 
    Game_Interpreter.prototype.troopMaleCount = function() {
        return this.maleCount($gameTroop.aliveMembers());
    };

    Game_Interpreter.prototype.troopFemaleCount = function() {
        return this.femaleCount($gameTroop.aliveMembers());
    };   

 }
 
Last edited:

Raggon

Veteran
Veteran
Joined
Sep 29, 2018
Messages
56
Reaction score
41
First Language
english
Primarily Uses
RMMV

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,915
Reaction score
3,148
First Language
English
Primarily Uses
RMMZ
Good to see you've released it! I hope it ends up being useful to people. I'll probably convert the Gender Requirements plugin sometime next week to be compatible with this.
 

Piyan Glupak

Veteran
Veteran
Joined
Nov 14, 2016
Messages
125
Reaction score
63
First Language
English
Good to see you've released it! I hope it ends up being useful to people. I'll probably convert the Gender Requirements plugin sometime next week to be compatible with this.
Thank you very much, Trihan. Must admit that I hadn't used your Gender Requirements plugin up to now. I had been thinking in terms of "chain mail bikinis" which seem a bit of a stretch even for fantasy. Weapons might be different, though; I remember reading about early steppe dwellers with a proportion of female warriors. Archaeologists found swords with small hilts suitable for women's hands that had damage to the blades consistent with use in combat. Perhaps a range of gender specific weapons might be on the cards for my future projects?
 

Piyan Glupak

Veteran
Veteran
Joined
Nov 14, 2016
Messages
125
Reaction score
63
First Language
English
Whoops! Error in the 'Help' section. Corrected version is 1.1. (Original post has been edited.) The correct code for female for the plugin commands is 3, and the correct code for male is 2.

My apologies to all.
 

iCorrect

Warper
Member
Joined
Jun 12, 2019
Messages
1
Reaction score
0
First Language
English
Primarily Uses
RMVX
Can you upload images to show how it works please?
 

Piyan Glupak

Veteran
Veteran
Joined
Nov 14, 2016
Messages
125
Reaction score
63
First Language
English
notetag.pngCan you upload images to show how it works please?
Not sure what you want, but I will try. Here are a couple of screen shots with notetags, a screenshot showing one of the plugin commands and a screen shot using some of the script calls.
notetag2.png

pluginCommand.png

scriptCallsCheckingParty.png
 

Sword_of_Dusk

Ace Attorney
Veteran
Joined
Sep 13, 2015
Messages
462
Reaction score
492
First Language
English
Primarily Uses
RMMV
Good to see you've released it! I hope it ends up being useful to people. I'll probably convert the Gender Requirements plugin sometime next week to be compatible with this.
Is this Gender Requirements plugin public?
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,915
Reaction score
3,148
First Language
English
Primarily Uses
RMMZ
I couldn't find it in a search, so I wasn't sure. If you can point me to it, I'd be grateful. Combined with OP's plugin, I can finally solve an old issue.
I haven't modified it for this one yet. My "next week" occasionally turns into "Blizzard Soon™". I will get to it shortly though!
 

Latest Threads

Latest Posts

Latest Profile Posts

Climbing to the top #mapping
1638160732198.png
I've started the first steps of the final few maps that I need to make for B:ms. I haven't been able to say that in a really, really long time. It'd probably be a good idea to blog about this or something.
Question for the Mods: What am I supposed to do when I can't make a synopsis 350 words long? (for project recruitment thread) @Shaz @mlogan
The game is meant to be more on the simple side in order to be achievable so I'm a bit stuck...
Had a nice visit with our family. Dad grilled some burgers and mom made baked beans and fudge. We also watched Foul Play. Chevy Chase and Goldie Hawn make an awesome duo. I am surprised how much of the movie I forgot LOL. How did everyone else's holidays go?

Forum statistics

Threads
117,041
Messages
1,104,053
Members
152,979
Latest member
easysqweasy
Top