Weber G wrote: ↑Thu Jan 21, 2021 2:34 pm
rest should be clear
Oh yeah, totally clear. Like SCBA-diving along the muddy bottom of the China Sea and kicking up dirty and mud everywhere. No confusion here. What-so-EVAR.
Ok, let's take the bardsword as example. The value of the bardsword in the $8356 table is 21(hex) 00100001(bin).
This value, as mentioned, is in X.
1. X is transferred to A
2. A is transferred to the stack
3. $A2B0 - $A2B4 selects bit 5-7 from A; in this case the one in brackets: (001)00001 => A = 1
4. A is stored in $48
5. transfer stack to A
6. A (in A is the former value of X again) AND 1F => select bit 0-4 from A; in this case the one in brackets: 001(00001) => A = 1
7. A is stored in $49
Weber G wrote: ↑Thu Jan 21, 2021 3:50 pm
Ok, let's take the bardsword as example. The value of the bardsword in the $8356 table is 21(hex) 00100001(bin).
This value, as mentioned, is in X.
1. X is transferred to A
2. A is transferred to the stack
3. $A2B0 - $A2B4 selects bit 5-7 from A; in this case the one in brackets: (001)00001 => A = 1
4. A is stored in $48
5. transfer stack to A
6. A (in A is the former value of X again) AND 1F => select bit 0-4 from A; in this case the one in brackets: 001(00001) => A = 1
7. A is stored in $49
Clear so far for you?
In the DOS version, the $48 value is an index into a dice size table and $49 is the number of times to roll. The dice table mask is:
drifting wrote: ↑Fri Jan 22, 2021 2:10 amIn the DOS version, the $48 value is an index into a dice size table and $49 is the number of times to roll. The dice table mask is:
So the Bardsword with $48 = 1 and $49 = 1 would do 1d8 damage.
- 3. $A2B0 - $A2B4 selects bit 5-7 from A; in this case the one in brackets: (001)00001 => A = 1
- 4. A is stored in $48
- 5. transfer stack to A
- 6. A (in A is the former value of X again) AND 1F => select bit 0-4 from A; in this case the one in brackets: 001(00001) => A = 1
- 7. A is stored in $49
There's no reference to value 8 Decimal so I'm not sure how it's 1-8 damage. Similarly I'm not sure how other weapons for example are 3-24 and the like.
drifting, you're completely right with $48 and $49, but not with the damage of the weapon.
Step 1 - 7 from above just seperate the byte $8356,weapon# in two numbers which are stored in $48 (base damage) and $49 (counter for base damage).
the next steps in the code are:
8. $A2BD - $A2C1 => clear $45 and $46 (MSB and LSB of damage)
9. $A2C3 - $A2C8 => load # of attacks form character address ($9B) and add it to $AA and then store the result in $3B (# of attacks); $AA usually contains 1 (with ZZGO it contains 8, if I'm not wrong).
10. now we have: $3B => # of attacks, $48 => base damage; $49 => counter for base damage; $45/ $46 => damage)
Clear so far?
11. $A2CE - $A2D9: creates a random number (00 - FF) and AND this number with the position of X ($48) in the table $AB32.
table $AB32: 03 07 0F 1F 3F 7F FF
Since we have for the bardsword the value 1 in $48, the random number is ANDed with 07. That means the result in A is 0-7. To this result, 1 is added. This increases the value in A to 1-8.
12. $A2DB - $A2E1: add the content of $45 (in our case 0) to A (1-8) and check if the carry flag = 0 (the carry flag is 1 if the result of the addition is > 255).
If carry = 0 => store A (1-8) in $45, else increase $46 (MSB damage) and store A (1-8) in $45.
13. decrease Y by 1 (Y contains $49 (counter for base damage); if Y >= 0 (BPL means if positive) => jump $A2EF (do the loop again).
Since the bardsword has 1 in $49, the loop is done 2 times (1x for 1 in Y and 1x for 0 in Y). So the damage for the bardsword is 2x 1-8 => 2-16.
That's all.
If you want to calculate the damage of a weapon, you have to seperate the damage byte in bit0-4 and bit5-7 as first step. Then take with the number which results from bit5-7 the number from table $AB32 and add 1. Then add 1 to the number which results from bit0-4. Then multiply both numbers => the result is the max. damage.
Take the value from $AB32 and add 1 ; 7 + 1 for the Bardsword
Multiply that by $49 plus 1 ; 1 + 1, so mask = 16
Generate a random number between 0 and 127 ; randomNumber = {0...127}
Divide the random number by the mask and keep the remainder ; value = {0...15}
If the remainder is less than $49, add $49 ; If value < ($49) then value += $49
I missed the "plus 1" part of the "$49 plus 1" so got 1d8 instead of 2d8.
With that logic, the DOS version has a slight bias for values in the $49 to $49+$49 range since a random value of zero will result in $49 damage too. Looks to be the same in DOS BT1 too. Interesting.