Jump to content

aigleborgne

Members
  • Posts

    100
  • Joined

  • Last visited

Posts posted by aigleborgne

  1. 10 hours ago, subtledoctor said:

    I guess I’m just not clear on whether things are “broken.” Like, DavidW may have just coded all kensai and berserkers to use their active abilities once, for the sake of simplicity and efficiency. And it’s his mod so that would be his choice. It may be working as intended. 

    Of course that’s an answerable question! 

    My point is only, when you say something like “I set this or that enemy to be a kensai or an illusionist and SCS isn’t applying their kit abilities properly,” the answer to that might be “SCS is not designed to assist you in kitting out enemies as you see fit.” To get what you seem to desire might require another mod. 

    Maybe, although it is clearly a weird choice assuming this is one. 

    A berserker is not likely to use more than one rage in most fights, but for other kits, this is a heavy loss. 

    I will see how SCS assign abilities and if clab files are used at all. As a developer, I would most likely seeing this as a functional regression or unwanted side effects to some recent changes. 

  2. On 4/4/2023 at 7:21 AM, jmerry said:

    It's a deliberate choice - they're scripted to use Enrage only once, rather than renewing it in the unlikely case of a prolonged fight. And since enemies only need to build for one encounter...

    Well, OK, they're probably scripted to just use Enrage if they have it. Which would have to be changed if they actually had multiple uses of the ability, setting up a timer so they don't try to use it either when it's already going or during the "winded" period.

    I have just studied a level 9 kensai with kai ability. SCS only gave one Kai and script is using what is really affected. I even made a test in game, and that kensai only used one cast.

    I'm going to reinstall BGT to see if it works better there.

  3. Ok, you have convinced me. Your arguments are solid. 

    But I'm still concerned with the fact they didn't recieved the right number of innates. In my install, they just get one innate. I haven't checked kensai but they should also get kai innate which is very important. Maybe scripts use them without depleting amount ? Or it's bug. 

  4. 1 hour ago, rigidjelly said:

    The inability of transmuters to remove spell protections and abjurers to use stoneskin means any enemy mage with those kits is free xp unless you have intentionally gimped your own party (eg. no arcane casters).

    On bg1 with low level mages, transmuter are fine. Thematically, it allows them to focus on transmuting school. For example, SR polymorph self is quite potentiel in bg1

    1 hour ago, rigidjelly said:

    Wild mages should never be enemies because they can kill themselves with their own spells on bad surges.

    Maybe, but they can also do great things too. Admitelly, maybe not at low level. 

    1 hour ago, rigidjelly said:

    llusionists could easily swap skulltrap for fireball but losing horrid wilting for -2 save modifier on spook was probably not worth the effort.

    Not an issue in bg1 and again, would add more diversity. 

    1 hour ago, rigidjelly said:

    I havent played with SR for years but unless stoneskin and mage duel spells are universal school and there are offensive divination spells they don't add anything in terms of enemy variety. 

    Through kit choice, it implies a dedicated spellbook. Having 1 or 2 spells per level on chosen school is all it requires. Of course, there are tradeof that might do more harm but it shouldn't be that bad. 

    Granted, diviner and abjurer are out. But I think transmuter and illusionnist have some potential. 

  5. 12 hours ago, jmerry said:

    For mages, SCS knows how to build conjurers, enchanters, invokers, and necromancers. The other four specializations are not available, and neither are wild mages. I personally think that illusionists should be added, but the last three (abjurer, diviner, transmuter) are clearly mechanically inferior.

    Totally agree, but if we take performance into considération, all single classes should have a kit, which is not the case, at least in bg1

    Personally, I don't think all mages should be limited to those kits, especially with SR

  6. On 3/31/2023 at 10:40 PM, subtledoctor said:

    Actually I’m pretty sure SCS already does this? I recall some back-and-forth with DavidW back in… v28? v30? SCS was scanning all kit tables in kitlist.2da to apply the proper kit effects. It got really unwieldy in games with hundreds of kits, because SCS was processing all those tables, but of course it was for no purpose because there were no AI NPCs with those kits. So, IIRC, SCS scaled it back and now only processes the vanilla game kits to apply kit abilities. 

    I have just looked a few CRE and they only get one ability when they should get 2 or 3, so it doesn't seem to work properly. I'm running EE, so it might be that.

    Additionally, I have looked at kit.2da for BG1 mages. Most of them are conjurer and invoker. I like more diversity so I tried to put TRANSMUTER to one of them and after install, it was NECROMANCER. I think there might be some bugs somewhere as TRANSMUTER is never affected in 2da files.

    I will have to look at these issues when I have time.

  7. Thanks for your detailed answer. I already knew it wouldn't be easy and I know that applying a kit does almost nothing except a few like assassin backstab multiplier.

    Still, I'm curious on how SCS does give rage ability in CRE as I wasn't able to find any relevant code. I just saw  that Drasus has only one rage at level 10 instead of 3, which means, as you said, that SCS doesn't parse CLAB files.

    Now, it would be great to have a WEIDU function that would parse CLAB files, adding innates and applying those AP_* files.

    I don't see much trouble in doing this:

    - read CRE level1

    - read CLAB

    - browse all columns and for each column where row1 <= level1, add CRE SPELL all GA_* innates and apply all AP_*

    For the later, either put them in their BAF file to be applied once, either those SPL files should be read and effects applied one by one.

     

     

     

  8. Hi,

    Are there any guidelines to affect kits from mods to enemies ?

    Readme explains how to affect a kit to a CRE through several kit files. This is the easy part. But then, I am wondering how does it applies clab*.2da files. I have searched in files but can't find any references. No more chance in script BAF files.

    Let's take an exemple, SCS is able to affect berserker kits to a few enemies in BG1. If installed, I can checked those CREs and I saw they can cast their ability (rage - SPCL321).

    However, in the sources, I can't find any reference to CLABFI02.2DA (berserker kit) nor SPCL321 anywhere. Admittedly, SCS is quite something when it comes to source code. Even through David W knows how to code, it would take quite some time to understand how everything works, even on a localized change like a CRE and its scripts.

    Understanding how it is done would allow me to check if every original kits are properly handled. I would also check for special cases like sorcerers, monks.

    Then, I want to adapt my installed SCS so it can properly use some kit mods (Faith and Powers, and maybe Artisan kitpack later on).

    For the first one, I need to:

    - properly apply CLAB*2DA files, hoping SCS already has a function for this.

    - make new scripts for those kits (here I think it is just coding those new abilities)

    - altering spell affectation for cleric and druid if sphere system is installed (just have to make one 2da files for each kit, as it was done for mage kits)

    - adding new spells to script (here, this is closed to kit abilities)

     

     

     

  9. 1 hour ago, argent77 said:

    You can assign the return value of a function to another variable:

    LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array1 = array END
    // PATCH_PHP_EACH array1 AS _ => v BEGIN ...
    
    LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array2 = array END
    // PATCH_PHP_EACH array2 AS _ => v BEGIN ...

     

    Thanks again, your knowledge is limitless 😉

  10. On 3/26/2023 at 2:56 PM, subtledoctor said:

    Neither here nor there: don’t need EVALUATE_BUFFER for integer variables in functions, only for string variables. AFAIK. 

    Thanks, I removed all of them!

    I have also learned a few other things:

    DEFINE_PATCH_FUNCTION STRING_TO_ARRAY
    STR_VAR
      string = ""     // string with space separator
    RET_ARRAY array
    BEGIN
      CLEAR_ARRAY array
      SET i=0
      INNER_PATCH ~%string%~ BEGIN
        REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN
          SPRINT $array("%i%") "%MATCH0%"
          i+=1
        END ~%MATCH0%~
      END    
    END

    Considering this function, and multiple calls:

      LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array END
      LPF STRING_TO_ARRAY STR_VAR string=""  RET_ARRAY array END

    It appears that array is not cleared at all if empty. I need to add a clear in between:

      LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array END
      CLEAR_ARRAY array
      LPF STRING_TO_ARRAY STR_VAR string=""  RET_ARRAY array END

    I assume I have to keep the same name for returned variable between caller and called function. Something like:

      LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array1 END
      PATCH_PHP_EACH array1 AS _ => v BEGIN
        PATCH_PRINT ~Loop 1, value = %v%~
      END
      LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array2 END
      PATCH_PHP_EACH array2 AS _ => v BEGIN
        PATCH_PRINT ~Loop 2, value = %v%~
      END

    But I can't do that. Returning variable is very special in WEIDU and not very intuitive.

    At this point, I think that I could remove CLEAR_ARRAY in STRING_TO_ARRAY function as it does probably nothing, at least in my tests. Well, it isn't entirely true, as it works when I have array with at least one value:

      LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array END
      PATCH_PHP_EACH array AS _ => v BEGIN
        PATCH_PRINT ~Loop 1, value = %v%~
      END
      LPF STRING_TO_ARRAY STR_VAR string="4" RET_ARRAY array END
      PATCH_PHP_EACH array AS _ => v BEGIN
        PATCH_PRINT ~Loop 2, value = %v%~
      END

    Of course, I could add a test to skip empty string, but in my mind, it shouldn't be necessary. It is a common thing to have empty array and you shouldn't test its length before a loop.

     

     

  11. I feel rather stupid about this one, but finally, it makes sense.I have just found out what was wrong by replacing ADD_CRE_EFFECT by a dummy function.

            LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%opcode%" END  
     

    I can't evaluate a variable named opcode because opcode is already an input parameter. So, WEIDU is using variable shadowing.

    As far as I understand, local function starts in INIT_VAR of LPF, whereas in a typical language, parameters are always evaluated before going inside a function.

     

     

  12. 20 hours ago, argent77 said:

    If you just want to evaluate the elements inside the string, then this code may suffice:

    INNER_PATCH ~%icons%~ BEGIN
      REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN
        PATCH_PRINT ~Processing string value: "%MATCH0%"~
      END ~%MATCH0%~
    END

     

    Thanks, it worked very well. Although I couldn't patch inside, probably because INNER_PATCH. I wrapped it into a function:

    DEFINE_PATCH_FUNCTION STRING_TO_ARRAY
    STR_VAR
      string = ""     // string with space separator
    RET_ARRAY array
    BEGIN
      CLEAR_ARRAY array
      SET i=0
      INNER_PATCH ~%string%~ BEGIN
        REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN
          SPRINT $array("%i%") "%MATCH0%"
          i+=1
        END ~%MATCH0%~
      END    
    END

    Then:

          LPF STRING_TO_ARRAY STR_VAR string=EVALUATE_BUFFER "%opcodes%" RET_ARRAY array END
          PATCH_PHP_EACH array AS _ => opcode BEGIN
            // Immunity to effect
            PATCH_PRINT ~Immunity to effect [%opcode%]~
            LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%opcode%" END  
          END
     

    But it doesn't work, I can't see what param2 value is written by function ADD_CRE_EFFECT but it isn't the value that are correctly displayed in console:

    Immunity to effect [25]

    Immunity to effect [78]

    I don't fully understand difference with this code (that works):

          PATCH_FOR_EACH ~effect~ IN ~90~ ~91~ BEGIN
            LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%effect%" END
          END

     

     

     

     

  13. 31 minutes ago, jmerry said:

    Well, yeah. DEFINE_ARRAY parses a space-delimited list of strings to an array. Using "icons=~14 130~" in your list of arguments just sets that particular string variable to the six-character string "14 130". It's not an array, and the space is part of the string.

    I found out, but is there a way to parse or convert a string into array ? API seems very very limited...

     

  14. I was partially wrong with last post:

    LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~opcodes~ icons=~14 130~ strings=~strings~ spells=~spells~ END

    icons don't get evaluated as array. I thought it worked, but I might had some interferences in my code.

  15.  I have found a solution:

      LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~opcodes~ icons=~14 130~ strings=~strings~ spells=~spells~ END
     

     

      PATCH_PHP_EACH EVAL ~%opcodes%~ AS _ => value BEGIN
        PATCH_PRINT ~op=%value%~
      END  
      PATCH_PHP_EACH EVAL ~%icons%~ AS _ => value BEGIN
        PATCH_PRINT ~icon=%value%~
      END  
     

    Finally, it works automatically :)

  16. Hi,

    I want to pass arrays as function parameters. I have looked at this thread which works nice for associative arrays:

    In my case, I have simple arrays.

    First patch function:

    DEFINE_PATCH_FUNCTION disease_immunity BEGIN
      DEFINE_ARRAY spells BEGIN  
        ~SPWI409~  
        ~FL#CSDIS~
      END
      DEFINE_ARRAY opcodes BEGIN 101 END
      DEFINE_ARRAY icons BEGIN 14 130 END
      DEFINE_ARRAY strings BEGIN 39752 54337 END
     
      LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~opcodes~ icons=~icons~ strings=~strings~ spells=~spells~ END
     
    END

    Called function:

    DEFINE_PATCH_FUNCTION ADD_IMMUNITY_CRE_ITM_SPL
    STR_VAR
      icons = ~~  
      strings = ~~  
      animations = ~~  
      spells = ~~  
    BEGIN
        PATCH_FOR_EACH value IN %opcodes%  BEGIN
             PATCH_PRINT ~op=%value%~
        END
    END  
     

    This doesn't work. PATCH_FOR_EACH seems to accept only raw values.

    As for caller, I was wondering if I could write without intermediate variables for short arrays. Something like this:

      LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~100 110 120~ icons=~36~ strings=~10050 5680~ spells=~spells~ END
     

    If I can't evaluate these values as array,  is there a way to split string into array ? Or, string parsing with REGEXP match, something like that.

    WEIDU is really lacking a good documentation. 

     

     

     

  17. 20 minutes ago, argent77 said:

    If "sometest" is only defined after the array definition, then this code might be more suitable:

    ACTION_DEFINE_ASSOCIATIVE_ARRAY my_files BEGIN
      ~a~ => 0
      ~b~ => 0
      ~c~ => 0
      ~d~ => 1
      ~e~ => 1
      ~f~ => 1
    END
    
    ACTION_PHP_EACH my_files AS file => condition BEGIN
      ACTION_IF (NOT condition || sometest && condition) BEGIN
        COPY_EXISTING ~%file%.cre~ ~override~
          // Do your stuff...
        BUT_ONLY IF_EXISTS
      END
    END

     

     

    Thanks a lot, I really like the second solution as it is more concise. It can still be simplify a bit by inversion and you don't need "&& condition":

    ACTION_DEFINE_ASSOCIATIVE_ARRAY my_files BEGIN
      ~a~ => 1
      ~b~ => 1
      ~c~ => 1
      ~d~ => 0
      ~e~ => 0
      ~f~ => 0
    END
    ACTION_PHP_EACH my_files AS file => do BEGIN
      ACTION_IF (do || sometest) BEGIN
          // Do your stuff...
      END
    END

    Good use of an associative array to add some logic ! I was too narrow mind with a tradionnal approach but we must be creative with WEIDU limitations :)

  18. Hi,

    I have to parse 2 arrays of string that executes the same code, with one of them beeing conditionnal:

    ACTION_FOR_EACH ~file~  ~a~ ~b~ ~c~
    BEGIN
      ACTION_IF FILE_EXISTS_IN_GAME ~%file%.cre~ BEGIN
        COPY_EXISTING ~%file%.cre~ ~override~
          // do some stuff
        BUT_ONLY_IF_IT_CHANGES
      END
    END
    ACTION_IF sometest = 1 BEGIN
        ACTION_FOR_EACH ~file~  ~d~ ~e~ ~f~
        BEGIN
            ACTION_IF FILE_EXISTS_IN_GAME ~%file%.cre~ BEGIN
                COPY_EXISTING ~%file%.cre~ ~override~
                // do some stuff
                BUT_ONLY_IF_IT_CHANGES
            END
        END
    END

    It is quite ugly, and considering there are dozens of block code like this one, something must be done. Is it possible to build a string array variable and use it in ACTION_IF ?

    In a typical language, you would something like:

    let array = [ 'a', 'b', 'c' ];
    
    if (sometest == 1) array = [ ...array, 'd', 'e', 'f' ];
    
    for (let f in array) {
    
          // do something
    
    }

    I need to something like this in WEIDU but don't know how. If it isn't possible, I guess I'll have to use a function with file parameter.

    I'd like to do it in the most concise and elegant way.

     

  19. 4 minutes ago, aigleborgne said:

    Hello,

    How can I choose a kit during character creation considering the current 11 kit limitation ? There are more than 11 kits per class (especially clerics).

    Is there a mod that add a scrollbar like TobEx in OG ?

     

    Just found it when randomly trying UI mods: LE UI mod specifically, it is fantastic and not only for kits ! Definitly a mandatory mod to install :)

  20. Out of those offered, skip:

    "More consistent Breach"

    "Anti-magic bypasses Imp.Invis"

    "Extra scrolls"

    "Freedom scrolls available early"

     

     

    Install "True Sight protects from Blindeness" (SR does the same but SCS won't know it).

     

    Thanks. I finally skip all of them except True sight as you said.

    All others are covered by SR. I wasn't sure for "More consistent Breach" and "Anti-magic bypasses Imp.Invis" but you confirmed it :)

     

    As for tra, good catch, I didn't think of it !

  21. Readme file is still not updated in v4beta. I assume it will be done last, just before release.

    But because the v4 detailed changes thread is not really updated with the current version, the only way to see (detailed) changes is to look with NI or in-game.

    I am still in the install process, trying to check compatibility with SCS spell changes and it is not easy without a proper document (ie: to decide what SCS spell components I want to install).

    I will now check with NI :)

  22. Ah, I see, now then tell me why shouldn't a bard with the exact same items, have the exact same fire power ? To what comes to the items. The scrolls, they are power items, yes, limited use ones that cost a lots. Yes, the BG1 portion of the game can get a little exceeding in the power jumps... but it's not a matter of fixing the shops, but more likely the random drops and stuff laying around, which have been kinda fixed in the Enhanced Edition, and in a few megamod variants if you decide to install the components. Which is a reason why not to install a luck +1 items that should be worth ~20 000 gold. If it's not your bag of beans.

     

     

    Bards are in the same boat, aren't they? I have almost never played one, so I can't tell.

     

    I'm still not convinced by EE. I'm pretty sure BGT + mods is more stable with less bugs overall. And yes, stores are not the only problem but they still contribute. BG1 has too many +1 items and I like mods that convert into fine weapons (SCS for example). All these +1 items can be sold for good amount of gold and then, you can buy a lot of stuff from stores.

    I guess that a mix of several things could bring more balance:

    - less items in the open world

    - limited supplies in store

    - higher price for magic items

     

    As for scrolls, they cost a lot, yes, but if you sell every unused items, you will have gold. Just stack several level 5 mage scrolls and wands (fireball, monster summoning) and use them in all major battles.

    I don't use this in my games (or just a little in the beginning when characters are very fragile) but I still sell them to accumulate potions. Potions are also an issue but to a lesser extent.

     

    I really like MacReady Hard Times mod, and I will see if it helps on this matter.

×
×
  • Create New...