chaos Posted March 25 Report Posted March 25 The Art of Shooting in NHL94 "How the hell did that shot not go on net?" is one of the common phrases to say when playing this game. Well, the 94 RNG gods have screwed with you more times than you can count. Is there a way to always make sure your shot goes where you want it to? Well, no. But the higher the Shot Accuracy (ShA) of the player the more likely you will get a "perfect shot". Aiming There are 9 places you can aim your shot at (this is looking at the top goal, when shooting up): 0 is up on the Dpad, 1 is top right on the Dpad, 2 is right on the Dpad, and go clockwise to get the rest. When you are not pressing a direction, 8 is the default direction (middle of the net). This direction is set while holding the C button to shoot. The game will remember the LAST direction you pressed and use that as your shot direction. So you can start your windup pressing right on the Dpad, and let go of the Dpad before the shot, and it will still shoot to position 8. You can press right on the Dpad, hold C to windup, then at the last second press left on the Dpad, and it will shoot at position 6. As long as you are still in windup, the direction can be changed. There is no aiming for one-timers (in Genesis at least). The CPU player and the one timer players go through a separate routine for aiming. It will use the current position of the goalie and aim to where the goalie is not (the game actually calculates the angle of where the puck is and the goalie's angle relative to the goal posts, and will aim away from that). There are 4 spots that will be used for aiming in this situation: Position 0, 2, 6 and 8 (if there's no goalie). Windup When you hold the shot button down, the player will go into a windup animation. If the player has a >= 4 Shot Power (ShP), they will have EXTRA frames to their windup animation. Why is this significant? Every frame, there is 1 added to a variable called passspeed when the shot button is held(or shot speed; passspeed is what the source code calls it, as it uses the same variables for passing and shooting). The base shot speed is 15 decimal. For players with < 20 ShP value (< 4 ShP attribute), holding down the C button for the duration of the shot windup, their max starting shot speed will be 31 decimal. For players with >= 20 ShP value (4 ShP attribute or higher), holding down the C button for the duration, their max starting shot speed will be 35 decimal. This may vary +/- 1 due to frame discrepencies. I list the ShP value, because this is the value after Hot/Cold is applied. So, for example, if you have a cold player who normally is a 4 ShP, he will not get the extra windup (because his total ShP will be 4 * 5 - Hot/Cold, and if cold, it will be less than 20). The only bonus that ShP gets is Hot/Cold. The Hot/Cold bonus is the regular ROM is between -4 and +3. Here's 2 screenshots showing the difference in max windup between ShP. Notice how high the stick goes: Note, because of the extra windup animation, a player with 4+ ShP will take longer to shoot a full power slapper than other players. Once the windup is completed, it's time to shoot the puck. One-timers are different. Since there is no windup involved, there is no extra addition to the base shot speed. Because of this, the base shot speed of all one-timers is 31 decimal. Shot Speed Once the stick hits the puck, it's time to shoot. If you are shooting a backhand, your base shot speed will be decreased by 25% (one-timers do not get this decrease). It does this by taking the value, dividing it by 4 (quotient only, remainder is dropped), and subtracting that result from the base shot speed. Next, it will determine the final shot speed. This is a complex calculation. If you are playing with line changes on, the shot speed will be scaled depending on the player's energy level. I'll list the calculation here: - Take ShP value (ShP attribute * 5 + Hot/Cold, a value between 0-30 dec) - Divide ShP value by 2 - Scale the result based on energy level of player - Add $14 (20 dec) - Multiply result by shot speed (from the windup, or 31 dec if one-timer) - Multiply result by $5249 (21,065 dec) - Swap the upper and lower words of the result (swap the upper and lower 2 bytes) - It then does a minor correction if the ShP was an odd value (because when dividing, it drops the remainder) To make it easier, here is a table with the shot speeds for full slapshots and for one-timers: Notice the difference between a base 3 ShP and a base 4 ShP for Shot Speed. This is due to the extra windup and extra frames added to the initial value. Notice how one-timers do not get this boost, and the Shot Speed for a one-timer by a player with a 6 ShP is close to a 4 ShP slapshot. Also, ShP of 3 and below have the same speed regardless if its a one-timer or a full slapper. Once the Shot Speed is determined, it's time to direct the puck in the right direction. Perfect Shot, or Not A "perfect shot", as named by the 92 source code, is a shot that goes EXACTLY to the spot on the net you were aiming at. This does not mean an instant goal, it just means where you aimed, is where it's going. It can be blocked along the way, tipped, saved, etc. It's just traveling along a straight line to the spot on the net you aimed at. There are some situations where the calculation is ignored, and you will either guaranteed a perfect shot, or you are guaranteed not to get one: Highlights always get a perfect shot Shootouts always get a perfect shot In order to be able to have a chance at a perfect shot, the puck needs to be within 200 pixels of the spot you are aiming at If you are within that 200 pixel distance, and your goalie is pulled, you get a perfect shot Outside of 200 pixel distance, no chance at a perfect shot Here's a photo showing the range you need to be in for a chance at a perfect shot: OK, so the shot passes the 200 pixel test, now what? The calculation for a "perfect shot" uses the players ShA and some RNG: - Start with 16 decimal ($10 hex) - Add the ShA value (ShA attribute * 5 + Bonuses (Hot/Cold, PP, PK, Team Bonus), within 0-30 dec range) - RNG the result - If the result is greater than 14 decimal ($E hex), you got a perfect shot! Here's a table showing base attribute values, and the probability of getting a perfect shot: So what if you missed out on the perfect shot? No worries! There's still a chance that your shot will go on net, more than likely not to the spot you were hoping for. "Adjustments" are made to the shot speed, based on the player's ShA, a starting value, and some RNG. Adjustments are made to the X, Y, and Z velocities of the puck. First, an adjustment value is calculated: - Take the final shot speed, divide by 16 - Divide ShA (0-30 value) by 2 and subtract it from the shot speed result - Add 16 dec to the result - Multiply the result by the straight line distance the puck will travel to the net - Divide that result by 64 - Check if the straight line distance was more than 250 pixels, if so, divide the result by 2 (extra shot accuracy adjust) Once we have the adjustment value, it will be used to modify the aiming spot of the puck. Earlier, the game saved X, Y, and Z locations of where you are aiming at. The adjustment value will be +/- RNGed for X and Y (so -value < RNG result < +value) and will be added to the aiming location. There are limits to how much it can adjust: - Max adjustment limit in X - +/- 136 pixels - Max adjustment limit in Y - +/- 60 pixels Z is slightly different, as it will take the adjustment value, divide by 2, and RNG the result (but only a positive RNG result, obviously the puck isn't going through the ice) If you shot behind the net (Y distance to goal line would be negative) or on the goal line, the adjustment value is halved before making the RNG calc for Y. After all this, perfect shot or not, the puck velocity is adjusted based on the shot speed and distance to the spot. There are checks for maximum velocity in X, Y and Z, and these are set if needed. There is a neat little adjustment made to the Z velocity based on a special circumstance. The game will check if you are in close with the puck (below the face-off dots). If you are aiming for top shelf (locations 0, 1 or 7), and the goalie is in a pad stack save, or if the goalie has been pulled (open net), it will give a little boost to the Z velocity. Watch the slow mo GIF: Without the extra boost to Z velocity, the puck would have enough time to gain height from that close. 4 3 Quote
smozoma Posted March 25 Report Posted March 25 Quote - Multiply result by $5249 (21,065 dec) - Swap the upper and lower words of the result (swap the upper and lower 2 bytes) wtf Is that some kind of randomizer trick, so shot speed isn't the same every time even if the hot/cold and windup is the same? Quote
chaos Posted March 26 Author Report Posted March 26 4 hours ago, smozoma said: wtf Is that some kind of randomizer trick, so shot speed isn't the same every time even if the hot/cold and windup is the same? Hahaha. No, it's actually some kind of calculation. The source code lists it as $4000 * 35/45. I don't know exactly where it's pulling those numbers from. Then it's just using the upper part of the result for some reason. Quote
AdamCatalyst Posted March 26 Report Posted March 26 (edited) Interesting! I've been working on revising the shooting logic for a bit, but I completely missed the bit about extra windup power being added on to some slap-shots! Where is that in the code? FWIW, here was how I understood it below. I know this sounds pedantic, but in your table listed above, you labeled it "Shot Speed", but I believe the calculated value is still technically "Shot Power" until it is multiplied by 68 to get the base "Shot Speed" of the puck, before any changes are made to compensate for shooting range. --- Forehand Shot, Even ShP Number ShotPower = (ShP/2 + 20) × PassSpeed × 21065 ÷ 65536 × 68 Forehand Shot, Odd ShP Number ShotPower = [(ShP/2 + 20) × PassSpeed × 21065 ÷ 65536 + PassSpeed ÷ 16] × 68 Where PassSpeed = 15 (minimum/no windup) 23 (medium/partial windup) 31 (maximum/full windup) --- Backhand Shot, Even ShP Number ShotPower = (ShP/2 + 20) × (PassSpeed × 0.75) × 21065 ÷ 65536 × 68 Backhand Shot, Odd ShP Number ShotPower = [(ShP/2 + 20) × (PassSpeed × 0.75) × 21065 ÷ 65536 + (PassSpeed × 0.75) ÷ 16] × 68 Where PassSpeed × 0.75 = 11.25 (minimum/no windup) 17.25 (medium/partial windup) 23.25 (maximum/full windup) --- One-Timer, Even ShP Number ShotPower = (ShP/2 + 20) × 31 × 21065 ÷ 65536 × 68 One-Timer, Odd ShP Number ShotPower = [(ShP/2 + 20) × 31 × 21065 ÷ 65536 + 31 ÷ 16] × 68 --- Base Factor = (ShP/2 + 20) Backhand passspeed = regular passspeed * 0.75 (except for one-timers) One-timers always use passspeed 31 ``` | ShP | Min B. | Min F. | Mid B. | Mid F. | One-T. B. | One-T. F. | Max B. | Max F. | |-----|--------|--------|--------|--------|-----------|-----------|--------|--------| | 0 | 4,918 | 6,557 | 7,541 | 10,053 | 13,552 | 13,552 | 10,164 | 13,552 | | 1 | 5,037 | 6,715 | 7,723 | 10,296 | 13,850 | 13,850 | 10,351 | 13,850 | | 2 | 5,155 | 6,874 | 7,905 | 10,539 | 14,149 | 14,149 | 10,540 | 14,149 | | 3 | 5,274 | 7,032 | 8,086 | 10,782 | 14,447 | 14,447 | 10,728 | 14,447 | | 4 | 5,392 | 7,190 | 8,268 | 11,025 | 14,745 | 14,745 | 10,917 | 14,745 | | 5 | 5,511 | 7,348 | 8,449 | 11,267 | 15,044 | 15,044 | 11,105 | 15,044 | | 6 | 5,629 | 7,506 | 8,631 | 11,510 | 15,342 | 15,342 | 11,293 | 15,342 | | 7 | 5,748 | 7,664 | 8,812 | 11,753 | 15,641 | 15,641 | 11,481 | 15,641 | | 8 | 5,901 | 7,868 | 9,046 | 12,063 | 16,039 | 16,039 | 11,764 | 16,039 | | 9 | 6,020 | 8,026 | 9,228 | 12,306 | 16,338 | 16,338 | 11,952 | 16,338 | | 10 | 6,138 | 8,184 | 9,409 | 12,549 | 16,636 | 16,636 | 12,140 | 16,636 | | 11 | 6,257 | 8,342 | 9,591 | 12,792 | 16,935 | 16,935 | 12,329 | 16,935 | | 12 | 6,375 | 8,500 | 9,772 | 13,035 | 17,233 | 17,233 | 12,517 | 17,233 | | 13 | 6,494 | 8,658 | 9,954 | 13,278 | 17,531 | 17,531 | 12,705 | 17,531 | | 14 | 6,612 | 8,816 | 10,135 | 13,521 | 17,830 | 17,830 | 12,893 | 17,830 | | 15 | 6,765 | 9,020 | 10,370 | 13,831 | 18,228 | 18,228 | 13,176 | 18,228 | **Column Details:** - Min B.: Minimum Backhand (passspeed = 11.25) - Min F.: Minimum Forehand (passspeed = 15) - Mid B.: Medium Backhand (passspeed = 17.25) - Mid F.: Medium Forehand (passspeed = 23) - One-T. B.: One-Timer Backhand (passspeed = 31) - One-T. F.: One-Timer Forehand (passspeed = 31) - Max B.: Maximum Backhand (passspeed = 23.25) - Max F.: Maximum Forehand (passspeed = 31) Edited March 26 by AdamCatalyst Quote
AdamCatalyst Posted March 26 Report Posted March 26 (edited) 17 hours ago, smozoma said: wtf Is that some kind of randomizer trick, so shot speed isn't the same every time even if the hot/cold and windup is the same? I thought the byte swap was a cpu-friendly way of dividing by 65536. Edited March 26 by AdamCatalyst Quote
chaos Posted March 26 Author Report Posted March 26 7 hours ago, AdamCatalyst said: Interesting! I've been working on revising the shooting logic for a bit, but I completely missed the bit about extra windup power being added on to some slap-shots! Where is that in the code? FWIW, here was how I understood it below. I know this sounds pedantic, but in your table listed above, you labeled it "Shot Speed", but I believe the calculated value is still technically "Shot Power" until it is multiplied by 68 to get the base "Shot Speed" of the puck, before any changes are made to compensate for shooting range. --- Forehand Shot, Even ShP Number ShotPower = (ShP/2 + 20) × PassSpeed × 21065 ÷ 65536 × 68 Forehand Shot, Odd ShP Number ShotPower = [(ShP/2 + 20) × PassSpeed × 21065 ÷ 65536 + PassSpeed ÷ 16] × 68 Where PassSpeed = 15 (minimum/no windup) 23 (medium/partial windup) 31 (maximum/full windup) --- Backhand Shot, Even ShP Number ShotPower = (ShP/2 + 20) × (PassSpeed × 0.75) × 21065 ÷ 65536 × 68 Backhand Shot, Odd ShP Number ShotPower = [(ShP/2 + 20) × (PassSpeed × 0.75) × 21065 ÷ 65536 + (PassSpeed × 0.75) ÷ 16] × 68 Where PassSpeed × 0.75 = 11.25 (minimum/no windup) 17.25 (medium/partial windup) 23.25 (maximum/full windup) --- One-Timer, Even ShP Number ShotPower = (ShP/2 + 20) × 31 × 21065 ÷ 65536 × 68 One-Timer, Odd ShP Number ShotPower = [(ShP/2 + 20) × 31 × 21065 ÷ 65536 + 31 ÷ 16] × 68 --- Base Factor = (ShP/2 + 20) Backhand passspeed = regular passspeed * 0.75 (except for one-timers) One-timers always use passspeed 31 ``` | ShP | Min B. | Min F. | Mid B. | Mid F. | One-T. B. | One-T. F. | Max B. | Max F. | |-----|--------|--------|--------|--------|-----------|-----------|--------|--------| | 0 | 4,918 | 6,557 | 7,541 | 10,053 | 13,552 | 13,552 | 10,164 | 13,552 | | 1 | 5,037 | 6,715 | 7,723 | 10,296 | 13,850 | 13,850 | 10,351 | 13,850 | | 2 | 5,155 | 6,874 | 7,905 | 10,539 | 14,149 | 14,149 | 10,540 | 14,149 | | 3 | 5,274 | 7,032 | 8,086 | 10,782 | 14,447 | 14,447 | 10,728 | 14,447 | | 4 | 5,392 | 7,190 | 8,268 | 11,025 | 14,745 | 14,745 | 10,917 | 14,745 | | 5 | 5,511 | 7,348 | 8,449 | 11,267 | 15,044 | 15,044 | 11,105 | 15,044 | | 6 | 5,629 | 7,506 | 8,631 | 11,510 | 15,342 | 15,342 | 11,293 | 15,342 | | 7 | 5,748 | 7,664 | 8,812 | 11,753 | 15,641 | 15,641 | 11,481 | 15,641 | | 8 | 5,901 | 7,868 | 9,046 | 12,063 | 16,039 | 16,039 | 11,764 | 16,039 | | 9 | 6,020 | 8,026 | 9,228 | 12,306 | 16,338 | 16,338 | 11,952 | 16,338 | | 10 | 6,138 | 8,184 | 9,409 | 12,549 | 16,636 | 16,636 | 12,140 | 16,636 | | 11 | 6,257 | 8,342 | 9,591 | 12,792 | 16,935 | 16,935 | 12,329 | 16,935 | | 12 | 6,375 | 8,500 | 9,772 | 13,035 | 17,233 | 17,233 | 12,517 | 17,233 | | 13 | 6,494 | 8,658 | 9,954 | 13,278 | 17,531 | 17,531 | 12,705 | 17,531 | | 14 | 6,612 | 8,816 | 10,135 | 13,521 | 17,830 | 17,830 | 12,893 | 17,830 | | 15 | 6,765 | 9,020 | 10,370 | 13,831 | 18,228 | 18,228 | 13,176 | 18,228 | **Column Details:** - Min B.: Minimum Backhand (passspeed = 11.25) - Min F.: Minimum Forehand (passspeed = 15) - Mid B.: Medium Backhand (passspeed = 17.25) - Mid F.: Medium Forehand (passspeed = 23) - One-T. B.: One-Timer Backhand (passspeed = 31) - One-T. F.: One-Timer Forehand (passspeed = 31) - Max B.: Maximum Backhand (passspeed = 23.25) - Max F.: Maximum Forehand (passspeed = 31) Ok, so you're missing a few things. I'm referring it as "Shot Speed" to make it easier for people to understand. In reality, it's using the variable called passspeed, and if you look in the 92 source code, it refers to the value stored in passspeed as "shot speed" on a comment before being multiplied by 68 (which is 1024/15). I'm just trying to keep the naming conventions the same as the source code, so if someone wanted to look it up in the 92 source code, they can. ShotMode subroutine - 0xC224 0xC24C is the comparison for ShP: cmpi.b #$14, $6C(a3) (which is where ShP value is stored for player struct) There are no decimals up in here. To get 25%, it divides by 4 and subtracts that from the value (quotient only, no remainder is used). I should have been more clear about that. I will edit. Ex: 25/4 = 6, 25-6 = 19 Also, I'm not sure about this 0-15 scale you are using, and how it is adjusted to the original 0-6 scale. In 92, which has a 0-15 scale, the divide by 2 is not there. If I were to take a one-timer with a 6 ShP player: 6 ShP = 30 ShP value 30 / 2 = 15 15 + 20 = 35 35 * 31 (one-timer fixed value) = 1,085 1,085 * 21,065 = 22,855,525 22,855,525 / 65536 = 348 348 * 68 = 23,664 Quote
77 Posted March 26 Report Posted March 26 how about those accidental fake shots? to be able to cancel a slapshot would be cool Quote
AdamCatalyst Posted March 26 Report Posted March 26 (edited) FYI, @smozoma did the 0-15 by just altering the multipliers, so rather than *5 preprocessing a 0-6 values it does *2 for a 0-15 value, so it scales with the same effective minimum and maximum. Every time I get deeper in the code and think I found a circumstance where I think he may have gotten it wrong, I marvel at how beautiful perfect it works. Yeah, I know there aren't actually any decimals used, it's just easer for me to think of it this way when I am modifying things. There is still a gap between when you wrote and what I understand. I'll go bang my head against the wall and take a look again in the morning. Thanks for sharing all this as always! EDIT: ASASAAHAHAHA! I see what I did. I forget to pre-multiply 0-15 x2. If I do that my numbers are the same as yours if I do that. OK, now I need to go find this full wind up bonus pass speed thing. Edited March 26 by AdamCatalyst Quote
chaos Posted March 26 Author Report Posted March 26 1 hour ago, AdamCatalyst said: FYI, @smozoma did the 0-15 by just altering the multipliers, so rather than *5 preprocessing a 0-6 values it does *2 for a 0-15 value, so it scales with the same effective minimum and maximum. Every time I get deeper in the code and think I found a circumstance where I think he may have gotten it wrong, I marvel at how beautiful perfect it works. Yeah, I know there aren't actually any decimals used, it's just easer for me to think of it this way when I am modifying things. There is still a gap between when you wrote and what I understand. I'll go bang my head against the wall and take a look again in the morning. Thanks for sharing all this as always! EDIT: ASASAAHAHAHA! I see what I did. I forget to pre-multiply 0-15 x2. If I do that my numbers are the same as yours if I do that. OK, now I need to go find this full wind up bonus pass speed thing. Yeah, he really only had to do it in one spot, where the attributes are loaded in. So that makes sense. ROM:0000C224 ; shot input ROM:0000C224 ROM:0000C224 ShotMode: ; CODE XREF: ROM:0000B754↑j ROM:0000C224 ; assshoot+28↓j ... ROM:0000C224 0C6B 001C 005A cmpi.w #$1C,$5A(a3) ; check animation index ROM:0000C22A 6C00 0048 bge.w prepshot ; end of animation so shoot ROM:0000C22E 0800 0003 btst #3,d0 ; checks dpad for direction ROM:0000C232 6600 000A bne.w _ss0 ROM:0000C236 0240 0007 andi.w #7,d0 ; pass the first 3 bits of d0 ROM:0000C23A 31C0 BEDC move.w d0,(passdir).w ; set shot direction ROM:0000C23E ROM:0000C23E _ss0: ; CODE XREF: ShotMode+E↑j ROM:0000C23E 0C6B 0010 005A cmpi.w #$10,$5A(a3) ROM:0000C244 6C00 002C bge.w _end ; past full windup so no more passspeed ROM:0000C248 DF78 BEDE add.w d7,(passspeed).w ROM:0000C24C 0C2B 0014 006C cmpi.b #$14,$6C(a3) ; 6C = shot speed ROM:0000C252 6C00 000C bge.w _checkcbut ROM:0000C256 0C6B 0008 005A cmpi.w #8,$5A(a3) ; SPANum - animation index ROM:0000C25C 6E00 000A bgt.w _chganim ROM:0000C260 ROM:0000C260 _checkcbut: ; CODE XREF: ShotMode+2E↑j ROM:0000C260 0802 0005 btst #5,d2 ; 5 = #cbut ROM:0000C264 6700 000C beq.w _end ; button hasnt changed so continue windup ROM:0000C268 ROM:0000C268 _chganim: ; CODE XREF: ShotMode+38↑j ROM:0000C268 446B 005A neg.w $5A(a3) ; end windup and swing through ROM:0000C26C 066B 001C 005A addi.w #$1C,$5A(a3) ; Add to SPANum ROM:0000C272 ROM:0000C272 _end: ; CODE XREF: ShotMode+20↑j ROM:0000C272 ; ShotMode+40↑j ROM:0000C272 4E75 rts ROM:0000C272 ; End of function ShotMode 1 Quote
AdamCatalyst Posted March 27 Report Posted March 27 OK, I see what's happening here. I was seeing this as wind-up maxing out at 16, unless a player has a ShP rating below 20, in which case they are limited to 8. I couldn't find the bonus wind-up frames for ShP≥20, because I was perceiving it as a limiting of wind-up frames for ShP<20. I was getting confused by language usage, but it is exactly the same thing, except for one small detail… …you mentioned a 6 decimal difference, yet I'm seeing an 8 decimal difference. Any more ideas on what I'm missing? Quote
chaos Posted March 27 Author Report Posted March 27 11 hours ago, AdamCatalyst said: OK, I see what's happening here. I was seeing this as wind-up maxing out at 16, unless a player has a ShP rating below 20, in which case they are limited to 8. I couldn't find the bonus wind-up frames for ShP≥20, because I was perceiving it as a limiting of wind-up frames for ShP<20. I was getting confused by language usage, but it is exactly the same thing, except for one small detail… …you mentioned a 6 decimal difference, yet I'm seeing an 8 decimal difference. Any more ideas on what I'm missing? Did you test this? I tested again, and I found I am off a little. This is because of the frame counter. You usually expect to add 1 each frame. But sometimes, 2 frames elapse before it gets back to this function. Depending on where those 2 frames fall, sometimes you will get an extra frame added (if it is the same frame when the player's frame counter is reset). Let's do the math: Each shot animation has a 5 frame timer. Once the frame timer is reset, the frame animation index changes by 4. A ShP value of >= 20 will get 5 frame animation index changes before to stops adding to the passspeed. (0, 4, 8, C, 10) before it ends at 0x10. ROM:0000C23E 0C6B 0010 005A cmpi.w #$10,$5A(a3) ROM:0000C244 6C00 002C bge.w _end ; past full windup so no more passspeed So that's 5 + 5 + 5 + 5 = 20 frames added to passspeed (shot speed whatever you want to call it). A ShP value of < 20 gets 4 frame animation index changes (0, 4, 8, C) before it ends at 0xC. So that's 5 + 5 + 5 = 15 frames added to passspeed (shot speed). But, since the check for ShP is not until AFTER the frame is added, they get an extra frame counted. 5 + 5 + 5 + 1 = 16 frames added. Again, these are normal conditions. ROM:0000C23E cmpi.w #$10,$5A(a3) ROM:0000C244 bge.w _end ; past full windup so no more passspeed ROM:0000C248 add.w d7,(passspeed).w ROM:0000C24C cmpi.b #$14,$6C(a3) ; 6C = shot speed ROM:0000C252 bge.w _checkcbut ROM:0000C256 cmpi.w #8,$5A(a3) ; SPANum ROM:0000C25C bgt.w _chganim So in a normal situation, the difference is not 6, but it's 4. This will vary +/-1 sometimes because of the frame counter and the player's frame timer. You can see, the compare to 0x10 of the frame animation index, and the 0x14 of the ShP are greater than/equal, and the compare for 8 of the frame animation index is a greater than (which will let it get to 0xC before it would branch). I will update the original post. 1 Quote
AdamCatalyst Posted March 27 Report Posted March 27 (edited) oh!!!! OK, ALL makes more sense now. No, I don't even know how to test this, I've been working on my own mental model of the code, from the stuff that you have shared. I'm proud to say I got most of it right, but most of it right was still wrong. Thanks again. Edited March 27 by AdamCatalyst 1 Quote
chaos Posted March 27 Author Report Posted March 27 13 minutes ago, AdamCatalyst said: oh!!!! OK, ALL makes more sense now. No, I don't even know how to test this, I've been working on my own mental model of the code, from the stuff that you have shared. I'm proud to say I got most of it right, but most of it right was still wrong. Thanks again. Thank you! Made me look at it again, and I figured out a mistake! 1 Quote
AdamCatalyst Posted March 29 Report Posted March 29 (edited) This is my simplified understanding of the Shot Speed calculations. Edited March 29 by AdamCatalyst 1 Quote
chaos Posted March 29 Author Report Posted March 29 12 hours ago, AdamCatalyst said: This is my simplified understanding of the Shot Speed calculations. I think it looks good, except that one-timer backhands don't get the backhand penalty 1 Quote
AdamCatalyst Posted April 2 Report Posted April 2 (edited) Paging Mr. @chaos. When I calculated Perfect Shot probabilities, I used the following maths: Therefore, a player with a 6/15 shot accuracy will have a ~71% (16+30-14 / 16+30) chance of making a perfect shot. A player with 0 Shot Accuracy will have a ~12.5% (16+0-14 / 16+0) chance of making a perfect shot. Your numbers are noticeably different. Quote I can't figure out how you arrived at yours. Can you see what I am missing? EDIT: I also noticed that you listed #16 as $14, which also breaks my brain. In my notes it was ShA + $10. Edited April 2 by AdamCatalyst Quote
chaos Posted April 3 Author Report Posted April 3 5 hours ago, AdamCatalyst said: Paging Mr. @chaos. When I calculated Perfect Shot probabilities, I used the following maths: Therefore, a player with a 6/15 shot accuracy will have a ~71% (16+30-14 / 16+30) chance of making a perfect shot. A player with 0 Shot Accuracy will have a ~12.5% (16+0-14 / 16+0) chance of making a perfect shot. Your numbers are noticeably different. I can't figure out how you arrived at yours. Can you see what I am missing? EDIT: I also noticed that you listed #16 as $14, which also breaks my brain. In my notes it was ShA + $10. Yeah, I messed up here, I'll fix the original post. Starting value is $10 or 16 decimal. Updated post and table. Your math in the first example is wrong, it would be 69.6% chance with a 6 ShA 1 Quote
AdamCatalyst Posted April 3 Report Posted April 3 (edited) Thanks! My math is off? That’s not surprising, considering my math education ended when I nearly failed grade 10 math. Now I get 69.6% too. Ok, good stuff. Edited April 3 by AdamCatalyst Quote
AdamCatalyst Posted April 5 Report Posted April 5 (edited) @chaos I'm working on the shot accuracy variance system right now, and I just wanted to verify something. - Take the final shot speed, divide by 16… When calculating accuracy variance, what is the "final shot speed'? If I understand correctly, it is the last value produced before the *68 velocity multiplication. OR is it the value before being scaled up, the 31 for one-timers, etc.? BTW, I did some tests setting the breaking the glass threshold with my velocity calculations. It plays out exactly as expected now. Thanks for your help! Edited April 5 by AdamCatalyst Quote
chaos Posted April 5 Author Report Posted April 5 4 hours ago, AdamCatalyst said: @chaos I'm working on the shot accuracy variance system right now, and I just wanted to verify something. - Take the final shot speed, divide by 16… When calculating accuracy variance, what is the "final shot speed'? If I understand correctly, it is the last value produced before the *68 velocity multiplication. OR is it the value before being scaled up, the 31 for one-timers, etc.? BTW, I did some tests setting the breaking the glass threshold with my velocity calculations. It plays out exactly as expected now. Thanks for your help! The *68 is done after adjustments are made, so this happens before (during the non-perfect shot calc) The *68 is just basically converting the shot speed to a pixel calculation This is in the end of HOCKEY1.ASM source code 1024/15 (which is commented on that *68 line) = 68 decimal ;Vel*((16*60)/$10000)=pix/sec ;Vel*(15/1024)=pix/sec Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.