Jump to content


Photo

BUT_ONLY_IF_IT_CHANGES


  • Please log in to reply
7 replies to this topic

#1 Idobek

Idobek

    Pocket Plane Gibberling

  • Member
  • 429 posts

Posted 01 April 2004 - 06:14 AM

Let's say we want to remove the 'lore to identify' value from all items so that we never have to have them identified. If we didn't want to copy all the item files to the override, we used to use IF_EVAL, like so:
BEGIN ~Identify All Items~
COPY_EXISTING_REGEXP GLOB ~.*\.itm~ ~override~
   READ_SHORT 0x42 "loretoidentify"
      WRITE_SHORT 0x42 0x0000
   IF_EVAL ("%loretoidentify%" > 0)
With the invention of BUT_ONLY_IF_IT_CHANGES we can don't need to evaluate the current lore value, we can just patch:
BEGIN ~Identify All Items~
COPY_EXISTING_REGEXP GLOB ~.*\.itm~ ~override~
    WRITE_SHORT 0x42 0x0000
BUT_ONLY_IF_IT_CHANGES

Edited by Idobek, 01 April 2004 - 08:57 AM.


#2 Idobek

Idobek

    Pocket Plane Gibberling

  • Member
  • 429 posts

Posted 01 April 2004 - 06:17 AM

Note: BUT_ONLY_IF_IT_CHANGES will trip over the iplot0xx items if you use C_E_R to copy all the items. See "this" thread. I have added this peice of code to the top of my tp2 to deal with this issue.
ALWAYS
  ACTION_IF NOT FILE_EXISTS ~override/iplot01k.itm~
    THEN BEGIN
      COPY ~IKTest/blank.itm~ ~override/iplot01k.itm~
    END
  ACTION_IF NOT FILE_EXISTS ~override/iplot04g.itm~
    THEN BEGIN
      COPY ~IKTest/blank.itm~ ~override/iplot04g.itm~
    END
  ACTION_IF NOT FILE_EXISTS ~override/iplot04h.itm~
    THEN BEGIN
     COPY ~IKTest/blank.itm~ ~override/iplot04h.itm~
    END
  ACTION_IF NOT FILE_EXISTS ~override/iplot04i.itm~
    THEN BEGIN
      COPY ~IKTest/blank.itm~ ~override/iplot04i.itm~
    END
END
I do it like this because then I don't have to remember copy the iplot0xx items everytime I use C_E_R on items.

#3 -Guest-

-Guest-
  • Guest

Posted 01 April 2004 - 08:16 AM

With the invention of BUT_ONLY_IF_IT_CHANGES we can don't need to evaluate the current lore value, we can just patch:

What, exactly, constitutes a change? Will WeiDU fail if any single change is not made, or will it work properly if multiple patch actions are executed (some of which wouldn't change the current value). I previously misunderstood how this worked (I had assumed that it was used only if changes were explicitly written to the file, instead of only if the value to be written differs from the current value).

This behavior is much more useful, but I want to make sure WeiDU won't barf when some of the values aren't patched in an action. So would the following work:

COPY_EXISTING_REGEXP ~.+\.ITM$~ ~override~
  WRITE_LONG (offset where the value is always 0) 0x00 // No changes
  WRITE_SHORT (offset where the value is never 0) 0x00 // Is changed
BUT_ONLY_IF_IT_CHANGES

or would WeiDU fail to patch the file once it realizes the WRITE_LONG won't change the file?

#4 Idobek

Idobek

    Pocket Plane Gibberling

  • Member
  • 429 posts

Posted 01 April 2004 - 08:57 AM

I would prefer I if Wes came along and answered this definitively, but until then...

I am using BUT_ONLY_IF_IT_CHANGES on patches with WHILE loops, that definately contain some patches that will not change the file. WeiDU will only not copy the file if no change is made at all, not if any one change is not made because the value is already the same. After you asked this I did a test:
COPY_EXISTING_REGEXP GLOB ~AMUL.*\.itm~ ~override~
  WRITE_SHORT 0x42 0x0000
  WRITE_LONG 0x34 0x00000000
BUT_ONLY_IF_IT_CHANGES
This code patches all the files in the regexp (27 files). 11 of these already have a zero value at offset 0x42.

I hope I understood what you were asking, my track record on answering the questioned asked (instead of what I thought was asked) is not great recently. :rolleyes:

#5 -Guest-

-Guest-
  • Guest

Posted 01 April 2004 - 10:45 AM

I hope I understood what you were asking, my track record on answering the questioned asked (instead of what I thought was asked) is not great recently. :rolleyes:

This is what I was looking for. Thanks.

#6 weimer

weimer
  • Member
  • 1569 posts

Posted 01 April 2004 - 04:00 PM

Without being too blase about it, BUT_ONLY_IF_IT_CHANGES can never hurt you and basically always does exactly what you are thinking :-). If there would be no point in writing out the new file (because it would be exactly the same as the old after all of your patches), it will not be written.

