[Fixed] Stadium Mechanics

Discussion in 'Solved Bugs' started by Lutra, Jan 27, 2015.

  1. Lutra

    Lutra All Gen Battler/Scripter

    Joined:
    Apr 25, 2010
    Messages:
    509
    Likes Received:
    188
    PO Trainer Name:
    Lutra
    froggy25 likes this.
  2. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    Just reading on that forum link you posted. I've played Pokemon Stadium 1 and 2 long ago and never heard about speed effecting critical hit ratio.
     
  3. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    I'll be happy to implement it, but I'm very lazy. I know we have a lot of stadium mechanics already in the code, but can you make a list of what we don't have? I'm going to assume there's also a formula behind the CH ratio, which would be nice to have as I'm not using hard values just in case someone doesn't want to use max speed for some reason.

    I should be able to add the HP displays as the max value though, so for most intents and purposes it would work. But then the calculation wouldn't be perfect, so the HP would have an error range of about 1% of max hp (as in, Chansey can be +/- 6, Charmander would be like +/- 3). Maybe I can get creative and add a server side message that only works in Stadium to send the damage dealt, then take max HP and subtract the damage as it adds up. Perhaps I can even access the pokemon's HP and send as well, since the server should have that information. By restricting it to only stadium gens too, it wouldn't be abusable if the server controls it.
     
    Last edited: Jan 28, 2015
    Lutra likes this.
  4. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    Formula for Stadium Crit Ratio (from Bulba):
    In Pokemon Stadium, critical hit probabilities are determined with a different formula, (BaseSpeed + 76) / 1024. Compared to the handheld games, this causes Pokémon with a base speed of lower than 76 to land critical hits more often and Pokémon with a base speed of higher than 76 to land critical hits less often. As in the handheld games, moves with a high critical-hit ratio are eight times more likely to land a critical hit, giving a formula of (BaseSpeed + 76) / 128. The effect of Focus Energy now correctly increases the critical hit rate, by changing the formula to (BaseSpeed + 236) / 512; this stacks with the use of a high critical hit rate move ((BaseSpeed + 236) / 64). While the 1/256 move accuracy error was fixed in Stadium, the probability of landing a critical hit is still capped at 255/256.
     
    Last edited: Jan 28, 2015
    Lutra likes this.
  5. Lutra

    Lutra All Gen Battler/Scripter

    Joined:
    Apr 25, 2010
    Messages:
    509
    Likes Received:
    188
    PO Trainer Name:
    Lutra
    I think only substitute blocking status and boom, no recoil when ko and haze are done at the moment, looking through this: https://github.com/po-devs/pokemon-online/search?p=1&q=Stadium&utf8=✓

    edit: sleep was done also I think (I assume it was in a .txt which is why it wasn't commented)

    Which leaves:

    + 1/256 accuracy misses shouldn't happen
    + recovery -255/511 glitch is removed

    ================================================

    On a slightly different subject, I think ideally we should have these subgens for 1st gen:

    RBY
    RBY Tradebacks
    Stadium
    Stadium Tradebacks

    As nice as it is to have symmetry between all gens, I don't think anyone cares about the Red/Blue movepool differences. Are any OU/Ubers pokes even affected?
     
    Last edited: Jan 30, 2015
  6. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    I looked into the code and it seems like the formula for Focus Energy in Stadium is already implemented.
    /* In RBY, Focus Energy reduces crit by 75% */
    if (tmove(player).critRaise & 2) {
    if (gen() <= Pokemon::gen(Gen::Yellow)) {
    baseSpeed /=4;
    } else {
    baseSpeed *= 4;
    }
    }
     
    Lutra likes this.
  7. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    Submitted fix for the 1/256 accuracy miss. I hope that it works this way.
     
  8. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
    Bulba is slightly incorrect, I kept doing modifications to fix it but someone doesn't give up and replace it with a wrong simplified formula, and I didn't want to start an edit war.

    As a general rule, don't follow Bulbapedia for accurate formulas.

    The correct formula is there:
    http://datacrystal.romhacking.net/wiki/Pokémon_Stadium:ROM_map#.C2.A1Un_Golpe_Cr.C3.ADtico.21
    Simplified explanation of the code:
    http://datacrystal.romhacking.net/wiki/User_talk:Zowayix

    So, this is incorrect:
    Also, Effect chance for Acid is 51/256, Effect chance for Aurora Beam is 77/256, and Effect chance for Bubblebeam is 77/256 in Stadium.
     
    Last edited: Jan 28, 2015
    Disaster Area and Lutra like this.
  9. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    Hyper Beam already does the recharge, I added that awhile back iirc.
    Code (text):
    1.  
    2.   /*Hyper Beam always needs to recharge in Stadium
    3.   *KOs and sub breaks dont cause recharge in RBY*/
    4.   if (b.gen() <= Pokemon::gen(Gen::Yellow) && (b.koed(t) || b.hadSubstitute(t)))
    5.   return;
    -----------------------

    This looks like some code for draining moves. Recoil < 0 means you heal damage instead of taking it. So essentially what this code is saying is if you kill a pokemon with a draining move in stadium you don't recover HP.
    Is this correct?
    Code (text):
    1.  
    2.   // If move KOs opponent's pokemon, no recoil damage is applied in stadium.
    3.   if (koed(target) && recoil < 0 && gen() > Pokemon::gen(Gen::Yellow)) {
    4.   return;
    5.   }
    -------------------------

    As far as accuracy goes, do you know if it calculates it out of 255 instead of 256? Or if 100% Acc moves are now 256 acc instead of 255?

    --------------------------

    As far as CH goes then, our formula should read something like this then just for Stadium?
    Code (text):
    1.  int ch = (baseSpeed + 76) >> 2;
    2. if (focus energy) {
    3. ch << 2 + 160 >> 1;
    4. }
    So for bulbasaur it would return CH = 30;
    With Focus Energy CH = 140;
    Then that's out of 256 so
    Bulbasaur = 11.71875%
    Bulbasaur with FE = 54.6875%
    Which seems to match that Smogon thread
     
    froggy25 likes this.
  10. Lutra

    Lutra All Gen Battler/Scripter

    Joined:
    Apr 25, 2010
    Messages:
    509
    Likes Received:
    188
    PO Trainer Name:
    Lutra
    The hyper beam recharge isn't working on the server for stadium.

    edit: explosion user survives against sub as well.
     
    Last edited: Jan 28, 2015
  11. sulcata

    sulcata stéphane curry best waifu Forum Moderator Server Administrator Forum Moderator Server Administrator

    Joined:
    Jun 13, 2012
    Messages:
    968
    Likes Received:
    744
    I would assume the moves still cap at 255 accuracy. 256 accuracy would take up two bytes, while 255 would only take one, so I'd imagine accuracy is still the same to save space on the cartridges. Although I guess Pokemon mechanics can be weird and I don't have a source \o/ (most likely the coders typo'd in RBY and did /256 instead of /255).
     
  12. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
    In RBY the game checks if a pseudo-random number between 0 and 255 is < 255.
    If random number == 255, the attack fails because 255 is not < 255.
    Hence the 255/256 accuracy.

    In Stadium, if random number == 255, the attack skips the accuracy check.
    This means every attack has an additional 1/256 accuracy.
    http://datacrystal.romhacking.net/wiki/Pokémon_Stadium:ROM_map#Move_Accuracy_check

    This does not affect Effects chances though, as Stadium simply skips the check if Effect chance == 255. So the Effects chances are [chance]/256.
    Edited my previous post for Acid / Aurora Beam / Bubblebeam Effects chances, the /255 was a typo.
    That is correct.
     
    Last edited: Jan 28, 2015
  13. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    our crit formula is a mess for Gen 1...
    Code (text):
    1.  
    2. void BattleBase::testCritical(int player, int target)
    3. {
    4.   (void) target;
    5.  
    6.   /* In RBY, Focus Energy reduces crit by 75%; in statium, it's * 4 */
    7.   int up (1), down(1);
    8.   if (tmove(player).critRaise & 1) {
    9.   up *= 8;
    10.   }
    11.   if (tmove(player).critRaise & 2) {
    12.   if (gen() == Gen::RedBlue || gen() == Gen::Yellow) {
    13.   down = 4;
    14.   } else {
    15.   up *= 4;
    16.   }
    17.   }
    18.   PokeFraction critChance(up, down);
    19.   int randnum = randint(512);
    20.   int baseSpeed = PokemonInfo::BaseStats(fpoke(player).id, gen()).baseSpeed();
    21.   bool critical = randnum < std::min(510, baseSpeed * critChance);
    22.  
    23.   if (critical) {
    24.   turnMem(player).add(TM::CriticalHit);
    25.   notify(All, CriticalHit, player);
    26.   } else {
    27.   turnMem(player).remove(TM::CriticalHit);
    28.   }
    29. }
    From what it looks like is, excluding Focus energy or high crit moves we do:

    Find a random number between 0 and 511.
    Find the base speed of a pokemon
    The lesser of 510 or the base speed of the pokemon is compared against the random number
    If the random number is smaller, its a crit (if not, its not a crit)

    If high crit move is used (like Slash) it does the same as above, but multiplies the base speed by 8. So Persian gets nearly 100% chance to crit because 8*115 > 510, so it compares if 510 is greater than or equal to random int from 0 to 511 inclusive (99.8% apparently from what I calculate).
    Using a move like Scratch or any other basic move will return a crit rate of about 22.46%

    ~~~
    It should be like
    Base: CH% rate = (User's base Speed) × 100 ÷ 512
    High crit move: CH% rate = (User's base Speed) × 100 ÷ 64
    RBY Focus Energy: ????
    Stadium Focus Energy: CH% rate = (User's base Speed) × 100 ÷ 128
    right? Idk what I'm doing at this point
     
    Last edited: Jan 29, 2015
  14. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
    Code (text):
    1. void BattleBase::testCritical(int player, int target)
    2. {
    3.     (void) target;
    4.    
    5.     int randnum = randint(256);
    6.     int baseSpeed = PokemonInfo::BaseStats(fpoke(player).id, gen()).baseSpeed();
    7.     /* Focus Energy */
    8.     if (gen() == Gen::RedBlue || gen() == Gen::Yellow) {
    9.         int criticalRatio = baseSpeed >> 1;
    10.         if (tmove(player).critRaise & 2) {
    11.             criticalRatio = criticalRatio >> 1;
    12.         }
    13.         else {
    14.             criticalRatio = criticalRatio << 1;
    15.         }
    16.     }
    17.     else {
    18.         int criticalRatio = (baseSpeed + 76) >> 2;
    19.         if (tmove(player).critRaise & 2) {
    20.             criticalRatio = (criticalRatio << 2) + 160;
    21.         }
    22.         else {
    23.             criticalRatio = criticalRatio << 1;
    24.         }
    25.     }
    26.     /* Karate Chop, Razor Leaf, Crabhammer, Slash */
    27.     if (tmove(player).critRaise & 1) {
    28.         criticalRatio = criticalRatio << 2;
    29.     }
    30.     else {
    31.         criticalRatio = criticalRatio >> 1;
    32.     }
    33.     /* Critical Hit check */
    34.     bool critical = randnum < std::min(255, criticalRatio);
    35.     if (critical) {
    36.         turnMem(player).add(TM::CriticalHit);
    37.         notify(All, CriticalHit, player);
    38.     }
    39.     else {
    40.         turnMem(player).remove(TM::CriticalHit);
    41.     }
    42. }
    I don't know how Pokémon Online handles Pseudo-Random Number Generation. Does randint(n) generates a pseudo-random number between 0 and n ?
     
    Last edited: Jan 30, 2015
  15. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    I fixed this. It will be implemented after the next battle server update.
    I can confirm that the user survives against sub, so our code to fix this doesn't work as it should
    Code (text):
    1.  
    2. /* Explosion doesn't faint the user if it breaks a sub.
    3. * However, it faints all the time in Stadium. */
    4. if (b.gen() <= Pokemon::gen(Gen::Yellow) && b.hadSubstitute(t))
    5. return;
    6.  
    7. b.selfKoer() = s;
    8. b.koPoke(s, s);
    9.  
     
    Lutra likes this.
  16. sulcata

    sulcata stéphane curry best waifu Forum Moderator Server Administrator Forum Moderator Server Administrator

    Joined:
    Jun 13, 2012
    Messages:
    968
    Likes Received:
    744
    our randint does 0 to n-1 inclusive because the implementation is something like:
    Generate random integer, A, with a mersenne twister algorithm.
    Return A%n.
     
  17. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
    Then randint(256) would produce a number in [0;255], correct ?
     
  18. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    By using scientific calculator from hex to dec conversion with only 2 values. The minimum 00 (hex) = 00 (dec). The maximum FF (hex) = 255 (dec).

    You can't have anything greater than 255 with 2 values. I don't know about Pokemon Stadium code but I thought I just mention the 1 to 256 might be 0 to 255.
     
  19. sulcata

    sulcata stéphane curry best waifu Forum Moderator Server Administrator Forum Moderator Server Administrator

    Joined:
    Jun 13, 2012
    Messages:
    968
    Likes Received:
    744
    correct (there's actually a bug I know of related to this on PO unless someone submitted a fix)
     
  20. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
    So I edited the code snippet in my previous post with randint(256)

    Nightfall Alicorn > ikr, Stadium and RBY use a pseudo-random between 0 and 255
     
  21. Lutra

    Lutra All Gen Battler/Scripter

    Joined:
    Apr 25, 2010
    Messages:
    509
    Likes Received:
    188
    PO Trainer Name:
    Lutra
    I think this is the todo at the moment:

    Fix doesn't work:
    Fix needs testing:

    Fixes need doing:
    Fuzzy edit: striking out what is done
     
    Last edited by a moderator: Apr 1, 2015
  22. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
  23. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    I looked into the code and it seems like this is already implemented.
    @Lutra Are you sure that it isn't working correctly?
     
  24. Lutra

    Lutra All Gen Battler/Scripter

    Joined:
    Apr 25, 2010
    Messages:
    509
    Likes Received:
    188
    PO Trainer Name:
    Lutra
    ok it already is, I'll get rid of that.
     
  25. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    Just mentioning I'm moving this to Bugs & Fixes forum because I keep forgetting about it here.
     
  26. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
  27. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    I fixed some RBY sprites too since they had transparency issues (Charizard, Dragonite, etc. Tails, arms, legs, and so on that created loops had white space in there, so I fixed them)

    Hyper Beam
    Start of turn 1
    The foe's Dragonite used Hyper Beam!
    Charmander lost 218 HP! (100% of its health)
    Charmander fainted!
    Fuzzysqurl sent out Golbat!

    Start of turn 2
    The foe's Dragonite must recharge!

    Golbat used Double-Edge!
    Start of turn 1
    Dragonite used Hyper Beam!
    The foe's Charmander lost 100% of its health!
    The foe's Charmander fainted!
    Fuzzysqurl sent out Golbat!

    Start of turn 2
    Dragonite used Hyper Beam!
    The foe's Golbat lost 49% of its health!


    Explosion:
    Start of turn 1
    The foe's Golem used Explosion!
    Porygon lost 301 HP! (100% of its health)
    Porygon fainted!
    The foe's Golem fainted!
    Fuzzysqurl sent out Golem!
    Fuzzysqurl2 sent out Lapras!

    Start of turn 2
    The foe's Lapras used Substitute!
    The foe's Lapras made a substitute!

    Golem used Explosion!
    The foe's Lapras's substitute faded!
    Golem fainted!
    Start of turn 1
    The foe's Lapras used Substitute!
    The foe's Lapras made a substitute!

    Golem used Explosion!
    The foe's Lapras's substitute faded!


    Start of turn 2
    Fuzzysqurl called Lapras back!
    Fuzzysqurl sent out Charmander!

    Golem used Explosion!
    The foe's Charmander lost 100% of its health!
    The foe's Charmander fainted!
    Golem fainted!

    Also as far as Critical hits and Focus energy needing testing, I'll let someone that knows what they are doing address those. I'll get around to the Partial Trapping and stat/status interaction (provided the latter wasn't fixed already) eventually.
     
    Last edited: Apr 1, 2015
    froggy25, Disaster Area and Lutra like this.
  28. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    Thrash was broken too. If you broke a sub with it, the duration reset. The bug shared its cause with Explosion breaking a sub. If a sub was broken in an attack, the attack didn't call the ending effects. This affected only 2 (4) moves: Explosion (and Selfdestruct) and Thrash (and Petal Dance).

    Fuzzysqurl sent out Porygon!
    Developer sent out Nidoking!

    Start of turn 1
    The foe's Porygon used Substitute!
    The foe's Porygon made a substitute!

    Nidoking used Thrash!
    The foe's Porygon's substitute faded!

    Start of turn 2
    The foe's Porygon used Substitute!
    The foe's Porygon made a substitute!

    Nidoking used Thrash!
    A critical hit!
    The foe's Porygon's substitute faded!

    Start of turn 3
    The foe's Porygon used Substitute!
    The foe's Porygon made a substitute!

    Nidoking used Thrash!
    The foe's Porygon's substitute faded!

    Start of turn 4
    The foe's Porygon used Substitute!
    The foe's Porygon made a substitute!

    Nidoking used Thrash!
    The foe's Porygon's substitute faded!

    Start of turn 5
    The foe's Porygon used Substitute!
    The foe's Porygon hasn't enough energy left!

    Nidoking used Thrash!
    A critical hit!
    The foe's Porygon lost 0% of its health!
    The foe's Porygon fainted!
    Fuzzysqurl sent out Nidoking!
    Developer: still can't select a move
    Developer: thrash is still automatically attacking


    Start of turn 6
    Fuzzysqurl called Nidoking back!
    Fuzzysqurl sent out Dragonite!

    Nidoking used Thrash!
    A critical hit!
    The foe's Dragonite lost 34% of its health!

    Start of turn 7
    Fuzzysqurl called Dragonite back!
    Fuzzysqurl sent out Golem!

    Nidoking used Thrash!
    It's not very effective...
    The foe's Golem lost 7% of its health!

    Start of turn 8
    Fuzzysqurl called Golem back!
    Fuzzysqurl sent out Lapras!

    Nidoking used Thrash!
    The foe's Lapras lost 18% of its health!
    Nidoking became confused!

    Developer: now it ends
    Developer: and i can select a move
    8 turns of thrash before I was able to select a move again

    @Lutra @Crystal_ this was a bug right? (double posting for notify)
     
    froggy25 likes this.
  29. Disaster Area

    Disaster Area Badged Deucer

    Joined:
    May 10, 2013
    Messages:
    615
    Likes Received:
    226
    PO Trainer Name:
    Disaster Area
    @froggy25 is your man for stadium crit mechanics fuzzy
     
  30. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    Submitted a fix for the crit chances.
    @froggy25 @Lutra Can you check whether the fix is correct?
     
  31. Lutra

    Lutra All Gen Battler/Scripter

    Joined:
    Apr 25, 2010
    Messages:
    509
    Likes Received:
    188
    PO Trainer Name:
    Lutra
    I don't know anything about the game code unfortunately. Maybe it's worth using a bit shift for the RBY stuff too though? Also is the *= needed for changing the up variable? It isn't used for changing down.
     
  32. sulcata

    sulcata stéphane curry best waifu Forum Moderator Server Administrator Forum Moderator Server Administrator

    Joined:
    Jun 13, 2012
    Messages:
    968
    Likes Received:
    744
    int randnum = randint(255) + 1; // randint [1; 256]

    no idea which way this line should be, but it's contradictory. randint(255) produces a random int from 0 inclusive to 255 exclusive. So that line is actually producing a random int [1, 255], not [1, 256] as the comment says it does.
     
  33. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    Whoops, it's a typo. Gonna fix this.
     
  34. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    I did a quick test of my formula by writing a test program and checking the results with the ones Fuzzy had and I got the same results.
    However, I am still not sure if the next part of my fix is 100% correct.
    Any opinions on this part?
     
  35. froggy25

    froggy25 Member

    Joined:
    Jun 7, 2013
    Messages:
    32
    Likes Received:
    20
    You're applying High Crit Ratio twice if both Focus Energy and High Crit Ratio are active.
    Also, randint(256) is the correct way to do it ; if it produces a 255 and ch >= 255, then randnum < std::min(255, ch) will be false, thus the move will not produce a critical.

    This would be correct way to implement it:
    Code (text):
    1.  
    2. else if (gen() == Gen::Stadium) {
    3.    int ch = (baseSpeed + 76) >> 2;
    4.  
    5.    if (tmove(player).critRaise & 2) // Focus Energy
    6.      ch = (ch << 2) + 160;
    7.    else ch = ch << 1;
    8.  
    9.    if (tmove(player).critRaise & 1) // Move with high crit ratio
    10.      ch = ch << 2;
    11.    else ch = ch >> 1;
    12.  
    13.    int randnum = randint(256); // randint [0; 255]
    14.    critical = randnum < std::min(255, ch); // highest possible crit chance is 255/256
    15. }
    16.  
     
    sulcata and turbedi like this.
  36. turbedi

    turbedi Professional circle clicker ~~~ Forum Moderator Developer Forum Moderator Developer

    Joined:
    Jul 18, 2013
    Messages:
    385
    Likes Received:
    155
    PO Trainer Name:
    turbedi
    Updated the PR. Thanks a lot for you help @froggy25
     
    froggy25 likes this.
  37. Fuzzysqurl

    Fuzzysqurl baa baa mareep I do what I want Server Owner Developer I do what I want Server Owner Developer

    Joined:
    Sep 12, 2012
    Messages:
    2,096
    Likes Received:
    967
    Can we get an updated list of mechanics that are still incorrect? If possible, someone compile the list and start a new thread. Thanks.