chaos Posted January 2 Report Posted January 2 In the game, a player can get injured for the game, or injured for the period. But there are some players who can never get a game injury (except if they get hit by a goon, more on that later)! What causes an injury? When the game determines a player is getting knocked down (the check is successful), it will check if there should be an injury. The impact value of player will be used in the calculation. To determine if there will be an injury: (starting at ROM address 0x14428) - Start with $A0 (160 decimal) - RNG (result will be from 0 up to 160 decimal) - Compare the impact of the player to the result (the impact value is calculated when the 2 players are about to collide, using their weight and velocity). - If the RNG result is higher than the impact, there will be no injury. If it is lower or equal to the impact, there will an injury, as long as the clock is running (no injuries post whistle) I should note that the impact value is cumulative. If the player was recently hit into, but survived the check (did not fall down), they will have a previous impact value stored. This value will decrease by 1 each frame (there are 60 frames in a second in Genesis). So if there are 2 checks in quick succession, the impact value will be much higher than from a single check. Also, any player collision causes impact, not just a check (bumping into a player for example, or getting hit by the puck). Injury for the period or game? Once the game determines there's an injury, it will now figure out the type of injury. In this case both the player who caused the injury and the player who is getting injured is used to figure this out. Each player has an H/F attribute byte, which stands for Hand/Fight. Now fighting is not in NHL94, but the Fight byte is used to determine injury type. The Hand part of the byte is just the first bit, which would make the number even or odd. The Fight portion of the byte is always even. For example, Jeremy Roenick has an H/F byte of 3. The number is odd, which makes him a Righty. His fight portion of the byte is 2 (round the odd number down to an even number to get the Fight). Alexnder Mogilny has an H/F byte of 4. The number is even, making him a Lefty. His fight portion of the byte is 4 (no rounding needed). Code to determine if injury for game or period (subroutine starts at 0x144AC. The starting code is for scroll locking on the injured player, and adding to the crowd meter. This part of the code starts at 0x144FE): - Get the Fight byte of the player checking, and divide it by 4 (no remainder) - Check if the result is 0 (which would be an H/F of 3 or below) - If zero, the injury will be for the period - If not zero (H/F of checker 4 or above): - Check if the result was 3 (H/F of 12, which is the max) - If it was 3, player is injured for the game - If less than 3 (H/F is 4-11): - Check the Fight byte of the player being injured - If the Fight byte is 2, 6, or 10 (H/F 2,3,6,7,10,11), the player will be injured for the game. - If the Fight byte is 0, 4, or 8 (H/F 0,1,4,5,8,9), the player will be injured for the period. There are 5 "goons" in the game with an H/F of 12. When these players cause injuries, they will always be for the game: Grant Ledyard (BUF) Louie DeBrusk (EDM) Shawn Cronin (PHI) Tony Twist (QUE) Basil McRae (STL) In all other cases, player that have an H/F of 0,1,4,5,8 or 9 will never be injured for the game. So in the above example, JR will be injured for the game if he's injured by a player with an H/F of 4 or above. If Mogilny is injured, it will always be for the period, unless by one of the goons, then it's for the game. Another fun example: If Mogilny injures JR, it will be for the game (Mogs H/F is a 4). 7 1 Quote
IAmFleury'sHipCheck Posted January 2 Report Posted January 2 I've been waiting for this breakdown for decades. Thanks Johnny C! 1 Quote
danTML7 Posted January 2 Report Posted January 2 I'm kind of surprised there hasn't been some accidental or anecdotal reports of this throughout the years. Like, Ledyard is a Buf starter most commonly and I have played a lot with them, and I can't recall ever thinking "wow he always injures people for the game". Has anyone else retrospectively thought that they might have known some of this information by feel? Quote
AdamCatalyst Posted January 3 Report Posted January 3 Oh wow! Interesting that "damage" is cumulative. Loving these breakdowns. 1 Quote
chaos Posted February 1 Author Report Posted February 1 20 minutes ago, AdamCatalyst said: @chaos Where is this in the code? The code to determine if there will be an injury is in the FallDown subroutine at 0x14428 (move.l #$A0, d0). The subroutine to determine injury type starts at 0x144AC. I updated the post above. Quote
AdamCatalyst Posted February 2 Report Posted February 2 Thanks for this! I was trying to force injuries, for testing purposes, but nothing I've done seems to work as I would expect so far. Will keep trying. Quote
chaos Posted February 3 Author Report Posted February 3 21 hours ago, AdamCatalyst said: Thanks for this! I was trying to force injuries, for testing purposes, but nothing I've done seems to work as I would expect so far. Will keep trying. Set the value at 0x1442D from A0 to something much less (I think anything between 00 and 20 will always be an injury). Quote
AdamCatalyst Posted February 3 Report Posted February 3 (edited) Setting it to 01 was the first thing I tried. I also tried reversing its branching logic. For some reason I neither approach worked. Will definitely try again. Edited February 3 by AdamCatalyst Quote
chaos Posted February 3 Author Report Posted February 3 If you set 0x14410 to from 84 to 34, most checks to the puck carrier will cause injuries. If you set 0x14404 from 66 00 00 8E to 67 00 00 3E, all checks to the puck carrier will cause injuries, even after the whistle. NOTE: The player getting checked has to be the puck carrier in order to have a shot at getting injured. 1 Quote
von Ozbourne Posted February 4 Report Posted February 4 (edited) Oh boy.... The potential.... for misuse... Although, on the interesting side, don't get to see this too often. Funny enough, this is not the first time I've seen this. Back in the day on the original hardware, I found out that if you have almost your entire team in the penalty box, the game will throw the backup goalies on the ice just to fill in for not having enough players. Ken Wregget was clearly not used to being on the wing and was caught with his head down. Disappointingly, I should note that you can't pull the Base Wars technique of winning a game by forfeit after taking out too many of the opponent's players. Seems that once you get down to a combined six live bodies on the ice and/or in the penalty box, injuring more players will apparently just result in the team doctors giving the oldest injured guy some morphine and tape and sending him back out there. Edited February 4 by von Ozbourne Quote
AdamCatalyst Posted February 4 Report Posted February 4 lol - I've been working on a "no-go trapezoid" patch, and almost released it the other day. I'm glad I didn't as I just noticed that my goalie could now stickhandle all the way down the ice, and shoot a decent enough shot to score on the other goalie. I have no idea who my logic to avoid the corners could possibly make that happen, but some of these goalies aren't half bad when playing as a forward. 1 1 Quote
von Ozbourne Posted February 22 Report Posted February 22 I've been kind of curious to see if this could be manipulated in a manner in which one might guarantee one to two injuries per period and came across some interesting patterns I figured I might as well share. To reference @chaos 's point that the bits at 0x14410 influence the results of a check, and by default is 0084, I noted that changing only the last digit, I was getting some drastically different results. Like such: [tested with 5 min periods] 00X8 = An especially big hit resulted in the game soft locking with the clock stopping but I could still skate around indefinitely. [I was able to initiate a line change and press the matter, but the following penalty bench screen started a full screen glitch, even though the game was still playable] 00X6 = I did get one game injury, but the ref seemed to think everything was a penalty. 0084 = default 00X2 = not that different, caused two injuries and both were for the game 00X0 = All hits to the puck carrier resulted in the ref blowing the play dead like it were an icing or offside. Odd numbers resulted in game crashes with Illegal Instruction errors. Not sure how any of this helps, beyond I guess only editing the first digit. Should also add a qualifier that I tested this on a version of the game where, we'll say a Scott Stevens type would be one of the softer players on the team. Quote
von Ozbourne Posted February 23 Report Posted February 23 Had a few minutes to try something else out and realized that This might not work in my context. While as previously mentioned, changing the value at 0x14410 from 84 to 34 will make every check of the puck carrier into an injury inducing hit, even after the whistle, Changing it to 74 apparently means that most hits will result in a penalty, even after the whistle. Quote
chaos Posted February 24 Author Report Posted February 24 4 hours ago, von Ozbourne said: Had a few minutes to try something else out and realized that This might not work in my context. While as previously mentioned, changing the value at 0x14410 from 84 to 34 will make every check of the puck carrier into an injury inducing hit, even after the whistle, Changing it to 74 apparently means that most hits will result in a penalty, even after the whistle. Weird, I thought I responded to your post earlier. The change from 84 to 34 is for a conditional branch. It's skipping over the other checks of code, and going directly to the "Add Penalty" part. So what you are changing there is how much of a jump ahead the branch is. Changing the branch 0084 to 0034, makes the branch go to 0x14444 ,which is the instruction before "setInjuryType". Quote
chaos Posted February 24 Author Report Posted February 24 I should probably link this on the forum in a new post, but here is my GitHub that has an LST file you can open in a text editor and see the disassembled code, along with what I've commented on so far. Unfortunately, it doesnt have the ROM addresses which is kind of stupid. If you want IDA Pro, DM me https://github.com/Chaos81/nhl94-disassembly 1 Quote
AdamCatalyst Posted February 24 Report Posted February 24 44 minutes ago, chaos said: I should probably link this on the forum in a new post, but here is my GitHub that has an LST file you can open in a text editor and see the disassembled code, along with what I've commented on so far. Unfortunately, it doesnt have the ROM addresses which is kind of stupid. If you want IDA Pro, DM me https://github.com/Chaos81/nhl94-disassembly YOU HAVE THIS DISASSEMBLED ON GITHUB!?!?!?!?! Good lord, how long have I been oblivious? Quote
chaos Posted February 24 Author Report Posted February 24 8 minutes ago, AdamCatalyst said: YOU HAVE THIS DISASSEMBLED ON GITHUB!?!?!?!?! Good lord, how long have I been oblivious? Haha, I just only posted it in the Discord like a week ago or so. Like I said, it's not all done, or nowhere near close. But a bunch of important stuff I've gone through and made comments to help better understand. 1 Quote
von Ozbourne Posted February 25 Report Posted February 25 22 hours ago, chaos said: The change from 84 to 34 is for a conditional branch. Yeah I realized that I originally misread the notes thinking that 84 was related to the 160 points bit and when I realized that mistake, I had already found out that changing the number was doing all sorts of other weird things. The unfortunate part is that all of this testing was conducted on a ROM where I also also had RNG on some heavy steroids, so Hot/Cold and checking boosts were pretty extreme. While the tests were consistent with themselves, I don't know how useful the findings will be on regular humans. 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.