Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improper HP calculation for Dual Class #43

Open
GoogleCodeExporter opened this issue Mar 19, 2015 · 3 comments
Open

Improper HP calculation for Dual Class #43

GoogleCodeExporter opened this issue Mar 19, 2015 · 3 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
1. Create a fighter (level 5) with high CON score, e.g. 17. 
2. Dual-class to thief.
3. Advance to level 6.

What is the expected output? What do you see instead?
Max HP should be 5x10 + 5x3 + 1x6 + 1x2 = 73.
Instead, it is 5x10 + 5x3 + 1x6 + 5x2 = 81

What version of the product are you using? On what operating system?
1.0.20 on Win XP

Please provide any additional information below.
References are from SVN dated 11 Sep 2009.
Notes marked with //S:

ovr024.cs, line 1076:
                    if (var_B > player.multiclassLevel)
                    {
                        var_B = player.multiclassLevel;

                        sub_647BE(var_B, var_C, stat_a, ref var_A, player);
                    }

//S: This code means that CON bonus for new class is calculated with 
//S: the level of the old class, not the excess levels.
//S: The minimum fix is that it should be -=
                    if (var_B > player.multiclassLevel)
                    {
                        var_B -= player.multiclassLevel;

                        sub_647BE(var_B, var_C, stat_a, ref var_A, player);
                    }

Even with this fix this calculation goes wrong once max_class_levels
(max_class_hit_dice) are reached.
E.g. Fighter level 9, Thief level 12: should receive 9x3 + 1x2 bonus.
Even with the fix above it will receive 9x3 + 3x2 bonus, because of this:

ovr024.cs, line 783:
        internal static void sub_647BE(byte arg_2, int class_index, byte
bp_var_1, ref byte bp_var_A, Player player)
        {
            if (gbl.max_class_levels[class_index] <= arg_2)
            {
                arg_2 = (byte)(gbl.max_class_levels[class_index] - 1);
            }


I.e. the levels (arg_2) are compared to max_class_levels only but only the
difference is passed as an argument.
A solution is calling it for current level, then substracting for
multiclasslevel:

                    if (var_B > player.multiclassLevel)
                    {
                        // calculate as if single class 
                        // (except ranger dual hit dice)
                        sub_647BE(var_B, var_C, stat_a, ref var_A, player);
                        byte multiclass_delta = 0;
                        // calculate as if old class would be current class
                        sub_647BE(player.multiclassLevel, var_C, stat_a,
                            ref multiclass_delta, player);
                        // The old class part is subtracted from the total
                        var_A -= multiclass_delta;
                    }

This way the calculation will go like:
10x2 for thief level 12
9x2 for thief level 9
Difference is 1x2 hp.

Original issue reported on code.google.com by surrano on 16 Sep 2009 at 8:25

@GoogleCodeExporter
Copy link
Author

the latter fix passed the basic tests.

Original comment by surrano on 18 Sep 2009 at 7:46

@GoogleCodeExporter
Copy link
Author

Original comment by simeon.pilgrim on 28 Jul 2010 at 10:32

@GoogleCodeExporter
Copy link
Author

Ok, four years later... the first point of the subtraction being wrong, the 
original code did subtract for the multiclass level, so fixed that.

I'm not 100% I follow the later example.

Original comment by simeon.pilgrim on 28 Oct 2013 at 10:14

  • Changed state: Started

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant