Author Topic: The CRE macros  (Read 2815 times)

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
The CRE macros
« on: October 26, 2010, 03:14:25 PM »
ADD_CRE_EFFECT_BG2 and DELETE_CRE_EFFECT pretty much break any cre file, since they go hog-wild adjusting offsets, even when the offsets shouldn't be adjusted.

While I was poking around in there I also altered ADD_CRE_EFFECT_BG1 and DELETE_CRE_ITEM to support non-standard orders and DELETE_CRE_EFFECT to support EFF V1. It probably also works.

Code: [Select]
--- g_macros_original.tpa 2010-09-29 23:47:12.000000000 +0200
+++ g_macros.tpa 2010-10-26 22:01:04.640625000 +0200
@@ -496,10 +496,12 @@
  WRITE_LONG 0x2c8 (___#fx_num + 1)
 
  //correcting offsets
- PATCH_FOR_EACH ___#offset IN 0x2b8 0x2bc BEGIN //item slots offset and items offset
- READ_LONG ___#offset ___#current_off
- WRITE_LONG ___#offset (___#current_off + 0x30)
- END
+         PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
+           READ_LONG ___#offset ___#current_off
+           PATCH_IF ___#current_off > ___#fx_off OR ((___#offset = 0x2b8 OR ___#offset = 0x2bc) AND ___#current_off = ___#fx_off) BEGIN
+             WRITE_LONG ___#offset (___#current_off + 0x30)
+           END
+         END
 
  //reset vars
  SET opcode = 0
@@ -580,7 +582,9 @@
      //correcting offsets
      PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
        READ_LONG ___#offset ___#current_off
-       WRITE_LONG ___#offset (___#current_off + 0x108)
+       PATCH_IF ___#current_off > ___#fx_off OR ((___#offset = 0x2b8 OR ___#offset = 0x2bc) AND ___#current_off = ___#fx_off) BEGIN
+         WRITE_LONG ___#offset (___#current_off + 0x108)
+       END
      END
 
    //reset vars
@@ -624,13 +628,14 @@
  DEFINE_PATCH_MACRO ~DELETE_CRE_EFFECT~ BEGIN
    PATCH_IF (SOURCE_SIZE > 0x2c8) BEGIN
 
+     READ_BYTE 0x33  ___#fx_flag
      READ_LONG 0x2c4 ___#fx_off
      READ_LONG 0x2c8 ___#fx_num
      SET ___#delta = 0
      FOR (___#index1 = 0; ___#index1 < ___#fx_num; ___#index1 = ___#index1 + 1) BEGIN
-       READ_LONG (___#fx_off + ___#index1 * 0x108 + 0x8) ___#opcode
+       READ_LONG (___#fx_off + ___#index1 * (___#fx_flag = 1 ? 0x108 : 0x30) + (___#fx_flag = 1 ? 0x8 : 0x0)) ___#opcode
        PATCH_IF ((___#opcode = opcode_to_delete) OR (opcode_to_delete = (0 - 1))) BEGIN
-         DELETE_BYTES (___#fx_off + ___#index1 * 0x108) 0x108
+         DELETE_BYTES (___#fx_off + ___#index1 * (___#fx_flag = 1 ? 0x108 : 0x30)) ___#fx_flag = 1 ? 0x108 : 0x30
          SET ___#delta = ___#delta + 1 //track deleted number
          SET ___#fx_num = ___#fx_num - 1 //decrease effects number to stop cycle properly
          SET ___#index1 = ___#index1 - 1 //step back to not miss an effect
@@ -641,7 +646,9 @@
        WRITE_LONG 0x2c8 ___#fx_num //corrected earlier
        PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
          READ_LONG ___#offset ___#current_off
-         WRITE_LONG ___#offset (___#current_off - ___#delta * 0x108)
+         PATCH_IF ___#current_off > ___#fx_off BEGIN
+           WRITE_LONG ___#offset (___#current_off - ___#delta * (___#fx_flag = 1 ? 0x108 : 0x30))
+         END
        END
      END
 
@@ -667,8 +674,13 @@
          SET ___#itm_num = ___#itm_num - 1
          SET ___#delta = ___#delta + 1
 
-         //correct islot offset
-         WRITE_LONG 0x2b8 (___#islot_off - 0x14)
+         //correct offsets
+         PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
+           READ_LONG ___#offset ___#current_off
+           PATCH_IF ___#current_off > ___#itm_off BEGIN
+             WRITE_LONG ___#offset (___#current_off - ___#delta * 0x14)
+           END
+         END
 
          FOR (___#cur_slot = 0; ___#cur_slot < 37; ___#cur_slot = ___#cur_slot + 1) BEGIN
            READ_LONG 0x2b8 ___#islot_off

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Moderator
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: The CRE macros
« Reply #1 on: October 26, 2010, 04:08:31 PM »
I love when people send me tested code.

I'll upload 222 with that fix once you can confirm that it works (if you can't tell, I'm not attentive enough to details and always end up missing glaring bugs when I test stuff myself).
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 Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: The CRE macros
« Reply #2 on: October 26, 2010, 04:19:42 PM »
How do you define "works"?
I tested the changes by using several macros in a row (a series of consisting of delete eff, add eff, delete itm, delete eff) on EFF V1 and EFF V2 creatures and they seemed all right after that. But they were standard-ordered. I guess I can construct a non-standard creature, but the order logic seems sound. I'll test it on QP's dragon.
« Last Edit: October 26, 2010, 04:24:51 PM by Wisp »

Offline GeN1e

  • Planewalker
  • *****
  • Posts: 267
  • Gender: Male
Re: The CRE macros
« Reply #3 on: October 26, 2010, 04:36:47 PM »
Quote
I love when people send me tested code.
Nope, I'm not at fault there. I've also added PATCH_IF check, which appears to be missing in 221.

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: The CRE macros
« Reply #4 on: October 26, 2010, 04:45:19 PM »
No, my alterations to the offset-adjusting code for ADD_CRE_EFFECT doesn't work so well with non-standard orders.

This works:
Code: [Select]
--- g_macros_original.tpa 2010-09-29 23:47:12.000000000 +0200
+++ g_macros.tpa 2010-10-26 23:39:59.406250000 +0200
@@ -496,10 +496,12 @@
  WRITE_LONG 0x2c8 (___#fx_num + 1)
 
  //correcting offsets
- PATCH_FOR_EACH ___#offset IN 0x2b8 0x2bc BEGIN //item slots offset and items offset
- READ_LONG ___#offset ___#current_off
- WRITE_LONG ___#offset (___#current_off + 0x30)
- END
+         PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
+           READ_LONG ___#offset ___#current_off
+           PATCH_IF ___#current_off >= ___#fx_off BEGIN
+             WRITE_LONG ___#offset (___#current_off + 0x30)
+           END
+         END
 
  //reset vars
  SET opcode = 0
@@ -580,7 +582,9 @@
      //correcting offsets
      PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
        READ_LONG ___#offset ___#current_off
-       WRITE_LONG ___#offset (___#current_off + 0x108)
+       PATCH_IF ___#current_off >= ___#fx_off BEGIN
+         WRITE_LONG ___#offset (___#current_off + 0x108)
+       END
      END
 
    //reset vars
@@ -624,13 +628,14 @@
  DEFINE_PATCH_MACRO ~DELETE_CRE_EFFECT~ BEGIN
    PATCH_IF (SOURCE_SIZE > 0x2c8) BEGIN
 
+     READ_BYTE 0x33  ___#fx_flag
      READ_LONG 0x2c4 ___#fx_off
      READ_LONG 0x2c8 ___#fx_num
      SET ___#delta = 0
      FOR (___#index1 = 0; ___#index1 < ___#fx_num; ___#index1 = ___#index1 + 1) BEGIN
-       READ_LONG (___#fx_off + ___#index1 * 0x108 + 0x8) ___#opcode
+       READ_LONG (___#fx_off + ___#index1 * (___#fx_flag = 1 ? 0x108 : 0x30) + (___#fx_flag = 1 ? 0x8 : 0x0)) ___#opcode
        PATCH_IF ((___#opcode = opcode_to_delete) OR (opcode_to_delete = (0 - 1))) BEGIN
-         DELETE_BYTES (___#fx_off + ___#index1 * 0x108) 0x108
+         DELETE_BYTES (___#fx_off + ___#index1 * (___#fx_flag = 1 ? 0x108 : 0x30)) ___#fx_flag = 1 ? 0x108 : 0x30
          SET ___#delta = ___#delta + 1 //track deleted number
          SET ___#fx_num = ___#fx_num - 1 //decrease effects number to stop cycle properly
          SET ___#index1 = ___#index1 - 1 //step back to not miss an effect
@@ -641,7 +646,9 @@
        WRITE_LONG 0x2c8 ___#fx_num //corrected earlier
        PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
          READ_LONG ___#offset ___#current_off
-         WRITE_LONG ___#offset (___#current_off - ___#delta * 0x108)
+         PATCH_IF ___#current_off > ___#fx_off BEGIN
+           WRITE_LONG ___#offset (___#current_off - ___#delta * (___#fx_flag = 1 ? 0x108 : 0x30))
+         END
        END
      END
 
@@ -667,8 +674,13 @@
          SET ___#itm_num = ___#itm_num - 1
          SET ___#delta = ___#delta + 1
 
-         //correct islot offset
-         WRITE_LONG 0x2b8 (___#islot_off - 0x14)
+         //correct offsets
+         PATCH_FOR_EACH ___#offset IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
+           READ_LONG ___#offset ___#current_off
+           PATCH_IF ___#current_off > ___#itm_off BEGIN
+             WRITE_LONG ___#offset (___#current_off - ___#delta * 0x14)
+           END
+         END
 
          FOR (___#cur_slot = 0; ___#cur_slot < 37; ___#cur_slot = ___#cur_slot + 1) BEGIN
            READ_LONG 0x2b8 ___#islot_off

The QP dragon will still CTD the game if you try to add an EFF to it, however, since it's eff offset is 0.

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Moderator
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: The CRE macros
« Reply #5 on: October 26, 2010, 05:22:17 PM »
Nope, I'm not at fault there. I've also added PATCH_IF check, which appears to be missing in 221.
Damn, I hate forgetting how to carefully read code  :(

This works:
Cheers.

Quote
The QP dragon will still CTD the game if you try to add an EFF to it, however, since it's eff offset is 0.
Is that something that should be fixed?
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 Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: The CRE macros
« Reply #6 on: October 26, 2010, 05:43:05 PM »
Quote
The QP dragon will still CTD the game if you try to add an EFF to it, however, since it's eff offset is 0.
Is that something that should be fixed?
There's some Nythrun-written creature-validity code that checks for bugs like that. I guess you could slap it into PATCH_INCLUDE it in the macros instead of that size check.

fj_cre_validity.tpp:
Code: [Select]
tmp_0 = 0x2d4
tmp_1 = 0x2d4
tmp_2 = 0x2d4
tmp_3 = 0
SPRINT m1 ~is corrupt~
SPRINT m2 ~below minimum length~
SPRINT m3 ~header misplaced~
SPRINT m4 ~extended structures point to header~
SPRINT sg ~CRE V1.0~
valid = 1
PATCH_IF ~%SOURCE_RES%~ STRING_EQUAL_CASE charbase BEGIN
  valid = 0
END ELSE BEGIN
  PATCH_IF SOURCE_SIZE < 0x2d4 BEGIN
    valid = 0
    PATCH_PRINT ~%SOURCE_FILE% %m1%: %m2%.~ //is corrupt: below minimum length
  END ELSE BEGIN
    READ_ASCII 0 sg
    PATCH_IF ~%sg%~ STR_CMP ~CRE V1.0~ BEGIN
      valid = 0
      PATCH_PRINT ~%SOURCE_FILE% %m1%: %m3%.~ //is corrupt: header misplaced
    END ELSE BEGIN
      DEFINE_ASSOCIATIVE_ARRAY cre_offset BEGIN
        0x2a0 => 0x2a4
        0x2a8 => 0x2ac
        0x2b0 => 0x2b4
        0x2b8 => 0x2c0
        0x2bc => 0x2c0
        0x2c4 => 0x2c8
      END
      PHP_EACH cre_offset AS tmp => tmp_1 BEGIN
        READ_LONG tmp_0 tmp_2
        READ_LONG tmp_1 tmp_3
        PATCH_IF tmp_3 = 0 && tmp_2 < 0x2d4 BEGIN
          WRITE_LONG tmp_0 0x2d4
        END
        PATCH_IF tmp_3 != 0 && tmp_2 < 0x2d4 BEGIN
          valid = 0
          PATCH_PRINT ~%SOURCE_FILE% %m1%: %m4%.~ //is corrupt: extended structures point to header
        END
      END
    END
  END
END

With
Code: [Select]
PATCH_IF (SOURCE_SIZE > 0x2c8) BEGIN being turned into
Code: [Select]
PATCH_IF valid BEGIN
« Last Edit: October 26, 2010, 05:50:38 PM by Wisp »

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Moderator
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: The CRE macros
« Reply #7 on: October 26, 2010, 07:22:14 PM »
Cheers.
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).

erik

  • Guest
Re: The CRE macros
« Reply #8 on: October 27, 2010, 12:19:12 PM »
WRITE_LONG seems a bit misplaced in pure validity-checking code, no? As a fixup, yes.

 

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)?: