Piyan Glupak

Veteran
Veteran
Joined
Nov 14, 2016
Messages
132
Reaction score
70
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
86
Reaction score
61
First Language
english
Primarily Uses
RMMV

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
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
132
Reaction score
70
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
132
Reaction score
70
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
3
Reaction score
1
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
132
Reaction score
70
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
594
Reaction score
633
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?
 

Sword_of_Dusk

Ace Attorney
Veteran
Joined
Sep 13, 2015
Messages
594
Reaction score
633
First Language
English
Primarily Uses
RMMV
It sure is!
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.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
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!
 

Wisshy

Villager
Member
Joined
Jan 16, 2019
Messages
20
Reaction score
4
First Language
Português
Primarily Uses
RMMV
Hi. Great plugin.
However I have an issue. How can I read an ememy's gender? (using something like $gameParty.allMembers()[INDEX].gender, but for enemies instead).
 

Piyan Glupak

Veteran
Veteran
Joined
Nov 14, 2016
Messages
132
Reaction score
70
First Language
English
@Wisshy Thank you for your kind comment.

Are you trying to read an enemy's gender during a battle? I would use:

$gameTroop.members()[index].gender

Please remember that "index" starts at 0, so to read the gender of the first enemy in a troop you would put "$gameTroop.members()[0].gender" in a "Control Variable" script box.

Please let me know if that is not what you want, or if it doesn't work for you.
 

Wisshy

Villager
Member
Joined
Jan 16, 2019
Messages
20
Reaction score
4
First Language
Português
Primarily Uses
RMMV
oh it worked perfectly. Thank you for it!
 

Attachments

  • Sem título.png
    Sem título.png
    954.3 KB · Views: 10

iCorrect

Warper
Member
Joined
Jun 12, 2019
Messages
3
Reaction score
1
First Language
English
Primarily Uses
RMVX
How do I download it?
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
4,969
Reaction score
4,553
First Language
English
Primarily Uses
RMMZ
Oh shoot I totally forgot to modify the other one. *adds that back on to the list*
 

Latest Threads

Latest Posts

Latest Profile Posts

Have you ever wondered what the lives of the NPC's are like in your hero's story? Come an find out with us as we play, "A Story Beside" by Wayward Prophet :LZSexcite:

Never in my life did I dream that I would be the proud owner of 5 jellyfish.
Working on Project Zelda!

The title screen lacked enough sparkles... this oversight has been rectified. :kaopride:
67 frames for a dragon transformation? Eh, seems about right. XD

Forum statistics

Threads
122,090
Messages
1,146,443
Members
160,379
Latest member
Mechazard
Top