# GMS 2 (SOLVED)defense vs Att

Discussion in 'Programming' started by Adjud, Jan 13, 2020.

Joined:
Sep 11, 2017
Posts:
73
Hi, I created a damage generator, the controller determines the att at the moment until I add in weapon damage etc,

but for now I set my att to "5" str to 5, then I set my character damage in the controllers create event
Code:
`global.dmg=global.str + 120/100 * global.att`
so my damage should be my strength plus 20% of my att (will be changing) that works fine the problem I am having is in the enemy's damage taken code, in objslime's create event:
Code:
```def=5;
hp=100;
damage = global.dmg - def+(110/100*def)```
then the mouse left click (representing attacking the monster) the code runs as followed:
Code:
```if atime=0 {
image_index=1;
alarm[0]=30;
hp-= damage
atime=1
}
else {
image_index=1;
}
```
my problem is the math seems wrong, if i make "damage" = to global.dmg the resulting damage is 6.20, with the code i posted above the damage actually increases instead of decreases...
im used to excel programming where if you take global.dmg - def+110/100*def; should subtract 10% of def from global damage but its adding to it...

what am I doing wrong?

2. ### TsukaYurikoQ&A Spawn CamperForum StaffModerator

Joined:
Apr 21, 2016
Posts:
1,840
Set damage to global.dmg.
Subtract def.
Add 110% of def... uhh, wait, what? ;P

The latter should probably be in parentheses.

kupo15 likes this.
3. ### Simon GustMember

Joined:
Nov 15, 2016
Posts:
3,243
You are adding (110/100*def) to the damage you're taking. I think you should subtract that or while you're at it, make a clearer calculation.
Code:
```damage = global.dmg - def * 1.10;
```
reduces the Damage by 110% of the defense.

Joined:
Sep 11, 2017
Posts:
73
okay, i have another issue, there is a button in the game that has a left mouse pressed event the code is
Code:
```image_index=1;
if global.ap > 0
{
global.str +=1;
global.ap-=1;
}
else {
time=1;
alarm[0]=120;
}
```
it has a draw event that displays global.str, when i push the button global.str increases and it works. but when i
click on the slime the damage dealt to him does not change even though global.dmg is based on global.str + 20% of att

controller sets att in create event:
Code:
```wepdmg=1
att = wepdmg+global.str+200/100*wepdmg
global.hexp=0;
global.dmg=global.str + 120/100*att```
so is there something im missing?

i'm also trying to create a random damage effect in the alarm fro the slime after taking damage i have it set to def=random(10).

this should cause the damage to change but again it stays the same. its like the create event for def=5; is permanent...

Last edited: Jan 13, 2020
5. ### TsukaYurikoQ&A Spawn CamperForum StaffModerator

Joined:
Apr 21, 2016
Posts:
1,840
The Create event runs once, when the instance is created. When you put the damage formula calculation in there, any evaluations will be done at that time and never again.

If you wish for the damage formula to update, you will have to run said code again whenever you want it to update. Usually, that's done right before it's used to calculate damage.

Joined:
Sep 11, 2017
Posts:
73
that worked, thank you

Joined:
Sep 11, 2017
Posts:
73
I am running into another problem with my att vs def equation...
everything works frine program wise, but I have a code for increasing damage based on str and att combined, if my attack increases my damage increases a decent amount, but when
I increase my str the dmg only increases 1 point per str point which is not right. the math is supposed to be att + str + 100% so essentially str should double my dmg but its not.

code in objcontroller create event:
Code:
```expreq=100;
global.ap=0;
global.str=5;
global.dex=5;
global.mag=5;
global.hp=20;
global.mp=20;
global.mdef=0;
global.def=0;
global.lvl=1;
wepdmg=1
global.att = wepdmg+global.str+200/100*wepdmg
global.hexp=0;
global.dmg=global.att + 140/100*global.str
instance_create_depth(mouse_x,mouse_y,0,objcursor);
instance_create_depth(94,318,0,objbutstr);
instance_create_depth(655,400,1,objslime);
```
Code for step event for objcontroller:
Code:
```if global.hexp > expreq {
global.lvl +=1;
global.ap+=5
wepdmg+=2
expreq = expreq + 100.01/100* expreq
global.att = wepdmg+global.str+200/100*wepdmg
global.dmg=global.att + 200/100*global.str
}```
I added the bottom to lines :
Code:
```global.att = wepdmg+global.str+200/100*wepdmg
global.dmg=global.att + 200/100*global.str```
to see if it would change, but im not sure mathematically what I'm doing wrong to get global.str to affect damage by a %, it should be increasing the amount of dmg by a % instead of 1 point per strength.

This is not part of a real game yet, just a damage/defense generator for a future game I will be programming. I am a graphics artist and a story writer mostly, so math and programming are not my strong suite.

sorry for all the posts, thanks for any help

8. ### Simon GustMember

Joined:
Nov 15, 2016
Posts:
3,243
I seriously suggest taking another try at this whole damage calculation, because right now it's a mess.
You need to take the order that terms are calculated in consideration.
multiplying and dividing comes before adding and subtracting.
Example:
Code:
```4 + 12 / 2
```
This does not equal 8. 12 is first divided by 2 before added to 4, resulting in a value of 10.
Code:
```global.att = wepdmg + global.str + 200/100 * wepdmg;
```
the only thing multiplied here is wepdmg by 2, then it is just added to global.str and then to wepdmg again for good measure (this is what I mean with it being messed up)

You have more variables for your own good. Start simple, right now this is too confusing. There are variables all over the place affecting each other which they shouldn't.
Here's an example of how it works in one of my games

player stats in the create event
Code:
```attack = 12;
attack_mult = 1.75;
```
weapon stats residing in the weapon create event (or if there isn't one, in the player's create event)
Code:
```damage = 5;
```
now in a script that is called because my weapon hit the enemy
Code:
```var damage_taken = (attack + damage) * attack_mult;
```
Now you can do some other adjustments afterwards!
Code:
```damage_taken *= random_range(1.20, 0.80);
```
This will make the damage range from 80% to 120% instead of always just 100%

Code:
```if (10 > random(100))
{
damage_taken *= 2.00;
}
```
This code makes a critical hit out of the damage and multiplies it by 2, the crit chance is 10%

Code:
```damage_taken = max(damage_taken - defense, 0);
```
This code reduces the inflicted damage by the enemies defense and also makes sure the damage never falls below 0 using the max() function.

The code I've displayed does not take into consideration which object the variable belongs to for simplicity, but if you do implement something like this you have to address the right object or instance.

TsukaYuriko likes this.
9. ### NimonoSolenzeMember

Joined:
Jul 25, 2017
Posts:
32
Parentheses help for ensuring your code executes properly. Based on your code, I'm assuming what you want here is the following:

"global.att" is equal to the sum of wepdmg, global.str, and the result of 200 divided by the result of 100 times wepdmg, and global.dmg is equal to that plus the result of 200 divided by the result of 100 times global.str.

So your code should look like the following:

Code:
```global.att = wepdmg+global.str+(200/(100*wepdmg))
global.dmg=global.att + (200/(100*global.str))```
Remember your order of operations: Parentheses (Brackets depending on your region), Exponents (x^y), Multiplication & Division, and Addition & Subtraction, from left to right. * and / are equal, as are + and -. To ensure that what you want to happen, happens in the order you want, enclose the code you want to happen first with parentheses.

Ultimately, however, I do agree with Simon Gust here- you're making this more complicated than it needs to be! Start simple.

TsukaYuriko likes this.

Joined:
Sep 11, 2017
Posts:
73
I will try to implement what you have there, my global variables are not set in stone, they are just test variables. does your program have stats affecting it as well like Str, Dex, Int, Vit? my damage calculator works very well at the moment, its simply the proper order of math that I am not good at, I have not used math in well over 10 years and have forgotten orders and things like that... I am also trying to remove the rube Goldberg from my codes.. im just starting out with a system like this so its interesting.

11. ### TsukaYurikoQ&A Spawn CamperForum StaffModerator

Joined:
Apr 21, 2016
Posts:
1,840
To help with (re-)learning the order of operations: PEMDAS. That's not a latin magic spell, but the initials of each operation in the order they're evaluated in.

12. ### TheouAegisMember

Joined:
Jul 3, 2016
Posts:
7,367
In every one of your codes, you make the SAME MISTAKE. You haven't just forgotten order of operations, you straight up forgot algebra in general. Did you even make it through algebra? That's fine if you never did, but then this is all beyond anything you were taught. So I'm going back to the first post here as well.

That's str plus 120% of your att, not 20%. That is a huge difference.

As was pointed out already, you were adding defense back into damage. If you added parentheses, it would become damage minus 210% of def.

How'd you get 6.2?
5 + 120/100*5 - 5 + 110/100*5 = 11.5
even ignoring str or att, that's still 5.5 or 6.5, not a .2 anywhere.

I am assuming by now you took that line of code out of the Create Event where it doesn't belong, also.

Same as your att/str code, you say "10%" but your code says 110%. Again, huge difference.

That's 300% of wepdmg.

I shouldn't flog a dead horse, but just to hammer it in: that's 120% of att.

So many things wrong here...

Once again, you put your damage calculations in a Create Event, even after Tsuriko told you not to.

wepdmg+global.str+200/100*wepdmg is global.str plus 300% of wepdmg, as I pointed out earlier. That's fine in and of itself, but now you have said it's supposed to be 200% str, even though your code says 200% wepdmg.

This is actually a completely different formula. In order for str to be a % of wepdmg, you need to multiply wepdmg by str.
global.att = wepdmg * n * (str * a + b) / 100
where n, a, and b are arbitrary modifiers; a multiplicatively increases str's effect, so str increases wepdmg by a%; b increases wepdmg by b%, and n increases wepdmg by a further n00%..

And to actually do this...
...the formula would be
global.att=wepdmg<<str

These two lines together are just
global.dmg = 3*(wepdmg + str)

TsukaYuriko likes this.

Joined:
Sep 11, 2017
Posts:
73
sorry, I'm more of a graphics artist, audio engineer and story writer then a programmer, I was homeschooled by my delusional mother who decided it was a good idea to not teach me certain things like algebra due to the fact that she herself dropped out of school at a young age... I know its not a great excuse but I have learned certain things on my own and work toward figuring out programming as I have for several years, but as you can see my lack of knowledge in the algebra department causes a great burden on my programming skills.
it would be great to have a partner who is good at programming since I'm good at just about everything else, but alas I am alone in my game making adventures, I will be revising my code as much as possible to be to the correct order of "PEMDAS" and the proper equations in place. I hope not to irritate you guys with too many idiotic questions as the time passes.

I do have another question regarding the best way to change a button image based on AP and if the mouse is in collision with the button....

Step event for objbutton

Code:
```if global.ap < 1 {
image_index=0;
}
else {
if ignore = 0 {
image_index=1;
}
}

if !position_meeting(mouse_x, mouse_y, all) {
ignore=1;
} else {
ignore=0;
}```
left pressed event:
Code:
```if global.ap > 0
{
image_index=2;
global.str +=1;
global.ap-=1;
}
else {
time=1;
alarm[0]=120;
}```
left released event:

Code:
```if global.ap < 1 {
image_index=0;
}
else {
image_index=1;
}```
I know theres a simpler way to accomplish this... the problem im having with it is that when I level up, my ap exceeds 0 the button stays at image_index=0; until I click on the button then it does its process correctly...

I hate to ask for so much without any kind of return, so I know its off topic but if anyone needs any help with graphics or eventually sound effects/audio stuff I would be glad to trade my services.

Thank you for any help, I will be posting again in here with the codes from my damage calculator after I have overhauled it.

14. ### TheouAegisMember

Joined:
Jul 3, 2016
Posts:
7,367
You're in the right track. You should probably keep everything in just the step event. The mouse left pressed event is for clicking on the object, I think, but I never use it --there should be a mouse pressed global event for clicking anywhere. So I'll just assume that's fine there.

Step event:
Code:
```if !alarm[1] {

image_index = global.ap>0;
if mouse_check_button_pressed(mb_left) && position_meeting(mouse_x,mouse_y,id) && global.ap {
global.str += 1;
image_index = 2;
global.ap -= 1;
alarm[1] = 16;
}
```
Alarm 1 event
Code:
`image_index = global.ap>0`