In your amulet example, making the lore-to-indentify 0 and the price 0 changes every amulet, so every amulet will be written out.

The PLOT thing is annoying -- basically, the game biffs include malformed items. One approach would be to have WeiDU not flag errors when you try to read or write from an offset that isn't there. Hmm. Or maybe invalid reads could always return 0. The thing I'm worried about here is masking actual errors in mods that people are developing. If WeiDU silently walks over your errors, you won't realize that your patch makes no sense.

#7 -Guest-

-Guest-
  • Guest

Posted 02 April 2004 - 11:55 AM

Without being too blase about it, BUT_ONLY_IF_IT_CHANGES can never hurt you and basically always does exactly what you are thinking :-). If there would be no point in writing out the new file (because it would be exactly the same as the old after all of your patches), it will not be written.

I haven't found this to be the case. I stay away from BUT_ONLY_IF_IT_CHANGES, simply because it causes too many problems. It will not work for textual changes, and doesn't seem to work for INSERT/DELETE_BYTES. For instance, the following change will fail if BUT_ONLY_IF_IT_CHANGES is used:

COPY_EXISTING ~SPPR302.SPL~ ~override~
  READ_LONG 0x64 ~abilitiesOffset~
  READ_LONG 0x6A ~effectsOffset~
  READ_SHORT 0x68 ~numberOfAbilities~
  INSERT_BYTES ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) 0x28
  WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x10 0x14
  WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x26 0x55
  INSERT_BYTES ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) 0x28
  WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x10 0x13
  WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x26 0x54
  WRITE_LONG 0x6A ~%effectsOffset%~ + (0x02 * 0x28)
  WRITE_SHORT 0x68 ~%numberOfAbilities%~ + 0x02
  SET ~index~ = 0x02
  WHILE (~%index%~ > 0x00) BEGIN
    WRITE_ASCII ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x04 ~SPPR302B~
    WRITE_BYTE ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) 0x01
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x02 0x02
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x0C 0x01
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x0E 0x50
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x12 0x09
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x16 0x06
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x1C 0x01
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x1E 0x02
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x22 0x01
    WRITE_SHORT ~%abilitiesOffset%~ + (~%numberOfAbilities%~ * 0x28) + 0x24 0x01
    SET ~abilitiesOffset~ = ~%abilitiesOffset%~ + 0x28
    SET ~index~ = ~%index%~ - 0x01
  END
Although there's really no point in using BUT_ONLY_IF_IT_CHANGES here (the file will *always* change), I wouldn't expect it to cause a problem. It does, however, as the following will now fail:

COPY_EXISTING ~SPPR302.SPL~ ~override~
  READ_LONG 0x6A ~effectsOffset~
  READ_SHORT 0x68 ~numberOfAbilities~
  READ_SHORT 0x70 ~numberOfEffects~
  SET ~numberOfEffects~ = (~%numberOfAbilities%~ - 0x02) * 0x02
  INSERT_BYTES ~%effectsOffset%~ + (~%numberOfEffects%~ * 0x30) 0xC0
  SET ~index~ = 0xC0
  WHILE (~%index%~ > 0x00) BEGIN
    READ_LONG ~%effectsOffset%~ ~cloneEffect~
    WRITE_LONG ~%effectsOffset%~ + (~%numberOfEffects%~ * 0x30) ~%cloneEffect%~
    SET ~effectsOffset~ = ~%effectsOffset%~ + 0x04
    SET ~index~ = ~%index%~ - 0x04
  END
  WRITE_LONG 0x84E 0x0B
  WRITE_LONG 0x87E 0x0A
  WRITE_LONG 0x8AE 0x0B
  WRITE_LONG 0x8DE 0x0B
Running this will give the generic "bad offset" error as WeiDU tries to modify bytes that don't exist (since the previous patch was never written).

The PLOT thing is annoying -- basically, the game biffs include malformed items. One approach would be to have WeiDU not flag errors when you try to read or write from an offset that isn't there. Hmm. Or maybe invalid reads could always return 0. The thing I'm worried about here is masking actual errors in mods that people are developing. If WeiDU silently walks over your errors, you won't realize that your patch makes no sense.

This would be terrible. Almost all of the errors I receive are incorrect offset errors. If WeiDU didn't report the error, I would happily be using these files until the game crashed. The problem is that WeiDU's error reporting is terrible (it's always the same set of error messages, regardless of the actual problem). Perhaps if WeiDU simply skipped zero-byte files?

#8 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 04 April 2004 - 01:09 AM

What about an error override option.
So, if you are aware of a problem, you could skip it gracefully, then turn the error reporting back.
Avenger