RMMV Damage Formula - ideas and help

Kryss

Villager
Member
Joined
Jun 12, 2019
Messages
16
Reaction score
1
First Language
Spanish
Primarily Uses
RMMV
Ah, that's a total goof on my part. If you want to use the damage formula to add this effect from the weapons you will need to check the actor has it equipped. The best check to use for this would be

Code:
a.hasWeapon($dataWeapons[id])

//where id = weapons database id
Now to get that into damage formulas with the above would look something like this:

Code:
if (a.hasWeapon($dataWeapons[weaponId]) && (b.isStateAffected(confusedId) || b.isStateAffected(blindId) || Math.randomInt(100) < 25)) {b.addState(stunId)}; damageFormula
It's messy, but it should work in your skills damage formula.
Thank you! I will try to put this and see if it works ^^
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
Code:
if (a.hasWeapon($dataWeapons[weaponId]) && (b.isStateAffected(confusedId) || b.isStateAffected(blindId) || Math.randomInt(100) < 25)) {b.addState(stunId)}; damageFormula
It's messy, but it should work in your skills damage formula.
That's a good solution! Actually I would put the damage formula before the state evaluation. For the reasons I mentioned in my last comment. If her character, for example, does more damage on stunned enemies than it could be faulty that way. Or if another bomb adds a debuff that reduces the defense, than the bomb would benefit itself from an effect that should be applied after the detonation, not before.

Code:
damageFormula; if (a.hasWeapon($dataWeapons[weaponId]) && (b.isStateAffected(confusedId) || b.isStateAffected(blindId) || Math.randomInt(100) < 25)) {b.addState(stunId)}



Edit:
I have two questions.

Question 1:
Is it possible to use global $variables in the formula field and will they be useable in the editors test battles?
I'm thinking of the case that I design 100 or 200 skills and then I realize that I need to rebalance my base formula. That would be pure horror!

I'm thinking of setting something like this up, in the common event that will initialize all important variables:

Code:
//base formula
$formula_physical = (1+(a.atk-b.def)/200).clamp(0.25, 1.75)
$formula_magical = (1+(a.mat-b.mdef)/200).clamp(0.25, 1.75)

And then use it in the skill formula field:

Code:
(a.luk * 1.5) * $formula_physical
The example above would have 150% weapon damage as base damage multiplied by the base formula.


Question 2:
How can I access the Off-Hands defense param?

When I have a mainhand weapon with wtype ID 7 equipped it works. But if not it doesn't work, even though I check for off-hand ID 5.

Code:
<Custom Requirement>
if (user.isAtypeEquipped(5)) {
value = true;
} else {
value = false;
}
</Custom Requirement>
That seems strange. Is there another way or does someone see the bug?
 
Last edited:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,696
Reaction score
3,005
First Language
Tagalog
Primarily Uses
RMVXA
Question 1:

Yes, you can use global variables in your damage formulas. You can also opt to use a function instead.

Personally I use a custom defined function as my base formula and just have each skill send parameters to that base formula.

Question 2: The behavior is weird, for one, it only checks the armors so your mainhand weapon shouldnt even be affecting the result of that code

Also, this probably wont help with the problem but I think you can shorten it to

value = a.isAtypeEquipped(id);

since the function returns true or false anyway, and you only need to know if its true or false. Using an if would only make more sense if you need to something else when its true or false.
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
Thank you for the reply!

Personally I use a custom defined function as my base formula and just have each skill send parameters to that base formula.
Oh that seems like a smart way to do! I will just ninja that. Do you set the function up in a .js plugin file? I will have to look into functions, as I never sat one up myself yet.

Question 2: The behavior is weird, for one, it only checks the armors so your mainhand weapon shouldnt even be affecting the result of that code
Yes it is weird. But I didn't bug hunt it extensively. Later I will smash some functions through the debug tool and check some IDs.

value = a.isAtypeEquipped(id);
Ahhh, you are totally right! Thank you for this advice. It is always beneficial to clean up and simplify the code. I will change and remember this. :LZScheeze:

Not sure if this is the right place to ask this but do you (or someone else) know if I can change the text color when gaining mp? The background is that I use Yanflys Skill Rewards plugin to restore "MP" on my Warrior-like class when Shield-Smashing. And the MP number is blue, but Rage is something like red. Just a very tiny detail. I could live with that, if it can't be done without great efforts. :LZSjoy:


Edit:
Okay after some more testing I found the fault by myself. xD
When I initially created the skill I sat weapon requirements in the skill tabs, for testing purposes. Obviously I forgot to remove that. :LZSoops:

I got it working that way:
Code:
<Custom Requirement>
if (user.equips()[1] && user.isAtypeEquipped(5)) {
value = true;
} else {
value = false; }
</Custom Requirement>
 
Last edited:

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
Oh that seems like a smart way to do! I will just ninja that. Do you set the function up in a .js plugin file? I will have to look into functions, as I never sat one up myself yet.
You can define them in a .js file or if it's only a short function you can use the script event command to define the function (autorun/parallel at start of game, perhaps). Using a .js file and adding it to your plugin list is probably the better option. Functions are relatively easy to define, something like this would work to replicate MV's default damage formula

Code:
baseDamageFormula = function(a, b) {
    var damage = a.atk * 4 - b.def * 2;
    return damage
}

//to call in battle formula
baseDamageFormula(a, b)
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
Code:
baseDamageFormula = function(a, b) {
    var damage = a.atk * 4 - b.def * 2;
    return damage
}

//to call in battle formula
baseDamageFormula(a, b)
Thank you for the example! What I did not understand yet is: Can the function use a.atk and b.def and things like a.equips()[1].params[3] or do I need to define every single param etc. in the function call?

Like this:
Code:
baseDamageFormula(a.atk, b.def, a.equips()[1].params[3])

Or would this work?
Code:
function damage_formula(type){
    switch(true){
        case (type == "physical"): return (1+(a.atk-b.def)/200).clamp(0.25, 1.75);
        case (type == "magical"): return (1+(a.matk-b.mdef)/200).clamp(0.25, 1.75);
        case (type == "shield"): return (a.equips()[1].params[3] * 2) * (1+(a.atk-b.def)/200).clamp(0.25, 1.75);
        case (type == "offhand"): return a.equips()[1].params[2] * (1+(a.atk-b.def)/200).clamp(0.25, 1.75);
    }
}
And in the skill databases formula field:
Code:
(a.luk*1.5) * damage_formula("physical")
Would it work that way or do I need to send all parameters like a.atk to the function?

And can I define constants in the .js file too that will always be defined (=usable)?
Like:
Code:
$hp = 0
$mp = 1
$atk = 2
$def = 3
$mat = 4
$mdef = 5
$agi = 6
$luk = 7
So that this can be done?
Code:
a.equips()[1].params[$atk]

Edit:

Meanwhile I did some testing and got to the following cognizances:
1) All battle parameters used need to be passed.
2) Constants can be set and are quite handy.

Code:
//function for custom damage formula in the editors database

function damage_formula(type, a_atk, a_mat, b_def, b_mdf){
    switch(true){
        case (type == "physical"): console.log("physical formula"); return (1+(a_atk-b_def)/200).clamp(0.25, 1.75);
        case (type == "magical"): console.log("magical formula"); return (1+(a_matk-b_mdf)/200).clamp(0.25, 1.75);
        case (type == "shield"): console.log("shield formula"); return (1+(a_atk-b_def)/200).clamp(0.25, 1.75);
        case (type == "offhand"): console.log("offhand formula"); return (1+(a_atk-b_def)/200).clamp(0.25, 1.75);
    }
}


//defining constants

//params
$hp = 0;
$mp = 1;
$atk = 2;
$def = 3;
$mat = 4;
$mdf = 5;
$agi = 6;
$dmg = 7;

//equip types
$main = 0;
$off = 1;
$head = 2;
$body = 3;
$belt = 4;
$legs = 5;
$feet = 6;
$hands = 7;
$acc = 8;

//script movement commands
$turn_left = 17;
$turn_up = 19;
$turn_right = 18;
$turn_down = 16;
$move_forward = 12;
$step_forward = 12;
 
Last edited:

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
Thank you for the example! What I did not understand yet is: Can the function use a.atk and b.def and things like a.equips()[1].params[3] or do I need to define every single param etc. in the function call?

Like this:
Code:
baseDamageFormula(a.atk, b.def, a.equips()[1].params[3])
There's no need to add anything extra for use with "a" and "b", anything that works in the damage formula on them will work in this function as well.

Or would this work?
Code:
function damage_formula(type){
    switch(true){
        case (type == "physical"): return (1+(a.atk-b.def)/200).clamp(0.25, 1.75);
        case (type == "magical"): return (1+(a.matk-b.mdef)/200).clamp(0.25, 1.75);
        case (type == "shield"): return (a.equips()[1].params[3] * 2) * (1+(a.atk-b.def)/200).clamp(0.25, 1.75);
        case (type == "offhand"): return a.equips()[1].params[2] * (1+(a.atk-b.def)/200).clamp(0.25, 1.75);
    }
}
And in the skill databases formula field:
Code:
(a.luk*1.5) * damage_formula("physical")
This wouldn't work because when you've declared your function you haven't added the parameters "a" or "b", but you are using them for your calculations, so this would cause errors "can't read property atk of undefined" etc. Example:

Code:
//function call
baseDamageFormula(a, b, type)

//function declaration
baseDamageFormula = function(a, b, type) {
 //code
}
There's nothing stopping you defining constants and variables in your .js file for later use as well.

EDIT: RE multiplying by the function - you can do this. eg a.luk * 1.5 * formula(a, b, type)
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
Oh I guess you didn't see my last comments spoiler. You are right, I got an error that a/b are not defined. So I edited it.

But I did it the stupid way. I didn't know that a and b can be sent to the function. And I thought I have to do this for all the params that I will ever use in the function.. :biggrin:
So, thanks for the example! :LZSsmile:
 

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
No problem. :) The a and b parameters are just references to the subject and target so you can do anything to them that you can do to a battler.

Another something you might find useful - because of where the damage formula is executed (ie. within Game_Action) you don't actually need to pass the action type to the function. You can refer to the action itself using "this" so rather than pass the type in the parameters you could use

Code:
this.isPhysical()
this.isMagical()
this.isCertainHit()
Along with any other function that is defined for Game_Action. I know that doesn't help with your "shield" and "offhand" types but it's still worth mentioning.
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
Code:
this.isPhysical()
this.isMagical()
this.isCertainHit()
Along with any other function that is defined for Game_Action. I know that doesn't help with your "shield" and "offhand" types but it's still worth mentioning.
Oh that's quite useful! The less I have to type the better it is!

That's what I've came up with:
Code:
function damage_formula(type, a, b) {
    if (this.isCertainHit()) { console.log("Certain"); return 1; }
    else {
    switch(true){
        case (type == ""):
            if (this.isPhysical()) { console.log("Normal Physical"); return (1+(a.atk-b.def)/200).clamp(0.25, 1.75); }
            if (this.isMagical()) { console.log("Normal Magical"); return (1+(a.matk-b.mdf)/200).clamp(0.25, 1.75); }
            break;
        case (type == "shield"):
            if (this.isPhysical()) { console.log("Shield Physical"); return (1+(a.atk-b.def)/200).clamp(0.25, 1.75); }
            if (this.isMagical()) { console.log("Shield Magical"); return (1+(a.matk-b.mdf)/200).clamp(0.25, 1.75); }
            break;
        case (type == "offhand"):
            if (this.isPhysical()) { console.log("Offhand Physical"); return (1+(a.atk-b.def)/200).clamp(0.25, 1.75); }
            if (this.isMagical()) { console.log("Offhand Magical"); return (1+(a.matk-b.mdf)/200).clamp(0.25, 1.75); }
            break;
        }
    }
}
Is it optimal that way? :LZSsmile:


Edit:
It didn't work that way. It tells me that this.isCertainHit() is not a function. :LZSsad:
 
Last edited:

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
That's a mistake on my part. It would work in the damage formula, so you can pass the function this and then use any of the Game_Action functions within your function. My apologies.

Code:
//example function
damageFormula(a, b, action) {
    if (action.isCertainHit()) return a.atk*4 - b.def*2
}

//example function call
damageFormula(a, b, this)
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
That's a mistake on my part. It would work in the damage formula, so you can pass the function this and then use any of the Game_Action functions within your function. My apologies.

Code:
//example function
damageFormula(a, b, action) {
    if (action.isCertainHit()) return a.atk*4 - b.def*2
}

//example function call
damageFormula(a, b, this)
Don't worry. Mistakes can happen. :LZScheeze:

Unfortunately I tried this already and I tried it again now. It crashes my game when the enemy attacks. (Normal attack calls the function too)



This is what I get. The text above is unimportant. :LZSgrin:


Edit:
That's how my function looks now:
Code:
function damage_formula(type, a, b, action) {
    console.log(action)
    if (action.isCertainHit()) { console.log("Certain"); return 1; }
    else {  
    switch(true){
        case (type == ""):
            if (action.isPhysical()) { console.log("Normal Physical"); return (1+(a.atk-b.def)/200).clamp(0.25, 1.75); }
            if (action.isMagical()) { console.log("Normal Magical"); return (1+(a.matk-b.mdf)/200).clamp(0.25, 1.75); }
            break;
        case (type == "shield"):
            if (action.isPhysical()) { console.log("Shield Physical"); return (1+(a.atk-b.def)/200).clamp(0.25, 1.75); }
            if (action.isMagical()) { console.log("Shield Magical"); return (1+(a.matk-b.mdf)/200).clamp(0.25, 1.75); }
            break;
        case (type == "offhand"):
            if (action.isPhysical()) { console.log("Offhand Physical"); return (1+(a.atk-b.def)/200).clamp(0.25, 1.75); }
            if (action.isMagical()) { console.log("Offhand Magical"); return (1+(a.matk-b.mdf)/200).clamp(0.25, 1.75); }
            break;
        }
    }
}
 

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
Looks to me like an issue drawing gauges rather than anything wrong with the values being passed to your function. Seems to be trying to draw gauges with incorrect numbers (null, undefined, infinity). The console is definitely logging the action itself.
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
But the game only crashes with my function call. I removed it from the skill formula windows and now it doesn't crash anymore. :LZSsad:
 

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
I can't say for certain what the issue is, but my concern is your switch statement. I don't think it's evaluating anything. It may be worth swapping these for if statements, and possibly adding a 'return 0' line to the bottom of your function so as to ensure you're still passing a finite number back from the function.
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
I can't say for certain what the issue is, but my concern is your switch statement. I don't think it's evaluating anything. It may be worth swapping these for if statements, and possibly adding a 'return 0' line to the bottom of your function so as to ensure you're still passing a finite number back from the function.
Oh you are absolutely right! With the return 0 added to the bottom the game will not crash anymore. But why is this? I thought I used a true switch successfully before. Did I use wrong syntax or wrong logic?


Edit:
Okay seems like I'm officially an idiot. I still had my old function call in the normal attack skill which sat type to "physical". :kaodes:
Setting that to "" solved the issue. The true switch is working now. :LZScheeze:
Thank you again for your help! :kaohi:
 
Last edited:

Silva

Scoobityboo
Veteran
Joined
Nov 5, 2018
Messages
394
Reaction score
212
First Language
English
Primarily Uses
RMMV
I'll be honest with you, I don't really use switch statements all that often. My understanding is for your use you'd want to set it up like so:

Code:
switch(type) {
   case "shield":
      //code
   case "offhand":
      //code
   default:
      //code
}
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,696
Reaction score
3,005
First Language
Tagalog
Primarily Uses
RMVXA
@XZINED - your way of using a Switch case is kinda off.. See Silva's code for a better or at least the normal usage of a Switch case
 

Nilom

Veteran
Veteran
Joined
Sep 9, 2013
Messages
178
Reaction score
39
First Language
German
Primarily Uses
RMMV
True switches are indeed normal ways to use switches.
Maybe it was not beneficial in my case though. But they are useful to have multiple cases trigger if the break is omitted.
But I already changed the switch to "normal usage". :LZScheeze:
 

jetboost

Veteran
Veteran
Joined
Sep 29, 2016
Messages
84
Reaction score
26
First Language
Dutch
Primarily Uses
RMMV
So i've been watching on as an onlooker mostly because i'm feeling a bit salty that I didn't think of something like this for my own.
I had used common events to create damage formulas but because you couldn't call a and b and thus also not their stats you had to define them all yourself and put them in gameVariables and then make use of them in the damage formula noteboxand this had to be done for every actor you may or may not want to have in your game.
Needless to say everything turned out very large, and in my defense it's something I had created 3 years ago while I couldn't read javaScript as well as I can now.

But to get to the point, I may or may not redo it and in case I do I have a few questions.
-In my understanding you have created an plugin with an function which can be called in an damage formula?
-What use is the 4th parameter of the function "action"?

Thank you for showing me a better way to do this, really if I had known this 3 years ago it would have at the very least halved my work.
 

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

Latest Threads

Latest Profile Posts

The more I think about it, the weirdest part of going to work post-virus will probably be getting used to seeing my coworkers' mouths again. :LZYshock:
I think one of my weirdest realizations is that my speed of game development would probably be about the same if I *didn't* work a full-time manual labor job.
Quick question, what's the best way to capture-er, I mean RECRUIT playtesters? Should I make a project thread and use that?
Node Graph out of Date. Rebuilding...
Does anyone know of any good Discord groups for art or biology discussion, that sort of thing?

Forum statistics

Threads
98,056
Messages
948,943
Members
129,333
Latest member
rootcf
Top