Jump to content
aVENGER_(RR)

WeiDU item and spell patching

Recommended Posts

1) Is there a template somewhere for adding additional effects to items via WeiDU? For example, I want to modify an existing item to glow in blue while equipped and deal an additional point of electrical damage on each hit.

 

2) How can I delete all effects from an item header without deleting the header itself? I need to remove the current skill bonuses from the thievery potions since their effects are applied via spell in RR.

 

3) I have a few custom items and spells with effect #139 Text: Display String. Now, I've currently set the parameters to display string 14094 (immunity to effect) but I'd like to replace this with a custom line from my .TRA file (i.e. @150). How can I do that? BTW, since this string appears in multiple headers of the same spell, the patch would probably have to account for that, right?

Share this post


Link to post

1) Check the Fixpack for .itm/.spl modifications with INSERT_BYTES

2) Reverse of the above using DELETE_BYTES (check this in the Fixroom - I think I had to tweak it to get it to work... can't check other computer right now though)

3) Pretty sure you can do this too - I think DavidW does it in SCS1

Share this post


Link to post
1) Check the Fixpack for .itm/.spl modifications with INSERT_BYTES

2) Reverse of the above using DELETE_BYTES (check this in the Fixroom - I think I had to tweak it to get it to work... can't check other computer right now though)

 

Thanks, I already took a peek at the Fixpack & Tweakpack code, as they are always my first reference for all things WeiDU, but at first glance I'd say that the majority of the examples from those .tp2s are fairly specific in their designated purpose.

 

Therefore, I was kind of hoping that one of the WeiDU Shinobi (Cam, Nythrun, A64, the bigg...) would give us a couple of well documented (i.e. // commented in great detail) general templates so that other modders can use and modify them with little effort and without fear of breaking anything. :) What I'd personally need are templates for the following:

  • Adding an equipping effect to an item
  • Adding an "on hit" effect to an item
  • Adding a new effect to a spell on a single header
  • Adding a new effect to a spell on all headers
  • Deletin a single equipping effect from an item
  • Deletin a single "on hit" effect from an item
  • Deleting all existing effects from an item header but leaving the header itself intact
  • Deleting all existing effects from a spell header but leaving the header itself intact

Also, as someone once suggested, such templates could be bundled with WeiDU within a "Templates" folder or something.

 

3) Pretty sure you can do this too - I think DavidW does it in SCS1

 

I can't seem to find it by merely glancing over the code. Could you give some hints where to look?

Share this post


Link to post
  • Adding an equipping effect to an item
  • Adding an "on hit" effect to an item
  • Adding a new effect to a spell on a single header
  • Adding a new effect to a spell on all headers
  • Deletin a single equipping effect from an item
  • Deletin a single "on hit" effect from an item
  • Deleting all existing effects from an item header but leaving the header itself intact
  • Deleting all existing effects from a spell header but leaving the header itself intact

Also, as someone once suggested, such templates could be bundled with WeiDU within a "Templates" folder or something.

Why not just use DLTCEP to edit the items, and then update them with WeiDU?

Share this post


Link to post
Why not just use DLTCEP to edit the items, and then update them with WeiDU?

 

Because I want to patch existing items whenever possible and overwrite them only if absolutely necessary. In general, this approach ensures better compatibility with other mods.

Share this post


Link to post
  • Adding an equipping effect to an item
  • Adding an "on hit" effect to an item
  • Adding a new effect to a spell on a single header
  • Adding a new effect to a spell on all headers
  • Deletin a single equipping effect from an item
  • Deletin a single "on hit" effect from an item
  • Deleting all existing effects from an item header but leaving the header itself intact
  • Deleting all existing effects from a spell header but leaving the header itself intact

Also, as someone once suggested, such templates could be bundled with WeiDU within a "Templates" folder or something.

Why not just use DLTCEP to edit the items, and then update them with WeiDU?

If you want them, I can write them for you. A number of these I have used (the most prominent being in the BG1-ification of Items BGTTweak component), not as macro format like Gort, but straight code. I can convert them into templates pretty easily.

Share this post


Link to post
If you want them, I can write them for you.

 

That would be great! Go for it. :)

 

