Jump to content


Photo

The uses and abuses of secondary types


13 replies to this topic

#1 Nythrun

Nythrun

    Long since out to pasture

  • Modders
  • 1761 posts
  • Gender:Female

Posted 13 December 2007 - 12:54 PM

(This space reserved for when I actually have type to explain what this does)
"You tell lies, too."
"Not I." The witch laughed; her laughter was clear and yet unpleasant. "I used to as a child, I confess. But I soon found the truth more disconcerting."

#2 Nythrun

Nythrun

    Long since out to pasture

  • Modders
  • 1761 posts
  • Gender:Female

Posted 13 December 2007 - 12:59 PM

Macros used:

Array of ascii characters
OUTER_PATCH ~this_is_not_a_variable~ BEGIN
  FOR ("ix" = 0x0; "ix" < 0x100; "ix" += 0x1) BEGIN
	WRITE_BYTE 0x0 "ix"
	READ_ASCII 0x0 ~c~ (0x1)
	SPRINT EVALUATE_BUFFER $t(~%ix%~) ~%c%~
  END
END

Fake SAY offset @%tra_ref%
DEFINE_ACTION_MACRO ~fj_plork_strref~ BEGIN
  <<<<<<<<nythruns/trash/plork.tpa
  DEFINE_ACTION_MACRO ~fj_plork_strref2~ BEGIN
	OUTER_PATCH ~this_is_not_a_variable~ BEGIN
	  SAY	   0x00 @placeholder
	  READ_LONG 0x00 tra_ref
	END
  END
  >>>>>>>>
  COPY - ~nythruns/trash/plork.tpa~ ~plork_temp.tpa~
	REPLACE_TEXTUALLY EXACT_MATCH ~placeholder~ ~%temp_ref%~
  REINCLUDE ~plork_temp.tpa~
  LAUNCH_ACTION_MACRO ~fj_plork_strref2~
END

Dynamic add Secondary Type macro
DEFINE_ACTION_MACRO ~fj_add_sectype~ BEGIN
  ACTION_IF !(FILE_EXISTS ~override/msectype.2da~) THEN BEGIN
	COPY_EXISTING ~msectype.2da~ ~override~
  END
  ACTION_IF !(FILE_CONTAINS ~override/msectype.2da~ EVALUATE_BUFFER ~^%sec_type%~) THEN BEGIN
	COPY_EXISTING ~msectype.2da~ ~override~
	  PATCH_IF SOURCE_SIZE BEGIN
		COUNT_2DA_ROWS 0x2 "r"
		INSERT_2DA_ROW "r" 0x2 ~%sec_type% %tra_ref%~
		SET EVALUATE_BUFFER "%sec_type%_sectype" = ("r" - 0x1)
	  END
	BUT_ONLY
  END ELSE BEGIN
	COPY_EXISTING - ~msectype.2da~ ~override~
	  PATCH_IF SOURCE_SIZE BEGIN
		FOR (COUNT_2DA_ROWS 0x2 "r"; "r" > 0x1; "r" -= 0x1) BEGIN
		  READ_2DA_ENTRY ("r" - 0x1) 0x0 0x2 ~v~
		  PATCH_IF (~%v%~ STRING_EQUAL_CASE ~%sec_type%~) THEN BEGIN
			SET EVALUATE_BUFFER "%sec_type%_sectype" = ("r" - 0x2)
			SET "r" = 0x0
		  END
		END
	  END
	// BUT_ONLY
  END
END

And everyone's favorite, nothing
<<<<<<<<null.inlined
>>>>>>>>

"You tell lies, too."
"Not I." The witch laughed; her laughter was clear and yet unpleasant. "I used to as a child, I confess. But I soon found the truth more disconcerting."

#3 Nythrun

Nythrun

    Long since out to pasture

  • Modders
  • 1761 posts
  • Gender:Female

Posted 13 December 2007 - 01:01 PM

Sleep dispels on hit without exe patches or lingering effects:
Curative spell fashioned out of whole cloth to work around forum attachments. Don't do this, use a prefix too.
OUTER_SPRINT ~sec_type~ ~Sleep~
OUTER_SPRINT ~tra_ref~  ~6299~
LAUNCH_ACTION_MACRO ~fj_add_sectype~

OUTER_SET "ho" = 0x72
OUTER_SET "hc" = 0x01
OUTER_SET "eo" = ("ho" + (0x28 * "hc"))
OUTER_SET "ec" = 0x02
COPY ~null.inlined~ ~override/cureslee.spl~
  PATCH_IF (SOURCE_SIZE = 0x00) THEN BEGIN
	INSERT_BYTES 0x00 (0x72 + (0x28 * "hc") + (0x30 * "ec"))
	WRITE_ASCII  0x00 ~SPL V1  ~
	WRITE_LONG   0x08 (` 0x00)
	WRITE_LONG   0x0c (` 0x00)
	WRITE_SHORT  0x38 0x01
	WRITE_LONG   0x50 (` 0x00)
	WRITE_LONG   0x54 (` 0x00)
	WRITE_LONG   0x64 "ho"
	WRITE_SHORT  0x68 "hc"
	WRITE_LONG   0x6a "eo"
	FOR ("i1" = 0x00; "i1" < ("hc" * 0x28); "i1" += 0x28) BEGIN
	  WRITE_BYTE   ("ho" + "i1" + 0x00) 0x01
	  WRITE_BYTE   ("ho" + "i1" + 0x02) 0x02
	  WRITE_BYTE   ("ho" + "i1" + 0x0c) 0x01
	  WRITE_SHORT  ("ho" + "i1" + 0x0e) 0x01
	  WRITE_SHORT  ("ho" + "i1" + 0x10) ("i1" + 0x01)
	  WRITE_SHORT  ("ho" + "i1" + 0x1e) "ec"
	  WRITE_SHORT  ("ho" + "i1" + 0x20) ("i1" * "ec")
	  WRITE_SHORT  ("ho" + "i1" + 0x26) 0x01
	  FOR ("i2" = ("i1" * "ec" * 0x30); "i2" < (("i1" + 0x01) * "ec" * 0x30); "i2" += ("ec" * 0x30)) BEGIN
		WRITE_SHORT  ("eo" + "i2" + 0x00) 0xdd
		WRITE_BYTE   ("eo" + "i2" + 0x02) 0x02
		WRITE_LONG   ("eo" + "i2" + 0x04) 0x09
		WRITE_LONG   ("eo" + "i2" + 0x08) "Sleep_sectype"
		WRITE_BYTE   ("eo" + "i2" + 0x0c) 0x01
		WRITE_BYTE   ("eo" + "i2" + 0x12) 0x64
		WRITE_SHORT  ("eo" + "i2" + 0x30) 0x02
		WRITE_BYTE   ("eo" + "i2" + 0x32) 0x02
		WRITE_BYTE   ("eo" + "i2" + 0x3c) 0x01
		WRITE_BYTE   ("eo" + "i2" + 0x42) 0x64
	  END
	END
  END

COPY_EXISTING ~spwi116.spl~  ~override~
  PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN
	READ_LONG  0x18 "fl"
	WRITE_LONG 0x18 ("fl" & 0xfffffbff)
	WRITE_BYTE 0x27 "Sleep_sectype"
	READ_LONG  0x64 "ho"
	READ_SHORT 0x68 "hc"
	READ_LONG  0x6a "eo"
	FOR ("i1" = "hc" * 0x28; "i1" > 0x00; "i1" -= 0x28) BEGIN
	  READ_SHORT   ("ho" + "i1" - 0x0a) "ec"
	  READ_SHORT   ("ho" + "i1" - 0x08) "ei"
	  WRITE_SHORT  ("ho" + "i1" - 0x0a) ("ec" + 0x01)
	  READ_ASCII   ("eo" + ("ei" * 0x30)) ~ef~ (0x30)
	  INSERT_BYTES ("eo" + (("ei" + "ec") * 0x30) + 0x00) 0x30
	  WRITE_ASCIIE ("eo" + (("ei" + "ec") * 0x30) + 0x00) ~%ef%~
	  WRITE_SHORT  ("eo" + (("ei" + "ec") * 0x30) + 0x00) 0xe8
	  WRITE_LONG   ("eo" + (("ei" + "ec") * 0x30) + 0x04) 0x00
	  WRITE_LONG   ("eo" + (("ei" + "ec") * 0x30) + 0x08) 0x00
	  WRITE_ASCII  ("eo" + (("ei" + "ec") * 0x30) + 0x14) ~cureslee~ #8
	END
	READ_SHORT 0x70 "ei"
	FOR ("i1" = 0x00; "i1" < "hc" * 0x28; "i1" += 0x28) BEGIN
	  WRITE_SHORT "ho" + "i1" + 0x20 "ei"
	  READ_SHORT  "ho" + "i1" + 0x1e "ec"
	  SET "ei" += "ec"
	END
  END

"You tell lies, too."
"Not I." The witch laughed; her laughter was clear and yet unpleasant. "I used to as a child, I confess. But I soon found the truth more disconcerting."

#4 Nythrun

Nythrun

    Long since out to pasture

  • Modders
  • 1761 posts
  • Gender:Female

Posted 13 December 2007 - 01:03 PM

Improved Invisibility grants a save bonus, doesn't stack, and doesn't block itself
OUTER_SPRINT ~sec_type~ ~ImprovedInvisibility~

OUTER_SPRINT ~tra_ref~  ~4294967295~

LAUNCH_ACTION_MACRO ~fj_add_sectype~

COPY_EXISTING ~balth10.spl~  ~override~ // Shadow Stance!

			  ~spdr401.spl~  ~override~ // Invisible Stalker Improved Invisibility

			  ~spin544.spl~  ~override~ // PSIONIC _SUPERIOR_INVISIBILITY

			  ~spin687.spl~  ~override~ // Create Shadows

			  ~spin698.spl~  ~override~ // Cerebus Improved Invisibility

			  ~spwi405.spl~  ~override~ // Improved Invisibility (mage)

			  ~spwi505.spl~  ~override~ // Shadow Door (mage)

			  ~spwi607.spl~  ~override~ // Mislead

			  ~spwi721.spl~  ~override~ // Mass Invisibility

  PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN

	WRITE_BYTE  0x27 "ImprovedInvisibility_sec_type"

	READ_LONG   0x64 "ho"

	READ_SHORT  0x68 "hc"

	READ_LONG   0x6a "eo"

	READ_SHORT  0x70 "gc"

	FOR ("i1" = ("hc" * 0x28); "i1"; "i1" -= 0x28) BEGIN

	  READ_SHORT   ("ho" + "i1" - 0x0a) "ec"

	  WRITE_SHORT  ("ho" + "i1" - 0x0a) ("ec" + 0x01)

	  READ_SHORT   ("ho" + "i1" - 0x08) "ei"

	  READ_ASCII   ("eo" + (0x30 * "ei") + 0x00) ~ef~ (0x30)

	  INNER_PATCH_SAVE ~ef~ ~%ef%~ BEGIN

		WRITE_SHORT  0x00 0xdd

		WRITE_LONG   0x04 0x09

		WRITE_LONG   0x08 "ImprovedInvisibility_sectype"

		WRITE_BYTE   0x0c 0x01

		WRITE_LONG   0x0e 0x00

		WRITE_ASCII  0x14 ~~ #8

	  END

	  INSERT_BYTES ("eo" + (0x30 * "ei") + 0x00) 0x30

	  WRITE_ASCIIE ("eo" + (0x30 * "ei") + 0x00) ~%ef%~

	END

	FOR ("i1" = 0x00; "i1" < ("hc" * 0x28); "i1" += 0x28) BEGIN

	  READ_SHORT  ("ho" + "i1" + 0x1c) "ec"

	  WRITE_SHORT ("ho" + "i1" + 0x20) "gc"

	  SET "gc" += "ec"

	END

	PATCH_IF !(~%SOURCE_RES%~ STRING_EQUAL_CASE ~spwi721~) THEN BEGIN

	  FOR ("i1" = ("hc" * 0x28); "i1"; "i1" -= 0x28) BEGIN

		READ_SHORT   ("ho" + "i1" - 0x0a) "ec"

		WRITE_SHORT  ("ho" + "i1" - 0x0a) ("ec" + 0x05)

		READ_SHORT   ("ho" + "i1" - 0x08) "ei"

		FOR ("i2" = (("ec" + "ei" - 0x01) * 0x30); "i2" > (("ei" - 0x01) * 0x30); "i2" -= 0x30) BEGIN

		  READ_LONG  ("eo" + "i2" + 0x0e) "dr"

		  PATCH_IF ("dr" > 0x07) THEN BEGIN

			READ_ASCII ("eo" + "i2" + 0x00) ~ef~ (0x30)

			INNER_PATCH_SAVE ~ef~ ~%ef%~ BEGIN

			  WRITE_LONG  0x04 0x04

			  WRITE_LONG  0x08 0x00

			  WRITE_ASCII 0x14 ~~ #8

			END

			SET "i2" = 0x00

		  END

		END

		INSERT_BYTES ("eo" + (0x30 * ("ei" + "ec")) + 0x00) (0x30 * 0x05)

		FOR ("i2" = 0x00; "i2" < 0x05; "i2" += 0x01) BEGIN

		  WRITE_ASCIIE ("eo" + (0x30 * ("ei" + "ec" + "i2"))) ~%ef%~

		  WRITE_SHORT  ("eo" + (0x30 * ("ei" + "ec" + "i2"))) (0x21 + "i2")

		END

	  END

	  FOR ("i1" = 0x00; "i1" < ("hc" * 0x28); "i1" += 0x28) BEGIN

		READ_SHORT  ("ho" + "i1" + 0x1c) "ec"

		WRITE_SHORT ("ho" + "i1" + 0x20) "gc"

		SET "gc" += "ec"

	  END

	END

  END

// BUT_ONLY

COPY_EXISTING ~jwtrue.spl~   ~override~ // Goofy FX

			  ~spcl232.spl~  ~override~ // True Sight (inquisitor)

			  ~spcl232d.spl~ ~override~ // True Sight (inquisitor) (triggered spell)

			  ~spcl732.spl~  ~override~ // True Sight (priest of Hat)

			  ~sppr309.spl~  ~override~ // Invisibility Purge

			  ~sppr505.spl~  ~override~ // True Seeing (priest)

			  ~sppr505d.spl~ ~override~ // True Seeing (priest) (triggered spell)

		   // ~sppr950.spl~  ~override~ // True Sight (clone)

			  ~spwi203.spl~  ~override~ // Detect Invisibility

			  ~spwi224.spl~  ~override~ // Glitterdust

			  ~spwi515.spl~  ~override~ // Oracle

			  ~spwi609.spl~  ~override~ // True Sight (wizard)

			  ~spwi609d.spl~ ~override~ // True Sight (wizard) (triggered spell)

  PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN

	READ_LONG   0x64 "ho"

	READ_SHORT  0x68 "hc"

	READ_LONG   0x6a "eo"

	READ_SHORT  0x70 "gc"

	FOR ("i1" = ("hc" * 0x28); "i1"; "i1" -= 0x28) BEGIN

	  READ_SHORT   ("ho" + "i1" - 0x0a) "ec"

	  WRITE_SHORT  ("ho" + "i1" - 0x0a) ("ec" + 0x01)

	  READ_SHORT   ("ho" + "i1" - 0x08) "ei"

	  FOR ("i2" = (("ec" + "ei" - 0x01) * 0x30); "i2" > (("ei" - 0x01) * 0x30); "i2" -= 0x30) BEGIN

		  READ_BYTE  ("eo" + "i2" + 0x02) "tt"

		  PATCH_IF ("tt" = 0x02) THEN BEGIN

			READ_ASCII ("eo" + "i2" + 0x00) ~ef~ (0x30)

			INNER_PATCH_SAVE ~ef~ ~%ef%~ BEGIN

			  WRITE_SHORT 0x00 0xdd

			  WRITE_LONG  0x04 0x09

			  WRITE_LONG  0x08 "ImprovedInvisibility_sectype"

			  WRITE_BYTE  0x0c 0x01

			  WRITE_LONG  0x0e 0x00

			  WRITE_ASCII 0x14 ~~ #8

			END

			SET "i2" = 0x00

		  END

		END

	  END

	  INSERT_BYTES ("eo" + (0x30 * "ei") + 0x00) 0x30

	  WRITE_ASCIIE ("eo" + (0x30 * "ei") + 0x00) ~%ef%~

	END

	FOR ("i1" = 0x00; "i1" < ("hc" * 0x28); "i1" += 0x28) BEGIN

	  READ_SHORT  ("ho" + "i1" + 0x1c) "ec"

	  WRITE_SHORT ("ho" + "i1" + 0x20) "gc"

	  SET "gc" += "ec"

	END

  END

// BUT_ONLY

"You tell lies, too."
"Not I." The witch laughed; her laughter was clear and yet unpleasant. "I used to as a child, I confess. But I soon found the truth more disconcerting."

#5 Gort

Gort
  • Members
  • 190 posts

Posted 13 December 2007 - 09:20 PM

ha, I thought I was the only one who was tinkering with it=). I've made some code that makes potions effects refreshable and non-stackable, but never got to release it. There were 2 issues, though - I could only make them dispel self within a second - immediate dispel didn't work with any order of effects, and each time such dispel used a hardcoded line from mssectype.2da appears. If there's no line or there is an immunity to it, then an empty line appears anyway. So I considered it non-suitable for the fixpack. Did you manage to avoid these? I'm too lazy to read your code thoroughly=)

#6 Ascension64

Ascension64
  • Members
  • 452 posts

Posted 13 December 2007 - 10:38 PM

I won't doubt that these work, but the code is a little hard to read if all the variables are a bunch of abbreviations that aren't immediately obvious as to what they represent.

#7 Nythrun

Nythrun

    Long since out to pasture

  • Modders
  • 1761 posts
  • Gender:Female

Posted 14 December 2007 - 08:00 AM

I'm sorry, I ran out of time just after starting this and won't be able to get back to it for a bit.

@Gort: I'm not sure what you're meaning with immediate dispel didn't work - I've never had to do anything fancy to get that. Remove SecType, Immunity to String 0 seconds works to prevent strings from running when they ought not, blocking them completely I only know how to do with a mix of global effects or an attached .eff.

People have been messing around with this stuff since before I was born :)

@A64 Yes, it's all but useless, as there's abbreviated code to illustrate a walkthrough that's unwritten, sorry :help: I didn't even start on dealing with nulling everyone's second favorite .bam or what the SAY off %var% is for. I'll get back to it.

Didn't mean to reach for your thunder on your Real Dalestyle .exe patch by the way, Sleep is just something people've been talking about ;)
"You tell lies, too."
"Not I." The witch laughed; her laughter was clear and yet unpleasant. "I used to as a child, I confess. But I soon found the truth more disconcerting."

#8 Ascension64

Ascension64
  • Members
  • 452 posts

Posted 14 December 2007 - 11:11 PM

@A64 Yes, it's all but useless, as there's abbreviated code to illustrate a walkthrough that's unwritten, sorry :) I didn't even start on dealing with nulling everyone's second favorite .bam or what the SAY off %var% is for. I'll get back to it.

Didn't mean to reach for your thunder on your Real Dalestyle .exe patch by the way, Sleep is just something people've been talking about :help:

No need for apologies. Take my thunder as you like it, I am totally supportive of, and much prefer, patches that don't require smashing bits and pieces of the .exe up. ;)

#9 Bearwere

Bearwere
  • Members
  • 164 posts

Posted 27 April 2008 - 03:53 AM

so, Nythrun, have you tried this in game? Improved Invisibility, in particular? I have some problems getting this to work.

#10 Nythrun

Nythrun

    Long since out to pasture

  • Modders
  • 1761 posts
  • Gender:Female

Posted 29 April 2008 - 09:24 AM

For a moment I was wondering who written such an unhelpful tutorial, hee. Yes, sorry - I'd forgotten this thread existed.

It's been a staple technique in my Frowny Face Empire for a couple years now, and I'm not quite vain enough to assume other people aren't using it as well.

What's giving you trouble? For the simpler uses there are only three things you need to do.

Add the new secondary type to msectype.2da, sequentially. Brief/ugly/unweird code:
COPY_EXISTING msectype.2da override
  COUNT_2DA_ROWS 2 rows
  INSERT_2DA_ROW rows 2 ~ImprovedInvisibility stringdisplay~
  REPLACE ~\bstringdisplay~ @1 // @1 = ~Improved Invisibility removed~
  READ_2DA_ENTRY rows 1 2 ImprovedInvisibilityRemovalString
  SET ImprovedInvisibilitySectype = rows - 1
UNLESS ImprovedInvisibility

Then add in two new effects at the beginning of each extended header of each spell that's participating in this tomfoolery.

The first of these is a zero duration immunity to string display, preventing the "Improved Invisibility removed" string from running iff there's not already some kind of Improved Invisibility active. Set the power level to greater than what the next effect will be removing, at least for now - there are tricksier ways to do this involving external resources. Since you've just added that string to the .tlk, a
WRITE_LONG effect_offset + 0x30 * effect_number + 0x04 ImprovedInvisibilityRemovalString
needs adding under your COPY to override.

The second effect you add is a remove by secondary type (opcode 221, I think?). Set the highest level removed to the highest power level you need to knock off (for Improved Invisibility, that'd be seven, so you can avoid cumulativity with Mass Invisibility).
WRITE_LONG effect_offset + 0x30 * effect_number + 0x04 7
You need also to add in what the new dynamically secondary type is:
WRITE_LONG effect_offset + 0x30 * effect_number + 0x08 ImprovedInvisibilitySectype

The third and last step is changing the secondary type in the spell header of whichever spell you're copying to the new one you've added:
WRITE_BYTE 0x27 ImprovedInvisibilitySectype

And that's it, pretty much.

/edit

Actually, if you just want Improved Invisibility, skip the string display prevention entirely - that's not one of the places it'll matter, I think.

Edited by Nythrun, 29 April 2008 - 10:39 AM.

"You tell lies, too."
"Not I." The witch laughed; her laughter was clear and yet unpleasant. "I used to as a child, I confess. But I soon found the truth more disconcerting."

#11 Galactygon

Galactygon

    Nostradoctopus

  • Members
  • 641 posts
  • Location:Hungary

Posted 04 September 2008 - 10:20 PM

@Gort: I'm not sure what you're meaning with immediate dispel didn't work - I've never had to do anything fancy to get that. Remove SecType, Immunity to String 0 seconds works to prevent strings from running when they ought not, blocking them completely I only know how to do with a mix of global effects or an attached .eff.


I should have been reading this earlier, but in case you are still around, Nythrun I have been unable to make this work.

I have tried using #101 protection from opcode (set to opcode #139) as well as #267 protection from display specific string, but none of this prevented a string from being displayed when I dispelled the sectype.

I have had trouble with this for years, and I hope it is me missing something rather than the engine being uncool.

-Galactygon



#12 Ardanis

Ardanis

    A very GAR character

  • Members
  • 2227 posts
  • Gender:Male
  • Location:Saint-Petersburg, Russia

Posted 05 September 2008 - 08:10 AM

A small bit of my knowledge - there is no need to update msectype.2da, secondary types seem to work perfectly with or without it (they did for).
"Uguu~ Boku Ayu."

Before you start breaking wall tiles with your bare fists, ask yourself first - do you truly need it?

#13 igi

igi

    IESDP Guardian

  • Gibberlings
  • 1210 posts
  • Gender:Male

Posted 05 September 2008 - 11:22 PM

A small bit of my knowledge - there is no need to update msectype.2da, secondary types seem to work perfectly with or without it (they did for).


Yes, they will. However it makes it harder for mods (or anything else) to find a unique secondary type to use, as it would mean scanning all games files. However, as some secondry types are hard-coded and do not appear in msectype.2da anyway...

#14 Galactygon

Galactygon

    Nostradoctopus

  • Members
  • 641 posts
  • Location:Hungary

Posted 06 September 2008 - 12:14 AM

However, as some secondry types are hard-coded and do not appear in msectype.2da anyway...


Could you please elaborate? I haven't seen or heard of anything like this.

-Galactygon





Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users