WeiDUorg / weidu

WeiDU is a program used to develop, distribute and install modifications for games based on the Infinity Engine.
http://www.weidu.org
GNU General Public License v2.0
90 stars 20 forks source link

APPLY_BCS_PATCH needs a proper documentation/tutorial #129

Closed 4Luke4 closed 5 years ago

4Luke4 commented 5 years ago

There is no documentation about this instruction. How am I supposed to use it?

FredrikLindgren commented 5 years ago

Can you be more specific? APPLY_BCS_PATCH explains what it does, albeit a bit tersely, and links to --bcmp-from et al. for further info on how to obtain a patch file. Where do you feel the documentation is lacking?

4Luke4 commented 5 years ago

Where do you feel the documentation is lacking?

Maybe here? Applies patchFile to the current file. See --bcmp-from and similar command-line arguments for constructing these patches. But then --bcmp-from simply states _Emit APPLY_BCSPATCH to turn this BCS file into this one. So?

Alternatively, could you provide an example usage?

FredrikLindgren commented 5 years ago

I'm still not seeing the issue. APPLY_BCS_PATCH explains how the patch is used. --bcmp-from and --bcmp-to explain how you obtain a patch suited for use with APPLY_BCS_PATCH.

On the command line: $ weidu --bcmp-from some.bcs --bcmp-to other.bcs This will emit to stdout a patch as an inlined file. The patch contains the changes for turning some.bcs into other.bcs. Unfortunately, there is some other stuff emitted as well, so you need to prune it before you get something useful. Included is actually a usage example for APPLY_BCS_PATCH.

Then you use the patch in TP2 as

COPY_EXISTING some.bcs "override/other.bcs"
  DECOMPILE_AND_PATCH BEGIN
    APPLY_BCS_PATCH some.patch // some.patch is the patch you obtained from --bcmp-from
  END
BUT_ONLY

It strikes me the name is poorly considered, as it is actually a BAF patch, not a BCS one. But I'm not seeing how the documentation is lacking. Suggestions?

4Luke4 commented 5 years ago

To tell the truth, I'm not sure APPLY_BCS_PATCH is what I need...... I'm looking for the most effective way of patching BCS scripts: in particular, I need to add a trigger every time the AI casts certain spells (via the actions Spell/ForceSpell.....) I know I can do this with REPLACE_BCS_BLOCK but I think it's too much time consuming (in fact, I need to inspect every single BCS file), so I was wondering if APPLY_BCS_PATCH is better in this case......

FredrikLindgren commented 5 years ago

It's not. Your best bet is probably COPY_EXISTING_REGEXP and REPLACE_TEXTUALLY.

If we are done here I'll close this issue.

4Luke4 commented 5 years ago

It's not. Your best bet is probably COPY_EXISTING_REGEXP and REPLACE_TEXTUALLY.

True, but I'm limited to match a single trigger..... In order to be safe, I'd like to do something like this:

COPY_EXISTING_REGEXP ~.*\.bcs~ ~override~
  DECOMPILE_AND_PATCH BEGIN
    REPLACE_TEXTUALLY
     ~General(LastSeenBy,HUMANOID)
    !StateCheck(LastSeenBy,STATE_DISABLED)~
     ~General(LastSeenBy,HUMANOID)
    !CheckSpellState(LastSeenBy,UNDISPELLABLE)
    !StateCheck(LastSeenBy,STATE_DISABLED)~
  END
BUT_ONLY

Unfortunately, this doesn't work..........

FredrikLindgren commented 5 years ago

Your regexp does not match the contents of the buffer. You assume tab indentation and whatever newline format you use for your TP2. WeiDU decompiles with LNL (\n) and 2 spaces of indentation.

When debugging issues like this it is good to sanity-check by decompiling the file you are trying to match against to make sure you are not tripping over issues like these.

There are additional issues that could cause issues on vanilla and/or non-EE games, but I assume you've got that covered.

4Luke4 commented 5 years ago

Your regexp does not match the contents of the buffer. You assume tab indentation and whatever newline format you use for your TP2. WeiDU decompiles with LNL (\n) and 2 spaces of indentation.

What do you mean exactly? I didn't manage to fix the issue via removing tab indentation..... I'm only interested in EE games by the way.......

FredrikLindgren commented 5 years ago

A dummy script decompiles into the following BAF:

IF
  General(LastSeenBy,HUMANOID)
  !StateCheck(LastSeenBy,STATE_DISABLED)
THEN
  RESPONSE #100
    Continue()
END

When you want to match several lines, you need to account for the kind of newlines used. To be on the safe side, that means accounting for all kinds. Additionally, it's a good idea to account for both tabs and spaces and not make any assumptions about the number of any of these things. Although WeiDU is predictable in what it uses, regexps errors are annoying and playing it safe tends to reduce the number of those.

  DECOMPILE_AND_PATCH BEGIN
    REPLACE_TEXTUALLY
      ~General(LastSeenBy,HUMANOID)[%WNL%%TAB% ]*!StateCheck(LastSeenBy,STATE_DISABLED)~
      ~General(LastSeenBy,HUMANOID)
      !StateCheck(LastSeenBy,UNDISPELLABLE)
      !StateCheck(LastSeenBy,STATE_DISABLED)~
  END

Note that WNL is a composite of \r and \n and thus matches both characters as well as any sequence of them, when used inside a character set like this.