Jump to content


Photo

Adding and patching projectiles


  • Please log in to reply
6 replies to this topic

#1 Miloch

Miloch

    Barbarian

  • Modder
  • 6579 posts

Posted 30 June 2008 - 10:09 AM

From a discussion started in this topic.

I would like to see in some shape or form some sample code that I could work off of:
1.) ADD_PROJECTILE (the easy part)
2.) Patching spells and items (still the easy part)
3.) Patching effects within spells that use projectile entries (ie physical mirror).
4.) Patching projectiles that use other projectiles (yes, there are some).

1. Adding a new projectile
ADD_PROJECTILE ~mymod/pros/PSHAMMA.pro~ //Green Thrown Hammer
2. Patching an item to use the new projectile (spell would be similar)
ACTION_IF FILE_EXISTS_IN_GAME ~aegis.itm~ THEN BEGIN //Aegis-Fang +3
  COPY_EXISTING ~aegis.itm~ ~override~
	PATCH_IF SOURCE_SIZE > 0x71 BEGIN
	  READ_LONG 0x64 hf //Extended header offset
	  READ_SHORT 0x68 hc //Extended header count
	  FOR (i = 0; i < hc; i += 1) BEGIN //Cycle through headers
		READ_BYTE (0x38 * i + hf) pt //Attack type
		PATCH_IF pt = 2 BEGIN
		  WRITE_ASCII (0x38 * i + hf + 4) ~T-AEGIST~ #8 //Use icon 1 (ranged)
		  WRITE_SHORT (0x38 * i + hf + 0x2a) ~%PSHAMMA%~ //Projectile animation
		END ELSE PATCH_IF pt = 1 BEGIN
		  WRITE_ASCII (0x38 * i + hf + 4) ~T-AEGISI~ #8 //Use icon 2 (melee)
		  WRITE_SHORT (0x38 * i + hf + 0x2a) 1 //Projectile animation (none)
		END
	  END
	END
  BUT_ONLY_IF_IT_CHANGES
END
3. Patching effects within spells that use projectiles
ADD_PROJECTILE ~mymod/pros/NEWAROW1.pro~ //New Arrow projectile 1
ADD_PROJECTILE ~mymod/pros/NEWAROW2.pro~ //New Arrow projectile 2

COPY_EXISTING ~sppr613.spl~ ~override~ //Physical Mirror
  PATCH_IF SOURCE_SIZE > 0x71 BEGIN
	READ_LONG 0x64 hf //Extended header offset
	READ_SHORT 0x68 hc //Extended header count
	READ_LONG 0x6a fb //Feature block offset
	hd = 0
	FOR (i1 = 0; i1 < hc; i1 += 1) BEGIN //Cycle through extended headers
	  READ_SHORT (hf + 0x1e + (0x28 * i1)) fc //Feature count
	  READ_SHORT (hf + 0x20 + (0x28 * i1)) fs //Feature offset
	  //Example 1: change an existing effect with a projectile
	  FOR (i2 = fs; i2 < (fs + fc); i2 += 1) BEGIN //Cycle through ability effects
		READ_SHORT (0x30 * i2 + fb) pc //Opcode
		READ_LONG (0x30 * i2 + fb + 8) p2 //Parameter 2
		PATCH_IF (pc = 197) AND (p2 = 1) BEGIN //If "Bounce Projectile" and "Arrow"
		  WRITE_LONG (fb + 0x30 * i2 + 8) ~%NEWAROW%~ //New Arrow projectile 1
		END
	  END
	  //Example 2: add a new effect with a projectile
	  PATCH_IF (i1 = (hd - 1)) OR (hd = 0) BEGIN //hd=1 means i1=0
		INSERT_BYTES (fb + (0x30 * (fc + fs))) 0x30
		WRITE_SHORT (fb + (0x30 * (fc + fs))) 197 //Opcode (Bounce Projectile)
		WRITE_BYTE (fb + 2 + (0x30 * (fc + fs))) 1 //Target (Self)
		WRITE_BYTE (fb + 3 + (0x30 * (fc + fs))) 6 //Power
		WRITE_LONG (fb + 8 + (0x30 * (fc + fs))) ~%NEWAROW2%~ //Parameter 2
		WRITE_BYTE (fb + 0xd + (0x30 * (fc + fs))) 3 //Dispellability
		WRITE_BYTE (fb + 0xe + (0x30 * (fc + fs))) 54 //Duration
		WRITE_BYTE (fb + 0x12 + (0x30 * (fc + fs))) 100 //Probability 1
		fc += 1 //Increment feature count
		hd += 1 //Increment header
		WRITE_SHORT (hf + 0x1e + (0x28 * i1)) fc //Update feature count
		FOR (i2 = 0; i2 < hc; i2 += 1) BEGIN //Update 1st effect indices
		  READ_SHORT (hf + i2 * 0x28 + 0x20) fx //1st effect index
		  PATCH_IF (fx > i1) BEGIN //If ability after current effect
			WRITE_SHORT (hf + i2 * 0x28 + 0x20) (fx + 1) //Increase 1st effect i1 by 1
		  END
		END
	  END
	END
  END
BUT_ONLY_IF_IT_CHANGES
4. Patch a projectile within a projectile
ADD_PROJECTILE ~mymod/pros/NEWDART.pro~ //New Dart projectile

COPY_EXISTING ~traptime.pro~ ~override~
  PATCH_IF SOURCE_SIZE > 0x2ff BEGIN //Needs the area effect structure
	READ_SHORT 0x21a xj //Explosion projectile
	PATCH_IF xj = 32 BEGIN //If old Dart projectile
	  WRITE_SHORT 0x21a ~%NEWDART%~ //New Dart projectile
	END
  END
BUT_ONLY_IF_IT_CHANGES
I cobbled this all together rather quickly from existing code and guesswork, so I can't guarantee it all works, but it should give you examples at least.

The best thing, really would be writing some sort of function that assigns a new projectile value based off an old value and making sure all projectiles, effects, spells, and items using some old value are patched to some new value.

What I am talking about is literally, patching thousands of spells with hundreds of projectiles. If I change SpellPack, then I have to change the rest of my work as well. I cannot deviate and split my work into two. This is no joke, and I am not willing to do this alone.

You could move a lot of the code above to macros and then patch spells en masse using COPY_EXISTING_REGEXP (which I think you already do with SpellPack). I do something similar in a couple different mods.

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


#2 -Guest-

-Guest-
  • Guest

Posted 30 June 2008 - 12:05 PM

Keep in mind that PRO references vary (some start from 0; others start with 1). IIRC, the bounce PRO effect parameter needs to be %NEWARROW% (or whatever) - 1 (or +1, or the ability projectile needs to be %blah% + 1 or something).

#3 Galactygon

Galactygon

    Modding since 2002

  • Member
  • 938 posts

Posted 25 July 2008 - 05:42 AM

Because various components use the same projectiles, and I would like to avoid adding a projectile that already exists, how would I determine if that projectile already exists in the PROJECTL.IDS? The other thing about projectiles, how would I assign projectiles based on finding the filename rather than the entry, as variables are lost when the user installs component A, quits, and goes back to install component B?

-Galactygon
Posted Image

#4 Miloch

Miloch

    Barbarian

  • Modder
  • 6579 posts

Posted 25 July 2008 - 08:44 AM

I copied your question in the G3 thread. No sense us writing macros if bigg is willing to do it, heh.

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


#5 Lord-Jyssev

Lord-Jyssev

    LĪJ

  • Member
  • 451 posts

Posted 29 July 2009 - 06:23 PM

Does the ADD_PROJECTILE command append the Projectl.ids to include the new projectile or does it simply copy the file over?

#6 Miloch

Miloch

    Barbarian

  • Modder
  • 6579 posts

Posted 29 July 2009 - 07:15 PM

Does the ADD_PROJECTILE command append the Projectl.ids to include the new projectile or does it simply copy the file over?

It copies the projectile to the override and appends it to the next open slot in projectl.ids which, being an unknown usually, you can reference with a variable with the same name of the projectile as in the examples above.

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


#7 Lord-Jyssev

Lord-Jyssev

    LĪJ

  • Member
  • 451 posts

Posted 29 July 2009 - 07:30 PM

Very nifty, I'll be using this soon!