Author Topic: Effect patching order  (Read 3841 times)

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Effect patching order
« on: September 06, 2008, 04:12:29 PM »
I am using a WHILE loop to patch an effect to a number of ability headers. Duration and header to patch to are dynamically generated, but only the former works as intended. There are nine abilities in the spell and in the first code sample, header goes from 1 to 9 and in the second, from 9 to 1. WeiDU applies the effects in the same order in both cases, though, which is from 9 to 1. Removing the loop and setting header to 1 works. What is going on here?

Code: [Select]
  SET "baseduration" = "12"
  SET "bonusduration" = "6"
  SET "#addedeffects" = "0"
  WHILE ("%#addedeffects%" < "%#abilities%") BEGIN
    SET "opcode" = "153"
    SET "target" = "2"
    SET "power" = "1"
    SET "parameter1" = "0"
    SET "parameter2" = "0"
    SET "timing" = "0"
    SET "resist_dispel" = "3"
    SET "duration" = ("%baseduration%" + ("%bonusduration%" * ("%#addedeffects%" + 1)))
    SET "probability1" = "100"
    SET "probability2" = "0"
    SPRINT "resource" ~~
    SET "dicenumber" = "0"
    SET "dicesize" = "0"
    SET "savingthrow" = "0"
    SET "savebonus" = "0"
    SET "header" = ("1" + "%#addedeffects%")
    LAUNCH_PATCH_MACRO ADD_SPELL_EFFECT
    SET "#addedeffects" += "1"
  END

