Jump to content

BG2 Level Up support (partial)


mattinm

Recommended Posts

Changes:

Saves what it updates, including: HP, saving throws, proficiencies, skills, thac0, lay on hands (not entirely correct), lore, and, most importantly, level

Moved the CharGen saving to the file directly after it is decided instead of lumping it all into CharGen9. This doesn't allow for true on-the-fly saving of character data, but it does allow scripts following a choice (i.e. race, alignment, class/kit, etc) to be able to reference the values directly.

 

Working on:

Code consolidation/cleanup.

Choosing new spells! - high priority

Fighter (no kit) showing up as barbarian.

 

It'd be nice if some people could patch and tell me if there are any errors. It works fine on my system, and I'd like to bug-test it thoroughly. I pretty much spend 10 min checking after each few changes, but I'm sure things have still eluded me.

 

As a note, the changes I made to character creation will output the values you selected to the console (if ran from console) as they are saved, allowing for some debuging there.

 

Here's a pastebin: http://pastebin.com/me0bea51

And a link to the tracker: http://sourceforge.net/tracker/?func=detai...amp;atid=310122

Link to comment

Nice work! Both the expansion on your levelup stuff and the chargen cleanup. That had a trap in it - you have to reset everything so players can go back in chargen without accumulating previos abilities, but you seem to handle that. :rolleyes:

 

Notes:

- str extra: I don't know about strength below 18, but for the ones higher than 18 IE just reset the extra to 0.

- swashbucklers missing from skills.2da: I'll go add it now.

- con hp bonus: I don't think this is displayed when leveling up. This will be handled by the core, since it not only depends on the constitution, but also on the fact if the class is a warrior type (more) or not.

- when setting the new hp, you first get the old one with GetPlayerStat. But you should add 1 as the last parameter, so the base stat is changed, not the modified one. Now the helm of balduran would give you an extra 5hp each levelup. :mwaha:

- the above applies to all GetPlayerStat/SetPlayerStat combos.

- backstab: hardcoding is bad. I see no table with that info, so it could be those two classes (maybe even thieves in general) get it as an applied effect. But how did the original display the change provided this wasn't hardcoded?

- barbarians: sigh, again. They were hacked in IE as fighter kits (same class ID, different kit id).

- since you opened a new patch submission, I'll just close the first - you included everything here too, right?

Link to comment

I've been busy with finals this week, but I've managed to put together an almost fully-featured level up script for BG2. The code needs some cleaning up, which I've been doing as I have time, but it's almost there. There are some additions that still need to be made, and I haven't tested DC characters yet (though the modified GetStatsOverview() handled Imoem fine).

 

Notable game-side additions:

- Sorcerer spell selection on level up

- Spell book updates for divine casters

- Update number of spells cast per level

- Innate abilities, including additional memorizations

- Lay On Hands (at least for Paladins) updates correctly

-
HLAs
work for multiclass characters (the button displays at the correct level)

- New
HP
, saves,
THAC0
, proficiencies, skills, and lore

 

Notable code-side additions:

- SpellIsLearned (actor, type, level, ref) to check if a spell is learned (couldn't find a comparable function)

- IsMultiClassed (actor, verbose) works similarly to IsDualClassed

- DualSwap (actor) to see if we need to swap the order of IE_LEVEL and IE_LEVEL2

- Changed GetStatsOverview in GUIREC.py to take advantage of the new functions and allow for true multiclass characters

- Changed SetupSpellLevels in GUICommon to check the table with strings to allow for classes that don't start spell casting at level 1 (rangers, bards, paladins, etc)

 

Known bugs:

- F/M/C do not work correctly. The debug information show the correct levels being set for each class; however, the cleric levels revert to 2 at the end of the script. You can then level the cleric individually to level 6. However, if you put any item on, the cleric reverts to level 5 and can be leveled back up to 6. I'm thinking there is some underlying error in the code (not sure why it only affects F/M/C and not F/M/T or F/C or M/C).

- (related) It seems clerics and druids are getting their spells backward of character generation. I'll look into it more in the coming days.

 

TODO:

- Test dual-classed characters

- Implement ranger, bard, and monk skills (pick pockets, move silently, etc)

- Implement
HLA
selection

- Implement DC ability restoration

- (related) Implement dual-classing

- More stats need updating (extra saves, etc)?

- More testing! (I've been testing in 32-/64-bit Ubuntu 9.04, 32-/64-bit Vista, 32-bit XP -- my development computer, however, is the 64-bit Ubuntu machine, so that's where most the testing has occurred)

 

I'm sure there are some bugs I've overlooked, and some coding that can be improved, but I'm fairly satisfied with the state it's in now. Any comments are welcome and I'll continue working on the TODO, cleaning up the code, and fixing any bugs found.

 

Patch Tracker (will update in a minute): http://sourceforge.net/tracker/?func=detai...amp;atid=310122

Pastebin: http://pastebin.com/m60cfabcf

Link to comment

Nice progress! I already merged parts of this patch, but left the levelup stuff alone. It looks pretty mature though.

 

Some ideas, questions and notes:

- why not always pass LevelDiff to GetStatOverview as an array and also default it to an array, so parsing can be made simpler.

- what's the benefit of changing the IsDualClassed return type from tuple to list?

- the GetPlayerStat/SetPlayerStat comment from my previous post still holds - you need to grab the base value, not the one with all the applied bonuses. Just supply the GetPlayerStat calls with 1 as the third parameter (I noticed this wasn't documented, but it's now fixed).

- swashbucklers can't backstab - this is part of the kit description

- backstabbing should be done as layonhands and you can get the change by comparing the values for the old and new level (doh, silly me)

- are you sure swapping the stored levels in the char for the wierd DCs is a good idea? This would likely break compatibility with IE (think savegames).

 

Imho the GetPlayerStat thing is the only blocker for application. On the other hand, you've layed out the basics and the sooner they get in the better, as the next patches can then be more incremental and easier to review.

Link to comment
Nice progress! I already merged parts of this patch, but left the levelup stuff alone. It looks pretty mature though.

 

Some ideas, questions and notes:

- why not always pass LevelDiff to GetStatOverview as an array and also default it to an array, so parsing can be made simpler.

- what's the benefit of changing the IsDualClassed return type from tuple to list?

- the GetPlayerStat/SetPlayerStat comment from my previous post still holds - you need to grab the base value, not the one with all the applied bonuses. Just supply the GetPlayerStat calls with 1 as the third parameter (I noticed this wasn't documented, but it's now fixed).

- swashbucklers can't backstab - this is part of the kit description

- backstabbing should be done as layonhands and you can get the change by comparing the values for the old and new level (doh, silly me)

- are you sure swapping the stored levels in the char for the wierd DCs is a good idea? This would likely break compatibility with IE (think savegames).

 

Imho the GetPlayerStat thing is the only blocker for application. On the other hand, you've layed out the basics and the sooner they get in the better, as the next patches can then be more incremental and easier to review.

 

I forgot to set my IRC nick to away earlier, sorry. Anyway, thanks for the input! I've altered the code to make use of the changes you listed (yeah, I didn't know I had to send 1 to get the base) and I've also made a few other changes as noted below. I'm going to be doing some testing on DC and HLAs, and then I'll submit another patch. Now that I've got some free time, I should move a little more swiftly.

 

Here's some responses to the above questions:

- Just changed GetStatOverview to default LevelDiff to [0,0,0] and always require a list for simplicity

- Changing IsDualClassed from a tuple to a list is merely for convenience and testing; however, I should probably change it and IsMultiClassed back to tuples to be more secure

- Changed the GetPlayerStat calls to base values

- Doing a backstab lookup as suggested for swashbucklers

- No, I'm not sure swapping DC levels is a good idea. I've got some save files that I just made on my Windows machine so I can test DC leveling functionality and adjust accordingly.

 

Here's some other things that I've implemented:

- Scrollbar on sorcerer spell selection to allow for > 24 spells per level

- Gnomes are now always considered specialists (they wouldn't get bonuses in MC)

- HLA selection -- I'm prepping to test the functionality of this after I get DC working

- (related) I've got the framework down for implementing dual-classing

Link to comment

Here's the most fully functional of all the patches so far. Again, it needs a little house cleaning, but I've got DC working, MC working, HLAs working (mostly) and sorc spell selection. For clarity sake, "forward" dual classes are ones that have the old class listed first in the new multiclass reference (i.e. a fighter dualing to a mage is listed as FIGHTER_MAGE); a "backward" dual class is one in which the old class is listed second (i.e. a mage dualing to a fighter is still listed as a FIGHTER_MAGE); and kitted dual classes are ones in which the original class was a kit (i.e swashbuckler->mage).

 

Notable game-side additions

- Full dual-class support (forward/backward/kitted)

-
HLA
selection with scroll bar allowing selection from all classes; it should be noted, however, that triple-classed mages will NEVER be able to cast the level 9 spells under a the default level cap

- Sorcerer spell selection with scroll bar allowing for > 24 spells per level

 

Notable code-side additions

- Kits from my Windows saves were saved as 16-bit, so I added a check to GetKitIndex to shift to 32-bit if the kit is 16-bits; I'm not 100% on this code, as I have little bit-wise experience, but it worked for my Windows saves and GemRB characters

- IsDualClass and IsMultiClass now return tuples to limit unwanted changes

- IsDualSwap had to be modified to use class names instead of masks; the first mask matching the class was erroneously perceived to be the first class in the multi-class pair when this wasn't always the case (i.e. mage (mask 1) would be found first in the FIGHER_MAGE pair) and led to incorrect swapping of the levels

- LevelDiff must be passed as an array to GetStatOverview and defaults to [0,0,0]

- Shortened many parts of GUIREC by utilizing IsDualClass and IsMultiClass, notably CanLevelUp

- Passing GetPlayerStat with a 1 at the end to get base values

 

Known bugs

- Still can't figure out why F/M/C are malfunctioning

 

To be implemented

- Can't figure out
how
to check the existence of AP
HLAs
(i.e. Cast another 6th level spell), as IsSpellLearned doesn't work (are the spells not actually learned, and if not, does anyone know
how
the system stores this data?); ApplySpell is also undocumented

- Need to implement a way for the
HLAs
to check pre-reqs on the fly, as the actual game does (i.e. to allow picking deathblow and then greater deathblow on the same level up) -- shouldn't be too difficult, but would be easier to look at as a separate patch

 

There might be a couple things that I'm overlooking, but I think that's just about it. As always, input welcome.

 

Pastebin - http://pastebin.com/m21697d41

Tracker - http://sourceforge.net/tracker/?func=detai...amp;atid=310122

Link to comment

If you have to mess with the kit value then something isn't clean.

A few questions:

 

1. is it an original windows save?

2. do you use the latest gemrb (after svn rev 5941)?

 

If you have an older version, you should update, as that version changed how kits are loaded.

If you already have the newer version, then we have a problem.

Link to comment

+ # display if our class has been reactivated

+ # TODO: figure out a way to stop this from appearing each subsequent levelup

That one is simple (same for reactivation), something like: if Level[0] - LevelDiff[0] < Level[1] and Level[0] > Level[1]

 

I added the standard doc for ApplySpell. Such spells of course aren't learned, so you have to check if the effect(s) that it provides are there. I don't think we expose such functionality to the guiscripts yet.

 

Things the core figures out by itself can be seen in Actor::CreateDerivedStatsBG (currently class level sum, loh, backstab, turn undead).

Link to comment

Avenger: Yeah, I'm running the latest svn version. I tend to do my GUIScript updates in a local branch (which I don't update as often) then patch them into the trunk which I keep up to date to test functionality. I just tried the code on my 32-bit Windows machine, and I'm having the same problem. I have a TOB install that has had most of it's Weidu removed; I'd like to re-install a clean version, but 2 of my discs are scratched and I haven't had time to go buy another set. However, there are 3 extra kits present (Ferelan, Fence, and one other I can't think of off the top of my head). They all work fine when I created them in GemRB. I'm not sure why that would change how kits are saved by the original game on my system though.

 

Lynx: Thanks for the ApplySpell docs. I figured it would be an effect I'd have to search for. And thanks for the snippet there.

Link to comment

Please recheck the kit stuff now, another change has been applied to the creature loader.

 

Please also remove your SpellIsLearned from LevelUp.py. I've added it to GUICommon as HasSpell.

 

Also, I've only thought of it now, but is it not possible to share most of the sorcerer code with the one in GUICG7 (cg mage spells)? I imagine the control ids are all different, but iirc the windows look the same, so we could load the cg windowpack for this and just use that.

Link to comment
Please recheck the kit stuff now, another change has been applied to the creature loader.

 

Please also remove your SpellIsLearned from LevelUp.py. I've added it to GUICommon as HasSpell.

 

Also, I've only thought of it now, but is it not possible to share most of the sorcerer code with the one in GUICG7 (cg mage spells)? I imagine the control ids are all different, but iirc the windows look the same, so we could load the cg windowpack for this and just use that.

 

Just got back from a couple days vacation. I'm implementing the updates now; I see some of the additions have made it into the SVN and I'll update LevelUp.py accordingly.

 

I'm still having trouble with the save files from my Windows machine. I thought it might be a 32-/64-bit compatibility issue, but I have the same problem when I compile GemRB natively on my 32-bit system. I'll keep peaking around and see if I can figure out the problem; I'm guessing that the kit was either saved as 16-bit or is somehow saved in reverse of what GemRB expects. I'm not sure how/why that would happen though.

 

I've done some reading through my IRC log and I'll check out the effects functions Avenger mentioned to see if I can get HLAs working for APs.

 

I could probably merge the sorcerer code with the GUICG7 code, if that is what you're asking. I guess it would be nice to have a more general spell selection code in GUICG7 in case we decide to allow starting character levels greater than 1. I'll hack something together in a branch and submit it separately to rest of it.

 

Hopefully I'll have a patch done tonight. Let me know if there's anything else :crazyeyes:

 

Edit: Sorry for submitting the patch from my Windows machine. I do all my dev work on my linux system, but was testing the patch on my Windows system when I noticed a small error. I fixed it and created a patch in TortoiseSVN then submitted it. I'll ensure the patches are created on my linux system from now on to attempt to avoid those nuisances.

Link to comment
I'm still having trouble with the save files from my Windows machine. I thought it might be a 32-/64-bit compatibility issue, but I have the same problem when I compile GemRB natively on my 32-bit system. I'll keep peaking around and see if I can figure out the problem; I'm guessing that the kit was either saved as 16-bit or is somehow saved in reverse of what GemRB expects. I'm not sure how/why that would happen though.

 

Could you perhaps provide an example save file or two, together with which kit it's meant to display? Your shift doesn't seem to cause any problems for me, I'm just worried about why it's not working properly in the first place.

 

I could probably merge the sorcerer code with the GUICG7 code, if that is what you're asking. I guess it would be nice to have a more general spell selection code in GUICG7 in case we decide to allow starting character levels greater than 1.

 

I would think that the 'next step' after fixing levelling up is to make it work for CharGen (obviously in real BG2, your character does start at a higher level), so anything you could do to help that would be much appreciated.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...