Jump to content


Photo

[HELP WANTED]


  • Please log in to reply
10 replies to this topic

#1 @vGur

@vGur
  • Member
  • 121 posts

Posted 10 September 2009 - 02:06 PM

I've done an animations for medium shields to be used as a weapon :devil: , but now i can't write wright code to add weapon ability to copies of existante shields
COPY_EXISTING ~shld04.itm~ ~override/_@shld04.itm~
			  ~shld04.itm~ ~override/shld04.itm~
  READ_BYTE   0x31 "prof"
  READ_LONG   0x64 "abil_off"
  READ_SHORT  0x68 "abil_num"
  WRITE_SHORT 0x68 ("%abil_num%" + 1)
  READ_LONG   0x6a "fx_off"
  WRITE_LONG  0x6a ("%fx_off%" + 0x38)
  READ_SHORT  0x70 "fx_num"
  READ_SHORT ("%abil_off%" + 0x1e + (("%abil_num%" - 1) * 0x38)) "last_fx_num"
  READ_SHORT ("%abil_off%" + 0x20 + (("%abil_num%" - 1) * 0x38)) "last_fx_idx"
  SET "new_fx" = ("%last_fx_idx%" + "%last_fx_num%")
  PATCH_IF (~%DEST_RES%~ STRING_COMPARE_CASE ~%SOURCE_RES%~ != 0) BEGIN // if battle
	WRITE_BYTE "0x1f" "0x70" //shield profeciency
	WRITE_SHORT "0x1c" "0x15" // hammer type
	READ_BYTE   0x18 "flags"
	WRITE_BYTE  0x18 ("%flags%" BAND 0b11111011) //set unmovable		  
	INSERT_BYTES	("%fx_off%" +		("%new_fx%" * 0x30)) 0x30 // new effect
	  WRITE_SHORT		   ("%fx_off%" +		("%new_fx%" * 0x30)) 235 // wing buffet
	  WRITE_BYTE			("%fx_off%" + 0x02 + ("%new_fx%" * 0x30)) 2	// target: pre-target
	  WRITE_BYTE			("%fx_off%" + 0x0c + ("%new_fx%" * 0x30)) 1	// instant/permanent till death
	  WRITE_BYTE			("%fx_off%" + 0x04 + ("%new_fx%" * 0x30)) 2	// distance 2
	  WRITE_BYTE			("%fx_off%" + 0x08 + ("%new_fx%" * 0x30)) 2	//type 2
	  WRITE_BYTE			("%fx_off%" + 0x12 + ("%new_fx%" * 0x30)) 100  // probability
	INSERT_BYTES  ("%fx_off%"	   ) 0x38		 // new ability
	  WRITE_BYTE  ("%fx_off%"	   ) 1		   //melee
	  WRITE_BYTE  ("%fx_off%" + 0x01) 0			// ID to use - no matter
	  WRITE_SHORT ("%fx_off%" + 0x02) 1			// in weapon slots
	  WRITE_ASCII ("%fx_off%" + 0x04) ~Ishld29~ //icon - useless
	  WRITE_SHORT ("%fx_off%" + 0x0c) 1   // target: creature
	  WRITE_BYTE ("%fx_off%" + 0x26) 1		   // use strength
	  WRITE_SHORT ("%fx_off%" + 0x0e) 0			// range: 0
	  WRITE_SHORT ("%fx_off%" + 0x12) 6			// speed 6
	  WRITE_SHORT ("%fx_off%" + 0x16) 6		  // damX
	  WRITE_SHORT ("%fx_off%" + 0x18) 1			// Xdam
	  WRITE_SHORT ("%fx_off%" + 0x1c) 2			// dam type - blunt
	  WRITE_SHORT ("%fx_off%" + 0x2c) 50			// overhand
	  WRITE_SHORT ("%fx_off%" + 0x2e) 50			// backhand
	  WRITE_SHORT ("%fx_off%" + 0x1e) 1			// num effects: 1
	  WRITE_SHORT ("%fx_off%" + 0x20) ("%new_fx%") // fx index
	  WRITE_SHORT ("%fx_off%" + 0x22) 0	// num charges: 0
	  WRITE_BYTE  ("%fx_off%" + 0x24) 0	// don't vanish
	  WRITE_SHORT ("%fx_off%" + 0x2a) 1	// projectile: none
  END
what isn't right? <_<
I Want to release this as sooner as possible, before my new work starts

Edited by @vGur, 10 September 2009 - 02:09 PM.


#2 Kaeloree

Kaeloree

    Head Molder

  • Administrator
  • 9198 posts

Posted 10 September 2009 - 02:08 PM

Not a Classifieds post, moved to IE Modding Help. :)

#3 Wisp

Wisp
  • Modder
  • 1353 posts

Posted 10 September 2009 - 03:28 PM

Try this:
COPY_EXISTING ~shld04.itm~ ~override/_@shld04.itm~
			  ~shld04.itm~ ~override/shld04.itm~
  READ_BYTE   0x31 "prof"
  READ_LONG   0x64 "abil_off"
  READ_SHORT  0x68 "abil_num"
  READ_LONG   0x6a "fx_off"
  READ_SHORT  0x70 "fx_num"
  FOR (i=0;i<abil_num;i+=1) BEGIN
	READ_SHORT abil_off + 0x1e + i*0x38 num_l_fx
	fx_num += num_l_fx
  END
  SET "new_fx" = fx_num
  PATCH_IF (~%DEST_RES%~ STRING_COMPARE_CASE ~%SOURCE_RES%~ != 0) BEGIN // if battle
	WRITE_SHORT 0x68 ("%abil_num%" + 1)
	WRITE_LONG  0x6a ("%fx_off%" + 0x38)
	WRITE_BYTE "0x1f" "0x70" //shield profeciency
	WRITE_SHORT "0x1c" "0x15" // hammer type
	READ_BYTE   0x18 "flags"
	WRITE_BYTE  0x18 ("%flags%" BAND 0b11111011) //set unmovable		  
	INSERT_BYTES	("%fx_off%" +		("%new_fx%" * 0x30)) 0x30 // new effect
	  WRITE_SHORT		   ("%fx_off%" +		("%new_fx%" * 0x30)) 235 // wing buffet
	  WRITE_BYTE			("%fx_off%" + 0x02 + ("%new_fx%" * 0x30)) 2	// target: pre-target
	  WRITE_BYTE			("%fx_off%" + 0x0c + ("%new_fx%" * 0x30)) 1	// instant/permanent till death
	  WRITE_BYTE			("%fx_off%" + 0x04 + ("%new_fx%" * 0x30)) 2	// distance 2
	  WRITE_BYTE			("%fx_off%" + 0x08 + ("%new_fx%" * 0x30)) 2	//type 2
	  WRITE_BYTE			("%fx_off%" + 0x12 + ("%new_fx%" * 0x30)) 100  // probability
	INSERT_BYTES  ("%abil_off%" + abil_num*0x38	   ) 0x38		 // new ability
	  WRITE_BYTE  ("%abil_off%" + abil_num*0x38	   ) 1		   //melee
	  WRITE_BYTE  ("%abil_off%" + abil_num*0x38 + 0x01) 0			// ID to use - no matter
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x02) 1			// in weapon slots
	  WRITE_ASCII ("%abil_off%" + abil_num*0x38 + 0x04) ~Ishld29~ //icon - useless
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x0c) 1   // target: creature
	  WRITE_BYTE ("%abil_off%" + abil_num*0x38 + 0x26) 1		   // use strength
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x0e) 0			// range: 0
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x12) 6			// speed 6
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x16) 6		  // damX
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x18) 1			// Xdam
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x1c) 2			// dam type - blunt
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x2c) 50			// overhand
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x2e) 50			// backhand
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x1e) 1			// num effects: 1
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x20) ("%new_fx%") // fx index
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x22) 0	// num charges: 0
	  WRITE_BYTE  ("%abil_off%" + abil_num*0x38 + 0x24) 0	// don't vanish
	  WRITE_SHORT ("%abil_off%" + abil_num*0x38 + 0x2a) 1	// projectile: none
  END

Presumably you want to add something to shld04 as well, in which case you want to update abil_num and fx_off for that item as well. In the code above, I moved those two WRITEs inside the PATCH_IF since they corrupt the file otherwise.
Also, you were not inserting the new effect last and if the item already had an ability, it'd get screwed up, since you inserted the new ability before any existing abilities.

#4 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 10 September 2009 - 03:31 PM

COPY_EXISTING ~shld04.itm~ ~override/_@shld04.itm~
~shld04.itm~ ~override/shld04.itm~
READ_BYTE 0x31 "prof"
READ_LONG 0x64 "abil_off"
READ_SHORT 0x68 "abil_num"
WRITE_SHORT 0x68 ("%abil_num%" + 1)
READ_LONG 0x6a "fx_off"
WRITE_LONG 0x6a ("%fx_off%" + 0x38)
READ_SHORT 0x70 "fx_num"
READ_SHORT ("%abil_off%" + 0x1e + (("%abil_num%" - 1) * 0x38)) "last_fx_num"
READ_SHORT ("%abil_off%" + 0x20 + (("%abil_num%" - 1) * 0x38)) "last_fx_idx"
SET "new_fx" = ("%last_fx_idx%" + "%last_fx_num%")

PATCH_IF (~%DEST_RES%~ STRING_COMPARE_CASE ~%SOURCE_RES%~ != 0) BEGIN // if battle
...

You presume that items already have at least one ability header, which may not be true.

Use this instead
PATCH_IF (abil_num > 0) BEGIN
  READ_SHORT ("%abil_off%" + 0x1e + (("%abil_num%" - 1) * 0x38)) "last_fx_num"
  READ_SHORT ("%abil_off%" + 0x20 + (("%abil_num%" - 1) * 0x38)) "last_fx_idx"
  SET "new_fx" = ("%last_fx_idx%" + "%last_fx_num%")
END ELSE BEGIN
  new_fx=fx_num
END

PS Wisp beated me.

Edited by GeN1e, 10 September 2009 - 03:32 PM.

Retired from modding.


#5 @vGur

@vGur
  • Member
  • 121 posts

Posted 11 September 2009 - 03:27 PM

Great Thanks!!! :cheers:
Now mod works fine, tomorow i'll release it in miscelaneus mods.
Another one (optional) component don't work (at all :crying: ), it's the last thing, that stopping me from release. However, tomorow it will happen
BEGIN @9 // Proper weight and AC bonus for Tower Shields
COPY_EXISTING ~shld05.itm~ ~override/_@twrshl.itm~
  READ_LONG  0x64 "abil_offset"
  READ_SHORT 0x68 "abil_number"
  READ_LONG  0x6A "fx_offset"
  READ_SHORT 0x70 "fx_number"
  SET "loops" = "%fx_number%"
  SET "fx_number_delta" = 0
  READ_SHORT ("%fx_offset%" + (("%loops%" - 1) * 0x30)) "ac"
