Issue with Pulling Weapon Notetag Data

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
95
Reaction score
16
First Language
English
Primarily Uses
RMMV
So I am still very new to javascript and how it interacts with MV. I am trying to figure out how to pull the weapon notetag data in my attack damage calculation script, and cannot figure out how to do so. I think it is because the code exists in a Game_Action prototype function and I need to reference Game_Actor to pull the player's currently equipped weapon to pull the notetag data, but I can't seem to get it to work. I also need the same to work for the enemies with their notetag data with a check to see if either the player initiated the attack or the enemy did (which this check fails too).

Here is the code.
Code:
Game_Action.prototype.rangedPhysicalAttack = function(a,b){
        damage = 0;
        $gameVariables.setValue(actualhitsvar, 0);
        var phits = Math.floor(eval(phitsform));
        var weapon = Game_Actor.this.weapons()[0];
        var low = weapon.meta.low;
        var high = weapon.meta.high;
        var enemy = Game_Enemy.this.enemies()[0];
        if(phits < 1) { phits = 1; }
        if(phits > mmagicposs) { phits = mmagicposs; }
        for(i=0; i < phits; i++){
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)){
                if(a.isActor()){
                    damage = damage + getRandomInt(low, high);
                    $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1);
                }
                else{
                    damage = damage + getRandomInt(enemy.meta.damageLow, enemy.meta.damageHigh);
                }
            }
            if($gameVariables.value(actualhitsvar) < 1){
                if(a.isActor()){
                    damage = getRandomInt(low, high);
                    $gameVariables.setValue(actualhitsvar, 1);
                }
                else{
                    damage = getRandomInt(enemy.meta.damageLow, enemy.meta.damageHigh);
                }
            }           
        }
        return damage;
    }
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
95
Reaction score
16
First Language
English
Primarily Uses
RMMV
Just like this.
<low: 8>
<high: 13>

And the error I get is the system complaining that it cannot pull meta from weapon as the variable weapon is undefined.

And I assume the enemy side of it does the same thing, but my a.isActor() check always returns true even if it is the enemy attacking. I got to figure out if I’m even doing that right.
 

Ossra

Formerly Exhydra
Veteran
Joined
Aug 21, 2013
Messages
1,022
Reaction score
768
First Language
English
Primarily Uses
RMMV
Be aware that whenever a notetag is not present in the weapon (or armor, etc) that 'meta' will not have any properties. Therefore, the 'low' and 'high' properties will not be present. So when your code attempts to access the values of those properties ... there will be none and there is a very high probability that the game will crash and/or pop out an error. You will need to double-check to ensure that the property that you want is present before you attempt to access it.

Code:
// Is 'weapon.meta.low' present? If so, return 'weapon.meta.low'. If not, return the default value (represented below by '0').
// Meta values are always a string. Use Number to force the string into a numeric value.
var low = weapon.meta.low ? Number(weapon.meta.low) : 0;
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
95
Reaction score
16
First Language
English
Primarily Uses
RMMV
Am I going about accessing the values the correct way? With setting weapon = Game_Actor.this.weapons()[0]?
Its giving me an error saying this variable itself is undefined
 

Ossra

Formerly Exhydra
Veteran
Joined
Aug 21, 2013
Messages
1,022
Reaction score
768
First Language
English
Primarily Uses
RMMV
Hmm, you may want to tap F12 to open the debug window and get a more precise error message. The debugger will give you the line that is causing the issue.

Also, where are the variables 'actualhitsvar' and 'phitsform' being set? From the code shown above, those are currently undefined. I imagine that is where everything is exploding.



EDIT: Also, to get the user of the attack and the target of the attack, you should be using the parameters given by the function. 'a' is the user of the attack, and 'b' is the target of the attack.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
2,355
Reaction score
1,512
First Language
English
Primarily Uses
RMMV
Game_Actor.this and Game_Enemy.this are not valid objects.
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
95
Reaction score
16
First Language
English
Primarily Uses
RMMV
Here is the entire code, instead of just that section.
Code:
/////////////////////////////////////////////////////////////////
// RFG-AttackSystem v0.3
// Author: RedFoxGaming
/////////////////////////////////////////////////////////////////

(function() {

/*:
* @plugindesc An attack plugin with a variety of features.
* @author RedFoxGaming
*
* This plugin has no plugin commands
*
* @param Maximum Possible Hits
* @desc The maximum possible amount of hits, without state modifiers
* @default 16
*
* @param Maximum Magic Hits
* @desc The maximum possible magic multipliers
* @default 6
*
* @param Double Hits State
* @desc The stateID of the state you want to double your hits (will go beyond max)
* @default 10
*
* @param Half Hits State
* @desc The stateID of the state you want to half your hits
* @default 11
*
* @param Possible Hits Formula
* @type text
* @desc The formula that calculates how many hits are possible
* @default a.agi / 16
*
* @param Possible Magic Hits Formula
* @type text
* @desc The formula that calculates how many magic hits are possible
* @default a.mat / 32
*
* @param Damage Formula
* @type text
* @desc The default damage formula
* @default a.atk * 4 - b.def * 2
*
* @param Magic Damage Formula
* @desc The default damage formula for spells (Base argument is used for a number base damage)
* @default base + a.mat * 2 - b.mdf * 2
*
* @param Healing Magic Formula
* @desc The default formula for healing magics
* @default base + a.mdf
*
* @param Actual Hits Variable
* @desc The ingame variable to store your hits scored (to use in messages)
* @default 1
*
* @help
*
* ----------------------------------------------
* RFG Attack System
* Version 0.3
* ----------------------------------------------
*
* The purpose of this plugin is to mimic the way Final Fantasy handles their
* attacking system, where your attack has the possibility of landing multiple
* hits. In order to use this plugin, all you have to do is replace your formulas
* in the skills you have set to attack, or your magic formulas to my functions.
*
* Function for Physical Attacks
* this.physicalAttack(a,b);
*
* Function for Magical Attacks
* this.magicalAttack(a,b,base); where base is a default number value
* Note: You must use base in the formula if you want a base number value for your spells, otherwise;
* use this.magicalAttack(a,b,0);
*
* Function for Healing Magic
* this.healingMagic(a,b,base); where base is a default number value
*/
    function getRandomInt (min,max) { //Define a function to get a random range of numbers
        min = Math.ceil(min);
        max = Math.floor(max) + 1;
        return Math.floor(Math.random() * (max - min)) + min;
    }  

    function toNumber(str, def) { //Define a function to assign parameters to a number value
        return isNaN(str) ? def : +(str || def);
    }

    var parameters = PluginManager.parameters("RFG-MultipleHitsSystem"); //Load all parameters into an array
    var mhitsposs = toNumber(parameters['Maximum Possible Hits'], 16); //Set variable for Max Possible Hits
    var mmagicposs = toNumber(parameters['Maximum Magic Hits'], 6); //Set a variable for Max Magic Multiplier
    var doublehitsstate = toNumber(parameters['Double Hits State'], 10); //Set a variable for a state that doubles hits
    var halfhitsstate = toNumber(parameters['Half Hits State'], 11); //Set a variable for a state that halves hits
    var phitsform = parameters['Possible Hits Formula'] || "a.agi / 16"; //Set a variable for a formula that defines possible hits
    var mhitsform = parameters['Possible Magic Hits Formula'] || "m.mat / 32"; //Set a variable to define same thing for magic hits
    var damageform = parameters['Damage Formula'] || "a.atk * 4 - b.def * 2"; //Set your default damage formula
    var magicdamform = parameters['Magic Damage Formula'] || "base + a.mat * 2 - b.mdf * 2"; //Set your default magic damage formula
    var healingmagform = parameters['Healing Magic Formula'] || "base + a.mdf"; //Set your default healing formula
    var actualhitsvar = toNumber(parameters['Actual Hits Variable'], 1); //Set the ingame variable to track hits landed
    var phits = 0; //Init phits variable
    var damage = 0; //Init damage variable

    Game_Action.prototype.physicalAttack = function(a,b){ //Physical attack function
        damage = 0; //Set damage to 0
        $gameVariables.setValue(actualhitsvar, 0); //Set hits landed to 0
        phits = Math.floor(eval(phitsform)); //Evaluate phits formula
        if(phits < 1) { phits = 1; } //If less than 1, make it 1
        if(phits > mhitsposs) { phits = mhitsposs; } //If higher than the max possible hits, set to max possible hits
        if(a.isStateAffected(doublehitsstate)) { phits = phits * 2; } //If double state inflicted, double hits
        if(a.isStateAffected(halfhitsstate)) { phits = phits / 2; } //If half state inflicted, half hits
        for(i=0; i < phits; i++){ //Main damage calculation for loop
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)) { //If both of these conditions are true, than this was a successful hit
                damage = damage + eval(damageform); //Add damage to damage pool
                $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1); //Add one to actual hits if sucessful
            }
            if($gameVariables.value(actualhitsvar) < 1){ //If there were 0 sucessful hits, set to 1. Let game engine handle misses and evasions
                $gameVariables.setValue(actualhitsvar, 1);
                damage = eval(damageform); //Do damage, even if the plugin scored 0 hits
            }
        }
        return damage;
    }

    Game_Action.prototype.magicalAttack = function(a,b,base){
        damage = 0;
        $gameVariables.setValue(actualhitsvar, 0);
        var phits = Math.floor(eval(mhitsform));
        if(phits < 1) { phits = 1; }
        if(phits > mmagicposs) { phits = mmagicposs; }
        for(i=0; i < phits; i++){
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)){
                damage = damage + eval(magicdamform);
                $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1);
            }
            if($gameVariables.value(actualhitsvar) < 1){
                $gameVariables.setValue(actualhitsvar, 1);
                damage = eval(magicdamform);
            }
        }
        return damage;
    }

    Game_Action.prototype.healingMagic = function(a,b,base){
        damage = 0;
        $gameVariables.setValue(actualhitsvar, 0);
        var phits = Math.floor(eval(mhitsform));
        if(phits < 1) { phits = 1; }
        if(phits > mmagicposs) { phits = mmagicposs; }
        for(i=0; i < phits; i++){
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)){
                damage = damage + eval(healingmagform);
                $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1);
            }
            if($gameVariables.value(actualhitsvar) < 1){
                $gameVariables.setValue(actualhitsvar, 1);
                damage = eval(healingmagform);
            }
        }
        return damage;
    }

    Game_Action.prototype.randomMagicAttack = function(a,b,min,max){
        damage = 0;
        $gameVariables.setValue(actualhitsvar, 0);
        var phits = Math.floor(eval(mhitsform));
        if(phits < 1) { phits = 1; }
        if(phits > mmagicposs) { phits = mmagicposs; }
        for(i=0; i < phits; i++){
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)){
                damage = damage + getRandomInt(min,max);
                $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1);
            }
            if($gameVariables.value(actualhitsvar) < 1){
                $gameVariables.setValue(actualhitsvar, 1);
                damage = getRandomInt(min,max)
            }
        }
        return damage;
    }

    Game_Action.prototype.rangedPhysicalAttack = function(a,b){
        damage = 0;
        $gameVariables.setValue(actualhitsvar, 0);
        var phits = Math.floor(eval(phitsform));
        var weapon = Game_Actor.this.weapons()[0];
        var low = weapon.meta.low;
        var high = weapon.meta.high;
        var enemy = Game_Enemy.this.enemies()[0];
        if(phits < 1) { phits = 1; }
        if(phits > mmagicposs) { phits = mmagicposs; }
        for(i=0; i < phits; i++){
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)){
                if(a.isActor()){
                    damage = damage + getRandomInt(low, high);
                    $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1);
                }
                else{
                    damage = damage + getRandomInt(enemy.meta.damageLow, enemy.meta.damageHigh);
                }
            }
            if($gameVariables.value(actualhitsvar) < 1){
                if(a.isActor()){
                    damage = getRandomInt(low, high);
                    $gameVariables.setValue(actualhitsvar, 1);
                }
                else{
                    damage = getRandomInt(enemy.meta.damageLow, enemy.meta.damageHigh);
                }
            }          
        }
        return damage;
    }
   
})();


EDIT: Well I thought I would try something. I didn't think about it but since I call these functions from within the Attack skill formula box, the values for a and b are set there and are referenced the same way (a = attacking) (b = defending)

I tried to set weapon = a.this.weapons()[0];
but I still got the same error, which is this, now that my power is back on and I can actually load my computer back up
TypeError: Cannot read property 'weapons' of undefined
 
Last edited:

Ossra

Formerly Exhydra
Veteran
Joined
Aug 21, 2013
Messages
1,022
Reaction score
768
First Language
English
Primarily Uses
RMMV
Ok, the following should function.

Code:
    Game_Action.prototype.rangedPhysicalAttack = function(a,b){
        var damage = 0;
        var phits = Math.floor(eval(phitsform));

        $gameVariables.setValue(actualhitsvar, 0);

        // Is user an Actor?
        if (a.isActor()) {
          // Get Actor's first weapon.
          // Does not account for multiple weapons!
          var weapon = a.weapons()[0];

          // Check and set low/high values from weapon meta data
          var low = weapon.meta.low ? Number(weapon.meta.low) : 0;
          var high = weapon.meta.high ? Number(weapon.meta.high) : 0;
        } else {
          // Get Enemies data
          var enemy = $dataEnemies[b._enemyId];

          // Check and set low/high values from enemy meta data
          var low = enemy.meta.damageLow ? Number(enemy.meta.damageLow) : 0;
          var high = enemy.meta.damageHigh ? Number(enemy.meta.damageHigh) : 0;
        }

        if(phits < 1) { phits = 1; }
        if(phits > mmagicposs) { phits = mmagicposs; }
        for(i=0; i < phits; i++){
            if(getRandomInt(0, 100) > 100 - (a.hit * 100) && getRandomInt(0, 100) > (b.eva * 100)){
                if(a.isActor()){
                    damage = damage + getRandomInt(low, high);
                    $gameVariables.setValue(actualhitsvar, $gameVariables.value(actualhitsvar) + 1);
                }
                else{
                    damage = damage + getRandomInt(low, high);
                }
            }
            if($gameVariables.value(actualhitsvar) < 1){
                if(a.isActor()){
                    damage = getRandomInt(low, high);
                    $gameVariables.setValue(actualhitsvar, 1);
                }
                else{
                    damage = getRandomInt(low, high);
                }
            }
        }

        return damage;
    };


