Curse of the Azure Bonds – build 1.0.19

Build 1.0.19 has been released. Fixed in this version:

  • Fixed the Pool of Radiance player import code. You may now transfer you older saved games
  • Fixed shop items displaying so the long items display correctly (same as DOS)
  • Fixed the way the list code controls when to display ‘Prev’ as it was not showing always correctly

Enjoy.

12 thoughts on “Curse of the Azure Bonds – build 1.0.19”

  1. I remember, AB or Hillsfar came with a utility to move characters from pool hillsfar cotab… so you could indefinitly move them around and bost XP etc as it let you move players backward iirc.

  2. CotAB could load players from Curse, Pool or Hillsfar. Not sure I remember any tools with Hillsfar, it could load Pool players I think

    I plan to make a tools that lets to load, edit, save the players, and beef them up and cheat your head-off it that’s peoples thing. But have not got there yet.

  3. Dear Simeon,
    Personally, I would not like to restart CotAB; what I need is the technical details about these errors in the transfer.

    Particularly, I transferred my characters — two fighters, all modified to max + Con 19 for one of them (manual of bodily health, of course).
    All their stats were displayed as 18. Okay, I fixed Con to 19 and indeed it worked from that point like Con 19.
    However, in the saved game I saw Cha to be 100/100 (assume original / current). This came to surface when I equipped Girdle of Dwarves — Con went to 20, and Cha went to 99. When I unequipped, Con went back to 19 and Cha to 100 :)
    So I fixed it in the saved games — now Cha properly goes from 18 to 17 and back to 18 upon equip/unequip.
    A more problematic matter is HP. My fighters are level 9 (well, plus 3 levels ranger after class change, just in case it would matter) and they have HP 126 and 135, i.e. max with Con 18 and 19, respectively.
    However, if I equip the girdle with any of them the max HP drops to 101 (independently from new Con of 19 or 20, but that’s OK since both should give +5/level) and when I remove it max HP decreases to 92 (101 minus number of hit dice; that one I would call consistent) in both cases which does not make sense when Con decreases from 20 to 19…

    One of my friend reported that other stat changes (e.g. Enlarge) do not work with transferred characters either.

    So definitely, things are messed up greatly with the converted characters.
    If you could just tell me (privately) what to look for in the transferred characters; or what to fix in an ongoing game’s save I would fix it once by using a hex editor.

    If you would not disclose this information I would understand (with significant amount of sadness :) ); in this case my question is: just how compatible is your CotAB with the original series?
    – can I use your version just to transfer the characters then use the saved games in the original version?
    – can I use your version overall and at the end transfer all to the original version of Secret?

    Cheers,
    Surranó

  4. Checked my saved game with your v1.0.20. The situation seems to be worse.
    The girdle was equipped by the Con 18 character (now 19), and HP was edited to proper value (135). Original game changes it to 92 on unequip so editing does not change anything…
    Your version, however, changed HP upon some equips from 135 to 43 to 9 to 0…
    If I equip the girdle with the Con 19 character the HP goes down to 34 (note: 34 = 135-101, see numbers above…) (however if I remove it it remains 34)
    This is, on the other hand, current hp. Dunno what happens with max hp.

    So, to make the long story short: your “fixed import” does not fix the error that is already present in original game…

    Do you see a possibility to fix it? (problem may be with item, not (only) with import, but item is claimed to work properly with not-imported chars)

    Should I (may I) add this as a new issue to Google Code?

    Cheers,
    Surranó

  5. Delved a bit into your code and found some strange issues:

    1. Glb.cs: Max Class Levels do not seem to be consistent
    public readonly static byte[] max_class_levels = { 10, 15, 10, 10, 11, 12, 11, 13 }; //
    A more suitable name would be hit_dice_limit, i.e. clerics, fighters and paladins have up to 10-1=9 hd, rangers 11-1=10 (+1 on first level, but that’s a different story), MUs 12-1=11, thieves 11-1=10.

    =========================================
    2. ovr024.cs: Name sub_647BE and its params
    This function actually computes constitution bonus to max hp.
    arg_2 should be class level, bp_var_1 should be constitution score.

    =========================================
    3. ovr024.cs: CalcStatBonuses uncertainty

    else if (stat_index == Stat.CON)
    {
    byte var_13 = 0;
    byte map_hp = player.hit_point_max;
    player.hit_point_max = player.field_12C;

    This particular field in my saved game is 0x38 = 56. Add 9×5=45 for Con bonus, and voila, magic number 101 :)
    So it seems that the import improperly fills this value. (at import time it was 0x2E = 46)

    This field should actually store the sum of rolled hit dice, without constitution bonus. You may name the field according to this.

    The field, by the way, is initialised during the import as:

    player.field_12C = bp_var_1C0.field_B1;

    and indeed, the original character files did contain a value of 0x2E.

    Now I’m playing with the thought that it is actually some security “feature” that was overseen in Pool of Radiance. Whenever I leveled up I edited the max hp and current hp fields at 0x32 and 0x11B but not the field at 0xB1 :) Sound a really fatal coincidence that for both of them 8d10 resulted in 56 HP :)

    =========================================
    4. I think there is some mistake here:

    if (player.hit_point_max > map_hp)
    {
    player.hit_point_current = (byte)(player.hit_point_max – map_hp);
    }

    if (player.hit_point_max map_hp – player.hit_point_max)
    {
    player.hit_point_current = (byte)(map_hp – player.hit_point_max);
    }
    else
    {
    player.hit_point_current = 0;
    }
    }

    I think it should be something like:

    if (player.hit_point_current > map_hp – player.hit_point_max)
    {
    player.hit_point_current += (byte)(player.hit_point_max – map_hp);
    }
    else
    {
    player.hit_point_current = 0;
    }

    Maybe a bit more difficult to understand, but the main thing here is:
    – if new max is higher than old (first condition is true, since right value is negative) then current should be the same difference higher (not the difference itself, as in your code)
    – if new max is lower than old but the player has more current than the diff it should be decreased by the diff.
    – otherwise, the character should be reduced to 0 (unconscious?).

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

    So to sum up the whole story: Having updated field 0x12C fixed the girdle.
    I leave the decision to you whether you would keep this “security” feature or implement something like initialising field 0x12C based on hit_point_max… I do not know though, what happens if you import a level-drained character ;)

    Oh, and one more thing: once a Con 19 character put up the girdle and became Con 20 it started regenerating HP every hour (just as in the rule books — outstanding!) and kept doing so even after having removed the girdle (reducing Con to 19).. seems to be a bug in the original game.

  6. Wow, lots of details in your three posts, thanks. Firstly the code is most likely wrong, as I was translating from assembly to C#, and at time tracking the jump targets for those nested if blocks gets hard.

    I’ll have a look into all the things you state here, if you have cut’n’dry issues, then writting them up as issues in the project issue list, makes it all easier for me.

    Cheers, Simeon

  7. Hmm were to start. I don’t think the game is doing anything fancy against your party on import on purpose. Now I may have bugs that are corrupting your players. I have not very well tested the Pool -> Curse import code, other than make it stop crashing….

    I’m happy to share any clues/insight/knowledge I have from the game.

    The port should be 100% (except for cheats and maybe UI layout changes) compatible with the original DOS version, I have no intention to make breaking changes with the save games file formats, therefore importing from older games, playing the in DOS version, and importing to later games should work.

    If it doesn’t then I’m introduced problems.

  8. Yes, but they are accessed from the right-click context menu, verse having to add command line options.

Comments are closed.