Jump to content

Possible to automate a script to change class requirements on all weapons?


Grand_Dracolich

Recommended Posts

The class weapon restrictions of 2nd edition always bugged me; why would Cyric care if his clerics used bladed or piercing weapons? Why can't a mage use a sword even if he has 18 strength and could possibly put a proficiency point in it? I really would like to see a mod that outright removes those restrictions, so taking a lesson that we have in the Doom modding community, "if it doesn't exist and you want it, look into making it yourself."

 

If I understand correctly, there's two 2da files that control proficiency, but the weapons themselves have the class restrictions on them. From some posts I've seen before, I'm pretty sure it's possible to write a Weidu script to edit those 2da files and allow them for all classes and kits (including ones added by mods). However, I don't know if it's possible to do a script that go through all weapons, including ones added in mods, and remove those restrictions (with special cases for some weapons like the Staff of the Magi and Staff of the Woodlands which have good lore reasons for those restrictions).

 

So, is it possible to do this? I realize there are other issues as well, such as modifying item descriptions to reflect that, for example, mages and clerics can now use bows and longswords, or writing it to be compatible with BG:EE, IWD:EE, original BG2 and Tutu. For the time being, I just want to write something quick-and-dirty that I can use in a playthrough on BG 1 and 2 EE, but I'll probably keep working on it and make it into an actual mod.

Link to comment

However, I don't know if it's possible to do a script that go through all weapons, including ones added in mods, and remove those restrictions plah plah plah.

It's entirely possible... but then specializing a few items to not have those restrictions will make the whole thing more cumbersome.

Check the original Ashes of Amber mod, it tries to do this.

The Level 1 NPCs has similar component as does the B!Tweaks, by Berelinde and others.

 

Now it's easiest to remove all the restrictions by just removing them and then allowing the player to restrict themselves from using an item type due to lack of proficiencies or other facts, and not because we are the jerks...

TP2 Code:

BACKUP ~ij#Items/backup~
AUTHOR ~well this is stolen from another mod by The Imp, so sue him if you wish.~
VERSION ~alpha~

BEGIN ~Allow all items to be used by everyone.~
 
COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~
  PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN // protects against invalid files
READ_BYTE "0x1e" "usab1"
READ_BYTE "0x1f" "usab2"
READ_BYTE "0x20" "usab3"
READ_BYTE "0x21" "usab4"
READ_BYTE "0x29" "ukit1"
READ_BYTE "0x2b" "ukit2"
READ_BYTE "0x2d" "ukit3"
READ_BYTE "0x2f" "ukit4"
  WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
  WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
  WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
  WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
  WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
  WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
  WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
  WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
END

Easy. So yes. Could it be done better ... NO ! :p

Link to comment

Now it's easiest to remove all the restrictions by just removing them and then allowing the player to restrict themselves from using an item type due to lack of proficiencies or other facts

Yeah, but if I have to self-restrict myself anyway, I could just use Shadow/EEKeeper to give everyone the Use Any Item HLA. It would be tougher, but I would rather try to do it the right-ish way, even if only as a challenge just to learn BG modding.

 

Easy. So yes. Could it be done better ... NO ! :p

I'm a computer science student. We learn that everything can always be done better, it just never is because of time constraints and/or laziness. :p
Link to comment

What Jarno posted should work fine. I would however add an extra PATCH_IF and specifically identify weapons, so you don't change armors, wand, and every other thing. I forget which byte has the item_type but you can just specify the various ones for all of the weapons. Look in Near Infinity for the proper values. Something like

READ_SHORT "0x__" "weap"
PATCH_IF (weap = 25, 26, etc) BEGIN
Then, to help your self-policing, there is always the proficiency system. I would edit WSPECIAL.2da so that having 0 stars gives you a massive penalty, like -10. So yes cleric can use longswords... but not well.

 

EDIT - that PATCH_IF should go right before Jarno's READ_BYTEs. It's not real code, just a demonstration of the logic to use. You can se various permutation of this in my mod (the .tp2 is 25,000 lines long but search for "crossbows" and you'll find an example). Or I can write up something proper later tonight.

Link to comment

I'm a computer science student. We learn that everything can always be done better, it just never is because of time constraints and/or laziness. :p

If you view differently as better then yes... thousand things can be done with this, but none of them are better in allowing the use of all items, cause you just end up removing items from the allowed list. :p

I will advice to look at the code in the B!Tweaks, if you wish to have your hands full of code. Or look at any of the other mods as well.

Link to comment

So, some pseudocode to make sure I understand correctly.

 

Iterate through all items
     if( item is one of the types we're concerned with AND not one of the items we're disallowing like Holy Avenger )
          remove class restrictions from said item

Yep, also you can have multiple of the PATCH_IF commands and only if the item passes all of them it gets patched... unless you of course do a WHILE loop with other checks too and juggle twenty things and million variants, well actually as many as you wish...

Also, ... erhm, knowing what you are patching helps, kinda, or not(look at the usability for classes and kits). :D He he.

Link to comment

Yes. You could try this (it was easier to copy and paste the block 20 times than to figure out the Weidu code for the disjunctive/iteration :p ):

 

 

BACKUP ~ij#Items/backup~
AUTHOR ~well this is stolen from another mod by The Imp, so sue him if you wish.~
VERSION ~alpha~

BEGIN ~Allow all weapons to be used by everyone.~
 
COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~
  PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN // protects against invalid files
    READ_SHORT "0x1c" weapons
    PATCH_IF (weapons = 5) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 14) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 15) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 16) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 17) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 18) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 19) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 20) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 21) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 22) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 23) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 24) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 25) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 26) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 27) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 29) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 30) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 31) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 44) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 57) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
    PATCH_IF (weapons = 69) BEGIN
      READ_BYTE "0x1e" "usab1"
      READ_BYTE "0x1f" "usab2"
      READ_BYTE "0x20" "usab3"
      READ_BYTE "0x21" "usab4"
      READ_BYTE "0x29" "ukit1"
      READ_BYTE "0x2b" "ukit2"
      READ_BYTE "0x2d" "ukit3"
      READ_BYTE "0x2f" "ukit4"
      WRITE_BYTE "0x1e" ("%usab1%" BAND "0b00000000")
      WRITE_BYTE "0x1f" ("%usab2%" BAND "0b00000000")
      WRITE_BYTE "0x20" ("%usab3%" BAND "0b00000000")
      WRITE_BYTE "0x21" ("%usab4%" BAND "0b00000000")
      WRITE_BYTE "0x29" ("%ukit1%" BAND "0b00000000")
      WRITE_BYTE "0x2b" ("%ukit2%" BAND "0b00000000")
      WRITE_BYTE "0x2d" ("%ukit3%" BAND "0b00000000")
      WRITE_BYTE "0x2f" ("%ukit4%" BAND "0b00000000")
    END
  END
  BUT_ONLY

COPY_EXISTING ~wspecial.2da~ ~override~
    SET_2DA_ENTRY 1 1 3 ~-5~
    BUT_ONLY

 

Copy that into a text files called all_weapons.tp2, drop it into your game folder, make a copy of Weidu called setup-all_weapons.exe, and run it. (This will add a -5 thac0 penalty for non-proficiency. If you want to make exceptions for certain characters to use certain weapons, now you can just give them proficiency.)

Link to comment

unless you of course do a WHILE loop with other checks too and juggle twenty things and million variants, well actually as many as you wish...

Would it look a little cleaner if it looked like:

 

while not done with item-editing

{

set "do it!" do 1

 

if it's not a weapon

-set "do it!" to 0

if it's this weapon we don't want to mess with

-set "do it!" to 0

if it's this other weapon we don't want to mess with

-set "do it!" to 0

if it's yet another weapon we don't want to mess with

-set "do it!" to 0

 

if "do it!" is 1

-change the item

 

move on to the next item

}

 

Yes. You could try this (it was easier to copy and paste the block 20 times than to figure out the Weidu code for the disjunctive/iteration :p

Having the same block repeated multiple times makes editing it more of a nightmare, though. Also, if I wanted to go with the default no-proficiency penalty, would I just remove that wspecial.2da block at the end?
Link to comment

Your earlier pseudocode is on point.

 

You probably want to leave racial and alignment restrictions in place. I'd also recommend leaving kit restrictions in place so that Kensai/Cavaliers don't start using ranged weapons, etc.

 

ACTION_DEFINE_ASSOCIATIVE_ARRAY uniqueWeapons BEGIN
  staf11 => 1 // staff of the magi
  sw2h10 => 1 // carsomyr +5
  sw2h19 => 1 // carsomyr +6
END

COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~
  PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
    READ_SHORT 0x1c type
    PATCH_IF (type == 0x05 || (type >= 0x0d && type < 0x1f)) BEGIN // weapon or ammo
      TO_LOWER SOURCE_RES
      PATCH_IF (NOT VARIABLE_IS_SET $uniqueWeapons(~%SOURCE_RES%~)) BEGIN
        // make usable by all classes
        WRITE_BYTE 0x1e (THIS BAND 0b00111111)
        WRITE_BYTE 0x1f 0
        WRITE_BYTE 0x20 (THIS BAND 0b10000000)
        WRITE_BYTE 0x21 (THIS BAND 0b10011111)
        
        // make usable by all kits
        //WRITE_BYTE 0x29 0
        //WRITE_BYTE 0x2b 0
        //WRITE_BYTE 0x2d 0
        //WRITE_BYTE 0x2f 0
      END
    END
  END
  BUT_ONLY
For EE, you don't need to modify item descriptions to account for usability changes, but you would on normal BG2.

 

Modifying weapprof.2da is a little trickier, because you have to take into account kits that can place a different number of points into different types of weapons (Swashbuckler) and kits that shouldn't be able to put points in things that they can't use (Kensai, Cavalier, Beastmaster, Monk). If you ignore that, it's just a matter of finding out how many points each kit/class can place into proficiencies they CAN use and updating all the ones they can't to that same value.

 

COPY_EXISTING ~weapprof.2da~ ~override~
  COUNT_2DA_COLS num_cols
  READ_2DA_ENTRIES_NOW r2en_weapprof num_cols
  FOR (col = 4; col < num_cols; col += 1) BEGIN
    // determine maximum number of points the class can put into a proficiency
    SET max = 1
    FOR (row = 8; row <= 27; row += 1) BEGIN
      READ_2DA_ENTRY_FORMER r2en_weapprof row col current
      PATCH_IF (current > max) BEGIN
        SET max = current
      END
    END
    // allow the class to put that many points into proficiencies that were previously unavailable
    FOR (row = 8; row <= 27; row += 1) BEGIN
      READ_2DA_ENTRY_FORMER r2en_weapprof row col current
      PATCH_IF (current == 0) BEGIN
        SET_2DA_ENTRY_LATER s2el_weapprof row col max
      END
    END
  END
  
  // write changes to file
  SET_2DA_ENTRIES_NOW s2el_weapprof num_cols
  BUT_ONLY
Link to comment

Having the same block repeated multiple times makes editing it more of a nightmare, though. Also, if I wanted to go with the default no-proficiency penalty, would I just remove that wspecial.2da block at the end?

Well yes, patching 20 different weapon types the same way is not great code. I have never taken a programming or computer science class in my life, so I'm much more comfortable selling for horribly inefficient code. Anyay somehow I guessed that Mike would swoop in here with something proper. :) (To be fair to myself, I had something remarkably similar to that PATCH_IF line but it wasn't working... I see now that my mistake was evaluating the type as strings rather than as hex values.)

 

Yeah, you can comment out or delete the WSPECIAL.2da stuff, that was just icing.

Link to comment

You probably want to leave racial and alignment restrictions in place. I'd also recommend leaving kit restrictions in place so that Kensai/Cavaliers don't start using ranged weapons, etc.

Yeah, I wasn't going to mess with race and alignment. That's a good point about the kits, though, since those are major balancing factors for those classes. Also, these wouldn't mess with the the restrictions on NPC-specific items like Anomen's shield, for example? And could I just add mod-added items to that array and have it exclude those just fine?

 

Now, to find the documentation so I know what all those functions do and all those hex-codes are.

Link to comment

 

unless you of course do a WHILE loop with other checks too and juggle twenty things and million variants, well actually as many as you wish...

Would it look a little cleaner if it looked like:

 

while not done with item-editing

{

set "do it!" do 1

 

if it's not a weapon

-set "do it!" to 0

 

Erhm, well, that check is counter factory....

As in, you just use PATCH_IF ~x~ BEGIN , where if the x is 1, the next proportion of the possible patching is done for the given item... if there's not another condition with another PATCH_IF code.

The WHILE loop can be used when one of those failed and so you don't need to copy the same items 20 times, but just ones and have multiple outcomes with different sort of things, like item types(armor, weapons, etc.)

 

Now, to find the documentation so I know what all those functions do and all those hex-codes are.

Quoting myself:

(look at the usability for classes and kits). :D He he.

Link to comment

Quoting myself

Ah, I did see that, I was just leaving a reminder to myself to actually read through that page and Weidu's documentation itself. The usability header part isn't completely clear, though. Does 1 mean it's restricted from that race/class/alignment, or that it's allowed? Assuming 1 means restrict, if I wanted to leave Cavaliers, Kensai and Wizard Slayers (if there's a weapon a Wizard Slayer can't use, it's probably for a good reason) alone, I would use "WRITE_BYTE 0x2f (THIS BAND 0b01110000)" ? They're warrior-type classes, so they can already use all types of weapons except for the ones that their classes specifically restrict for balance reasons, so I'm not that concerned with them.

 

weapprof.2da and certain kits like Archers, Berserkers and the aforementioned Cavaliers and etc. have me a bit more concerned, though. It would probably be as simple (as if it ever is) as doing that pass over the whole file and then replacing the entries for those kits.

 

Also, found the page for wspecial.2da. BG2 really has no penalties for not being proficient in a weapon? I definitely thought it had something like a -4 to-hit like 3rd edition has.

 

By the way, I really appreciate all the help!

Link to comment

I would use "WRITE_BYTE 0x2f (THIS BAND 0b01110000)" ?

That's in the completely wrong order, the last bit is conjurer(-s, the very left one after the 0b), then abjurer, undead hunter, inquisitor, cavalier, kensai, wizard slayer, berserker. (0b76543210)

So that's 0b00001110 to leave the restriction on Cavaliers, Kensai and Wizard Slayers if they can't use it already.

Link to comment

Archived

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

×
×
  • Create New...