A number of these I have used (the most prominent being in the BG1-ification of Items BGTTweak component), not as macro format like Gort, but straight code. I can convert them into templates pretty easily.

 

Heh, I actually prefer pure code templates since I can then further adapt them and write specific macros based on my own needs. :)

Share this post


Link to post

Here we go. This patches do nonsense on some BGII files, only because I tested whether they work on these files.

 

Adding a global (equipping) effect to an item

//assume global effects go before ability effectsa, if not, you are in trouble!
COPY_EXISTING ~BOW20.ITM~ ~override/BOW20.ITM~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off
 READ_SHORT 0x70 fx_global_num

 //add effect
 INSERT_BYTES %fx_off% 0x30

 //effect fields
 WRITE_SHORT %fx_off% 1 //type
 WRITE_BYTE (%fx_off% + 0x2) 2 //target
 WRITE_BYTE (%fx_off% + 0x3) 3 //power
 WRITE_LONG (%fx_off% + 0x4) 4 //param1
 WRITE_LONG (%fx_off% + 0x8) 5 //param2
 WRITE_BYTE (%fx_off% + 0xc) 6 //timing mode
 WRITE_BYTE (%fx_off% + 0xd) 7 //dispel/resistance
 WRITE_LONG (%fx_off% + 0xe) 8 //duration
 WRITE_BYTE (%fx_off% + 0x12) 9 //prob1
 WRITE_BYTE (%fx_off% + 0x13) 10 //prob2
 WRITE_ASCII (%fx_off% + 0x14) ~11~ #8 //resource
 WRITE_LONG (%fx_off% + 0x1c) 12 //#dice, maxlevel
 WRITE_LONG (%fx_off% + 0x20) 13 //dicesize, minlevel
 WRITE_LONG (%fx_off% + 0x24) 14 //save type
 WRITE_LONG (%fx_off% + 0x28) 15 //save bonus
 WRITE_LONG (%fx_off% + 0x2c) 16 //unknown

 //update #global effects
 SET %fx_global_num% += 1
 WRITE_SHORT 0x70 %fx_global_num%

 //update ability effect indices
 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN
READ_SHORT (%abil_off% + %i% * 0x38 + 0x20) abil_fx_idx
WRITE_SHORT (%abil_off% + %i% * 0x38 + 0x20) (%abil_fx_idx% + 1)
 END

 

Adding an ability (on-hit) effect to an item

COPY_EXISTING ~BOW20.ITM~ ~override/BOW20.ITM~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off

 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN //parse each ability
//verify specific ability - check the ability is the correct one to change here, must be unique
READ_BYTE (%abil_off% + %i% * 0x38) abil_type
PATCH_IF (%abil_type% = 3) BEGIN
  READ_SHORT (%abil_off% + %i% * 0x38 + 0x1e) abil_fx_num
  READ_SHORT (%abil_off% + %i% * 0x38 + 0x20) abil_fx_idx

  //add effect
  INSERT_BYTES (%fx_off% + %abil_fx_idx% * 0x30) 0x30

  //effect fields
  WRITE_SHORT (%fx_off% + %abil_fx_idx% * 0x30) 1 //type
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x2) 2 //target
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x3) 3 //power
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x4) 4 //param1
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x8) 5 //param2
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0xc) 6 //timing mode
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0xd) 7 //dispel/resistance
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0xe) 8 //duration
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x12) 9 //prob1
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x13) 10 //prob2
  WRITE_ASCII (%fx_off% + %abil_fx_idx% * 0x30 + 0x14) ~11~ #8 //resource
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x1c) 12 //#dice, maxlevel
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x20) 13 //dicesize, minlevel
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x24) 14 //save type
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x28) 15 //save bonus
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x2c) 16 //unknown

  //update #ability effects
  SET %abil_fx_num% += 1
  WRITE_SHORT (%abil_off% + %i% * 0x38 + 0x1e) %abil_fx_num%

  //update ability effect indices for abilities after current one
  FOR (j = i + 1; j < "%abil_num%"; j += 1) BEGIN
	READ_SHORT (%abil_off% + %j% * 0x38 + 0x20) abil_fx_idx
	WRITE_SHORT (%abil_off% + %j% * 0x38 + 0x20) (%abil_fx_idx% + 1)
  END

