Post reply

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:
Subject:
Message icon:

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

shortcuts: hit alt+s to submit/post or alt+p to preview


Topic Summary

Posted by: GeN1e
« 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.
Posted by: Wisp
« 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.
Posted by: Miloch
« 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?
Posted by: Wisp
« 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.
Posted by: Miloch
« 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?
Posted by: CamDawg
« 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!
Posted by: CamDawg
« 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.
Posted by: Wisp
« 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".
Posted by: CamDawg
« 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.
Posted by: Wisp
« 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.)
Posted by: CamDawg
« 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
Posted by: Miloch
« 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).
Posted by: Miloch
« 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.
Posted by: the bigg
« on: April 08, 2012, 04:08:45 PM »

What functions (if any) should I add? Can you provide documentation for those?
Posted by: Galactygon
« 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