GMS 2 (SOLVED)defense vs Att

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

  1. Adjud

    Adjud Member

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

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    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 Gust

    Simon Gust Member

    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.
     
  4. Adjud

    Adjud Member

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

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    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.
     
  6. Adjud

    Adjud Member

    Joined:
    Sep 11, 2017
    Posts:
    73
    that worked, thank you :)
     
  7. Adjud

    Adjud Member

    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 Gust

    Simon Gust Member

    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.
    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.
     
    TsukaYuriko likes this.
  9. NimonoSolenze

    NimonoSolenze Member

    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.
  10. Adjud

    Adjud Member

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

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    1,840
    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.
     
  12. TheouAegis

    TheouAegis Member

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

    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.
  13. Adjud

    Adjud Member

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

    TheouAegis Member

    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
  15. Adjud

    Adjud Member

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

    TheouAegis Member

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

    Adjud Member

    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
  18. Adjud

    Adjud Member

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

    TailBit Member

    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?
     
  20. Adjud

    Adjud Member

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

    robproctor83 Member

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

    TailBit Member

    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.
     
  23. Adjud

    Adjud Member

    Joined:
    Sep 11, 2017
    Posts:
    73
    yes alarm 2 does set sets, but it works without it
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice