RMMV [SOLVED] (YEP) Can't figure out how to javascript a damage formula into a state's notetags

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
Using Yanfly's plugins, I'm currently trying to create a state where upon the end of the inflicted target's action, an animation plays and they take damage. I know how to get the animation portion working but cannot for the life of me figure out how MV's damage formula works in Javascript form; nor how to even execute said damage formula.

Yes force action sounds like the easy solution, but weird thing about Yanfly's Buff & States core is that executing a force action upon action end, causes the game to softlock completely. If anyone is familiar with MV's JS please help!

I have attempted using an altered version of a JS damage formula that a friend sent me. (Had to be modified due to it being from MZ, but MV's JS is handled slightly differently)

Instead of it working as it should, it displays the target's damage taken as "NNN" but even then only does it on the second action end, not the first like it's supposed to

Edit: Found out the reason NNN kept coming up as a damage number was because I made a slight error in the code, but the fix only made it stop displaying damage and stopped attempting to deal damage entirely
 
Last edited:

Kenen

Regular
Regular
Joined
Apr 3, 2012
Messages
546
Reaction score
959
First Language
English
Primarily Uses
RMMZ
You're asking for help in a JavaScript support forum but haven't included anything other than a vague description of your problem.

No one can help you with your JavaScript damage code if you don't post it.

You also need to post the note tag(s) you are running the code in, because the note tags dictate when the code runs, which can impact the kind of data that is available for the code to work with.

Ideally post screenshots showing the full RPG Maker program and the formula or code you are trying to run.

If you can't post actual code or screenshots, then I suggest posting a very literal explanation of what you want to accomplish with the YEP plugins, without adding any anecdotal stuff (e.g. what your friend sent you or what your personal evaluation of the problem is). None of that is likely to be useful and is just going to prolong the thread.

Just post either some screenshots, or your code with brief commentary, or a short and to the point explanation of what you want to achieve.
 

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
You're asking for help in a JavaScript support forum but haven't included anything other than a vague description of your problem.

No one can help you with your JavaScript damage code if you don't post it.

You also need to post the note tag(s) you are running the code in, because the note tags dictate when the code runs, which can impact the kind of data that is available for the code to work with.

Ideally post screenshots showing the full RPG Maker program and the formula or code you are trying to run.

If you can't post actual code or screenshots, then I suggest posting a very literal explanation of what you want to accomplish with the YEP plugins, without adding any anecdotal stuff (e.g. what your friend sent you or what your personal evaluation of the problem is). None of that is likely to be useful and is just going to prolong the thread.

Just post either some screenshots, or your code with brief commentary, or a short and to the point explanation of what you want to achieve.
My bad, I was typing this in a rush due to having to get to sleep early for work the next morning lol. Here's the code in question:

<Custom Action End Effect> function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms));} async function skill() { let a = $gameActors.actor(2); let b = user; let d = (4 * a.atk - 2 * b.mdf) * 1.5; let e = 10; let f = 1; let g = d * target.elementRate(e); if (f = 0) { g * target.pdr; } else { g * target.mdr; } let rand = Math.random() * .4; g *= (rand + 0.8); let z = (Math.max(Math.round(g), 0) * -1); await sleep(500); user.startAnimation(422, true, 15); Game_Interpreter.prototype.changeHp(user, z, true); target.startDamagePopup(); target.clearResult(); if (target.elementRate(e).toFixed(2) > 1) { user.startAnimation(422, true, 15); } if (target.elementRate(e).toFixed(2) < 1) { user.startAnimation(422, true, 15); } } skill(); </Custom Action End Effect>

A little update I was going to post was that we discovered it actually was dealing damage properly, however, it's just not displaying the damage popup itself and can't figure out why that's the case
 

ATT_Turan

Forewarner of the Black Wind
Regular
Joined
Jul 2, 2014
Messages
12,755
Reaction score
11,365
First Language
English
Primarily Uses
RMMV
Wow, why on Earth do you have all of that in the notetag? Where is there a sleep and promise and all that...to be generous, stuff? :wink:

You don't need to define all of those variables, Yanfly's notetag already provides user and target (as well as a and b if you prefer those).

My personal recommendation for you, aside from simply not needing so many variables, is to name them a bit more descriptively. It will help you keep track and it will help your code make much more sense to anyone else who reads it.

Instead of that massive function that I don't think will work correctly, all you need to do is call the gainHp() method.

Code:
let f = 1;
...
if (f = 0)
This doesn't mean anything. You just defined f to be 1, and didn't do anything that could change it. So this condition of f being 0 can never happen.

However, you typed it incorrectly - checking equality is ==. So what you're actually doing here is setting it to 0, and then that will always be true.

I'm not sure what you actually want to happen here, because you have these conditionals for f to indicate whether you're looking at mdr or pdr, but you define f as a static value. So I'm not going to bother trying to translate this bit.

Code:
Game_Interpreter.prototype.changeHp(user, z, true);
This is also incorrect syntax - you can't just call a function definition. You need to call it as a method of an instance of the Game_Interpreter object - e.g. the battle manager's interpreter. But again, you shouldn't be using this function at all.

Code:
if (target.elementRate(e).toFixed(2) > 1)
What's the point of using toFixed() here? That won't change whether or not it's greater than 1. The odds of someone's element rate being 1.005 are extremely slim, unless you know you're doing weird things with your rates in your game.

And while the next condition isn't wrong, it would be more efficient typing to just use else rather than type out that whole condition again. It looks like you're trying to establish that the target's rate is not a flat 1, which would be much simpler to type (elementRate(e)!=1).

Except you call the exact same animation above. So I just don't know what this section of code is for.

So all that said...all you need to do is this:

Code:
<Custom Action End Effect>
let dam = ((4 * user.atk - 2 * target.mdf) * 1.5) * target.elementRate(10) * target.pdr;
dam = Math.round(dam * (Math.random() * .4 + .8);
user.startAnimation(422, true, 15);
target.gainHp(0-dam);
// You might get the damage popup naturally, but if not:
target.startDamagePopup();
</Custom Action End Effect>
 

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
Wow, why on Earth do you have all of that in the notetag? Where is there a sleep and promise and all that...to be generous, stuff? :wink:

You don't need to define all of those variables, Yanfly's notetag already provides user and target (as well as a and b if you prefer those).

My personal recommendation for you, aside from simply not needing so many variables, is to name them a bit more descriptively. It will help you keep track and it will help your code make much more sense to anyone else who reads it.

Instead of that massive function that I don't think will work correctly, all you need to do is call the gainHp() method.


This doesn't mean anything. You just defined f to be 1, and didn't do anything that could change it. So this condition of f being 0 can never happen.

However, you typed it incorrectly - checking equality is ==. So what you're actually doing here is setting it to 0, and then that will always be true.

I'm not sure what you actually want to happen here, because you have these conditionals for f to indicate whether you're looking at mdr or pdr, but you define f as a static value. So I'm not going to bother trying to translate this bit.


This is also incorrect syntax - you can't just call a function definition. You need to call it as a method of an instance of the Game_Interpreter object - e.g. the battle manager's interpreter. But again, you shouldn't be using this function at all.


What's the point of using toFixed() here? That won't change whether or not it's greater than 1. The odds of someone's element rate being 1.005 are extremely slim, unless you know you're doing weird things with your rates in your game.

And while the next condition isn't wrong, it would be more efficient typing to just use else rather than type out that whole condition again. It looks like you're trying to establish that the target's rate is not a flat 1, which would be much simpler to type (elementRate(e)!=1).

Except you call the exact same animation above. So I just don't know what this section of code is for.

So all that said...all you need to do is this:

Code:
<Custom Action End Effect>
let dam = ((4 * user.atk - 2 * target.mdf) * 1.5) * target.elementRate(10) * target.pdr;
dam = Math.round(dam * (Math.random() * .4 + .8);
user.startAnimation(422, true, 15);
target.gainHp(0-dam);
// You might get the damage popup naturally, but if not:
target.startDamagePopup();
</Custom Action End Effect>
So I implemented the code you sent and it just straight up didn't work for some reason. Even put it in a function of its own and tried calling that function (Because sometimes you have to do it that way with these state notetags, dunno why), but it still didn't work either. Didn't even implement damage, nor play the animation like the previous code did
 

ATT_Turan

Forewarner of the Black Wind
Regular
Joined
Jul 2, 2014
Messages
12,755
Reaction score
11,365
First Language
English
Primarily Uses
RMMV
Even put it in a function of its own and tried calling that function (Because sometimes you have to do it that way with these state notetags, dunno why)
You really don't/should not.

Please show a screenshot of the skill in your database, as well as your plugin manager.

Also, press F8, go to the Console tab, and post a screenshot of that. If I made a typo in my code someplace, it'll be visible there.
 

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
You really don't/should not.

Please show a screenshot of the skill in your database, as well as your plugin manager.

Also, press F8, go to the Console tab, and post a screenshot of that. If I made a typo in my code someplace, it'll be visible there.
It isn't a skill, this is a notetag for a state, hence the excessive amount of code on there; because trying to force a damage formula to work within a state is very much a pain.

And it does deal damage, the issue though is getting it to actually display the damage dealt since Damage Popup isn't doing what it's supposed to do
 

ATT_Turan

Forewarner of the Black Wind
Regular
Joined
Jul 2, 2014
Messages
12,755
Reaction score
11,365
First Language
English
Primarily Uses
RMMV
That doesn't really change anything. I could quote my prior post and change the word "skill" to "state" if it makes you feel better :stickytongue:
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,882
Reaction score
7,969
First Language
English
Primarily Uses
RMMZ
"This is also incorrect syntax - you can't just call a function definition."

This isn't actually strictly true. Since functions are just objects like anything else, you absolutely can call them independently of an instance, but you need to use .call and pass an instance as the first argument to act as the "this" context, so you could do

Game_Interpreter.prototype.changeHp.call($gameMap._interpreter, user, z, true);

There are very few use cases for this though (the only one that springs to mind is that there are a few custom windows in my Star Knightess Aura menu plugins that use Window_Base but need functions from other window classes, so rather than define the function again I just call it from that window class and pass in my custom object for the execution context).
 

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
That doesn't really change anything. I could quote my prior post and change the word "skill" to "state" if it makes you feel better :stickytongue:
Even then, the order of the plugins is set to the order Yanfly has recommened in the plugin manager. Everything in there is ordered in the same way his site has recommended, so everything is functioning as intended.

Screenshot of the state would just be me sending you the same code as well since it has nothing special going on outside of an action end removal and the same code I showed before; I think what's going on is that change HP likely isn't considered "Damage" by the MV engine so it won't show it as a damage popup.

Ok so while I was typing this message, I went and did a quick test

Change the changeHp line to user.gainHp(z);

and that ALSO did damage as it was intended. However it still won't popup the damage like it's meant to. But I have a guess on what may be going on and am going to tamper with putting an await sleep function in between the damage popup and clear damage popup.

Update: IT WAS BECAUSE IT NEEDED THE SLEEP FUNCTION

I placed it in between and it finally popped up the damage like it was supposed to. So basically the issue this whole time was simply the fact that I needed to put a wait function in between the damage popup and result clear. Such a simpler solution than I initially thought lol

So I ended up changing nothing regarding the original version of the code I sent before, outside of simply adding an await sleep(ms); function in between the damage popup and result clear!
 

ATT_Turan

Forewarner of the Black Wind
Regular
Joined
Jul 2, 2014
Messages
12,755
Reaction score
11,365
First Language
English
Primarily Uses
RMMV
I guarantee you that is not necessary. I have used code like this tons of times and it's never been necessary to use any degree of convolution like you have above.

I'm glad it works for you, and if you're happy then that's fine - but there is something weird/wrong going on in your setup.
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,882
Reaction score
7,969
First Language
English
Primarily Uses
RMMZ
The thing I've found (and you can see this in some of my tips & tricks porting in the topic for it) is that to show a damage popup manually in a notetag, you need a startDamagePopup() call both before *and* after the changeHp/gainHp call. I'm not sure why this is the case, tbh.
 

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
I guarantee you that is not necessary. I have used code like this tons of times and it's never been necessary to use any degree of convolution like you have above.

I'm glad it works for you, and if you're happy then that's fine - but there is something weird/wrong going on in your setup.
Yanfly doesn't exactly like to treat MV JS the way it's supposed to at times. Especially when it's being executed within a state. There's nothing wrong with the setup, Yanfly is just like that when it comes to to shoving entire damage formulas and skill sequences into states.

in regards to the F variable you asked about before. It's used to declare whether the damage formula is a physical damaging type, or magical damaging type; it's left as a variable so that it's much easier to find and change. So that way if I ever want to make other states that also deal damage, I can easily go to the top of the code and change the number there. The friend of mine made this code in such a way for the sake of flexibility, not as the result of not knowing how to JS
 

ATT_Turan

Forewarner of the Black Wind
Regular
Joined
Jul 2, 2014
Messages
12,755
Reaction score
11,365
First Language
English
Primarily Uses
RMMV
So the only problem with what I posted earlier is that the Action End Effect is the version of state eval that doesn't include the target reference from battle. If you use another notetag to store that then reset target inside your notetag, it works fine.

Then, as @Trihan said, include a before and after call for startDamagePopup()

No non-MV script is necessary.

Code:
<Custom Initiate Effect>
user._tempTarget = target;
</Custom Initiate Effect>

<Custom Action End Effect>
target = user._tempTarget;
let dam = ((4 * user.atk - 2 * target.mdf) * 1.5) * target.elementRate(10) * target.pdr;
dam = Math.round(dam * (Math.random() * .4 + .8));
user.startAnimation(422, true);
target.startDamagePopup();
target.gainHp(0-dam);
target.startDamagePopup();
</Custom Action End Effect>

doubledam.gif
 

FireAngelDev

Master of Overscoping
Member
Joined
Sep 30, 2023
Messages
8
Reaction score
0
First Language
English
Primarily Uses
RMMV
So the only problem with what I posted earlier is that the Action End Effect is the version of state eval that doesn't include the target reference from battle. If you use another notetag to store that then reset target inside your notetag, it works fine.

Then, as @Trihan said, include a before and after call for startDamagePopup()

No non-MV script is necessary.

Code:
<Custom Initiate Effect>
user._tempTarget = target;
</Custom Initiate Effect>

<Custom Action End Effect>
target = user._tempTarget;
let dam = ((4 * user.atk - 2 * target.mdf) * 1.5) * target.elementRate(10) * target.pdr;
dam = Math.round(dam * (Math.random() * .4 + .8));
user.startAnimation(422, true);
target.startDamagePopup();
target.gainHp(0-dam);
target.startDamagePopup();
</Custom Action End Effect>

View attachment 278577
So tried this one and it still didn't work. Though from the looks of the gif you sent, it may be because mine is being used differently. Instead of trying to explain, I'll just nab the description of the skill using the state in question real quick.

Spike Trap: Ranged damage on an enemy and places a Spike Trap beneath them.
At the end of that enemy's next 2 actions, they will take damage x1.5 of Lucy's attack. [Multiplier: x1.15] (CD: 5)

So instead of executing on the turn of, it's meant to execute at any point after the turn it was applied.

The variation I'm using works just fine though, simply needed to add a sleep function and it's working now. But thanks for the help!
 

ATT_Turan

Forewarner of the Black Wind
Regular
Joined
Jul 2, 2014
Messages
12,755
Reaction score
11,365
First Language
English
Primarily Uses
RMMV
So instead of executing on the turn of, it's meant to execute at any point after the turn it was applied.
Then what you'd want to do is replace all references to user with origin to refer to the actor who placed the state on the target, then target stays as is as it will correctly reference the battler with the state on. I don't see why the rest of it wouldn't work as is.

You wouldn't even need that extra notetag in that case.

Good luck with your project.
 

Latest Threads

Latest Posts

Latest Profile Posts

So in my SRPG, when kill monsters, they leave an aura that grants +20% Crit, +20% PDMG MDMG. Aura lasts only for 1 turn, it forces players when and where to last hit.

1702177938686.png
So frustrating when you just wanna work on your game but people want to do stuff in RL... :p
Day #9 of Advent is all ready in one spot! Do you prefer doing your shopping way before Xmas, or…do you like the chaos? Are you done shopping and/or crafting for Xmas?
Fast test with Wagon and horse no animation. yes it looks strange horse is Ralph and wagon is follower xDDDD
Should first boss be easy or maybe little medium, I don't want to be overwhelmingly hard

Forum statistics

Threads
136,887
Messages
1,271,056
Members
180,662
Latest member
funky-taco
Top