END

 END

 

Adding an effect to a spell on a single ability (header) or all abilities (headers)

COPY_EXISTING ~BALTH01.SPL~ ~override/BALTH01.SPL~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off

 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN //parse each ability
//verify specific ability - check the ability is the correct one to change here, must be unique
READ_BYTE (%abil_off% + %i% * 0x28) abil_type
PATCH_IF (%abil_type% = 0||1||2||3||4) BEGIN // ...or catch all abilities, this line not necessary for catch all anyway
  READ_SHORT (%abil_off% + %i% * 0x28 + 0x1e) abil_fx_num
  READ_SHORT (%abil_off% + %i% * 0x28 + 0x20) abil_fx_idx

   //add effect
  INSERT_BYTES (%fx_off% + %abil_fx_idx% * 0x30) 0x30

  //effect fields
  WRITE_SHORT (%fx_off% + %abil_fx_idx% * 0x30) 1 //type
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x2) 2 //target
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x3) 3 //power
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x4) 4 //param1
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x8) 5 //param2
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0xc) 6 //timing mode
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0xd) 7 //dispel/resistance
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0xe) 8 //duration
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x12) 9 //prob1
  WRITE_BYTE (%fx_off% + %abil_fx_idx% * 0x30 + 0x13) 10 //prob2
  WRITE_ASCII (%fx_off% + %abil_fx_idx% * 0x30 + 0x14) ~11~ #8 //resource
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x1c) 12 //#dice, maxlevel
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x20) 13 //dicesize, minlevel
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x24) 14 //save type
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x28) 15 //save bonus
  WRITE_LONG (%fx_off% + %abil_fx_idx% * 0x30 + 0x2c) 16 //unknown  END

  //update #ability effects
  SET %abil_fx_num% += 1
  WRITE_SHORT (%abil_off% + %i% * 0x28 + 0x1e) %abil_fx_num%

  //update ability effect indices for abilities after current one
  FOR (j = %i% + 1; j < "%abil_num%"; j += 1) BEGIN
	READ_SHORT (%abil_off% + %j% * 0x28 + 0x20) abil_fx_idx
	WRITE_SHORT (%abil_off% + %j% * 0x28 + 0x20) (%abil_fx_idx% + 1)
  END

END

 END

 

Deleting a global (equipping) effect from an item

//assumes global effects go before ability effects, if not, patch does nothing
COPY_EXISTING ~BOW20.ITM~ ~override/BOW20.ITM~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off
 READ_SHORT 0x70 fx_global_num

 //find the index of the first ability effect
 SET abil_fx_idx_lowest = 65536
 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN //parse each ability
READ_SHORT (%abil_off% + %i% * 0x38 + 0x20) abil_fx_idx
SET abil_fx_idx_lowest = (%abil_fx_idx_lowest% > %abil_fx_idx% ? %abil_fx_idx% : %abil_fx_idx_lowest%)
 END

 FOR (i = 0; i < "%abil_fx_idx_lowest%"; i += 1) BEGIN //parse each global effect
//verify specific effect - check the effect is the correct one to change here, must be unique
READ_SHORT (%fx_off% + %i% * 0x30) fx_type
PATCH_IF (%fx_type% = 1) BEGIN
  //delete effect
  DELETE_BYTES (%fx_off% + %i% * 0x30) 0x30

  //update #global effects
  SET %fx_global_num% -= 1
  WRITE_SHORT 0x70 %fx_global_num%

  //update ability effect indices
  FOR (j = 0; j < "%abil_num%"; j += 1) BEGIN
	READ_SHORT (%abil_off% + %j% * 0x38 + 0x20) abil_fx_idx
	WRITE_SHORT (%abil_off% + %j% * 0x38 + 0x20) (%abil_fx_idx% - 1)
  END

  //since current effect deleted, re-read current offset in next loop (since this becomes the next effect)
  SET abil_fx_idx_lowest -= 1
  SET i -= 1
END
 END

 

Deleting an ability (on-hit) effect from an item

COPY_EXISTING ~BOW20.ITM~ ~override/BOW20.ITM~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off

 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN //parse each ability

READ_BYTE (%abil_off% + %i% * 0x38) abil_type
//verify specific ability - check the ability is the correct one to change here, must be unique
PATCH_IF (%abil_type% = 0||1||2||3||4) BEGIN // ...or catch all abilities, this line not necessary for catch all anyway
  READ_SHORT (%abil_off% + %i% * 0x38 + 0x1e) abil_fx_num
  READ_SHORT (%abil_off% + %i% * 0x38 + 0x20) abil_fx_idx

  FOR (j = %abil_fx_idx%; j < "%abil_fx_idx%" + "%abil_fx_num%"; j += 1) BEGIN //parse each ability effect specific to current ability
	//verify specific effect - check the effect is the correct one to change here, must be unique
	READ_SHORT (%fx_off% + %j% * 0x30) fx_type
	PATCH_IF (%fx_type% = 1) BEGIN
	  //delete effect
	  DELETE_BYTES (%fx_off% + %j% * 0x30) 0x30

	  //update #ability effects
	  SET %abil_fx_num% -= 1
	  WRITE_SHORT (%abil_off% + %i% * 0x38 + 0x1e) %abil_fx_num%

	  //update ability effect indices for abilities after current one
	  FOR (k = i + 1; k < "%abil_num%"; k += 1) BEGIN
		READ_SHORT (%abil_off% + %k% * 0x38 + 0x20) abil_fx_idx
		WRITE_SHORT (%abil_off% + %k% * 0x38 + 0x20) (%abil_fx_idx% - 1)
	  END

	  //since current effect deleted, re-read current offset in next loop (since this becomes the next effect)
	  //abil_fx_num already updated above
	  SET j -= 1

	END

  END

END

 END

 

Deleting all effects from an item ability (header)

COPY_EXISTING ~AX1H16.ITM~ ~override/AX1H16.ITM~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off

 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN //parse each ability
//verify specific ability - check the ability is the correct one to change here, must be unique
READ_BYTE (%abil_off% + %i% * 0x38) abil_type
PATCH_IF (%abil_type% = 2) BEGIN
  READ_SHORT (%abil_off% + %i% * 0x38 + 0x1e) abil_fx_num
  READ_SHORT (%abil_off% + %i% * 0x38 + 0x20) abil_fx_idx

  //delete all effects in current ability
  DELETE_BYTES (%fx_off% + %abil_fx_idx% * 0x30) (%abil_fx_num% * 0x30)

  //update #ability effects
  WRITE_SHORT (%abil_off% + %i% * 0x38 + 0x1e) 0

  //update ability effect indices for abilities after current one
  FOR (j = i + 1; j < "%abil_num%"; j += 1) BEGIN
	READ_SHORT (%abil_off% + %j% * 0x38 + 0x20) abil_fx_idx
	WRITE_SHORT (%abil_off% + %j% * 0x38 + 0x20) (%abil_fx_idx% - %abil_fx_num%)
  END
END

 END

 

Deleting all effects from a spell ability (header)

COPY_EXISTING ~BALTH01.SPL~ ~override/BALTH01.SPL~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off

 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN //parse each ability
//verify specific ability - check the ability is the correct one to change here, must be unique
READ_BYTE (%abil_off% + %i% * 0x28) abil_type
READ_SHORT (%abil_off% + %i% * 0x28 + 0x10) abil_minlvl
PATCH_IF (%abil_type% = 2 && %abil_minlvl% = 1) BEGIN
  READ_SHORT (%abil_off% + %i% * 0x28 + 0x1e) abil_fx_num
  READ_SHORT (%abil_off% + %i% * 0x28 + 0x20) abil_fx_idx

  //delete all effects in current ability
  DELETE_BYTES (%fx_off% + %abil_fx_idx% * 0x30) (%abil_fx_num% * 0x30)

  //update #ability effects
  WRITE_SHORT (%abil_off% + %i% * 0x28 + 0x1e) 0

  //update ability effect indices for abilities after current one
  FOR (j = i + 1; j < "%abil_num%"; j += 1) BEGIN
	READ_SHORT (%abil_off% + %j% * 0x28 + 0x20) abil_fx_idx
	WRITE_SHORT (%abil_off% + %j% * 0x28 + 0x20) (%abil_fx_idx% - %abil_fx_num%)
  END
END

 END

Edited by Ascension64

Share this post


Link to post

I need to get ahold of Gort and get his fixes/changes listed, and get these up on the Wikki codebank too (though perhaps it is less useful than I originally thought. Reading the threads is a good exercise, too - I am not so sure that clipping code from disparate threads and setting them aside in the code bank is actually assisting anyone.)

Share this post


Link to post

I'll only speak for myself, but I used to just take code from other mods rather than a 'code commons' area, e.g. the cross-platform modding stuff that I put into BG1UB I stole from berelinde's Gavin NPC mod (shh....) and made some amendments to.

Edited by Ascension64

Share this post


Link to post
3) Pretty sure you can do this too - I think DavidW does it in SCS1
I can't seem to find it by merely glancing over the code. Could you give some hints where to look?
I thought he looked up StrRefs somehow with the Fineweapons macro or another one, but maybe not.

 

I also recall a vague discussion with Ascension64 about this sort of thing with reference to STRING_SET but I don't know if it went anywhere definite.

 

EVALUATE_BUFFER or something might do it, not sure.

Share this post


Link to post
3) Pretty sure you can do this too - I think DavidW does it in SCS1
I can't seem to find it by merely glancing over the code. Could you give some hints where to look?
I thought he looked up StrRefs somehow with the Fineweapons macro or another one, but maybe not.

 

I also recall a vague discussion with Ascension64 about this sort of thing with reference to STRING_SET but I don't know if it went anywhere definite.

 

EVALUATE_BUFFER or something might do it, not sure.

No no, you simply use SAY, a la nonsense to BGII files...

 

COPY_EXISTING ~RING09.ITM~ ~override/RING09.ITM~
 READ_LONG 0x64 abil_off
 READ_SHORT 0x68 abil_num
 READ_LONG 0x6a fx_off
 READ_SHORT 0x70 fx_global_num

 SET fx_total_num = %fx_global_num%

 //parse each ability to determine total number of effects
 FOR (i = 0; i < "%abil_num%"; i += 1) BEGIN
READ_SHORT (%abil_off% + %i% * 0x38 + 0x1E) abil_fx_num
SET fx_total_num += %abil_fx_num%
 END

 FOR (i = 0; i < "%fx_total_num%"; i += 1) BEGIN //parse each effect
//verify specific effect - check the effect is the correct one to change here, must be unique
READ_SHORT (%fx_off% + %i% * 0x30) fx_type
READ_LONG (%fx_off% + %i% * 0x30 + 0x4) fx_param1
PATCH_IF (%fx_type% = 267 && %fx_param1% = 14023) BEGIN //Disable Display String && "Hasted" (couldn't be bothered finding the right opcode, but you get the idea)
  SAY (%fx_off% + %i% * 0x30 + 0x4) @100
END
 END

 

setup.tra

@100 = "WASTED!"

Edited by Ascension64

Share this post


Link to post
Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...