//  READ_LONG (0x04 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) "ex_ac"
  READ_LONG (0x08 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) "zero"
  WHILE ("%loops%" > 0) BEGIN // this major WHILE loop examines existing effects and adjusts them accordingly
	PATCH_IF (("%ac%" = 0) AND ("%zero%" = 0)) BEGIN // looking for existante ac bonus
	  READ_LONG (0x04 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) "ex_ac"
	  SET "new_ac" = (4 - "%ex_ac%") // additinal amount of ac bonus (ordinar shield must have 4)
	  INNER_ACTION BEGIN // large-tower shields
		ACTION_FOR_EACH ~item~ IN
  ~_shld05.itm~
  ~_shld06.itm~
  ~_shld07.itm~
  ~_shld15.itm~
  ~_shld16.itm~
  ~_shld18.itm~
  ~_shld19.itm~
  ~cb351g03.itm~
  ~cbcl037.itm~   // mystery of the dead (large shield)
  ~cblyshld.itm~  // lyrar's shield (large shield)
  ~cbmhshld.itm~  // large shield +3 (large shield)
  ~cbmilt03.itm~
  ~cbmilt13.itm~
  ~cbrolfsh.itm~  // rolf sureblade's shield (medium shield? or tower shield?)
  ~cbsbmltx.itm~
  ~cbsbmlty.itm~
  ~cbtempus.itm~  // holy shield of tempus (large shield)
  ~cbtssd01.itm~  // large shield +5 (large shield)
  ~cbwtni5a.itm~  // shield of belvin (large shield?)
  ~cmshld01.itm~  // shield +3 (kite/tower/body shield)
  ~deitm122.itm~
  ~dsshld02.itm~
  ~dsshld54.itm~
  ~frozshld.itm~
  ~fwshld01.itm~
  ~gcmsh02.itm~
  ~guardshz.itm~  // soul guard (tower shield)
  ~holyshld.itm~
  ~jers.itm~
  ~mashld01.itm~  // large mithril shied +3 (large shield)
  ~mystery.itm~
  ~newshp1.itm~
  ~newshpo.itm~
  ~newsl01.itm~
  ~newsl02.itm~
  ~ntshld02.itm~  // shield of the firewine (large shield)
  ~ntshld03.itm~  // reinforced large shield (large shield)
  ~orrshld.itm~   // orrick's rhino beetle shield (tower shield)
  ~psq117.itm~
  ~psq58.itm~
  ~s!shld02.itm~  // supreme shelter +6 (tower shield)
  ~shld05.itm~
  ~shld06.itm~
  ~shld07.itm~
  ~shld15.itm~
  ~shld16.itm~
  ~shld18.itm~
  ~shld19.itm~
  ~shld23.itm~
  ~shld30.itm~
  ~shld31.itm~
  ~shld54.itm~	// large shield +2, +7 vs. missiles: 'the wall' (large shield)
  ~shldraid.itm~
  ~shldxz.itm~
  ~tzshld01.itm~
  ~ushld3b.itm~   // storming shield +3 (tower shield)
  ~x#fash01.itm~
		BEGIN
		  ACTION_IF (FILE_EXISTS_IN_GAME ~%item%~) BEGIN
			COPY_EXISTING ~%item%~ ~override~
			  PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
				WRITE_SHORT 0x1C 194 //type
				WRITE_LONG 0x4C 45  // D&D 3,5 wt
				READ_LONG  0x64 "abil_offset"
				READ_SHORT 0x68 "abil_number"
				READ_LONG  0x6A "fx_offset"
				READ_SHORT 0x70 "fx_number"
				SET "loops" = "%fx_number%"
				SET "fx_number_delta" = 0
				WHILE ("%loops%" > 0) BEGIN // this major WHILE loop examines existing effects and adjusts them accordingly
				  READ_SHORT ("%fx_offset%" + (("%loops%" - 1) * 0x30)) "effect"
				  READ_LONG (0x04 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) "value"
				  READ_LONG (0x08 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) "button"
				  SET "patch_ac" = "0"
				  PATCH_IF (("%effect%" = 0) AND ("%patch_ac%" = 0) AND ("%button%" = 0)) BEGIN // ac value is in this effect
					WRITE_LONG (0x04 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) ("%value%" + "%new_ac%")
					SET "patch_ac" = 1
				  END
				END //while
			  END //patch_if size
		  END //action_if file exist
		END //action_in
	  END //inner_action
	END //patch_if
  END //while

Edited by @vGur, 11 September 2009 - 03:31 PM.


#6 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 11 September 2009 - 05:13 PM

Your code is... wierd... a little...

Are you trying to set new weight, item type, and base AC to all items listed?
ACTION_FOR_EACH item IN
~shld05~
/* LONG_LIST */
BEGIN
COPY_EXISTING ~%item%.itm~ ~override~
  PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
	WRITE_LONG 0x1c 194 // I do not know what it means
	WRITE_LONG 0x4c 45

	READ_LONG 0x6a ef_off
	READ_SHORT 0x6e ef_ind
	READ_SHORT 0x70 ef_num
	FOR (i=0;i<ef_num;i+=1) BEGIN
	  READ_SHORT (ef_off+(ef_ind+i)*0x30) opcode
	  READ_LONG (ef_off+(ef_ind+i)*0x30+0x4) par1 // currect AC
	  READ_LONG (ef_off+(ef_ind+i)*0x30+0x8) par2
	  PATCH_IF opcode=0 & par2=0 BEGIN
		WRITE_LONG (ef_off+(ef_ind+i)*0x30+0x4) (par1+3) // current AC + 3
	  END
	END
  END
BUT_ONLY

END

Retired from modding.


#7 @vGur

@vGur
  • Member
  • 121 posts

Posted 12 September 2009 - 02:27 AM

I'm not a *real* coder, I'm only learning this to improve my skills & my english, merging pieces of code, trying to understand how things works, and yes, sometimes weird things happen.
Here I'm try to discover what current base ac bonus (after so many mods installed) is giving from tower shield, I want it to be 4, but i can't just set it to 4, so i distract current ac (from not-enchanted tower shield) from 4 (4 - current ac bonus = ac bonus, that i want to merge with current tower shield bonus (Is it still understandable?). Type update is only for Item revision compatibility. For now i'll wait till evening (20.00 CET), maeby someone can provide a way it can be done.
Still, Thanks for help :D

#8 Mike1072

Mike1072
  • Modder
  • 539 posts

Posted 12 September 2009 - 03:40 AM

I can see the reasoning behind your code. In general though, using an INNER_ACTION where you don't need to is something to avoid - you can accomplish what you're attempting by setting a variable when you find "new_ac", exiting the shld05.itm patch, and then starting the ACTION_FOR_EACH in its own action, not in the middle of copying the other item.
Ex:
BEGIN @9 // Proper weight and AC bonus for Tower Shields
OUTER_SET "found_ac" = 0 // false
COPY_EXISTING ~shld05.itm~ ~override/_@twrshl.itm~
  // reads go here
  // loop starts here
	PATCH_IF (("%ac%" = 0) AND ("%zero%" = 0)) BEGIN // looking for existante ac bonus
	  READ_LONG (0x04 + "%fx_offset%" + (("%loops%" - 1) * 0x30)) "ex_ac"
	  SET "new_ac" = (4 - "%ex_ac%") // additinal amount of ac bonus (ordinar shield must have 4)
	  SET "found_ac" = 1 // true
	END
  END // end loop
  BUT_ONLY_IF_IT_CHANGES // only copy the item if changes were actually made (assuredly none were made here)

ACTION_IF ("found_ac" == 1) BEGIN // if we were able to get the new AC bonus information out of shld05
  ACTION_FOR_EACH ~item~ IN // large-tower shields
	// long list here
  BEGIN
	ACTION_IF (FILE_EXISTS_IN_GAME ~%item%~) BEGIN
	  COPY_EXISTING ~%item%~ ~override~
		PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
		  // patch to increase AC by "new_ac" goes here
		END
		BUT_ONLY_IF_IT_CHANGES
	END
  END // end action_for_each
END

Type update is only for Item revision compatibility.

WRITE_SHORT 0x1C 194 //type
This is not needed for IR compatibility, and indeed may be causing some of your problems.

I'll try to explain why you may have seen that code used in IR or the BG2 Tweak Pack. These mods apply some patches to armours and shields. Since there is no foolproof way to tell exactly what type of armour or shield an item is from the .itm file, they rely on a manually-edited list of all known vanilla and mod items. This list identifies the different items as belonging to certain categories (splint mail, hide armor, medium shield) by temporarily changing the type of those items to an arbitrary value (like 194) that is unused by anything else. Then, all items can be run through a patch to set thieving penalties or arcane casting penalties at the same time. The patch checks the item type field to determine what kind of armour/shield the .itm is, and when it's done, it resets each item's type back to 2 (armor) or 12 (shield).

#9 @vGur

@vGur
  • Member
  • 121 posts

Posted 14 September 2009 - 01:38 PM

Thanks for help! Still, your code isn't work for me <_< , BUT, I spend more time than I wish & did little bit more (now it's not only concept demo, regardless it's name, I proud to present new mod - Pre-release Unfinished Business - Shield as a weapon (Revised Shields) Readme inside
:cheers:

p.s. Last question, how i can add tooltips? (strings, that appear when you point the shield in equipment menu)

p.p.s This isn't right place to publish mod, if You find no bugs, tell me, And I release this in proper place. Thanks for help!

Attached Files


Edited by @vGur, 15 September 2009 - 12:45 AM.


#10 Miloch

Miloch

    Barbarian

  • Modder
  • 6573 posts

Posted 15 September 2009 - 01:31 AM

p.s. Last question, how i can add tooltips? (strings, that appear when you point the shield in equipment menu)

You have to APPEND ~tooltip.2da~ ~%SOURCE_RES% [STRING1] [STRING2] -1 [...]~ UNLESS ~%SOURCE_RES%~
This can get nasty, because some mods have added columns to tooltip.2da (hence the [...]). And if your item's already there, you'll have to patch it instead. And if you're adding *new* strings, it's even trickier. There's some code in Thrown Hammers to this effect, though I don't recall if it's in the current version.

p.p.s This isn't right place to publish mod, if You find no bugs, tell me, And I release this in proper place. Thanks for help!

I'll try to look at it next time I test stuff in the game - kinda busy coding stuff right now though. But yes, it should go in Misc. Released Mods eventually :).

Infinity Engine Contributions
Aurora * BG1 NPC * BG1 Fixpack * Haiass * Infinity Animations * Level 1 NPCs * P5Tweaks
PnP Free Action * Thrown Hammers * Unique Containers * BG:EE * BGII:EE * IWD:EE
================================================================
Player & Modder Resources
BAM Batcher * Creature Lister * Creature Checker * Creature Fixer * Tutu/BGT Area Map & List * Tutu Mod List
================================================================
"Infinity turns out to be the opposite of what people say it is. It is not 'that which has nothing beyond itself' that is infinite, but 'that which always has something beyond itself'." -Aristotle


#11 Daulmakan

Daulmakan

    Comfortably numb

  • Member
  • 1065 posts

Posted 15 September 2009 - 02:12 AM

p.s. Last question, how i can add tooltips? (strings, that appear when you point the shield in equipment menu)

Here's the relevant code, courtesy of the amazing Mike1072. :Bow:

There's a macro used in Item Revisions that will help:

/*-----------------Tooltip Macro-----------------*/

OUTER_SPRINT tooltip_string_1 ~mi_1_default~
OUTER_SPRINT tooltip_string_2 ~mi_2_default~
OUTER_SPRINT tooltip_string_3 ~mi_3_default~
// macro to set the tooltip references for items' activated abilities - requires 'tooltip_itm' be set to the name of the .itm file we are changing, and 'tooltip_string_1', _2, and _3 to be set to the new tooltips - those that are not set will have their position set to -1 instead of a strref
DEFINE_ACTION_MACRO ~SET_ITEM_ABILITY_TOOLTIPS~ BEGIN
  
  // set column values, including placeholders for future strrefs
  ACTION_IF (~%tooltip_string_1%~ STRING_EQUAL ~mi_1_default~) BEGIN // tooltip_string_1 was not set to a new tooltip
	OUTER_SPRINT mi_col_1 ~-1~ // no strref
  END ELSE BEGIN // tooltip_string_1 has been set to a new tooltip, so we'll stick in the strref using a later REPLACE
	OUTER_SPRINT mi_col_1 ~mi_placeholder_1~
  END
  
  ACTION_IF (~%tooltip_string_2%~ STRING_EQUAL ~mi_2_default~) BEGIN // tooltip_string_2 was not set to a new tooltip
	OUTER_SPRINT mi_col_2 ~-1~
  END ELSE BEGIN // tooltip_string_2 has been set to a new tooltip, so we'll stick in the strref using a later REPLACE
	OUTER_SPRINT mi_col_2 ~mi_placeholder_2~
  END
  
  ACTION_IF (~%tooltip_string_3%~ STRING_EQUAL ~mi_3_default~) BEGIN // tooltip_string_3 was not set to a new tooltip
	OUTER_SPRINT mi_col_3 ~-1~
  END ELSE BEGIN // tooltip_string_3 has been set to a new tooltip, so we'll stick in the strref using a later REPLACE
	OUTER_SPRINT mi_col_3 ~mi_placeholder_3~
  END

  // modify the file
  COPY_EXISTING ~tooltip.2da~ ~override~
	SET exists = 0
	COUNT_2DA_ROWS 4 num_rows
	FOR (i = 0; i < num_rows; i += 1) BEGIN
	  READ_2DA_ENTRY %i% 0 4 current_item
	  // if we find the item already has tooltips
	  PATCH_IF (~%current_item%~ STRING_EQUAL_CASE ~%tooltip_itm%~) BEGIN
		SET exists = 1
		
		SET_2DA_ENTRY %i% 1 4 ~%mi_col_1%~ // set 1st tooltip
		SET_2DA_ENTRY %i% 2 4 ~%mi_col_2%~ // set 2nd tooltip
		SET_2DA_ENTRY %i% 3 4 ~%mi_col_3%~ // set 3rd tooltip
	  END
	END
	
	// if the .itm is not in the list yet
	PATCH_IF (exists == 0) BEGIN
	  // add a row for it
	  INSERT_2DA_ROW 0 4 ~%tooltip_itm%			%mi_col_1%		%mi_col_2%	   %mi_col_3%~
	END
	
	// replace any placeholder values
	PATCH_IF (NOT ~%mi_col_1%~ STRING_EQUAL ~-1~) BEGIN
	  REPLACE ~mi_placeholder_1~ ~%tooltip_string_1%~
	END
	PATCH_IF (NOT ~%mi_col_2%~ STRING_EQUAL ~-1~) BEGIN
	  REPLACE ~mi_placeholder_2~ ~%tooltip_string_2%~
	END
	PATCH_IF (NOT ~%mi_col_3%~ STRING_EQUAL ~-1~) BEGIN
	  REPLACE ~mi_placeholder_3~ ~%tooltip_string_3%~
	END
	
	BUT_ONLY_IF_IT_CHANGES
  
  // reset variables
  OUTER_SPRINT tooltip_string_1 ~mi_1_default~
  OUTER_SPRINT tooltip_string_2 ~mi_2_default~
  OUTER_SPRINT tooltip_string_3 ~mi_3_default~
END

To use it, just do:
OUTER_SPRINT tooltip_itm ~AMUL17~
OUTER_SPRINT tooltip_string_1 ~Mind Shield~
LAUNCH_ACTION_MACRO ~SET_ITEM_ABILITY_TOOLTIPS~

Or:
OUTER_SPRINT tooltip_itm ~CLCK27~
OUTER_SPRINT tooltip_string_1 ~Polymorph: Rat~
OUTER_SPRINT tooltip_string_2 ~Polymorph: Troll~
OUTER_SPRINT tooltip_string_3 ~Polymorph: Mustard Jelly~
LAUNCH_ACTION_MACRO ~SET_ITEM_ABILITY_TOOLTIPS~

item_pack.jpg   Drows.jpg