Last edited: Jan 15, 2020

Joined:
Sep 11, 2017
Posts:
73
that code isn't functioning properly, I left out the draw event for that previous code... alarm[0] and variable time has to do with it.
Draw Event for objbutton:

Code:
```draw_self()
if time > 0 {
draw_text_color(250,318,"No AP Available",c_red,c_red,c_red,c_red,1)
}```

16. ### TheouAegisMember

Joined:
Jul 3, 2016
Posts:
7,367
Then use alarm 1 in my code. I didn't notice you were using 0 already.

Joined:
Sep 11, 2017
Posts:
73
EDIT: revised the code a little bit, the only part that does not work now is the actual left click part when I have ap available

I couldn't get it to work, I altered my code but it still has issues im assuming the order of if statements is off for me...

Code:
```if position_meeting(mouse_x, mouse_y, all) {
ignore=1;
} else {
ignore=0;
}

if ignore =0 {
if global.ap < 1 {
image_index=0;
}
else {
image_index=1;
}
}
else {
if mouse_check_button_pressed(mb_left) {
if global.ap < 1 {
image_index=0;
time=1;
alarm[1]=120;
}
else {
if global.ap >0 {
if sets=0 {
image_index=2;
global.str +=1;
global.ap-=1;
sets=1;
alarm[2]=5;

}
}
}
}
}

```
in my mind i have this setup to basically be image 0 if theres no ap if the mouse is in collision or not, if there is ap the image goes to 1, in collision or not, if the mouse button is pressed while in collision with the object and the ap is above 0 it should change to image 2, setting str +1 ap -1 then sets a timer sets to keep it from using all ap available in one click

Last edited: Jan 15, 2020

Joined:
Sep 11, 2017
Posts:
73
I tried multiple ways to arrange this code and it still doesn't work...
Code:
```if position_meeting(mouse_x, mouse_y, all) {
ignore=1;
} else {
ignore=0;
}

if ignore = 1 {
if global.ap > 0 {
if mouse_check_button(mb_left) {
if sets=0 {
image_index=2;
global.str +=1;
global.ap-=1;
sets=1;
alarm[2]=5;
}
}
else {
image_index=1;
}
}
else {
image_index=0;
if mouse_check_button(mb_left) {
time=1;
alarm[1]=120;

}
}

} ```

its supposed to be image_index 0 if theres no ap, image index 2 if there is ap and image_index 3 if there is ap and you click the mouse while in collision with the button.
"sets" is there to make sure all of the available ap doesn't get used in one click.

19. ### TailBitMember

Joined:
Oct 16, 2019
Posts:
134
Hm, maybe something like this:
Code:
```if(instance_place(mouse_x, mouse_y, object_index) == id) exit; // if you are above this exact button

image_index = (global.ap>0) * 2;

if mouse_check_button_pressed(mb_left)
if global.ap>0 {
image_index = 3;
global.str+=1;
global.ap-=1;
}else{
time=1;
alarm[1]=120;
}```
- if this was in the mouse pressed event then you could maybe skip 1st and mouse_check line .. what event even is this?
- sets is just to make it function like mouse_check_button_pressed?

Joined:
Sep 11, 2017
Posts:
73
oh sorry this is the STEP event for objbutstr, so its button to increase the strength stat,
that worked though, thank you very much!

21. ### robproctor83Member

Joined:
Sep 30, 2019
Posts:
214
nevermind you got ti working

22. ### TailBitMember

Joined:
Oct 16, 2019
Posts:
134
Okay, I think this should do it:
Code:
```// step event
if(alarm[2]==-1) image_index = (global.ap>0) * 2; // do not change sprite while alarm is active

// mouse left pressed event
if global.ap>0 {
image_index=3;
global.str+=1;
global.ap-=1;
alarm[2]=5;
}else{
time=1;
alarm[1]=120;
}```
is alarm 2 just supposed to set "sets" back to 0, here I just used it to keep it as image_index 3 for a brief moment?
there have to at least be a comment in the alarm for it to be active.