EDIT: Oop, I mucked up the enemy low/high meta data. I have updated the above code.
 
Last edited:

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
95
Reaction score
16
First Language
English
Primarily Uses
RMMV
Okay, that worked. But I also just realized something stepping through the code.

How does the isActor() check work? Because if(a.isActor()) never fails, and I need the code to execute a different damage block if the enemy is attacking as they don't have any weapons, and they have the damageLow and damageHigh values in their notetags as well.

Stepping through the code, isActor() is just this block
Game_Actor.prototype.isActor = function() {
return true;
};

So that will always return true? And is a always the actor and b always the enemy no matter who is attacking?
 

Ossra

Formerly Exhydra
Veteran
Joined
Aug 21, 2013
Messages
1,022
Reaction score
768
First Language
English
Primarily Uses
RMMV
No, 'isActor' will only return true when 'Game_Actor' is the object. Game_Enemy -- which is always used by the enemies -- uses the 'isActor' function inherited from 'Game_BattlerBase' which always returns false.

'a' is the "user" of the skill. The user can be either an actor or an enemy. 'b' is the target. which can also be either an actor or an enemy.



EDIT: Oop, that is another mistake. For the enemy, I should have used 'a._enemyId' instead of 'b._enemyId'.
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
95
Reaction score
16
First Language
English
Primarily Uses
RMMV
Okay, it's working the way I expect it to. Thank you so much for your help
 

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

Latest Threads

Latest Profile Posts

Yaaay! My second public script is out and approved! A VX Ace Final Fantasy IX styled Throw Script!

I look forward to all the constructive feedback I get but most importantly I hope everyone who ends up using it enjoys!

Yaaaay! Making scripts is fun lol. :D
When you're lost out therrrrre and you're alllll alone, ahwahwah waitin, to carry you hooooommmme, uhhheverywhere you look! (someone hit me with those backing vocals)
X.X cant focus... too many thing want do... help!
Day 2 of teaching MV, student can move cat across the map.
Got inspired and started writing a simple tower defence battle system last night :o

Forum statistics

Threads
100,525
Messages
976,810
Members
132,080
Latest member
nwr
Top