Code: [Select]
  SET "baseduration" = "12"
  SET "bonusduration" = "6"
  SET "#addedeffects" = "0"
  WHILE ("%#addedeffects%" < "%#abilities%") BEGIN
    SET "opcode" = "153"
    SET "target" = "2"
    SET "power" = "1"
    SET "parameter1" = "0"
    SET "parameter2" = "0"
    SET "timing" = "0"
    SET "resist_dispel" = "3"
    SET "duration" = ("%baseduration%" + ("%bonusduration%" * ("%#addedeffects%" + 1)))
    SET "probability1" = "100"
    SET "probability2" = "0"
    SPRINT "resource" ~~
    SET "dicenumber" = "0"
    SET "dicesize" = "0"
    SET "savingthrow" = "0"
    SET "savebonus" = "0"
    SET "header" = ("%#abilities%" - "%#addedeffects%")
    LAUNCH_PATCH_MACRO ADD_SPELL_EFFECT
    SET "#addedeffects" += "1"
  END

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #1 on: September 08, 2008, 02:09:43 PM »
So the abilities end up with the wrong effects or is it just cosmetics (i.e. order of effects in file) ?

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #2 on: September 08, 2008, 02:16:16 PM »
In both cases, ability header #1 gets the effect with the duration set to 66 and ability header #9 (with minimum level 9) gets the effect with duration 18. Of course, I can change the way I generate duration to take this into account (SET "duration" = ("%baseduration%" + (("%bonusduration%" * "%#abilities%") - ("%bonusduration%" * "%#addedeffects%")))) but I would prefer not to do things backwards. I would also like to know why WeiDU is not doing things as expected.

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: Effect patching order
« Reply #3 on: September 08, 2008, 06:41:32 PM »
You should add a couple of PATCH_PRINTs in there to see if you got the indexes correctly or not.
Author or Co-Author: WeiDU (http://j.mp/bLtjOn) - Widescreen (http://j.mp/aKAiqG) - Generalized Biffing (http://j.mp/aVgw3U) - Refinements (http://j.mp/bLHoCc) - TB#Tweaks (http://j.mp/ba02Eg) - IWD2Tweaks (http://j.mp/98OFYY) - TB#Characters (http://j.mp/ak8J55) - Traify Tool (http://j.mp/g1Ry9A) - Some mods that I won't mention in public
Maintainer: Semi-Multi Clerics (http://j.mp/9UeIwB) - Nalia Mod (http://j.mp/dng9l0) - Nvidia Fix (http://j.mp/aRWjjg)
Code dumps: Detect custom secondary types (http://j.mp/hVzzXG) - Stutter Investigator (http://j.mp/gdtBn8)

If possible, send diffs, translations and other contributions using Git (http://j.mp/aBZFrq).

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #4 on: September 09, 2008, 01:53:57 AM »
Can I have a look at the spell file?

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #5 on: September 09, 2008, 07:35:16 AM »
Sure.

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #6 on: September 11, 2008, 02:35:46 AM »
Countless Hours of Testing has led me to believe this error is caused by ADD_SPELL_EFFECT not updating the effect index correctly when adding an effect to an empty ability header.

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #7 on: September 11, 2008, 11:55:56 AM »
Sorry forgot about that one.

Can you give me the file from before patching with the above code?
(It looks like this was already done in the version you posted.)

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 374
  • Gender: Male
  • Not an AD&D rules lawyer.
Re: Effect patching order
« Reply #8 on: September 11, 2008, 11:56:20 AM »
It might have to do with the macro not updating the first effect offset at the start of every header. INSERT_BYTES sets everything to zero, and you will have to update not only the number of effects (variable "___#abil_fx_num") but also the offset the engine should start reading the effects (variable "___#abil_fx_idx").

-Galactygon

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #9 on: September 11, 2008, 01:27:39 PM »
It might have to do with the macro not updating the first effect offset at the start of every header.

Only if the header is empty. I have had it update the index correctly.

Taimon: Before adding the effects, I remove the existing ones and add 8 headers.

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #10 on: September 11, 2008, 04:07:30 PM »
So you have multiple headers with zero effects?
I don't think Gort expected something like this. (It's possible, but not used ingame, as far as I know.)
But yeah, effects index correction will fail in this case:
Code: [Select]
//correcting effects number
SET ___#abil_fx_num = (___#abil_fx_num + 1)
WRITE_SHORT (___#abil_off + 0x1e + (0x28 * ___#index1)) ___#abil_fx_num

//correcting 1st effect indexes
FOR (___#index2 = 0 ; ___#index2 < ___#abil_num ; ___#index2 = ___#index2 + 1) BEGIN
  READ_SHORT (___#abil_off + ___#index2 * 0x28 + 0x20) ___#1effect_index
  PATCH_IF (___#1effect_index > ___#abil_fx_idx) BEGIN //if abilility after current effect
    WRITE_SHORT (___#abil_off + ___#index2 * 0x28 + 0x20) (___#1effect_index + 1) //increase 1 effect ___#index1 by 1
  END
END
The PATCH_IF should alternatively look for (___#1effect_index == ___#abil_fx_idx) AND (___#abil_fx_num == 1), I guess. [ if they shared the index and the number of effects was zero ]
I bet the other ADD_*_EFFECT macros are affected by this as well.

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #11 on: September 12, 2008, 12:17:20 AM »
Yes. I figured this was the easiest way to do the spell patching.

Do you know how to update the macros?

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #12 on: September 12, 2008, 01:26:29 AM »
For the moment you would have to redefine the macro yourself.
Code: [Select]
DEFINE_PATCH_MACRO ~MY_ADD_SPELL_EFFECT~ BEGIN
  PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN
    READ_LONG  0x64 ___#abil_off
    READ_SHORT 0x68 ___#abil_num
    READ_LONG  0x6a ___#fx_off

    FOR (___#index1 = 0 ; ___#index1 < ___#abil_num ; ___#index1 = ___#index1 + 1) BEGIN

      PATCH_IF (___#index1 = (header - 1)) OR (header = 0) BEGIN //header=1 means ___#index1=0
        READ_SHORT  (___#abil_off + 0x1e + (0x28 * ___#index1)) ___#abil_fx_num
        READ_SHORT  (___#abil_off + 0x20 + (0x28 * ___#index1)) ___#abil_fx_idx

        INSERT_BYTES (___#fx_off +        (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) 0x30

        WRITE_SHORT  (___#fx_off +        (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) opcode
        WRITE_BYTE   (___#fx_off + 0x02 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) target
        WRITE_BYTE   (___#fx_off + 0x03 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) power
        WRITE_LONG   (___#fx_off + 0x04 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) parameter1
        WRITE_LONG   (___#fx_off + 0x08 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) parameter2
        WRITE_BYTE   (___#fx_off + 0x0c + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) timing
        WRITE_BYTE   (___#fx_off + 0x0d + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) resist_dispel
        WRITE_LONG   (___#fx_off + 0x0e + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) duration
        WRITE_BYTE   (___#fx_off + 0x12 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) probability1
        WRITE_BYTE   (___#fx_off + 0x13 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) probability2
        WRITE_EVALUATED_ASCII (___#fx_off + 0x14 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) ~%resource%~ #8
        WRITE_LONG   (___#fx_off + 0x1c + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) dicenumber
        WRITE_LONG   (___#fx_off + 0x20 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) dicesize
        WRITE_LONG   (___#fx_off + 0x24 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) savingthrow
        WRITE_LONG   (___#fx_off + 0x28 + (0x30 * (___#abil_fx_num + ___#abil_fx_idx))) savebonus

        //correcting effects number
        SET ___#abil_fx_num = (___#abil_fx_num + 1)
        WRITE_SHORT (___#abil_off + 0x1e + (0x28 * ___#index1)) ___#abil_fx_num

        //correcting 1st effect indexes
        FOR (___#index2 = 0 ; ___#index2 < ___#abil_num ; ___#index2 = ___#index2 + 1) BEGIN
          READ_SHORT (___#abil_off + ___#index2 * 0x28 + 0x20) ___#1effect_index
          PATCH_IF (___#1effect_index > ___#abil_fx_idx) //if abilility after current effect
                OR ((___#1effect_index == ___#abil_fx_idx) AND (___#abil_fx_num == 1)) BEGIN
            WRITE_SHORT (___#abil_off + ___#index2 * 0x28 + 0x20) (___#1effect_index + 1) //increase 1 effect ___#index1 by 1
          END
        END
        //no offsets to correct
      END
    END
    //reset vars
    SET opcode = 0
    SET target = 0
    SET timing = 0
    SET resist_dispel = 0
    SET power = 0
    SET header = 0
    SET parameter1 = 0
    SET parameter2 = 0
    SET probability1 = 100
    SET probability2 = 0
    SET duration = 0
    SPRINT resource ~%___#nil%~
    SET dicenumber = 0
    SET dicesize = 0
    SET savingthrow = 0
    SET savebonus = 0

  END
END

I guess, the bigg will point you to the beta location when it get's fixed in WeiDU source, so that you can test if it fixes your problem.

bigg: Will post a diff, when I checked the other macros.

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: Effect patching order
« Reply #13 on: September 12, 2008, 02:28:09 AM »
For the moment you would have to redefine the macro yourself.
You can re-define a macro, you know (I.E. DEFINE_PATCH_MACRO ADD_SPELL_EFFECT will overwrite Gort's).

Quote
bigg: Will post a diff, when I checked the other macros.
OK.
Author or Co-Author: WeiDU (http://j.mp/bLtjOn) - Widescreen (http://j.mp/aKAiqG) - Generalized Biffing (http://j.mp/aVgw3U) - Refinements (http://j.mp/bLHoCc) - TB#Tweaks (http://j.mp/ba02Eg) - IWD2Tweaks (http://j.mp/98OFYY) - TB#Characters (http://j.mp/ak8J55) - Traify Tool (http://j.mp/g1Ry9A) - Some mods that I won't mention in public
Maintainer: Semi-Multi Clerics (http://j.mp/9UeIwB) - Nalia Mod (http://j.mp/dng9l0) - Nvidia Fix (http://j.mp/aRWjjg)
Code dumps: Detect custom secondary types (http://j.mp/hVzzXG) - Stutter Investigator (http://j.mp/gdtBn8)

If possible, send diffs, translations and other contributions using Git (http://j.mp/aBZFrq).

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #14 on: September 12, 2008, 03:46:21 AM »
You can re-define a macro, you know (I.E. DEFINE_PATCH_MACRO ADD_SPELL_EFFECT will overwrite Gort's).
Wasn't sure if you used replace or not, so I went better safe than sorry. :)

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: Effect patching order
« Reply #15 on: September 12, 2008, 03:55:52 AM »
Wether I used Hashtbl.replace or Hashtbl.add, the newest definition would be the winner either way. Hashtbl.add would just leave the old one referenced.
Author or Co-Author: WeiDU (http://j.mp/bLtjOn) - Widescreen (http://j.mp/aKAiqG) - Generalized Biffing (http://j.mp/aVgw3U) - Refinements (http://j.mp/bLHoCc) - TB#Tweaks (http://j.mp/ba02Eg) - IWD2Tweaks (http://j.mp/98OFYY) - TB#Characters (http://j.mp/ak8J55) - Traify Tool (http://j.mp/g1Ry9A) - Some mods that I won't mention in public
Maintainer: Semi-Multi Clerics (http://j.mp/9UeIwB) - Nalia Mod (http://j.mp/dng9l0) - Nvidia Fix (http://j.mp/aRWjjg)
Code dumps: Detect custom secondary types (http://j.mp/hVzzXG) - Stutter Investigator (http://j.mp/gdtBn8)

If possible, send diffs, translations and other contributions using Git (http://j.mp/aBZFrq).

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #16 on: September 13, 2008, 08:16:02 AM »
Taimon: Thanks for the updated macro. Effects are now added correctly to SPLs with multiple headers and no effects. Unfortunately, it now screws up the effect index if the SPL does contain effects.

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #17 on: September 13, 2008, 12:03:53 PM »
Wether I used Hashtbl.replace or Hashtbl.add, the newest definition would be the winner either way. Hashtbl.add would just leave the old one referenced.
Yeah. I was too lazy to look at the code and needed an excuse. ;)

Unfortunately, it now screws up the effect index if the SPL does contain effects.
Can you be more specific on the test case? (test.tp2 + spl file would be perfect)
I did a quick check on vanilla sppr110.spl with your code above, and it seems as it is doing what it's supposed to be doing.

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #18 on: September 13, 2008, 01:07:48 PM »
I have attached the TP2. As you can see, I remove the existing effects from sppr109, add 8 headers and then add an effect to each of them. This works as intended. Then try pointing the code at sppr202 instead, remove the lines that clear the original effects and watch the results.

I am not attaching any spells since I am using the standard version of both.

Offline Taimon

  • Planewalker
  • *****
  • Posts: 326
Re: Effect patching order
« Reply #19 on: September 13, 2008, 03:42:44 PM »
Well, stumbled across multiple things here.

First, the effects index correction should also check, that its not correcting the current ability.
Change
Code: [Select]
                OR ((___#1effect_index == ___#abil_fx_idx) AND (___#abil_fx_num == 1)) BEGIN
to something like
Code: [Select]
                OR ((___#1effect_index == ___#abil_fx_idx)
                   AND (___#abil_fx_num == 1)
                   AND (___#index2 != ___#index1)) BEGIN

And second, I don't think it's a good idea to initialize the effects index in the new abilities with 0.
If I remember correctly, the engine is expecting a special order of the effects (at least on Macintosh).
First global effects, then all the effects in the order of the abilities.

In fact, I believe Near Infinity is currently disregarding the effects index in the abilities and just reads them as they are in the file. (Only using the effects number to attach them to abilities.)
Not sure, if this is a bug or intended. (Can anyone clarify/confirm this?)

So it would be better to set it to the currently last index + 1. (You would have to write some code to find that index.)

Offline Echon

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 1941
  • Gender: Male
    • The Fields of the Dead
Re: Effect patching order
« Reply #20 on: September 13, 2008, 06:43:55 PM »
With the updated index correction code and the index on new headers (I already had some code to count the number of effects), it is finally working. I have tried to break the macro in all the ways it has failed so far but it only does what it should do.

Thanks for helping me find the solution to this problem. I appreciate being able to get back to updating my mod again.

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color is grass?:
What is the seventh word in this sentence?:
What is five minus two (use the full word)?: