Author Topic: More functions  (Read 7582 times)

Offline Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
More functions
« on: November 26, 2010, 12:00:19 PM »
Might as well include Nythrun's reindexing and v1->v2 EFF functions. I reversed the latter to provide BG1 conversion compatibility, should any rare modders want that.

fj_cre_reindex
Code: [Select]
DEFINE_PATCH_FUNCTION ~fj_cre_reindex~ BEGIN
  fv = 0
  kso = 0x2d4
  ksc = 0
  smo = 0x2d4
  smc = 0
  mso = 0x2d4
  msc = 0
  iso = 0x2d4
  ilo = 0x2d4
  ilc = 0
  elo = 0x2d4
  elc = 0
  i_0 = 0
  off_0 = 0
  off_1 = 0
  tmp_0 = 0
  tmp_1 = 0
  SPRINT ks fail
  SPRINT sm fail
  SPRINT ms fail
  SPRINT is fail
  SPRINT il fail
  SPRINT el fail
  READ_BYTE 0x33 fv //EFF version
  PATCH_IF (fv = 0) AND NOT (FILE_EXISTS_IN_GAME ~ar0125.are~) BEGIN
    LAUNCH_PATCH_FUNCTION ~fj_cre_eff_v2~ END
  END
  PATCH_IF (fv != 0) AND (FILE_EXISTS_IN_GAME ~ar0125.are~) BEGIN
    LAUNCH_PATCH_FUNCTION ~t-cre_eff_v1~ END
  END
  PATCH_IF FILE_EXISTS_IN_GAME ~fw0125.are~ BEGIN //Fix buggered Tutu refs
    FOR (s1 = 0xa4; s1 < 0x234; s1 += 0x4) BEGIN
      READ_LONG s1 ss //Soundslots
      PATCH_IF ss > 10000000 BEGIN
        WRITE_LONG s1 ~-1~
      END
    END
  END
  READ_LONG 0x2a0 kso //Known spells offset
  READ_LONG 0x2a4 ksc //Known spells count
  READ_LONG 0x2a8 smo //Spell memorization info offset
  READ_LONG 0x2ac smc //Spell memorization info count
  READ_LONG 0x2b0 mso //Memorized spells offset
  READ_LONG 0x2b4 msc //Memorized spells count
  READ_LONG 0x2b8 iso //Item slot offset
  READ_LONG 0x2bc ilo //Item offset
  READ_LONG 0x2c0 ilc //Item count
  READ_LONG 0x2c4 elo //Effects offset
  READ_LONG 0x2c8 elc //Effects count
  READ_ASCII kso ks ELSE fail (0xc * ksc)
  READ_ASCII smo sm ELSE fail (0x10 * smc)
  READ_ASCII mso ms ELSE fail (0xc * msc)
  READ_ASCII iso is ELSE fail (0x50)
  READ_ASCII ilo il ELSE fail (0x14 * ilc)
  READ_ASCII elo el ELSE fail (elc * (0x30 + ((fv & 0x1) = 0x1 ? 0xd8 : 0)))
  DELETE_BYTES 0x2d4 SOURCE_SIZE - 0x2d4
  off_0 = 0x2d4
  WRITE_LONG 0x2a0 off_0
  PATCH_IF ~%ks%~ STR_CMP fail BEGIN
    INSERT_BYTES off_0 0xc * ksc
    WRITE_ASCIIE off_0 ~%ks%~
  END ELSE BEGIN
    ksc = 0
    WRITE_LONG 0x2a4 ksc
  END
  off_0 += 0xc * ksc
  WRITE_LONG 0x2a8 off_0
  INSERT_BYTES off_0 0x10 * 0x11
  PATCH_IF ~%sm%~ STR_CMP fail && smc = 0x11 BEGIN
    WRITE_ASCIIE off_0 ~%sm%~
  END ELSE BEGIN
    FOR (i_0 = 0; i_0 < 7; i_0 += 1) BEGIN
      WRITE_SHORT off_0 + i_0 * 0x10 i_0
    END
    FOR (i_0 = 0; i_0 < 9; i_0 += 1) BEGIN
      WRITE_SHORT off_0 + i_0 * 0x10 + 0x70 i_0
      WRITE_SHORT off_0 + i_0 * 0x10 + 0x76 1
    END
    WRITE_SHORT off_0 + 0x106 0x2
    PATCH_IF ~%sm%~ STR_CMP fail BEGIN
      PATCH_IF smc > 0x11 BEGIN
        msc = 0
        SPRINT ms fail
      END ELSE PATCH_IF smc < 0x11 && smc > 0 BEGIN
        PATCH_IF STRING_LENGTH EVALUATE_BUFFER ~%sm%~ = 0x10 * smc BEGIN
          smc = 0x11
          WHILE STRING_LENGTH EVALUATE_BUFFER ~%sm%~ > 0 BEGIN
            off_1 = 0
            INNER_PATCH_SAVE sm ~%sm%~ BEGIN
              READ_SHORT 0 tmp_0
              off_1 += tmp_0 * 0x10
              READ_SHORT 6 tmp_0
              off_1 += 0x70 * tmp_0 + (tmp_0 = 0x2 ? 0x10 : 0)
              READ_SHORT 8 tmp_0
              READ_ASCII 0 tmp_1 (0x10)
              DELETE_BYTES 0 0x10
            END
            WRITE_ASCIIE off_0 + off_1 ~%tmp_1%~
            FOR (off_1 += 0x10; off_1 < 0x110; off_1 += 0x10) BEGIN
              WRITE_SHORT off_0 + off_1 + 0x8 tmp_0
            END
          END
        END ELSE BEGIN
          smc = 0x11
          msc = 0
          SPRINT ms fail
        END
      END
    END
  END
  off_0 += 0x110
  WRITE_LONG 0x2b0 off_0
  PATCH_IF ~%ms%~ STR_CMP fail && ~%sm%~ STR_CMP fail && smc = 0x11 BEGIN
    INSERT_BYTES off_0 0xc * msc
    WRITE_ASCIIE off_0 ~%ms%~
  END ELSE BEGIN
    msc = 0
    WRITE_LONG 0x2b4 msc
  END
  smc = 0x11
  WRITE_LONG 0x2ac smc
  off_0 += 0xc * msc
  WRITE_LONG 0x2c4 off_0
  PATCH_IF ~%el%~ STR_CMP fail BEGIN
    INSERT_BYTES off_0 (elc * (0x30 + (((fv & 0x1) = 0x1) ? 0xd8 : 0)))
    WRITE_ASCIIE off_0 ~%el%~
  END ELSE BEGIN
    elc = 0
    WRITE_LONG 0x2c8 elc
  END
  off_0 += (elc * (0x30 + (((fv & 0x1) = 0x1) ? 0xd8 : 0)))
  WRITE_LONG 0x2bc off_0
  PATCH_IF ~%il%~ STR_CMP fail BEGIN
    INSERT_BYTES off_0 (0x14 * ilc)
    WRITE_ASCIIE off_0 ~%il%~
  END ELSE BEGIN
    ilc = 0
    WRITE_LONG 0x2c0 ilc
  END
  off_0 += 0x14 * ilc
  WRITE_LONG 0x2b8 off_0
  INSERT_BYTES off_0 0x50
  PATCH_IF ~%is%~ STR_CMP fail BEGIN
    WRITE_ASCIIE off_0 ~%is%~
  END ELSE BEGIN
    FOR (i_0 = 0; i_0 < 0x4c; i_0 += 2) BEGIN
      WRITE_SHORT off_0 + i1 0xffff
    END
  END
  SOURCE_SIZE = off_0 + 0x50
END
fj_cre_eff_v2
Code: [Select]
DEFINE_PATCH_FUNCTION ~fj_cre_eff_v2~ BEGIN
  PATCH_IF BYTE_AT 0x33 != 1 BEGIN
    WRITE_BYTE 0x33 1
    READ_LONG 0x2c8 fc //Effects count
    PATCH_IF (fc > 0x0) BEGIN
      READ_LONG 0x2c4 fs //Effects offset
      READ_ASCII fs fx (0x30 * fc)
      PATCH_FOR_EACH f1 IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
        READ_LONG f1 f2
        WRITE_LONG f1 ((f2 > fs) ? (f2 + (fc * (0x108 - 0x30))) : (f2 < 0x2d4 ? 0x2d4 : f2))
      END
      DELETE_BYTES fs (0x30 * fc)
      INSERT_BYTES fs (0x108 * fc)
      SPRINT rfx ~~
      INNER_PATCH ~%fx%~ BEGIN
        FOR (i1 = 0; i1 < fc; i1 += 1) BEGIN
          SOURCE_SIZE += 0xd8
          READ_SHORT ((i1 * 0x30) + 0x00) pc //Opcode
          READ_BYTE  ((i1 * 0x30) + 0x02) tg //Target
          READ_BYTE  ((i1 * 0x30) + 0x03) pw //Power
          READ_LONG  ((i1 * 0x30) + 0x04) p1 //Parameter 1
          READ_LONG  ((i1 * 0x30) + 0x08) p2 //Parameter 2
          READ_BYTE  ((i1 * 0x30) + 0x0c) tm //Timing mode
          READ_BYTE  ((i1 * 0x30) + 0x0d) dp //Dispellability
          READ_LONG  ((i1 * 0x30) + 0x0e) dr //Duration
          READ_BYTE  ((i1 * 0x30) + 0x12) b1 //Probability 1
          READ_BYTE  ((i1 * 0x30) + 0x13) b2 //Probability 2
          READ_ASCII ((i1 * 0x30) + 0x14) rf //ResRef
          READ_LONG  ((i1 * 0x30) + 0x1c) dt //Dice thrown
          READ_LONG  ((i1 * 0x30) + 0x20) dz //Die size
          READ_LONG  ((i1 * 0x30) + 0x24) st //Save type
          READ_LONG  ((i1 * 0x30) + 0x28) sb //Save bonus
          INNER_PATCH_SAVE ~rfx~ ~%rfx%~ BEGIN
            INSERT_BYTES ((i1 * 0x108) + 0x00) 0x110
            WRITE_LONG   ((i1 * 0x108) + 0x10) pc
            WRITE_LONG   ((i1 * 0x108) + 0x14) tg
            WRITE_LONG   ((i1 * 0x108) + 0x18) pw
            WRITE_LONG   ((i1 * 0x108) + 0x1c) p1
            WRITE_LONG   ((i1 * 0x108) + 0x20) p2
            WRITE_BYTE   ((i1 * 0x108) + 0x24) tm
            WRITE_LONG   ((i1 * 0x108) + 0x28) dr
            WRITE_SHORT  ((i1 * 0x108) + 0x2c) b1
            WRITE_SHORT  ((i1 * 0x108) + 0x2e) b2
            WRITE_ASCIIE ((i1 * 0x108) + 0x30) ~%rf%~
            WRITE_LONG   ((i1 * 0x108) + 0x38) dt
            WRITE_LONG   ((i1 * 0x108) + 0x3c) dz
            WRITE_LONG   ((i1 * 0x108) + 0x40) st
            WRITE_LONG   ((i1 * 0x108) + 0x44) sb
            WRITE_BYTE   ((i1 * 0x108) + 0x5c) dp
            WRITE_LONG   ((i1 * 0x108) + 0x80) (`0)
            WRITE_LONG   ((i1 * 0x108) + 0x84) (`0)
            WRITE_LONG   ((i1 * 0x108) + 0x88) (`0)
            WRITE_LONG   ((i1 * 0x108) + 0x8c) (`0)
            WRITE_LONG   ((i1 * 0x108) + 0xa4) (`0)
            DELETE_BYTES ((i1 * 0x108) + 0x08) 8
          END
        END
      END
      WRITE_ASCIIE fs ~%rfx%~
    END
  END
END
t-cre_eff_v1
Code: [Select]
DEFINE_PATCH_FUNCTION ~t-cre_eff_v1~ BEGIN
  PATCH_IF BYTE_AT 0x33 != 0 BEGIN
    WRITE_BYTE 0x33 0
    READ_LONG 0x2c8 fc //Effects count
    PATCH_IF fc > 0 BEGIN
      READ_LONG 0x2c4 fs //Effects offset
      READ_ASCII fs fx (0x108 * fc)
      DELETE_BYTES fs (0x108 * fc)
      sz = 0 //Size to reduce
      SPRINT rfx ~~
      INNER_PATCH ~%fx%~ BEGIN
        FOR (i1 = 0; i1 < fc; i1 += 1) BEGIN
          READ_SHORT ((i1 * 0x108) + 0x08) pc //Opcode
          READ_BYTE  ((i1 * 0x108) + 0x0c) tg //Target
          READ_BYTE  ((i1 * 0x108) + 0x10) pw //Power
          READ_LONG  ((i1 * 0x108) + 0x14) p1 //Parameter 1
          READ_LONG  ((i1 * 0x108) + 0x18) p2 //Parameter 2
          READ_BYTE  ((i1 * 0x108) + 0x1c) tm //Timing mode
          READ_LONG  ((i1 * 0x108) + 0x20) dr //Duration
          READ_BYTE  ((i1 * 0x108) + 0x24) b1 //Probability 1
          READ_BYTE  ((i1 * 0x108) + 0x26) b2 //Probability 2
          READ_ASCII ((i1 * 0x108) + 0x28) rf //ResRef
          READ_LONG  ((i1 * 0x108) + 0x30) dt //Dice thrown
          READ_LONG  ((i1 * 0x108) + 0x34) dz //Die size
          READ_LONG  ((i1 * 0x108) + 0x38) st //Save type
          READ_LONG  ((i1 * 0x108) + 0x3c) sb //Save bonus
          READ_BYTE  ((i1 * 0x108) + 0x54) dp //Dispellability
          INNER_PATCH_SAVE rfx ~%rfx%~ BEGIN
            PATCH_IF pc < 191 BEGIN //If a valid BG1 opcode
              sz += 0xd8
              INSERT_BYTES ((i1 * 0x30) + 0x00) 0x30
              WRITE_SHORT  ((i1 * 0x30) + 0x00) pc
              WRITE_BYTE   ((i1 * 0x30) + 0x02) tg
              WRITE_BYTE   ((i1 * 0x30) + 0x03) pw
              WRITE_LONG   ((i1 * 0x30) + 0x04) p1
              WRITE_LONG   ((i1 * 0x30) + 0x08) p2
              WRITE_BYTE   ((i1 * 0x30) + 0x0c) tm
              WRITE_BYTE   ((i1 * 0x30) + 0x0d) dp
              WRITE_LONG   ((i1 * 0x30) + 0x0e) dr
              WRITE_BYTE   ((i1 * 0x30) + 0x12) b1
              WRITE_BYTE   ((i1 * 0x30) + 0x13) b2
              WRITE_ASCIIE ((i1 * 0x30) + 0x14) ~%rf%~
              WRITE_LONG   ((i1 * 0x30) + 0x1c) dt
              WRITE_LONG   ((i1 * 0x30) + 0x20) dz
              WRITE_LONG   ((i1 * 0x30) + 0x24) st
              WRITE_LONG   ((i1 * 0x30) + 0x28) sb
            END ELSE BEGIN
              sz += 0x108
              fc -= 1
            END
          END
        END
      END
      PATCH_FOR_EACH f1 IN 0x2a0 0x2a8 0x2b0 0x2b8 0x2bc BEGIN
        READ_LONG f1 f2
        WRITE_LONG f1 ((f2 > fs) ? (f2 - sz) : (f2 < 0x2d4 ? 0x2d4 : f2))
      END
      INSERT_BYTES fs (0x30 * fc)
      WRITE_ASCIIE fs ~%rfx%~
      WRITE_LONG 0x2c8 fc //Update effects count
      SOURCE_SIZE -= sz
    END
  END
END

Not much in the way of documentation, since I don't think any input or output variables are necessary.
Quote
\verb+fj_cre_reindex+: reorders creatures with nonstandard offset orders.\\
This is a PATCH function.

\verb+fj_cre_eff_v2+: Converts creatures using version 1 effects to version 2. Called by fj_cre_reindex automatically if relevant.\\
This is a PATCH function.

\verb+t-cre_eff_v1+: Converts creatures using version 2 effects to version 1. Called by fj_cre_reindex automatically if relevant.\\
This is a PATCH function.

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Moderator
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: More functions
« Reply #1 on: November 26, 2010, 03:44:42 PM »
I already rolled those into FJ_CRE_VALIDITY:

Code: [Select]
\verb+FJ_CRE_VALIDITY+: Checks whether a CRE file is well-formed or not, fixes some common bugs, and reports whether the CRE file is still broken or not. In particular:
\begin{itemize}
\item reports invalidity if it is charbase.cre, shorter than the minimum size, the signature mismatches, or a sub-structure has members and its offset is in the header.
\item if a empty sub-structure's offset is in the header, point them to the end of the header.
\item if the cre is valid, force it to use proper order (known spells, spell memorization info, memorized spells, effects, items, item slot).
\item forces the CRE file to use EFF V2 effects internally (or EFF V1 if on BG1).
\end{itemize}
This is a PATCH function.
\begin{itemize}
\item INT_VAR do_message to 1 if you want explicit an explicit message regarding the cre invalidity. Defaults to 0.
\item RET valid returns 1 if the CRE is well-formed, 0 otherwise.
\end{itemize}
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 Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
Re: More functions
« Reply #2 on: November 27, 2010, 06:38:00 AM »
Can you still call the subfunctions? There may be situations where you don't need or want to check validity or reorder CREs. For example, I've got a Tutu mod I want to make installable on BG1. The mod CREs are already ordered properly , so I just want to call t-cre_eff_v1 if the game is BG1 (and also call some Tutu-to-BG1/BGT resource conversion functions but I doubt those are too useful to other modders).

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Moderator
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: More functions
« Reply #3 on: November 27, 2010, 08:30:01 AM »
Sure. I prefer to have standard macros and functions to have upper-case names, though, to avoid potential conflicts.
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 GeN1e

  • Planewalker
  • *****
  • Posts: 267
  • Gender: Male
Re: More functions
« Reply #4 on: February 18, 2012, 07:21:29 PM »
I just saw there were other than me people who add headers to SPL/ITMs, so I thought the following may be useful? No documentation yet, but I guess v232 is not in a great hurry.

FJ_SPL_ITM_REINDEX - I think it is Nythrun's
CREATE_SPELL - mostly for 146/148/206 opcodes, not "real" spells
CREATE_EFFECT
ADD_ITEM_HEADER
ADD_SPELL_HEADER


Also, there're few issues with existing macros:
1) ADD_CRE_EFFECT
Code: [Select]
    WRITE_BYTE (___#fx_off + 0x58) parameter3
    WRITE_BYTE (___#fx_off + 0x59) parameter4
Must be
Code: [Select]
    WRITE_LONG (___#fx_off + 0x58) parameter3
    WRITE_LONG (___#fx_off + 0x5c) parameter4

2) ADD_SPELL_CFEFFECT simply calls the ADD_ITEM_EQEFFECT, which isn't suited to handle spl's 0x28 header size. There is no function of the same name btw.

Code: [Select]
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////


// found by Ardanis in Rogue Rebalancing, had apparently been written by Nythrun
// fixed two things, wrapped a function over it

DEFINE_PATCH_FUNCTION ~FJ_SPL_ITM_REINDEX~ BEGIN

PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.spl~) BEGIN
  hs = 0x28
  WRITE_LONG 0xc ~-1~ //Identified name
  WRITE_LONG 0x54 ~-1~ //Identified description
  PATCH_FOR_EACH tz IN 0x44 0x48 0x58 0x5c BEGIN
    WRITE_LONG tz 0
  END
END ELSE PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.itm~) BEGIN
  hs = 0x38
END
READ_LONG 0x64 hf //Extended header offset
READ_SHORT 0x68 hc //Extended header count
READ_LONG 0x6a fb //Feature block table offset
READ_SHORT 0x70 fc //Feature block count
PATCH_IF ((hf > fb) AND (hc > 0)) BEGIN // Ardanis: fixed "hc > 1" to "hc > 0"
  READ_ASCII hf ~eh~ ELSE ~fail~ (hs * hc)
  PATCH_IF (~%eh%~ STRING_EQUAL ~fail~) BEGIN
    WHILE ((~%eh%~ STRING_EQUAL ~fail~) AND (hc > 0)) BEGIN
      READ_ASCII hf ~eh~ ELSE ~fail~ (hs * hc)
      hc -= 1
    END
  END
  DELETE_BYTES hf (hs * hc)
  hf = 0x72
  WRITE_LONG 0x64 hf
  WRITE_SHORT 0x68 hc
  fb = (0x72 + (hs * hc))
  WRITE_LONG 0x6a fb
  PATCH_IF !(~%eh%~ STRING_EQUAL ~fail~) BEGIN
    INSERT_BYTES hf (hs * hc)
    WRITE_ASCIIE hf ~%eh%~
  END
END ELSE PATCH_IF ((hf != 0x72) AND (hc = 0)) BEGIN
  hf = 0x72
  WRITE_LONG 0x64 hf
END
FOR (i1 = 0; i1 < (hs * hc); i1 += hs) BEGIN
  WRITE_SHORT (hf + i1 + 0x20) fc
  READ_SHORT (hf + i1 + 0x1e) cx
  fc += cx
END
PATCH_IF (SOURCE_SIZE > (0x72 + (hs * hc) + (0x30 * fc))) BEGIN
  DELETE_BYTES (0x72 + (hs * hc) + (0x30 * fc)) (SOURCE_SIZE - (0x72 + (hs * hc) + (0x30 * fc)))
END

// added by Ardanis
WRITE_SHORT 0x6e 0

END // end of function

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

DEFINE_ACTION_FUNCTION ~CREATE_EFFECT~
  INT_VAR
    opcode=0
    target=0
    power=0
    parameter1=0
    parameter2=0
    timing=0
    duration=0
    probability1=100
    probability2=0
    dicenumber=0
    dicesize=0
    savingthrow=0
    savebonus=0
    resist_dispel=0
    parameter3=0
    parameter4=0
  STR_VAR
    effect=~ag#dummy~
    resource=~~
    vvcresource=~~
    resource2=~~
    effvar=~~
BEGIN
<<<<<<<<...inlined/ag#dummy.eff
>>>>>>>>
COPY ~...inlined/ag#dummy.eff~ ~override/%effect%.eff~
  INSERT_BYTES 0 0x110
  WRITE_ASCII 0 ~EFF V2.0~
  WRITE_ASCII 8 ~EFF V2.0~

  WRITE_LONG 0x10 opcode
  WRITE_LONG 0x14 target
  WRITE_LONG 0x18 power
  WRITE_LONG 0x1c parameter1
  WRITE_LONG 0x20 parameter2
  WRITE_SHORT 0x24 timing
  WRITE_LONG 0x28 duration
  WRITE_SHORT 0x2c probability1
  WRITE_SHORT 0x2e probability2
  WRITE_ASCIIE 0x30 ~%resource%~ (8)
  WRITE_LONG 0x38 dicenumber
  WRITE_LONG 0x3c dicesize
  WRITE_LONG 0x40 savingthrow
  WRITE_LONG 0x44 savebonus
  WRITE_LONG 0x5c resist_dispel
  WRITE_LONG 0x60 parameter3
  WRITE_LONG 0x64 parameter4
  WRITE_ASCIIE 0x70 ~%vvcresource%~ (8)
  WRITE_ASCIIE 0x78 ~%resource2%~ (8)
  WRITE_ASCIIE 0xa8 ~%effvar%~ (32)
END

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

DEFINE_ACTION_FUNCTION ~CREATE_SPELL~
  INT_VAR
    type=4
    level=1
    school=0
    sectype=0
    flags=0
  STR_VAR
    spell=~ag#dummy~
BEGIN
<<<<<<<<...inlined/ag#dummy.spl
>>>>>>>>
COPY ~...inlined/ag#dummy.spl~ ~override/%spell%.spl~
  INSERT_BYTES 0 0x72
  WRITE_ASCII 0 ~SPL V1  ~

  WRITE_LONG 0x18 flags
  WRITE_SHORT 0x1c type
  WRITE_SHORT 0x25 school
  WRITE_BYTE 0x27 sectype
  WRITE_LONG 0x34 level

  WRITE_LONG 0xc `0
  WRITE_LONG 0x54 `0
  WRITE_LONG 0x64 0x72
  WRITE_LONG 0x6a 0x72
END

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

DEFINE_PATCH_FUNCTION ~ADD_SPELL_HEADER~
  INT_VAR
    type=1
    location=4
    target=1
    target_count=0
    range=0
    required_level=1
    speed=0
    projectile=1

    copy_header=0
    insert_point=~-1~
  STR_VAR
    icon=~~
  RET
    insert_point
BEGIN
  LPF ~FJ_SPL_ITM_REINDEX~ END
  hs=0x28

  READ_LONG 0x64 ho
  READ_SHORT 0x68 hc
  READ_LONG 0x6a eo
  insert_point = (insert_point>hc || insert_point<0) ? hc : insert_point
  copy_header = (copy_header<0) ? 0 : copy_header

  PATCH_IF copy_header>hc BEGIN
    PATCH_WARN ~Unable to copy %copy_header%th header, %SOURCE_FILE% contains only %hc% headers!~
  END ELSE BEGIN
    INSERT_BYTES ho+insert_point*hs hs
    hc+=1
    eo+=hs
    PATCH_IF copy_header BEGIN
      READ_SHORT ho+(copy_header - 1)*hs+0x1e ec
      READ_SHORT ho+(copy_header - 1)*hs+0x20 ei
      READ_ASCII eo+ei*0x30 effs (ec*0x30)
      READ_ASCII ho+(copy_header - 1)*hs copy (hs)
      WRITE_ASCIIE ho+insert_point*hs ~%copy%~ (hs)
    END
    WRITE_SHORT 0x68 hc
    WRITE_LONG 0x6a eo

    READ_SHORT 0x70 ei // technically, it is a counter
    FOR (i=ho;i<ho+hc*hs;i+=hs) BEGIN
      READ_SHORT i+0x1e ec
      WRITE_SHORT i+0x20 ei
      ei+=ec
    END

    PATCH_IF copy_header BEGIN
      READ_SHORT ho+insert_point*hs+0x1e ec
      READ_SHORT ho+insert_point*hs+0x20 ei
      INSERT_BYTES eo+ei*0x30 ec*0x30
      WRITE_ASCIIE eo+ei*0x30 ~%effs%~ (ec*0x30)
    END ELSE BEGIN
      off=ho+insert_point*hs
      WRITE_BYTE off type
      WRITE_BYTE off+0x2 location
      WRITE_ASCIIE off+0x4 ~%icon%~ (8)
      WRITE_BYTE off+0xc target
      WRITE_BYTE off+0xd target_count
      WRITE_SHORT off+0xe range
      WRITE_SHORT off+0x10 required_level
      WRITE_LONG off+0x12 speed
      WRITE_SHORT off+0x26 projectile
    END
  END
END

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

DEFINE_PATCH_FUNCTION ~ADD_ITEM_HEADER~
  INT_VAR
    type=3
    required_id=0
    location=3
    alt_dicesize=0
    target=1
    target_count=0
    range=0
    projectile_type=0
    alt_dicenumber=0
    speed=0
    alt_damage=0
    thaco=0
    dicesize=0
    school=0
    dicenumber=0
    sectype=0
    damage=0
    damage_type=0
    charges=0
    depletion=0
    flags=0
    projectile=1
    overhand=0
    backhand=0
    thrust=0
    is_bow=0
    is_xbow=0
    is_sling=0

    copy_header=0
    insert_point=~-1~
  STR_VAR
    icon=~~
  RET
    insert_point
BEGIN
  LPF ~FJ_SPL_ITM_REINDEX~ END
  hs=0x38

  READ_LONG 0x64 ho
  READ_SHORT 0x68 hc
  READ_LONG 0x6a eo
  insert_point = (insert_point>hc || insert_point<0) ? hc : insert_point
  copy_header = (copy_header<0) ? 0 : copy_header

  PATCH_IF copy_header>hc BEGIN
    PATCH_WARN ~Unable to copy %copy_header%th header, %SOURCE_FILE% contains only %hc% headers!~
  END ELSE BEGIN
    INSERT_BYTES ho+insert_point*hs hs
    hc+=1
    eo+=hs
    PATCH_IF copy_header BEGIN
      READ_SHORT ho+(copy_header - 1)*hs+0x1e ec
      READ_SHORT ho+(copy_header - 1)*hs+0x20 ei
      READ_ASCII eo+ei*0x30 effs (ec*0x30)
      READ_ASCII ho+(copy_header - 1)*hs copy (hs)
      WRITE_ASCIIE ho+insert_point*hs ~%copy%~ (hs)
    END
    WRITE_SHORT 0x68 hc
    WRITE_LONG 0x6a eo

    READ_SHORT 0x70 ei // technically, it is a counter
    FOR (i=ho;i<ho+hc*hs;i+=hs) BEGIN
      READ_SHORT i+0x1e ec
      WRITE_SHORT i+0x20 ei
      ei+=ec
    END

    PATCH_IF copy_header BEGIN
      READ_SHORT ho+insert_point*hs+0x1e ec
      READ_SHORT ho+insert_point*hs+0x20 ei
      INSERT_BYTES eo+ei*0x30 ec*0x30
      WRITE_ASCIIE eo+ei*0x30 ~%effs%~ (ec*0x30)
    END ELSE BEGIN
      off=ho+insert_point*hs
      WRITE_BYTE off type
      WRITE_BYTE off+0x1 required_id
      WRITE_BYTE off+0x2 location
      WRITE_BYTE off+0x3 alt_dicesize
      WRITE_ASCIIE off+0x4 ~%icon%~ (8)
      WRITE_BYTE off+0xc target
      WRITE_BYTE off+0xd target_count
      WRITE_SHORT off+0xe range
      WRITE_BYTE off+0x10 projectile_type
      WRITE_BYTE off+0x11 alt_dicenumber
      WRITE_BYTE off+0x12 speed
      WRITE_BYTE off+0x13 alt_damage
      WRITE_SHORT off+0x14 thaco
      WRITE_BYTE off+0x16 dicesize
      WRITE_BYTE off+0x17 school
      WRITE_BYTE off+0x18 dicenumber
      WRITE_BYTE off+0x19 sectype
      WRITE_SHORT off+0x1a damage
      WRITE_SHORT off+0x1c damage_type
      WRITE_SHORT off+0x22 charges
      WRITE_SHORT off+0x24 depletion
      WRITE_LONG off+0x26 flags
      WRITE_SHORT off+0x2a projectile
      WRITE_SHORT off+0x2c overhand
      WRITE_SHORT off+0x2e backhand
      WRITE_SHORT off+0x30 thrust
      WRITE_SHORT off+0x32 is_bow
      WRITE_SHORT off+0x34 is_xbow
      WRITE_SHORT off+0x36 is_sling
    END
  END
END

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
« Last Edit: January 16, 2013, 05:16:15 PM by GeN1e »

Offline Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
Re: More functions
« Reply #5 on: February 25, 2012, 01:35:34 PM »
I just saw there were other than me people who add headers to SPL/ITMs, so I thought the following may be useful?

ADD_ITEM_HEADER
ADD_SPELL_HEADER
Apparently, you saw what I did in BP. Since items and spells are substantially the same format except for the header size, why not just do what I did and combine them into one function? Easier to do maintenance on one than two.
Code: [Select]
DEFINE_PATCH_FUNCTION t-add_spl_itm_header
  INT_VAR
  t-headers   = 1
  t-copy      = 1
  //Header variables
  t-atk_type  = 0
  t-id_req    = 0
  t-use_loc   = 1
  t-adie_size = 0
  t-hdr_targ  = 1
  t-targ_num  = 0
  t-range     = 30
  t-level     = 0
  t-adice     = 0
  t-speed     = 0
  t-adm_bonus = 0
  t-hit_bonus = 0
  t-hdie_size = 0
  t-pri_type  = 0
  t-hdice     = 0
  t-sec_type  = 0
  t-dmg_bonus = 0
  t-dmg_type  = 4
  t-charges   = 0
  t-deplete   = 0
  t-flags     = 0b0000000000000001
  t-projectl  = 1
  t-melee1    = 100
  t-melee2    = 0
  t-melee3    = 0
  t-bow       = 0
  t-xbow      = 0
  t-sling     = 0
  //Effect variables
  t-opcode    = 0
  t-eff_targ  = 2
  t-power     = 0
  t-param1    = 0
  t-param2    = 0
  t-timing    = 1
  t-dispel    = 2
  t-duration  = 0
  t-prob1     = 100
  t-prob2     = 0
  t-fdie_size = 0
  t-fdice     = 0
  t-sav_throw = 0
  t-sav_bonus = 0
  t-tool_1    = ` 0
  t-tool_2    = ` 0
  t-tool_3    = ` 0
  STR_VAR
  t-bam       = ~~
  t-resref    = ~~
  RET
  t-tool_1
  t-tool_2
  t-tool_3
BEGIN
  READ_LONG 0x64  t-hdr_off
  READ_SHORT 0x68 t-hdr_num
  READ_LONG 0x6a  t-eq_off
  PATCH_IF (~%SOURCE_EXT%~ STRING_EQUAL_CASE ~spl~ = 1) BEGIN
    t-hdr_size = 0x28
    t-proj_off = 0x26
    WRITE_LONG 0xc (0 - 1)
    WRITE_LONG 0x54 (0 - 1)
    PATCH_FOR_EACH t-junk IN 0x44 0x48 0x58 0x5c BEGIN
      WRITE_LONG t-junk 0
    END
  END ELSE BEGIN
    t-hdr_size = 0x38
    t-proj_off = 0x2a
    PATCH_IF t-copy = 1 BEGIN
      t-hdr_read = t-hdr_size * (t-hdr_num - 1) + t-hdr_off
      READ_SHORT (t-hdr_read + 0x26) t-flags
      READ_SHORT (t-hdr_read + 0x2c) t-melee1
      READ_SHORT (t-hdr_read + 0x2e) t-melee2
      READ_SHORT (t-hdr_read + 0x30) t-melee3
      READ_SHORT (t-hdr_read + 0x32) t-bow
      READ_SHORT (t-hdr_read + 0x34) t-xbow
      READ_SHORT (t-hdr_read + 0x36) t-sling
    END
  END
  PATCH_IF ((t-copy = 1) AND (t-hdr_num > 0)) BEGIN
    t-hdr_read = t-hdr_size * (t-hdr_num - 1) + t-hdr_off
    PATCH_IF t-atk_type = 0 BEGIN
      READ_BYTE t-hdr_off t-atk_type
    END
    READ_BYTE (t-hdr_read + 1) t-id_req
    READ_BYTE (t-hdr_read + 2) t-use_loc
    READ_BYTE (t-hdr_read + 3) t-adie_size
    READ_ASCII (t-hdr_read + 4) t-bam
    READ_BYTE (t-hdr_read + 0xc) t-hdr_targ
    READ_BYTE (t-hdr_read + 0xd) t-targ_num
    READ_SHORT (t-hdr_read + 0xe) t-range
    PATCH_IF t-level = 0 BEGIN
      READ_BYTE (t-hdr_read + 0x10) t-level
    END
    READ_BYTE (t-hdr_read + 0x11) t-adice
    READ_BYTE (t-hdr_read + 0x12) t-speed
    READ_BYTE (t-hdr_read + 0x13) t-adm_bonus
    READ_SHORT (t-hdr_read + 0x14) t-hit_bonus
    READ_BYTE (t-hdr_read + 0x16) t-hdie_size
    READ_BYTE (t-hdr_read + 0x17) t-pri_type
    READ_BYTE (t-hdr_read + 0x18) t-hdice
    READ_BYTE (t-hdr_read + 0x19) t-sec_type
    READ_SHORT (t-hdr_read + 0x1a) t-dmg_bonus
    READ_SHORT (t-hdr_read + 0x1c) t-dmg_type
    READ_SHORT (t-hdr_read + 0x1e) t-eff_num
    READ_SHORT (t-hdr_read + 0x20) t-eff_off
    READ_SHORT (t-hdr_read + 0x22) t-charges
    READ_SHORT (t-hdr_read + 0x24) t-deplete
    READ_SHORT (t-hdr_read + t-proj_off) t-projectl
    INSERT_BYTES (t-eq_off + 0x30 * (t-eff_num + t-eff_off)) (t-headers * t-eff_num * 0x30) //New effects
  END ELSE BEGIN
    READ_SHORT 0x70 t-eff_num
    t-eff_off = t-eq_off
  END
  INSERT_BYTES (t-hdr_off + (t-hdr_size * t-hdr_num)) (t-headers * t-hdr_size) //New headers
  WRITE_SHORT 0x68 (t-hdr_num + t-headers) //Update header count
  t-eq_off = t-hdr_off + (t-hdr_num + t-headers) * t-hdr_size
  WRITE_LONG 0x6a t-eq_off //Update equipping effect offset
  FOR (t-hdr_cycle = t-hdr_num; t-hdr_cycle < (t-hdr_num + t-headers); t-hdr_cycle += 1) BEGIN
    t-hdr_write = t-hdr_size * t-hdr_cycle + t-hdr_off
    WRITE_BYTE t-hdr_write t-atk_type //Attack type
    PATCH_IF t-atk_type = 2 BEGIN
      SET $t-tool(~%t-hdr_cycle%~) = 15527 //Thrown
    END ELSE BEGIN
      PATCH_IF t-atk_type = 1 BEGIN
        SET $t-tool(~%t-hdr_cycle%~) = 15529 //Melee
      END
    END
    WRITE_BYTE (t-hdr_write + 1) t-id_req
    WRITE_BYTE (t-hdr_write + 2) t-use_loc
    WRITE_BYTE (t-hdr_write + 3) t-adie_size
    WRITE_ASCIIE (t-hdr_write + 4) ~%t-bam%~ #8
    WRITE_BYTE (t-hdr_write + 0xc) t-hdr_targ
    WRITE_BYTE (t-hdr_write + 0xd) t-targ_num
    WRITE_SHORT (t-hdr_write + 0xe) t-range
    WRITE_BYTE (t-hdr_write + 0x10) t-level
    WRITE_BYTE (t-hdr_write + 0x11) t-adice
    WRITE_BYTE (t-hdr_write + 0x12) t-speed
    WRITE_BYTE (t-hdr_write + 0x13) t-adm_bonus
    WRITE_SHORT (t-hdr_write + 0x14) t-hit_bonus
    WRITE_BYTE (t-hdr_write + 0x16) t-hdie_size
    WRITE_BYTE (t-hdr_write + 0x17) t-pri_type
    WRITE_BYTE (t-hdr_write + 0x18) t-hdice
    WRITE_BYTE (t-hdr_write + 0x19) t-sec_type
    WRITE_SHORT (t-hdr_write + 0x1a) t-dmg_bonus
    WRITE_SHORT (t-hdr_write + 0x1c) t-dmg_type
    WRITE_SHORT (t-hdr_write + 0x1e) t-eff_num
    WRITE_SHORT (t-hdr_write + 0x20) (t-eff_off + t-eff_num * t-headers)
    WRITE_SHORT (t-hdr_write + 0x22) t-charges
    WRITE_SHORT (t-hdr_write + 0x24) t-deplete
    WRITE_SHORT (t-hdr_write + t-proj_off) t-projectl
    PATCH_IF (~%SOURCE_EXT%~ STRING_EQUAL_CASE ~itm~ = 1) BEGIN
      WRITE_SHORT (t-hdr_write + 0x26) t-flags
      WRITE_SHORT (t-hdr_write + 0x2c) t-melee1
      WRITE_SHORT (t-hdr_write + 0x2e) t-melee2
      WRITE_SHORT (t-hdr_write + 0x30) t-melee3
      WRITE_SHORT (t-hdr_write + 0x32) t-bow
      WRITE_SHORT (t-hdr_write + 0x34) t-xbow
      WRITE_SHORT (t-hdr_write + 0x36) t-sling
    END
    PATCH_IF t-copy = 1 BEGIN
      FOR (t-eff_cycle = t-eff_off; t-eff_cycle < (t-eff_off + t-eff_num); t-eff_cycle += 1) BEGIN
        t-eff_read = t-eq_off + t-eff_cycle * 0x30
        READ_SHORT t-eff_read t-opcode
        READ_BYTE (t-eff_read + 2) t-eff_targ
        READ_BYTE (t-eff_read + 3) t-power
        READ_LONG (t-eff_read + 4) t-param1
        READ_LONG (t-eff_read + 8) t-param2
        READ_BYTE (t-eff_read + 0xc) t-timing
        READ_BYTE (t-eff_read + 0xd) t-dispel
        READ_LONG (t-eff_read + 0xe) t-duration
        PATCH_IF (t-duration = 0) AND (t-timing = 0) BEGIN //If bogus duration
          t-timing = 1 //Make it instantaneous
          WRITE_BYTE (t-eff_read + 0xc) t-timing
        END
        READ_BYTE (t-eff_read + 0x12) t-prob1
        READ_BYTE (t-eff_read + 0x13) t-prob2
        READ_ASCII (t-eff_read + 0x14) t-resref
        READ_LONG (t-eff_read + 0x1c) t-fdice
        READ_LONG (t-eff_read + 0x20) t-fdie_size
        READ_LONG (t-eff_read + 0x24) t-sav_throw
        READ_LONG (t-eff_read + 0x28) t-sav_bonus
        t-eff_write = t-eq_off + (t-eff_cycle + t-eff_num) * 0x30
        WRITE_SHORT t-eff_write t-opcode
        WRITE_BYTE (t-eff_write + 2) t-eff_targ
        WRITE_BYTE (t-eff_write + 3) t-power
        WRITE_LONG (t-eff_write + 4) t-param1
        WRITE_LONG (t-eff_write + 8) t-param2
        WRITE_BYTE (t-eff_write + 0xc) t-timing
        WRITE_BYTE (t-eff_write + 0xd) t-dispel
        WRITE_LONG (t-eff_write + 0xe) t-duration
        WRITE_BYTE (t-eff_write + 0x12) t-prob1
        WRITE_BYTE (t-eff_write + 0x13) t-prob2
        WRITE_ASCIIE (t-eff_write + 0x14) ~%t-resref%~ #8
        WRITE_LONG (t-eff_write + 0x1c) t-fdice
        WRITE_LONG (t-eff_write + 0x20) t-fdie_size
        WRITE_LONG (t-eff_write + 0x24) t-sav_throw
        WRITE_LONG (t-eff_write + 0x28) t-sav_bonus
      END
    END
  END
END
I noticed some other defects in the functions. I'll post another topic with diffs so the changes don't get buried here. Might make it easier for the bigg, whenever he gets back from holiday, prison camp or wherever he is.

Offline plainab

  • Sasha al'Therin
  • Planewalker
  • *****
  • Posts: 491
    • Infinity Engine Modding
Re: More functions
« Reply #6 on: February 25, 2012, 04:50:49 PM »
Quote
I noticed some other defects in the functions. I'll post another topic with diffs so the changes don't get buried here. Might make it easier for the bigg, whenever he gets back from holiday, prison camp or wherever he is.
You know he'll tell you to use GIT, make a fork and make the changes yourself...  :P
My working mods:
an AI Party Script for BG2 game engine DOWNLOAD LINK ONLY!
Interactive Tweaks for BG series with some IWD support. DOWNLOAD LINK ONLY!
Rest For 8 Hours an IWD mod
-------------------------------------------
My contributions: BG1Fixpack, BG1Tweaks
On Hold: Solestia an NPC for SOA
-------------------------------------------
My website: http://sasha-altherin.webs.com

Offline Galactygon

  • Modding since 2002
  • Planewalker
  • *****
  • Posts: 378
  • Gender: Male
  • Creator of spells
Re: More functions
« Reply #7 on: February 26, 2012, 07:47:49 AM »
I have written a series of macros that work as a search function for spell and item effects, so one could dynamically look for certain effects, and then do any of the following: add, change, or delete new effects. One major feature that I also have written is their ability to insert effects anywhere in the effects list.

The drawback is that the execution of these macros is slow during install.

I would be more than happy to contribute, and I would like to see some sort of community standard with regards to having a powerful and effective way to deal with finding, adding, deleting, and duplicating effects from spells/items. If you download SpellPack, much of the code can be found in SpellPackB6/Macros/spl_itm_effect.tph.

-Galactygon

Offline the bigg

  • The Avatar of Fighter / Thieves
  • Moderator
  • Planewalker
  • *****
  • Posts: 3804
  • Gender: Male
Re: More functions
« Reply #8 on: April 08, 2012, 04:08:45 PM »
What functions (if any) should I add? Can you provide documentation for those?
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 Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
Re: More functions
« Reply #9 on: April 08, 2012, 10:44:31 PM »
Might as well add FJ_SPL_ITM_REINDEX since it isn't big. I haven't used it frequently but there is some infrequent usage, and it isn't huge. Offhand I can't say whether GeN1e's functions are useful or tested. Should definitely add some version of add_spell/item_header. The one I posted appears to be somewhat more comprehensive than GeN1e's and also combines both spell and item editing to reduce maintenance. Also, it's in use in some mods in final beta testing, and appears to work. I guess I could produce documentation (eventually) - lack of that has never stopped WeiDU heh. The parameters are mainly just references to IESDP values.

Edit: in response to Galactygon, I would be suspicious of any WeiDU functions that are notably "slow during install" unless you're calling them 100s or 1000s of times. Even fj_are_structure being the monster it is takes less than a second or so per call. Might want to double-check the code. Most of the functionality is already available, with the exception of being able to change effects. I do have some similar functions as perhaps does plainab but would have to double-check them.
« Last Edit: April 08, 2012, 10:48:22 PM by Miloch »

Offline Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
Re: More functions
« Reply #10 on: October 25, 2012, 03:46:50 PM »
This should be changed in fj_cre_validity.tpa:
Code: [Select]
  PATCH_IF (fv = 0) AND NOT (FILE_EXISTS_IN_GAME ~ar0125.are~) BEGIN
    LAUNCH_PATCH_FUNCTION ~fj_cre_eff_v2~ END
  END
  PATCH_IF (fv != 0) AND (FILE_EXISTS_IN_GAME ~ar0125.are~) BEGIN
    LAUNCH_PATCH_FUNCTION ~t-cre_eff_v1~ END
  END
To:
Code: [Select]
  PATCH_IF (fv = 0) AND NOT (GAME_IS ~bg1 totsc~) BEGIN
    LAUNCH_PATCH_FUNCTION FJ_CRE_EFF_V2 END
  END
  PATCH_IF (fv != 0) AND (GAME_IS ~bg1 totsc~) BEGIN
    LAUNCH_PATCH_FUNCTION T-CRE_EFF_V1 END
  END
Otherwise, it will convert BGEE CREs to v1 EFFs, which is an epic fail.

While we're at it, we should implement a GAME_IS ~bgee~ check (look for oh2010.are or the like). [Edit: also means GAME_IS ~bg1~ and ~totsc~ need to include && not ~bgee~ or the above will make no difference.]

Edit: oh and as I think I mentioned elsewhere, all references to the functions need to be uppercased or they'll fail (there's at least one t-CRE_EFF_V1 somewhere else I think).
« Last Edit: October 27, 2012, 03:39:19 PM by Miloch »

Offline CamDawg

  • Infidel
  • Planewalker
  • *****
  • Posts: 859
  • Dreaming of a red Xmas
    • The Gibberlings Three
Re: More functions
« Reply #11 on: November 01, 2012, 11:38:58 AM »
If we're suggesting functions, here's a bunch I've been using for lazy IWD/BGEE fixpack patching. I'll happily write up docs if they get included:

Code: [Select]
DEFINE_PATCH_FUNCTION cd_convert_bg_iwd_durations BEGIN

  READ_LONG  0x6a fx_off
  READ_LONG  0x64 abil_off
  READ_SHORT 0x68 abil_num
  PATCH_IF ("%SOURCE_FILE%" STRING_COMPARE_REGEXP "^.+\.itm" = 0) BEGIN SET abil_length = 0x38 END ELSE BEGIN SET abil_length = 0x28 END
  PATCH_IF (abil_num > 0) BEGIN // if there are headers, figure out the final effect
    READ_SHORT (abil_off + 0x1e + ((abil_num - 1) * abil_length)) abil_fx_num
    READ_SHORT (abil_off + 0x20 + ((abil_num - 1) * abil_length)) abil_fx_idx
    SET fx_num = abil_fx_num + abil_fx_idx
  END ELSE BEGIN // else read the last global
    READ_SHORT 0x70 fx_num
  END
  FOR (index = 0 ; index < fx_num ; ++index) BEGIN
    READ_LONG (fx_off + 0x0e + (index * 0x30)) duration
    PATCH_IF (duration > 5) BEGIN // skip 0 duration or short lived cosmetic/auditory
      WRITE_LONG (fx_off + 0x0e + (index * 0x30)) ((duration * 7) / 6)
    END
  END

END

/////                                                  \\\\\
///// area functions                                   \\\\\
/////                                                  \\\\\

DEFINE_PATCH_FUNCTION cd_area_alter_entrance
  INT_VAR x_coord = "-1" // negative values not written
          y_coord = "-1" // negative values not written
          orient  = "-1" // negative values not written
  STR_VAR entry_name = ""
BEGIN

  READ_LONG  0x68 ent_off
  READ_LONG  0x6c ent_num
  FOR (index = 0 ; index < ent_num ; ++index) BEGIN
    READ_ASCII (ent_off +        (index * 0x68)) "ent_name" (32) NULL
    PATCH_IF ("%ent_name%" STRING_COMPARE_REGEXP  "%entry_name%" = 0) BEGIN
      PATCH_IF ("%x_coord%" >= 0) BEGIN WRITE_SHORT (ent_off + 0x20 + (index * 0x68)) "%x_coord%" END
      PATCH_IF ("%y_coord%" >= 0) BEGIN WRITE_SHORT (ent_off + 0x22 + (index * 0x68)) "%y_coord%" END
      PATCH_IF ("%orient%" >= 0)  BEGIN WRITE_LONG  (ent_off + 0x24 + (index * 0x68)) "%orient%" END
    END
  END

END

DEFINE_PATCH_FUNCTION cd_area_alter_triggers
  INT_VAR type        = "-1"
          cursor      = "-1"
          trap_detect = "-1"
          trap_remove = "-1"
          trapped     = "-1"
          detected    = "-1"
          flag_locked           = "-1"
          flag_resets           = "-1"
          flag_party_required   = "-1"
          flag_trap_detectable  = "-1"
          flag_trap_enemies     = "-1"
          flag_tutorial         = "-1"
          flag_trap_npcs        = "-1"
          flag_silent           = "-1"
          flag_deactivated      = "-1"
          flag_impassable_npc   = "-1"
          flag_activation_point = "-1"
          flag_connect_to_door  = "-1"
  STR_VAR trig_name   = ""
          dest_area   = "same"
          ent_name    = "same"
          door_key    = "same"
          door_script = "same"
BEGIN

  READ_SHORT 0x5a trig_num
  READ_LONG  0x5c trig_off
  FOR (index = 0 ; index < trig_num ; ++index) BEGIN
    READ_ASCII (trig_off +        (index * 0xc4)) "trig_name_file" (32) NULL
    PATCH_IF ("%trig_name%" STRING_COMPARE_REGEXP  "%trig_name_file%" = 0) BEGIN
      PATCH_IF ("%type%" >= 0)        BEGIN WRITE_SHORT (trig_off + 0x20 + (index * 0xc4)) "%type%"        END
      PATCH_IF ("%cursor%" >= 0)      BEGIN WRITE_LONG  (trig_off + 0x34 + (index * 0xc4)) "%cursor%"      END
      PATCH_IF ("%trap_detect%" >= 0) BEGIN WRITE_SHORT (trig_off + 0x68 + (index * 0xc4)) "%trap_detect%" END
      PATCH_IF ("%trap_remove%" >= 0) BEGIN WRITE_SHORT (trig_off + 0x6a + (index * 0xc4)) "%trap_remove%" END
      PATCH_IF ("%trapped%" >= 0)     BEGIN WRITE_SHORT (trig_off + 0x6c + (index * 0xc4)) "%trapped%"     END
      PATCH_IF ("%detected%" >= 0)    BEGIN WRITE_SHORT (trig_off + 0x6e + (index * 0xc4)) "%detected%"    END
      PATCH_IF ("%flag_locked%" = 0)           BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11111110) END
      PATCH_IF ("%flag_resets%" = 0)           BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11111101) END
      PATCH_IF ("%flag_party_required%" = 0)   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11111011) END
      PATCH_IF ("%flag_trap_detectable%" = 0)  BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11110111) END
      PATCH_IF ("%flag_trap_enemies%" = 0)     BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11101111) END
      PATCH_IF ("%flag_tutorial%" = 0)         BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b11011111) END
      PATCH_IF ("%flag_trap_npcs%" = 0)        BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b10111111) END
      PATCH_IF ("%flag_silent%" = 0)           BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BAND 0b01111111) END
      PATCH_IF ("%flag_deactivated%" = 0)      BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11111110) END
      PATCH_IF ("%flag_impassable_npc%" = 0)   BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11111101) END
      PATCH_IF ("%flag_activation_point%" = 0) BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11111011) END
      PATCH_IF ("%flag_connect_to_door%" = 0)  BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BAND 0b11110111) END
      PATCH_IF ("%flag_locked%" = 1)           BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT0) END
      PATCH_IF ("%flag_resets%" = 1)           BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT1) END
      PATCH_IF ("%flag_party_required%" = 1)   BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT2) END
      PATCH_IF ("%flag_trap_detectable%" = 1)  BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT3) END
      PATCH_IF ("%flag_trap_enemies%" = 1)     BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT4) END
      PATCH_IF ("%flag_tutorial%" = 1)         BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT5) END
      PATCH_IF ("%flag_trap_npcs%" = 1)        BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT6) END
      PATCH_IF ("%flag_silent%" = 1)           BEGIN WRITE_BYTE (trig_off + 0x60 + (index * 0xc4)) (THIS BOR BIT7) END
      PATCH_IF ("%flag_deactivated%" = 1)      BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT0) END
      PATCH_IF ("%flag_impassable_npc%" = 1)   BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT1) END
      PATCH_IF ("%flag_activation_point%" = 1) BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT2) END
      PATCH_IF ("%flag_connect_to_door%" = 1)  BEGIN WRITE_BYTE (trig_off + 0x61 + (index * 0xc4)) (THIS BOR BIT3) END
      PATCH_IF ("%dest_area%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (trig_off + 0x38 + (index * 0xc4)) "%dest_area%" #8 // value from str_var
      END
      PATCH_IF ("%ent_name%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (trig_off + 0x40 + (index * 0xc4)) "%ent_name%" #32 // value from str_var
      END
      PATCH_IF ("%door_key%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (trig_off + 0x74 + (index * 0xc4)) "%door_key%" #8 // value from str_var
      END
      PATCH_IF ("%door_script%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (trig_off + 0x7c + (index * 0xc4)) "%door_script%" #8 // value from str_var
      END
    END
  END

END
 
DEFINE_PATCH_FUNCTION cd_area_alter_cre
  INT_VAR x_coord = "-1"
          y_coord = "-1"
          orient  = "-1"
  STR_VAR cre_name         = ""
          dlg_file         = "same"
          script_override  = "same"
          script_general   = "same"
          script_class     = "same"
          script_race      = "same"
          script_default   = "same"
          script_specifics = "same"
          cre_file         = "same"
BEGIN

  READ_LONG  0x54 cre_off
  READ_SHORT 0x58 cre_num
  FOR (index = 0 ; index < cre_num ; ++index) BEGIN
    READ_ASCII (cre_off +        (index * 0x110)) cre_name_file (32) NULL
    PATCH_IF ("%cre_name%" STRING_COMPARE_CASE "%cre_name_file%" = 0) BEGIN
      PATCH_IF ("%x_coord%" >= 0) BEGIN WRITE_SHORT (cre_off + 0x20 + (index * 0x110)) "%x_coord%"
                                        WRITE_SHORT (cre_off + 0x24 + (index * 0x110)) "%x_coord%" END
      PATCH_IF ("%y_coord%" >= 0) BEGIN WRITE_SHORT (cre_off + 0x22 + (index * 0x110)) "%y_coord%"
                                        WRITE_SHORT (cre_off + 0x26 + (index * 0x110)) "%y_coord%" END
      PATCH_IF ("%orient%" >= 0)  BEGIN WRITE_SHORT (cre_off + 0x34 + (index * 0x110)) "%orient%" END
      PATCH_IF ("%dlg_file%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x48 + (index * 0x110)) "%dlg_file%" #8 // value from str_var
      END
      PATCH_IF ("%script_override%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x50 + (index * 0x110)) "%script_override%" #8 // value from str_var
      END
      PATCH_IF ("%script_general%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x58 + (index * 0x110)) "%script_general%" #8 // value from str_var
      END
      PATCH_IF ("%script_race%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x68 + (index * 0x110)) "%script_race%" #8 // value from str_var
      END
      PATCH_IF ("%script_default%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x70 + (index * 0x110)) "%script_default%" #8 // value from str_var
      END
      PATCH_IF ("%script_class%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x60 + (index * 0x110)) "%script_class%" #8 // value from str_var
      END
      PATCH_IF ("%script_specifics%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x78 + (index * 0x110)) "%script_specifics%" #8 // value from str_var
      END
      PATCH_IF ("%cre_file%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cre_off + 0x80 + (index * 0x110)) "%cre_file%" #8 // value from str_var
      END
    END
  END

END

DEFINE_PATCH_FUNCTION cd_area_alter_container
  INT_VAR cont_icon     = "-1"
          lock_diff     = "-1"
          flag_locked   = "-1"
          flag_mlocked  = "-1"
          flag_resets   = "-1"
          flag_disabled = "-1"
          trap_det_diff = "-1"
          trap_rem_diff = "-1"
          trapped       = "-1"
          detected      = "-1"
          string        = "-1"
  STR_VAR cont_name   = ""
          cont_script = "same"
          cont_key    = "same"
BEGIN

  READ_LONG  0x70 cont_off
  READ_SHORT 0x74 cont_num
  FOR (index = 0 ; index < cont_num ; ++index) BEGIN
    READ_ASCII (cont_off +        (index * 0xc0)) cont_name_file (32) NULL
    PATCH_IF ("%cont_name%" STRING_COMPARE_CASE "%cont_name_file%" = 0) BEGIN
      PATCH_IF (cont_icon     >= 0) BEGIN WRITE_SHORT (cont_off + 0x24 + (index * 0xc0)) cont_icon     END // value from int_var
      PATCH_IF (lock_diff     >= 0) BEGIN WRITE_SHORT (cont_off + 0x26 + (index * 0xc0)) lock_diff     END // value from int_var
      PATCH_IF (trap_det_diff >= 0) BEGIN WRITE_SHORT (cont_off + 0x2c + (index * 0xc0)) trap_det_diff END // value from int_var
      PATCH_IF (trap_rem_diff >= 0) BEGIN WRITE_SHORT (cont_off + 0x2e + (index * 0xc0)) trap_rem_diff END // value from int_var
      PATCH_IF (trapped       >= 0) BEGIN WRITE_SHORT (cont_off + 0x30 + (index * 0xc0)) trapped       END // value from int_var
      PATCH_IF (detected      >= 0) BEGIN WRITE_SHORT (cont_off + 0x32 + (index * 0xc0)) detected      END // value from int_var
      PATCH_IF (string        >= 0) BEGIN WRITE_LONG  (cont_off + 0x84 + (index * 0xc0)) string        END // value from int_var

      PATCH_IF (flag_locked   = 0) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS & `BIT0 END
      PATCH_IF (flag_mlocked  = 0) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS & `BIT2 END
      PATCH_IF (flag_resets   = 0) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS & `BIT3 END
      PATCH_IF (flag_disabled = 0) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS & `BIT5 END
      PATCH_IF (flag_locked   = 1) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS | BIT0  END
      PATCH_IF (flag_mlocked  = 1) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS | BIT2  END
      PATCH_IF (flag_resets   = 1) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS | BIT3  END
      PATCH_IF (flag_disabled = 1) BEGIN WRITE_BYTE  (cont_off + 0x28 + (index * 0xc0)) THIS | BIT5  END

       // update script if matched
      PATCH_IF ("%cont_script%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cont_off + 0x48 + (index * 0xc0)) "%cont_script%" #8 // value from str_var
      END
       // update script if matched
      PATCH_IF ("%cont_key%" STRING_COMPARE_CASE "same") BEGIN // if script not set to same
        WRITE_ASCIIE (cont_off + 0x78 + (index * 0xc0)) "%cont_key%" #8 // value from str_var
      END
    END
  END

END
 
DEFINE_PATCH_FUNCTION cd_area_alter_doors
  INT_VAR door_icon   = "-1"
          trap_detect = "-1"
          trap_remove = "-1"
          trapped     = "-1"
          detected    = "-1"
          door_detect = "-1"
          lock_diff   = "-1"
  STR_VAR door_name   = ""
          door_key    = "same"
          door_script = "same"
BEGIN

  READ_LONG 0xa4 door_num
  READ_LONG 0xa8 door_off
  FOR (index = 0 ; index < door_num ; ++index) BEGIN
    READ_ASCII (door_off +        (index * 0xc8)) door_name_file (32) NULL
    PATCH_IF ("%door_name%" STRING_COMPARE_CASE "%door_name_file%" = 0) BEGIN
      PATCH_IF ("%door_icon%" >= 0)   BEGIN WRITE_LONG  (door_off + 0x68 + (index * 0xc8)) "%door_icon%"   END
      PATCH_IF ("%trap_detect%" >= 0) BEGIN WRITE_SHORT (door_off + 0x6c + (index * 0xc8)) "%trap_detect%" END
      PATCH_IF ("%trap_remove%" >= 0) BEGIN WRITE_SHORT (door_off + 0x6e + (index * 0xc8)) "%trap_remove%" END
      PATCH_IF ("%trapped%" >= 0)     BEGIN WRITE_SHORT (door_off + 0x70 + (index * 0xc8)) "%trapped%"     END
      PATCH_IF ("%detected%" >= 0)    BEGIN WRITE_SHORT (door_off + 0x72 + (index * 0xc8)) "%detected%"    END
      PATCH_IF ("%door_detect%" >= 0) BEGIN WRITE_LONG  (door_off + 0x88 + (index * 0xc8)) "%door_detect%" END
      PATCH_IF ("%lock_diff%" >= 0)   BEGIN WRITE_LONG  (door_off + 0x8c + (index * 0xc8)) "%lock_diff%"   END
      PATCH_IF ("%door_key%" STRING_COMPARE_CASE "same") BEGIN // if key not set to same
        WRITE_ASCIIE (door_off + 0x78 + (index * 0xc8)) "%door_key%" #8 // value from str_var
      END
      PATCH_IF ("%door_script%" STRING_COMPARE_CASE "same") BEGIN // if key not set to same
        WRITE_ASCIIE (door_off + 0x80 + (index * 0xc8)) "%door_script%" #8 // value from str_var
      END
    END
  END

END

/////                                                  \\\\\
///// item functions                                   \\\\\
/////                                                  \\\\\

DEFINE_PATCH_FUNCTION cd_item_alter_effect
  INT_VAR equipped      = 0  // check global fx: 0 for no, 1 for yes
          headers       = 0  // check ability fx; 0 for no, 1 for yes
          type          = "-1" // -1 is all headers, otherwise of type specified
          opcode        = "-1" // opcode to match, -1 for all
          opcode_new    = "-1" // change to this opcode
          target        = "-1" // for rest, -1 means no change
          timing        = "-1"
          power         = "-1"
          parameter1    = "-1"
          parameter2    = "-1"
          power         = "-1"
          resist_dispel = "-1"
          duration      = "-1"
          duration_high = "-1" // special, only replaces if existing duration is > one round
          probability1  = "-1"
          probability2  = "-1"
          dicenumber    = "-1"
          dicesize      = "-1"
          savingthrow   = "-1"
          savebonus     = "-11"
  STR_VAR resource     = "same" // same means no change, otherwise use this value
BEGIN

  READ_LONG 0x6a fx_off
  PATCH_IF (equipped = 1) BEGIN
    READ_SHORT 0x70 fx_num
    FOR (index = 0 ; index < fx_num ; ++index) BEGIN
      READ_SHORT (fx_off +        (index * 0x30)) opcode_file
      PATCH_IF ((opcode = opcode_file) OR (opcode < 0)) BEGIN
        PATCH_IF (opcode_new >= 0)    BEGIN WRITE_SHORT (fx_off +        (index * 0x30)) opcode_new    END
        PATCH_IF (target >= 0)        BEGIN WRITE_BYTE  (fx_off + 0x02 + (index * 0x30)) target        END
        PATCH_IF (power >= 0)         BEGIN WRITE_BYTE  (fx_off + 0x03 + (index * 0x30)) power         END
        PATCH_IF (parameter1 >= 0)    BEGIN WRITE_LONG  (fx_off + 0x04 + (index * 0x30)) parameter1    END
        PATCH_IF (parameter2 >= 0)    BEGIN WRITE_LONG  (fx_off + 0x08 + (index * 0x30)) parameter2    END
        PATCH_IF (timing >= 0)        BEGIN WRITE_BYTE  (fx_off + 0x0c + (index * 0x30)) timing        END
        PATCH_IF (resist_dispel >= 0) BEGIN WRITE_BYTE  (fx_off + 0x0d + (index * 0x30)) resist_dispel END
        PATCH_IF (duration >= 0)      BEGIN WRITE_LONG  (fx_off + 0x0e + (index * 0x30)) duration      END
        PATCH_IF (probability1 >= 0)  BEGIN WRITE_BYTE  (fx_off + 0x12 + (index * 0x30)) probability1  END
        PATCH_IF (probability2 >= 0)  BEGIN WRITE_BYTE  (fx_off + 0x13 + (index * 0x30)) probability2  END
        PATCH_IF (dicenumber >= 0)    BEGIN WRITE_LONG  (fx_off + 0x1c + (index * 0x30)) dicenumber    END
        PATCH_IF (dicesize >= 0)      BEGIN WRITE_LONG  (fx_off + 0x20 + (index * 0x30)) dicesize      END
        PATCH_IF (savingthrow >= 0)   BEGIN WRITE_LONG  (fx_off + 0x24 + (index * 0x30)) savingthrow   END
        PATCH_IF (savebonus >= "-10") BEGIN WRITE_LONG  (fx_off + 0x28 + (index * 0x30)) savebonus     END
        PATCH_IF (duration_high >= 0) BEGIN
          READ_LONG (fx_off + 0x0e + (index * 0x30)) duration_file
          PATCH_IF (duration_file > 6) BEGIN
            WRITE_LONG (fx_off + 0x0e + (index * 0x30)) duration_high
          END
        END
        PATCH_IF ("%resource%" STRING_COMPARE_CASE "same") BEGIN
          WRITE_ASCIIE (fx_off + 0x14 + (index * 0x30)) "%resource%" #8
        END
      END
    END
  END
  PATCH_IF (headers = 1) BEGIN
    READ_LONG   0x64 "abil_off"
    READ_SHORT  0x68 "abil_num"
    FOR (index2 = 0 ; index2 < abil_num ; ++index2) BEGIN // looks through headers
      READ_BYTE (abil_off +        (index2 * 0x38)) abil_type
      PATCH_IF ((abil_type = type) OR (type < 0)) BEGIN
        READ_SHORT (abil_off + 0x1e + (index2 * 0x38)) abil_fx_num
        READ_SHORT (abil_off + 0x20 + (index2 * 0x38)) abil_fx_idx
        FOR (index = 0 ; index < abil_fx_num ; index = index + 1) BEGIN
          READ_SHORT (fx_off +        ((abil_fx_idx + index) * 0x30)) opcode_file
          PATCH_IF ((opcode = opcode_file) OR (opcode < 0)) BEGIN
            PATCH_IF (opcode_new >= 0)    BEGIN WRITE_SHORT (fx_off +        ((index + abil_fx_idx) * 0x30)) opcode_new    END
            PATCH_IF (target >= 0)        BEGIN WRITE_BYTE  (fx_off + 0x02 + ((index + abil_fx_idx) * 0x30)) target        END
            PATCH_IF (power >= 0)         BEGIN WRITE_BYTE  (fx_off + 0x03 + ((index + abil_fx_idx) * 0x30)) power         END
            PATCH_IF (parameter1 >= 0)    BEGIN WRITE_LONG  (fx_off + 0x04 + ((index + abil_fx_idx) * 0x30)) parameter1    END
            PATCH_IF (parameter2 >= 0)    BEGIN WRITE_LONG  (fx_off + 0x08 + ((index + abil_fx_idx) * 0x30)) parameter2    END
            PATCH_IF (timing >= 0)        BEGIN WRITE_BYTE  (fx_off + 0x0c + ((index + abil_fx_idx) * 0x30)) timing        END
            PATCH_IF (resist_dispel >= 0) BEGIN WRITE_BYTE  (fx_off + 0x0d + ((index + abil_fx_idx) * 0x30)) resist_dispel END
            PATCH_IF (duration >= 0)      BEGIN WRITE_LONG  (fx_off + 0x0e + ((index + abil_fx_idx) * 0x30)) duration      END
            PATCH_IF (probability1 >= 0)  BEGIN WRITE_BYTE  (fx_off + 0x12 + ((index + abil_fx_idx) * 0x30)) probability1  END
            PATCH_IF (probability2 >= 0)  BEGIN WRITE_BYTE  (fx_off + 0x13 + ((index + abil_fx_idx) * 0x30)) probability2  END
            PATCH_IF (dicenumber >= 0)    BEGIN WRITE_LONG  (fx_off + 0x1c + ((index + abil_fx_idx) * 0x30)) dicenumber    END
            PATCH_IF (dicesize >= 0)      BEGIN WRITE_LONG  (fx_off + 0x20 + ((index + abil_fx_idx) * 0x30)) dicesize      END
            PATCH_IF (savingthrow >= 0)   BEGIN WRITE_LONG  (fx_off + 0x24 + ((index + abil_fx_idx) * 0x30)) savingthrow   END
            PATCH_IF (savebonus >= "-10") BEGIN WRITE_LONG  (fx_off + 0x28 + ((index + abil_fx_idx) * 0x30)) savebonus     END
            PATCH_IF (duration_high >= 0) BEGIN
              READ_LONG (fx_off + 0x0e + (index * 0x30)) duration_file
              PATCH_IF (duration_file > 6) BEGIN
                WRITE_LONG (fx_off + 0x0e + (index * 0x30)) duration_high
              END
            END
            PATCH_IF ("%resource%" STRING_COMPARE_CASE "same") BEGIN
              WRITE_ASCIIE (fx_off + 0x14 + ((index + abil_fx_idx) * 0x30)) "%resource%" #8
            END
          END
        END
      END
    END
  END

END

DEFINE_PATCH_FUNCTION cd_item_alter_header
  INT_VAR type          = "-1" // -1 is all headers, >4 forces icon match, otherwise use value here
          header        = 0    // 0 matches all headers, otherwise just modify specified header - use with type = -1
          type_new      = "-1" // for rest, -1 means no change
          identify      = "-1"
          location      = "-1"
          target        = "-1"
          range         = "-1"
          launcher      = "-1"
          speed         = "-1"
          thac0_bonus   = "-1"
          dicesize      = "-1"
          dicenum       = "-1"
          damage_bonus  = "-1"
          damage_type   = "-1"
          effects_num   = "-1"
          effects_index = "-1"
          charges       = "-1"
          drained       = "-1"
          flag_strength = "-1"
          flag_break    = "-1"
          flag_hostile  = "-1"
          flag_recharge = "-1"
          flag_bypass   = "-1"
          flag_keenedge = "-1"
          projectile    = "-1"
          anim_overhead = "-1"
          anim_backhand = "-1"
          anim_thrust   = "-1"
          arrow         = "-1"
          bolt          = "-1"
          bullet        = "-1"
  STR_VAR icon          = "same" // same means no change, otherwise use this value; may just be used as match if type is > 4
BEGIN

  READ_LONG   0x64 "abil_off"
  READ_SHORT  0x68 "abil_num"
  PATCH_IF (header = 0) BEGIN SET loop_start = 0            SET loop_end = abil_num END
                   ELSE BEGIN SET loop_start = (header - 1) SET loop_end = header   END
  FOR (index = loop_start ; index < loop_end ; ++index) BEGIN
    READ_BYTE  (abil_off +        (index * 0x38)) abil_type
    READ_ASCII (abil_off + 0x04 + (index * 0x38)) icon_file
    PATCH_IF ((type < 0) OR (abil_type = type) OR ((type > 4) AND ("%icon_file%" STRING_COMPARE_CASE "%icon%" = 0))) BEGIN
      PATCH_IF (type_new >= 0)      BEGIN WRITE_SHORT (abil_off +        (index * 0x38)) type_new      END
      PATCH_IF (identify >= 0)      BEGIN WRITE_BYTE  (abil_off + 0x01 + (index * 0x38)) identify      END
      PATCH_IF (location >= 0)      BEGIN WRITE_SHORT (abil_off + 0x02 + (index * 0x38)) location      END
      PATCH_IF (target >= 0)        BEGIN WRITE_SHORT (abil_off + 0x0c + (index * 0x38)) target        END
      PATCH_IF (range >= 0)         BEGIN WRITE_SHORT (abil_off + 0x0e + (index * 0x38)) range         END
      PATCH_IF (launcher >= 0)      BEGIN WRITE_SHORT (abil_off + 0x10 + (index * 0x38)) launcher      END
      PATCH_IF (speed >= 0)         BEGIN WRITE_SHORT (abil_off + 0x12 + (index * 0x38)) speed         END
      PATCH_IF (thac0_bonus >= 0)   BEGIN WRITE_SHORT (abil_off + 0x14 + (index * 0x38)) thac0_bonus   END
      PATCH_IF (dicesize >= 0)      BEGIN WRITE_SHORT (abil_off + 0x16 + (index * 0x38)) dicesize      END
      PATCH_IF (dicenum >= 0)       BEGIN WRITE_SHORT (abil_off + 0x18 + (index * 0x38)) dicenum       END
      PATCH_IF (damage_bonus >= 0)  BEGIN WRITE_SHORT (abil_off + 0x1a + (index * 0x38)) damage_bonus  END
      PATCH_IF (damage_type >= 0)   BEGIN WRITE_SHORT (abil_off + 0x1c + (index * 0x38)) damage_type   END
      PATCH_IF (effects_num >= 0)   BEGIN WRITE_SHORT (abil_off + 0x1e + (index * 0x38)) effects_num   END
      PATCH_IF (effects_index >= 0) BEGIN WRITE_SHORT (abil_off + 0x20 + (index * 0x38)) effects_index END
      PATCH_IF (charges >= 0)       BEGIN WRITE_SHORT (abil_off + 0x22 + (index * 0x38)) charges       END
      PATCH_IF (drained >= 0)       BEGIN WRITE_SHORT (abil_off + 0x24 + (index * 0x38)) drained       END
      PATCH_IF (projectile >= 0)    BEGIN WRITE_SHORT (abil_off + 0x2a + (index * 0x38)) projectile    END
      PATCH_IF (anim_overhead >= 0) BEGIN WRITE_SHORT (abil_off + 0x2c + (index * 0x38)) anim_overhead END
      PATCH_IF (anim_backhand >= 0) BEGIN WRITE_SHORT (abil_off + 0x2e + (index * 0x38)) anim_backhand END
      PATCH_IF (anim_thrust >= 0)   BEGIN WRITE_SHORT (abil_off + 0x30 + (index * 0x38)) anim_thrust   END
      PATCH_IF (arrow >= 0)         BEGIN WRITE_SHORT (abil_off + 0x32 + (index * 0x38)) arrow         END
      PATCH_IF (bolt >= 0)          BEGIN WRITE_SHORT (abil_off + 0x34 + (index * 0x38)) bolt          END
      PATCH_IF (bullet >= 0)        BEGIN WRITE_SHORT (abil_off + 0x36 + (index * 0x38)) bullet        END
      PATCH_IF (flag_strength = 0)  BEGIN WRITE_BYTE  (abil_off + 0x26 + (index * 0x38)) THIS & `BIT0  END
      PATCH_IF (flag_break = 0)     BEGIN WRITE_BYTE  (abil_off + 0x26 + (index * 0x38)) THIS & `BIT1  END
      PATCH_IF (flag_hostile = 0)   BEGIN WRITE_BYTE  (abil_off + 0x27 + (index * 0x38)) THIS & `BIT2  END
      PATCH_IF (flag_recharge = 0)  BEGIN WRITE_BYTE  (abil_off + 0x27 + (index * 0x38)) THIS & `BIT3  END
      PATCH_IF (flag_bypass = 0)    BEGIN WRITE_BYTE  (abil_off + 0x28 + (index * 0x38)) THIS & `BIT0  END
      PATCH_IF (flag_keenedge = 0)  BEGIN WRITE_BYTE  (abil_off + 0x28 + (index * 0x38)) THIS & `BIT1  END
      PATCH_IF (flag_strength = 1)  BEGIN WRITE_BYTE  (abil_off + 0x26 + (index * 0x38)) THIS | BIT0   END
      PATCH_IF (flag_break = 1)     BEGIN WRITE_BYTE  (abil_off + 0x26 + (index * 0x38)) THIS | BIT1   END
      PATCH_IF (flag_hostile = 1)   BEGIN WRITE_BYTE  (abil_off + 0x27 + (index * 0x38)) THIS | BIT2   END
      PATCH_IF (flag_recharge = 1)  BEGIN WRITE_BYTE  (abil_off + 0x27 + (index * 0x38)) THIS | BIT3   END
      PATCH_IF (flag_bypass = 1)    BEGIN WRITE_BYTE  (abil_off + 0x28 + (index * 0x38)) THIS | BIT0   END
      PATCH_IF (flag_keenedge = 1)  BEGIN WRITE_BYTE  (abil_off + 0x28 + (index * 0x38)) THIS | BIT1   END
      PATCH_IF ("%icon%" STRING_COMPARE_CASE "same") BEGIN
        WRITE_ASCIIE (abil_off + 0x04 + (index * 0x38)) "%icon%" #8
      END
    END
  END

END

DEFINE_PATCH_FUNCTION cd_item_delete_header
  INT_VAR type = 0 // -1 for all headers, otherwise match type
  BEGIN

    READ_LONG   0x64 abil_off
    READ_SHORT  0x68 abil_num
    READ_LONG   0x6a fx_off
    READ_SHORT  0x70 fx_num
    SET fx_delta = 0
    FOR (index = 0 ; index < abil_num ; ++index) BEGIN // looks for default ability header
      READ_BYTE   (abil_off +        (index * 0x38)) type_file
      PATCH_IF ((type = type_file) OR (type < 0)) BEGIN // default ability check
        READ_SHORT  (0x1e + abil_off + (index * 0x38)) abil_fx_num
        READ_SHORT  (0x20 + abil_off + (index * 0x38)) abil_fx_idx
        DELETE_BYTES (fx_off + (0x30 * (abil_fx_idx - fx_delta))) (0x30 * abil_fx_num) // deletes all associated effects
        DELETE_BYTES (abil_off + (index * 0x38)) 0x38                                  // deletes ability itself
        SET fx_delta = (fx_delta + abil_fx_num)
        SET abil_num = (abil_num - 1)
        SET index = (index - 1)
        SET fx_off = (fx_off - 0x38)
      END ELSE BEGIN // if non-matched ability, need to adjust effect indices
        READ_SHORT  (0x20 + abil_off + (index * 0x38)) abil_fx_idx
        WRITE_SHORT (0x20 + abil_off + (index * 0x38)) (abil_fx_idx - fx_delta)
      END
    END
    WRITE_SHORT  0x68 abil_num
    WRITE_LONG   0x6a fx_off
   
END

/////                                                  \\\\\
///// spell functions                                  \\\\\
/////                                                  \\\\\

DEFINE_PATCH_FUNCTION cd_spell_alter_effect
  INT_VAR header        = 0  // 0 for all, otherwise use number
          type          = "-1" // -1 is all headers, otherwise of type specified
          opcode        = "-1" // opcode to match, -1 for all
          opcode_new    = "-1" // change to this opcode
          target        = "-1" // for rest, -1 means no change
          timing        = "-1"
          power         = "-1"
          parameter1    = "-1"
          parameter2    = "-1"
          power         = "-1"
          resist_dispel = "-1"
          duration      = "-1"
          duration_high = "-1" // special, only replaces if existing duration is > one round
          probability1  = "-1"
          probability2  = "-1"
          dicenumber    = "-1"
          dicesize      = "-1"
          savingthrow   = "-1"
          savebonus     = "-11"
  STR_VAR resource     = "same" // same means no change, otherwise use this value
BEGIN

  READ_LONG  0x6a fx_off
  READ_LONG  0x64 abil_off
  READ_SHORT 0x68 abil_num
  PATCH_IF (header = 0) BEGIN SET loop_start = 0            SET loop_end = abil_num END
                   ELSE BEGIN SET loop_start = (header - 1) SET loop_end = header   END
  FOR (index2 = loop_start ; index2 < loop_end ; ++index2) BEGIN // looks through headers
    READ_BYTE (abil_off +        (index2 * 0x28)) abil_type
    PATCH_IF ((abil_type = type) OR (type < 0)) BEGIN
      READ_SHORT (abil_off + 0x1e + (index2 * 0x28)) abil_fx_num
      READ_SHORT (abil_off + 0x20 + (index2 * 0x28)) abil_fx_idx
      FOR (index = 0 ; index < abil_fx_num ; index = index + 1) BEGIN
        READ_SHORT (fx_off +        ((abil_fx_idx + index) * 0x30)) opcode_file
        PATCH_IF ((opcode = opcode_file) OR (opcode < 0)) BEGIN
          PATCH_IF (opcode_new >= 0)    BEGIN WRITE_SHORT (fx_off +        ((index + abil_fx_idx) * 0x30)) opcode_new    END
          PATCH_IF (target >= 0)        BEGIN WRITE_BYTE  (fx_off + 0x02 + ((index + abil_fx_idx) * 0x30)) target        END
          PATCH_IF (power >= 0)         BEGIN WRITE_BYTE  (fx_off + 0x03 + ((index + abil_fx_idx) * 0x30)) power         END
          PATCH_IF (parameter1 >= 0)    BEGIN WRITE_LONG  (fx_off + 0x04 + ((index + abil_fx_idx) * 0x30)) parameter1    END
          PATCH_IF (parameter2 >= 0)    BEGIN WRITE_LONG  (fx_off + 0x08 + ((index + abil_fx_idx) * 0x30)) parameter2    END
          PATCH_IF (timing >= 0)        BEGIN WRITE_BYTE  (fx_off + 0x0c + ((index + abil_fx_idx) * 0x30)) timing        END
          PATCH_IF (resist_dispel >= 0) BEGIN WRITE_BYTE  (fx_off + 0x0d + ((index + abil_fx_idx) * 0x30)) resist_dispel END
          PATCH_IF (duration >= 0)      BEGIN WRITE_LONG  (fx_off + 0x0e + ((index + abil_fx_idx) * 0x30)) duration      END
          PATCH_IF (probability1 >= 0)  BEGIN WRITE_BYTE  (fx_off + 0x12 + ((index + abil_fx_idx) * 0x30)) probability1  END
          PATCH_IF (probability2 >= 0)  BEGIN WRITE_BYTE  (fx_off + 0x13 + ((index + abil_fx_idx) * 0x30)) probability2  END
          PATCH_IF (dicenumber >= 0)    BEGIN WRITE_LONG  (fx_off + 0x1c + ((index + abil_fx_idx) * 0x30)) dicenumber    END
          PATCH_IF (dicesize >= 0)      BEGIN WRITE_LONG  (fx_off + 0x20 + ((index + abil_fx_idx) * 0x30)) dicesize      END
          PATCH_IF (savingthrow >= 0)   BEGIN WRITE_LONG  (fx_off + 0x24 + ((index + abil_fx_idx) * 0x30)) savingthrow   END
          PATCH_IF (savebonus >= "-10") BEGIN WRITE_LONG  (fx_off + 0x28 + ((index + abil_fx_idx) * 0x30)) savebonus     END
          PATCH_IF (duration_high >= 0) BEGIN
            READ_LONG (fx_off + 0x0e + (index * 0x30)) duration_file
            PATCH_IF (duration_file > 6) BEGIN
              WRITE_LONG (fx_off + 0x0e + (index * 0x30)) duration_high
            END
          END
          PATCH_IF ("%resource%" STRING_COMPARE_CASE "same") BEGIN
            WRITE_ASCIIE (fx_off + 0x14 + ((index + abil_fx_idx) * 0x30)) "%resource%" #8
          END
        END
      END
    END
  END

END

DEFINE_PATCH_FUNCTION cd_spell_alter_header
  INT_VAR type          = "-1" // -1 is all headers, >4 forces icon match, otherwise use value here
          header        = 0    // 0 matches all headers, otherwise just modify specified header - use with type = -1
          type_new      = "-1" // for rest, -1 means no change
          location      = "-1"
          target        = "-1"
          range         = "-1"
          min_level     = "-1"
          speed         = "-1"
          thac0_bonus   = "-1"
          dicesize      = "-1"
          dicenum       = "-1"
          damage_bonus  = "-1"
          damage_type   = "-1"
          effects_num   = "-1"
          effects_index = "-1"
          charges       = "-1"
          projectile    = "-1"
  STR_VAR icon          = "same" // same means no change, otherwise use this value; may just be used as match if type is > 4
BEGIN

  READ_LONG   0x64 "abil_off"
  READ_SHORT  0x68 "abil_num"
  PATCH_IF (header = 0) BEGIN SET loop_start = 0            SET loop_end = abil_num END
                   ELSE BEGIN SET loop_start = (header - 1) SET loop_end = header   END
  FOR (index = loop_start ; index < loop_end ; ++index) BEGIN
    READ_BYTE  (abil_off +        (index * 0x28)) abil_type
    READ_ASCII (abil_off + 0x04 + (index * 0x28)) icon_file
    PATCH_IF ((type < 0) OR (abil_type = type) OR ((type > 4) AND ("%icon_file%" STRING_COMPARE_CASE "%icon%" = 0))) BEGIN
      PATCH_IF (type_new >= 0)      BEGIN WRITE_SHORT (abil_off +        (index * 0x28)) type_new      END
      PATCH_IF (location >= 0)      BEGIN WRITE_SHORT (abil_off + 0x02 + (index * 0x28)) location      END
      PATCH_IF (target >= 0)        BEGIN WRITE_SHORT (abil_off + 0x0c + (index * 0x28)) target        END
      PATCH_IF (range >= 0)         BEGIN WRITE_SHORT (abil_off + 0x0e + (index * 0x28)) range         END
      PATCH_IF (min_level >= 0)     BEGIN WRITE_SHORT (abil_off + 0x10 + (index * 0x28)) min_level     END
      PATCH_IF (speed >= 0)         BEGIN WRITE_SHORT (abil_off + 0x12 + (index * 0x28)) speed         END
      PATCH_IF (thac0_bonus >= 0)   BEGIN WRITE_SHORT (abil_off + 0x14 + (index * 0x28)) thac0_bonus   END
      PATCH_IF (dicesize >= 0)      BEGIN WRITE_SHORT (abil_off + 0x16 + (index * 0x28)) dicesize      END
      PATCH_IF (dicenum >= 0)       BEGIN WRITE_SHORT (abil_off + 0x18 + (index * 0x28)) dicenum       END
      PATCH_IF (damage_bonus >= 0)  BEGIN WRITE_SHORT (abil_off + 0x1a + (index * 0x28)) damage_bonus  END
      PATCH_IF (damage_type >= 0)   BEGIN WRITE_SHORT (abil_off + 0x1c + (index * 0x28)) damage_type   END
      PATCH_IF (effects_num >= 0)   BEGIN WRITE_SHORT (abil_off + 0x1e + (index * 0x28)) effects_num   END
      PATCH_IF (effects_index >= 0) BEGIN WRITE_SHORT (abil_off + 0x20 + (index * 0x28)) effects_index END
      PATCH_IF (charges >= 0)       BEGIN WRITE_SHORT (abil_off + 0x22 + (index * 0x28)) charges       END
      PATCH_IF (projectile >= 0)    BEGIN WRITE_SHORT (abil_off + 0x26 + (index * 0x28)) projectile    END
      PATCH_IF ("%icon%" STRING_COMPARE_CASE "same") BEGIN
        WRITE_ASCIIE (abil_off + 0x04 + (index * 0x28)) "%icon%" #8
      END
    END
  END

END

DEFINE_PATCH_FUNCTION cd_spell_delete_header
  INT_VAR type      = 0    // -1 for all headers, otherwise match type
          min_level = "-1" // -1 for all headers, otherwise match
  BEGIN

    READ_LONG   0x64 abil_off
    READ_SHORT  0x68 abil_num
    READ_LONG   0x6a fx_off
    READ_SHORT  0x70 fx_num
    SET fx_delta = 0
    FOR (index = 0 ; index < abil_num ; ++index) BEGIN // looks for default ability header
      READ_BYTE   (abil_off +        (index * 0x28)) type_file
      READ_SHORT  (abil_off + 0x10 + (index * 0x28)) min_level_file
      PATCH_IF (((type = type_file) OR (type < 0)) AND
                ((min_level = min_level_file) OR (min_level < 0))) BEGIN // default ability check
        READ_SHORT  (0x1e + abil_off + (index * 0x28)) abil_fx_num
        READ_SHORT  (0x20 + abil_off + (index * 0x28)) abil_fx_idx
        DELETE_BYTES (fx_off + (0x30 * (abil_fx_idx - fx_delta))) (0x30 * abil_fx_num) // deletes all associated effects
        DELETE_BYTES (abil_off + (index * 0x28)) 0x28                                  // deletes ability itself
        SET fx_delta = (fx_delta + abil_fx_num)
        SET abil_num = (abil_num - 1)
        SET index = (index - 1)
        SET fx_off = (fx_off - 0x28)
      END ELSE BEGIN // if non-matched ability, need to adjust effect indices
        READ_SHORT  (0x20 + abil_off + (index * 0x28)) abil_fx_idx
        WRITE_SHORT (0x20 + abil_off + (index * 0x28)) (abil_fx_idx - fx_delta)
      END
    END
    WRITE_SHORT  0x68 abil_num
    WRITE_LONG   0x6a fx_off
   
END
The Gibberlings Three - Home of IE Mods

The BG2 Fixpack - All the fixes of Baldurdash, plus a few hundred more. Now available, with more fixes being added in every release.

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: More functions
« Reply #12 on: January 11, 2013, 05:46:42 PM »
I declare Thunderdome on the itm/spl header stuff. Alternatively, if nothing happens, I will be reviewing/adapting/complementing it at some unspecified time in the future.

Cam's alter-this-and-that functions (from BG2-Fixpack on github) will be in, under new names. The name format is ALTER_FOO_BAR instead of cd_foo_alter_bar. (Assuming I can swing it in a nice manner, I will also be making fj_* and sc#* functions available under compliant aliases.)

Offline CamDawg

  • Infidel
  • Planewalker
  • *****
  • Posts: 859
  • Dreaming of a red Xmas
    • The Gibberlings Three
Re: More functions
« Reply #13 on: January 12, 2013, 06:03:54 AM »
I'll make the suggested changes and put up a new library on Github. I'll also start working on docs.
The Gibberlings Three - Home of IE Mods

The BG2 Fixpack - All the fixes of Baldurdash, plus a few hundred more. Now available, with more fixes being added in every release.

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: More functions
« Reply #14 on: January 12, 2013, 10:43:18 AM »
A late addition, but what do you say about changing the "area cre" function into "area actor" and renaming the cre_name variable into either just name or actor_name? Other functions and tools generally refer to this substructure as "actor", rather than "cre".

Offline CamDawg

  • Infidel
  • Planewalker
  • *****
  • Posts: 859
  • Dreaming of a red Xmas
    • The Gibberlings Three
Re: More functions
« Reply #15 on: January 12, 2013, 06:38:40 PM »
Sure, and I think I'll also change the trigger function to region, since that seems to be the IESDP nomenclature. So something like

CONVERT_BG_IWD_DURATION
AREA_ALTER_ENTRANCE
AREA_ALTER_REGION
AREA_ALTER_ACTOR
AREA_ALTER_CONTAINER
AREA_ALTER_DOOR
ITEM_ALTER_EFFECT
ITEM_ALTER_HEADER
ITEM_DELETE_HEADER
SPELL_ALTER_EFFECT
SPELL_ALTER_HEADER
SPELL_DELETE_HEADER

as the macro names? I went back and forth on the plural/singular and just decided to make them singular, even though they could all patch multiples. A few other additions you'll see when the revised macros go up--BG/IWD durations now goes both ways, and the TobEx flags for backstab and non-invis targeting have been added to the soon-to-be-former cd_item_alter_header.
The Gibberlings Three - Home of IE Mods

The BG2 Fixpack - All the fixes of Baldurdash, plus a few hundred more. Now available, with more fixes being added in every release.

Offline CamDawg

  • Infidel
  • Planewalker
  • *****
  • Posts: 859
  • Dreaming of a red Xmas
    • The Gibberlings Three
Re: More functions
« Reply #16 on: January 14, 2013, 11:11:35 AM »
Alright, I've uploaded these to my site. I didn't update BG2FP's version yet since I'll need to re-point all of the calls in the tp2 and I didn't want you to wait on me. Here's the new library and the accompanying documentation. Enjoy!
The Gibberlings Three - Home of IE Mods

The BG2 Fixpack - All the fixes of Baldurdash, plus a few hundred more. Now available, with more fixes being added in every release.

Offline Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
Re: More functions
« Reply #17 on: January 14, 2013, 12:03:45 PM »
I declare Thunderdome on the itm/spl header stuff.
Why, exactly? Cam's functions get in because he's better known than GeN1e and I or something?

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: More functions
« Reply #18 on: January 14, 2013, 01:32:05 PM »
Why, exactly?
I thought the reference was clear. No one posted an alternate set of alter-this-and-that functions, so there is no need for "two [sets of functions] enter; one [set of functions] leaves". I'm not adding two functions for adding item/spell headers, I'm not arbitrarily adding one of them and I'm deferring adding one or the other based on its merits until a later date because I'm busy with getting this thing to run on BGEE now.

Offline Miloch

  • Barbarian
  • Planewalker
  • *****
  • Posts: 1032
  • Gender: Male
Re: More functions
« Reply #19 on: January 15, 2013, 04:04:52 PM »
I thought the reference was clear. No one posted an alternate set of alter-this-and-that functions, so there is no need for "two [sets of functions] enter; one [set of functions] leaves". I'm not adding two functions for adding item/spell headers, I'm not arbitrarily adding one of them and I'm deferring adding one or the other based on its merits until a later date because I'm busy with getting this thing to run on BGEE now.
Oh, I see. And I just watched that movie too but I'm just a half-orc. :P So basically it requires someone to review the code options and come up with the best/most versatile function, aye?

Offline Wisp

  • Moderator
  • Planewalker
  • *****
  • Posts: 1176
Re: More functions
« Reply #20 on: January 16, 2013, 03:18:40 PM »
So basically it requires someone to review the code options and come up with the best/most versatile function, aye?
Pretty much, yeah. The best thing would of course be if you and Ardanis talked it over and produced something you are both satisfied with.

Offline GeN1e

  • Planewalker
  • *****
  • Posts: 267
  • Gender: Male
Re: More functions
« Reply #21 on: January 16, 2013, 05:15:32 PM »
It appears to be habitual of me to post stuff from outdated sources... Updated my post with macros to the version in use by Item Revisions :facepalm:

My "selling point" would be standard variable names, as well as the bonus ability to copy existing headers (we use it for halberds' slashing/piercing modes).

I'd prefer to steer clear of incorporating ADD_***_EFFECT in there, because you can only add one effect without the array input - and that imo tends to be cumbersome.

 

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