Jump to content

WeiDU question


Galactygon

Recommended Posts

Does it happen with every spell file?

 

No, only the ones that have their names match the string "Breach". Because some of these Breach spells are used by Mislead, they have no actual effects. So this piece of code checks if the Breach we are talking about is real or not.

 

Because Breach always uses one extended header, this ought to work. Maybe I could try looping through and counting the number of extended headers, but I would like to see why my way doesn't work.

 

-Galactygon

Link to comment
Yes, what Taimon said. You want to do:
READ_LONG 0x64 hd_off
READ_SHORT 0x68 hd_num
READ_LONG 0x6a fb_off
FOR (loops = 0; loops < hd_num; loops = loops + 1) BEGIN
 READ_SHORT (loops * 0x28 + hd_off + 0x1e) fx_num
 READ_SHORT (loops * 0x28 + hd_off + 0x20) fx_off
 FOR (loops2 = fx_off; loops2 < (fx_off + fx_num); loops2 += 1)
READ_SHORT (loops2 * 0x30 + fb_off) check //Opcode
  PATCH_IF ( "check" = 221 ) BEGIN
	SET "correct" = 1
	PATCH_PRINT ~Hit: %SOURCE_FILE% header %loops%.~ //Useful for debugging
  END
  END
END

Or something like that.

 

Why is the extended header size 0x28 at some points, and 0x30 at some other points, rather than 0x30 all the way?

 

-Galactygon

Link to comment
Also, be sure to use NO_IF_EVAL_BUG as tp2 flag.
I never quite understood this. "Solves a long-standing bug with the IF_EVAL action... IF_EVAL will not work if used in a tp2." So what's the point if you're not using IF_EVAL (which, I believe, was phased out before I even started modding)?
Link to comment
Can you show us some more of your code? (Difficult to reproduce without the WRITE.)

 

The rest works perfectly, and I doubt it has anything to do with running out of bounds. Nonetheless, here it is:

 

Can you show us some more of your code? (Difficult to reproduce without the WRITE.)

 

The rest works perfectly, and I doubt it has anything to do with running out of bounds. Nonetheless, here it is. It looks messy here, so you are better off copying and pasting it into some .tp2.

 

-Galactygon

 

// Breach affects Invulnerability to (Normal and Magical) Weapons, Guardian Mantle
COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ ~override~
 READ_LONG   0x08 "name"  ELSE 0
 PATCH_IF ( (SOURCE_SIZE > 0x71) AND ( ("%name%"=5021) OR ("%name%"=16969) OR ("%name%"=25914) ) ) THEN BEGIN // protects against invalid files and is the spell really breach?
 SET "numsectype" = 3
 SET "correct" = 0
 READ_LONG   0x64 "abil_off"
 READ_SHORT  0x68 "abil_num"
 READ_LONG   0x6a "fx_off"
 READ_SHORT  0x90 "fx_num"
 FOR (loops = 0; loops < fx_num; loops = loops + 1) BEGIN // Checks if there are any other opcodes using opcode #221
  READ_SHORT  ("%fx_off%" + ("%loops%" * 0x30)) "check"	// Checks the opcode number
	PATCH_IF ( "check" = 221 ) BEGIN
	   SET "correct" = 1
  END
 END
 FOR (outerloops = 0; outerloops < numsectype; outerloops = outerloops + 1) BEGIN
	READ_LONG   0x64 "abil_off"
	READ_SHORT  0x68 "abil_num"
	READ_LONG   0x6a "fx_off"
	READ_SHORT  0x90 "fx_num"
	SET "new_fx" = 1
  SET "check" = 0
  PATCH_IF ("%correct%" = 1) BEGIN
	WRITE_SHORT 0x90 ("%fx_num%" + "%new_fx%")
	INSERT_BYTES ("%fx_off%" +		("%fx_num%" * 0x30)) 0x30 			// new effect
	WRITE_SHORT  ("%fx_off%" +		("%fx_num%" * 0x30)) 221			  // Remove secondary type
  READ_BYTE	   ("%fx_off%" + 0x03 + (("%fx_num%"-1) * 0x30)) "power"		// Read power of previous effect
	WRITE_BYTE   ("%fx_off%" + 0x03 + ("%fx_num%" * 0x30)) "%power%"   		// Set power to same as previous effect
	WRITE_LONG   ("%fx_off%" + 0x04 + ("%fx_num%" * 0x30)) 9				// Maximum Level dispelled [Param 1]
	WRITE_BYTE   ("%fx_off%" + 0x0c + ("%fx_num%" * 0x30)) 1				// Duration Instant
  READ_BYTE	   ("%fx_off%" + 0x0d + (("%fx_num%"-1) * 0x30)) "resist"		// Read resisttype of previous effect
	WRITE_BYTE   ("%fx_off%" + 0x0d + ("%fx_num%" * 0x30))  "%resist%"		// Set resisttype to same as previous effect
	WRITE_BYTE   ("%fx_off%" + 0x12 + ("%fx_num%" * 0x30)) 100			  // probability 100
  READ_LONG	   ("%fx_off%" + 0x02 + (("%fx_num%"-1) * 0x30)) "targettype"	// Read targettype of previous effect
	WRITE_LONG   ("%fx_off%" + 0x02 + ("%fx_num%" * 0x30)) "%targettype%"		// Set targettype to same as previous effect
	END
	PATCH_IF ("%outerloops%" = 0) BEGIN
		WRITE_LONG   ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 33	// Removes Invulnerability to Normal Weapons [Param 2]
	END ELSE
  PATCH_IF ("%outerloops%" = 1) BEGIN
		WRITE_LONG   ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 34	// Removes Invulnerability to Normal Weapons [Param 2]
	END ELSE
  PATCH_IF ("%outerloops%" = 2) BEGIN
		WRITE_LONG   ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 109	// Removes Guardian Mantle [Param 2]
	END
 END
 END
BUT_ONLY_IF_IT_CHANGES

Link to comment

Nevermind, I figured it out. I forgot to include these under the PATCH_IF ("%correct%" = 1). My "END" did not include these, but I for some reason placed it before this piece of code.

 

PATCH_IF ("%outerloops%" = 0) BEGIN
		WRITE_LONG   ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 33	// Removes Invulnerability to Normal Weapons [Param 2]
	END ELSE
  PATCH_IF ("%outerloops%" = 1) BEGIN
		WRITE_LONG   ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 34	// Removes Invulnerability to Normal Weapons [Param 2]
	END ELSE
  PATCH_IF ("%outerloops%" = 2) BEGIN
		WRITE_LONG   ("%fx_off%" + 0x08 + ("%fx_num%" * 0x30)) 109	// Removes Guardian Mantle [Param 2]
	END

 

So then what happened was the patching went out of bounds when "%correct%" was not 1. Which happened when the spell in question didn't have effects attached to it that do something other than play graphics. Now I feel stupid.

 

-Galactygon

Link to comment

No need to feel stupid.

 

By the way, the quotes/tildes and percentages around variables are optional in most patch expressions. (Exceptions are the string comparisions.)

I only mention this, because you seem to care about readability.

Link to comment

Here's another one (there has to be more) :

 

I am simply attempting to add a blank effect to each extension header for some spell (here it's SPPR707.spl). The patched spell is either unreadable, reorders the effects in a way I don't like, or does some funny stuff (ie gives a saving throw type of 12412353 or something like that).

 

COPY_EXISTING ~SPPR707.spl~ ~override~
READ_LONG  0x64 ext_off
READ_SHORT 0x68 ext_num
FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN
  READ_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) eff_num
  READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_off
  WRITE_SHORT	( outerloops * 0x28 + ext_off + 0x1e ) (eff_num + 1)
  INSERT_BYTES   ("%eff_off%" + ("%eff_num%" * 0x30))	0x30
END
BUT_ONLY_IF_IT_CHANGES

 

And I noticed this happens for some of the patched spells in G3's Detectable Spells as well.

 

-Galactygon

Link to comment

Use Nythrun's spell_item_reordering macro before doing any patching of this nature. There's the code floating around here somewhere, but I haven't been able to search effectively on this forum for some time. Pretty much the same code is in p5_spl_eff_copy.tpp in p5tweaks.

Link to comment

I've included this macro, but it doesn't help or improve my situation.

 

-Galactygon

 

DEFINE_PATCH_MACRO ~reindex_spell_or_item_extra_effects~ BEGIN
 PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN
PATCH_IF		  !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.spl~) THEN BEGIN
  SET "hs" = 0x28
END ELSE PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.itm~) THEN BEGIN
  SET "hs" = 0x38
END
READ_LONG  0x64 "ho"
READ_SHORT 0x68 "hc"
READ_LONG  0x6a "eo"
READ_SHORT 0x70 "ei"
PATCH_IF (("ho" > "eo") AND ("hc" > 0x01)) THEN BEGIN
  READ_ASCII "ho" ~eh~ ELSE ~fail~ ("hs" * "hc")
  PATCH_IF (~%eh%~ STRING_EQUAL ~fail~) THEN BEGIN
	WHILE ((~%eh%~ STRING_EQUAL ~fail~) AND ("hc" > 0x00)) BEGIN
	  READ_ASCII "ho" ~eh~ ELSE ~fail~ ("hs" * "hc")
	  SET "hc" -= 0x01
	END
  END
  DELETE_BYTES "ho" ("hs" * "hc")
  SET "ho" = 0x72
  WRITE_LONG   0x64 "ho"
  WRITE_SHORT  0x68 "hc"
  SET "eo" = (0x72 + ("hs" * "hc"))
  WRITE_LONG   0x6a "eo"
  PATCH_IF !(~%eh%~ STRING_EQUAL ~fail~) THEN BEGIN
	INSERT_BYTES "ho" ("hs" * "hc")
	WRITE_ASCIIE "ho" ~%eh%~
  END
END ELSE PATCH_IF (("ho" != 0x72) AND ("hc" = 0x00)) THEN BEGIN
  SET "ho" = 0x72
  WRITE_LONG   0x64 "ho"
END
FOR ("i1" = 0x00; "i1" < ("hs" * "hc"); "i1" += "hs") BEGIN
  WRITE_SHORT ("ho" + "i1" + 0x20) "ei"
  READ_SHORT  ("ho" + "i1" + 0x1e) "ec"
  SET "ei" += "ec"
END
PATCH_IF (SOURCE_SIZE > (0x72 + ("hs" * "hc") + (0x30 * "ei"))) THEN BEGIN
  DELETE_BYTES (0x72 + ("hs" * "hc") + (0x30 * "ei")) (SOURCE_SIZE - (0x72 + ("hs" * "hc") + (0x30 * "ei")))
END
 END
END

Link to comment
I am simply attempting to add a blank effect to each extension header for some spell (here it's SPPR707.spl). The patched spell is either unreadable, reorders the effects in a way I don't like, or does some funny stuff (ie gives a saving throw type of 12412353 or something like that).

 

COPY_EXISTING ~SPPR707.spl~ ~override~
READ_LONG  0x64 ext_off
READ_SHORT 0x68 ext_num
FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN
  READ_SHORT ( outerloops * 0x28 + ext_off + 0x1e ) eff_num
  READ_SHORT ( outerloops * 0x28 + ext_off + 0x20 ) eff_off
  WRITE_SHORT	( outerloops * 0x28 + ext_off + 0x1e ) (eff_num + 1)
  INSERT_BYTES   ("%eff_off%" + ("%eff_num%" * 0x30))	0x30
END
BUT_ONLY_IF_IT_CHANGES

You need to adjust the eff_off (which is only an index) in the other extended headers, if they are after the one, you currently inserted. By coincidence, Miloch posted about a bug in Gort's macros related to this recently.

Link to comment

Have you LAUNCH_PATCH_MACROed it (or PATCH_INCLUDEd it if it's in a separate file) before your patching?

 

It's possible it doesn't account for every messed up spell, but I don't think it's failed me, and I think I've even tested it on all spells in a BGT/BWP install...

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...