Jump to content

Ardanis

Modders
  • Posts

    2,789
  • Joined

  • Last visited

Posts posted by Ardanis

  1. 4 hours ago, temnix said:

    By the way, can someone confirm that a door with Lock difficulty 100 gives the "This door does not have a conventional lock and may be warded..." message?

    This is a thing, yes. You can pick a lock with difficulty 98, 99, 101, 102 etc. but not 100.

  2. Doors don't close if there's an object inside of their blocking region. Can't remember if CloseDoor() gives a damn about it, though.

     

    Not directly possible, although if you *really* want, then you can remove clickable polygon from your door entirely and instead add two another invisible door objects (say, Closed and Opened) with their "closed" polys matching the main door's closed and opened states and no polys for their opened state. Then you start with:

    Main - closed (no poly), Closed - closed (visible clickable poly), Opened - opened (no poly)

    When player clicks on Closed, its attached script does OpenDoor("Main") CloseDoor("Opened"), so now you have:

    Main - opened (no poly), Closed - opened (no poly), Opened - closed (visible clickable poly)

    Clicking on Opened similarly changes Main and Closed back to initial closed state.

    When you want to disable Main entirely, just CloseDoor("Main") OpenDoor("Opened") OpenDoor("Closed"), so that the passage is blocked and no polys are active.

  3. 1 hour ago, subtledoctor said:

    Or, as I said, you can ‘close your eyes’ while in melee and then hide, and your enemy will lose track of you - because you can’t see them.

     

    1 hour ago, temnix said:

    I did and got my ass punctured by an arrow of ice from an invisible Black Talon elite.

    The difference between your results may be due to "Enable Offscreen AI" stat set for the Talon. I had to manually set it for all the SoD actors involved in Crusade/Allied activities, because otherwise they would barely act outside of party's vision range.

  4. PATCH_IF ((~%SOURCE_RES%~ STRING_CONTAINS_REGEXP ~ACT0~) == 0) | ((~%SOURCE_RES%~ STRING_CONTAINS_REGEXP ~CTALARM~) == 0) THEN BEGIN

    Not sure if it's the issue, but you seem to be using | (aka BOR) operator, which should be used for things like matching bits in a value, instead of || (aka OR), which is the "one or the other" kind. I fell into the same trap long ago, thinking they were the same.

    Also, as others mentioned, just because you never had issues using INNER_ACTION on the current file, doesn't mean they don't exist - much like I myself kept using BOR because it worked so far, but then one day it didn't and I had to find out I was doing it wrong all the time.

    PS Probably not the issue, since your values are either 0 or 1 anyway. Still, something to keep in mind for future reference.

  5. 3 hours ago, grodrigues said:

    This is, minus some details with working with in-game files that I have elided, a direct translation of the example in the READ_BYTE and PATCH_IF WeiDU tutorial. There are no offsets to remember, error checking is much stricter, you have to try *really* hard to put the item in an invalid state, etc. The syntax is sane, there are no wacky loony things like dynamic scoping to trip you up, you have actual data structures and a vast, solid library of code to reuse, etc. But is it enough? No, not really.

    The only reason there's no such consolidated data library for WeiDU is because nobody bothered yet. There're numerous functions - either included in WeiDU or shipped with mods - for adding/editing file contents without offset juggling.

    Tutorial is rather outdated anyway, as it only shows the basics. The more advanced mods have been operating their data on higher levels for over a decade.

    WeiDU syntax certainly has its share of issues, the LONG_NAMES_IN_CAPS eyesore being one of my pet peeves since ever, but lack of ability to handle your data on abstract level is not one of those.

  6. 39 minutes ago, Taylan said:

    However, in programming language lingo we have this term called a "Turing tarpit." Just because something is possible in a language, doesn't mean that language is as good as any other language.

    True, but there's also saying "don't fix what's not broken". WeiDU's syntax is certainly far from optimal, not in the least because it started as a simple dialog updater/compiler and over two decades grew into what it is now, but it gets the job done and is widely accepted by the IE community as the standard of IE modding.
    I.e. you can certainly do things your own way, but expect a lot complaints if it won't be fully compatible with WeiDU-based install routine 😛

  7. 16 hours ago, Taylan said:

    You're missing a crucial aspect of the code I've written: it allows you to define *everything* about the sound sets in INI files. The Python code doesn't ever need to be touched. I.e. a person creating a sound set package wouldn't need to know either Python nor TP2, just put WAV files in a directory and write a definitions.ini file, then put the installer.py script in the same directory and zip it up.

    I think you're the one missing it, honestly. There's nothing stopping you from writing code with exact same functionality in WeiDU syntax, put it into useful_functions_lib.tph, and call it with modder-defined arguments whenever you need it. That's what more advanced mods have been doing for over a decade.

    You could say that your version is more compact because it doesn't need to ship WeiDU.exe along, but as far as I'm aware Python isn't natively supported by Windows either.

    PS Speaking of Python, it's an awful dysfunctional language that breaks apart if you don't meticulously keep your tabs and whitespaces in order every time you update a tiny bit of your code.

  8. On 12/20/2020 at 7:08 PM, Jarno Mikkola said:

    Well, like this says, you can only have a spell upto 7 characters. And you have 8 in both.

    RES actions accept any 8 characters.

     

    Nothing catches my eye, so I would suspect it may be a SPL itself - name, targeting, whatever. Does it work if you remove all other actions?

  9. On 8/18/2020 at 2:45 AM, subtledoctor said:

    Bioware shipped the game with a ~250-page manual, much of which was taken straight from the PnP literature. A lot of stuff, in the manual and in the game text itself, was actually straight-up incorrect - and still is. Is it fine? Is the game fun in spite of that? Sure. I think I expressed that numerous times now. But is it good? Should that be what a game company aspires to do? If you think so... agree to disagree. You can put Bioware up on a big shiny pedestal, you can look at the game through the lens of 20-year stan... I try to consider things from a more detached perspective.

    Minor nuances like this thread's subject aren't discussed by a council of game designers at round table. They're just put in by whoever is responsible for implementing the content on the "does it break something? If not, then let's roll with it" basis, before moving on to the next item from a very lengthy list.

  10. It works if you put it the last in trigger block.

    gibberlings3.net/forums/topic/31466-looking-for-a-talked-to-such-and-such-condition/?tab=comments#comment-282595

    Quote

     

    TriggerOverride() doesn't work on objects not present in the active area. Worse, it doesn't return false either in such cases. And *worse yet*, it will even break OR() trigger if you put it in there as workaround, unless it goes the last in the entire condition section. From SoD's BDJAHEIR.D, this is how I managed to check that Jaheira is not inside of any Flaming Fist camps, without having to put dummy ff_camp region into each and every area:

    
    IF ~IsValidForPartyDialog("khalid") OR(2) !Range("ff_camp",999) !TriggerOverride("ff_camp",IsOverMe("jaheira"))~

    Changing the order of triggers would break it.

     

     

  11. Unless you know what you're doing, follow this template for launching cutscenes.

     

    Activation script:

    IF
    // triggers
    THEN
        RESPONSE #100
            StartCutSceneMode()
            ClearAllActions() // optional
            StartCutSceneEx("#L_Cut07",TRUE) // if you need triggers within cutscene evaluated
            // StartCutscene("#L_Cut07") // or if you don't
    END

    Cutscene itself:

    IF
        True()
    THEN
        RESPONSE #100
            CutsceneID(Player1)
            // actions
            EndCutSceneMode()
    END

     

  12. As Lauriel says, can't you instead use global vars instead of myarea for regions? Master-slave relationship isn't particularly reliable.

    E.g. patch this into all master regions:

    IF
      !Global("current_region","global",3300)
    THEN
      RESPONSE #100
        SetGlobal("current_region","global",3300)
    END

    For reputation change use SetGlobal("change_rep","global",1).

    Finally, put this into baldur.bcs:

    IF
      GlobalGT("change_rep","global",0)
      Switch("current_region","global")
    THEN
      RESPONSE #1100
        IncrementGlobal("rep_1100","global",1)
        IncrementGlobal("change_rep","global",-1)
      RESPONSE #3300
        IncrementGlobal("rep_3300","global",1)
        IncrementGlobal("change_rep","global",-1)
    END
    
    IF
      GlobaLT("change_rep","global",0)
      Switch("current_region","global")
    THEN
      RESPONSE #1100
        IncrementGlobal("rep_1100","global",1)
        IncrementGlobal("change_rep","global",1)
      RESPONSE #3300
        IncrementGlobal("rep_3300","global",1)
        IncrementGlobal("change_rep","global",1)
    END

     

  13. 13 hours ago, jastey said:

    You think? ..

    Almost the entire dialog consists of "choose party member" states, four initial and then four per each party member if PC refuses to bet them.

     

    13 hours ago, jastey said:

    I understand the concept but I have no idea how to code that. Suggestions very welcome.

    I'm a little rusty to give you an actually working piece, but the logic would be like:

    COPY_EXISTING - bdthrix.dlg override
      READ_LONG 0xc states
      x = 0
      FOR (i=21; i<24; ++i) BEGIN
        READ_LONG states + i * 16 + 8 trans_num
        SET insert%i% = ( (trans_num - 1) / 4) * x
        x = (x<3) ? x+1 : 0
      END
      FOR (i=30; i<85; ++i) BEGIN
        READ_LONG states + i * 16 + 8 trans_num
        SET insert%i% = ( (trans_num - 1) / 4) * x
        x = (x<3) ? x+1 : 0
      END

    Then in your .d use for each state

    EXTEND_BOTTOM bdthrix 21 #%insert21% /* trans list */ END

    You'll probably need to EVAL the .d

     

    13 hours ago, jastey said:

    How would I make sure I add to the correct reply option even if its number count was shifted by another mod?

     I think this may do https://weidu.org/~thebigg/README-WeiDU.html#dActionWhen

    Otherwise, you'd have to read the .dlg structure, similar to above.

  14. The original dialog is already twice, if not thrice, as messy, so... I'd be cautious about making it even worse.

    Looking at it again, I recall you can refuse Thrix his choice of a party member and have him choose again. So technically you can go with 3rd idea and append NPC at the bottom - even if two mods will conflict there, you can still write "nope, choose someone else" option to stay in line with the original, and get the previous NPC mod as a next choice.

  15. I would read the number of transitions in each state, divide it by 4, and insert mod transitions at (trans_num / 4) * (state_ind - 21) points.

    EDIT So basically, what you suggest in 1, it seems. As for compatibility... You might have a point, but imo it's the least evil nonetheless - because in order to break something it requires another mod to 1) try to edit vanilla transitions and 2) do it without reading data first.

    PPS ...and also 3) be willing to poke the awful mess that is Thrix dialog file with a ten foot pole. This dialog was the worst in the entire SoD by a huge margin, because writers wanted to have random element added. In retrospect, may we should've added small cutscene effect and move all the rng calculations in there🤔

  16. 7 hours ago, temnix said:

    By the way, Ardanis, your code suggestion here - are you sure the \s are in the right place? Shouldn't it be \[GOODCUTOFF]\ ?

    I am - special characters need to be preceded by \, to reverse them as a part of regexp formula.

    7 hours ago, temnix said:

    Okay, this is for a different script, but I get an "empty token error" now.

    A-aand it only needs to be done when matching the string😐

    COPY_EXISTING ~SHOUT.BCS~ ~override~
      DECOMPILE_AND_PATCH BEGIN
        REPLACE_TEXTUALLY ~Heard(\[NOTEVIL\],99)~
        ~Heard([NOTEVIL],99)
        Detect(LastHeardBy)~
        REPLACE_TEXTUALLY ~Heard(\[NOTGOOD\],99)~
        ~Heard([NOTGOOD],99)
        Detect(LastHeardBy)~
      END
    BUT_ONLY

     

     

    IIRC the only regexp allowed in replacement string is \1, \2 etc. to denote a match variable:

    REPLACE_TEXTUALLY ~\(Heard\)~ ~True() \1~ // WeiDu will substitute \1 with whatever has been matched by the first \(\) expression, \2 - with the second etc.

    As you can see, in case of match expression the parenthesis and numbers get preceded by \, to mark them as regexp and not part of a string. Fun, huh?🙄

  17. If you donate the amount equal or greater than value corresponding to the current reputation (specified in reputati.2da), then it will increase by 1 point.

    No means of detection that I know of. You could try appending StartStore() actions with SetGlobal() to run a check afterwards if reputation is now greater than it used to be before starting dialog.

×
×
  • Create New...