GameMaker (SOLVED)defense vs Att

A

Adjud

Guest
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?
 

Simon Gust

Member
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.
 
A

Adjud

Guest
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 by a moderator:

TsukaYuriko

☄️
Forum Staff
Moderator
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.
 
A

Adjud

Guest
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
 

Simon Gust

Member
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.
Similar with your damage calculation
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.
 
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.
 
A

Adjud

Guest
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.
 

TsukaYuriko

☄️
Forum Staff
Moderator
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.
In addition to this...
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.
 

TheouAegis

Member
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.
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.

Code:
global.dmg=global.str + 120/100 * global.att
so my damage should be my strength plus 20% of my att
That's str plus 120% of your att, not 20%. That is a huge difference.

damage = global.dmg - def+(110/100*def)
As was pointed out already, you were adding defense back into damage. If you added parentheses, it would become damage minus 210% of def.

if i make "damage" = to global.dmg the resulting damage is 6.20
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.

global.dmg - def+110/100*def; should subtract 10% of def from global damage
Same as your att/str code, you say "10%" but your code says 110%. Again, huge difference.

att = wepdmg+global.str+200/100*wepdmg
That's 300% of wepdmg.

global.dmg is based on global.str + 20% of att
global.dmg=global.str + 120/100*att
I shouldn't flog a dead horse, but just to hammer it in: that's 120% of att.

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
So many things wrong here... :bash:

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.

global.str to affect damage by a %, it should be increasing the amount of dmg by a %
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...
str should double my dmg
...the formula would be
global.att=wepdmg<<str

global.att = wepdmg+global.str+200/100*wepdmg global.dmg=global.att + 200/100*global.str
These two lines together are just
global.dmg = 3*(wepdmg + str)
 
A

Adjud

Guest
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.
 

TheouAegis

Member
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:
A

Adjud

Guest
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)
}
 
A

Adjud

Guest
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 by a moderator:
A

Adjud

Guest
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.
 

TailBit

Member
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?
 
A

Adjud

Guest
oh sorry this is the STEP event for objbutstr, so its button to increase the strength stat,
that worked though, thank you very much!
 

TailBit

Member
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.
 
Top