The uses and abuses of secondary types
Started by Nythrun, Dec 13 2007 12:54 PM
13 replies to this topic
#2
Posted 13 December 2007 - 12:59 PM
Macros used:
Array of ascii characters
Fake SAY offset @%tra_ref%
Dynamic add Secondary Type macro
And everyone's favorite, nothing
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."
"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
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.
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."
"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
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."
"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
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=)
#7
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
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
@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
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."
"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
Posted 14 December 2007 - 11:11 PM
Nythrun, on Dec 15 2007, 03:00 AM, said:
@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
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
#10
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:
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
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).
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:
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.
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 ImprovedInvisibilityRemovalStringneeds 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 7You 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."
"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
Posted 04 September 2008 - 10:20 PM
Nythrun, on Dec 14 2007, 09:00 AM, said:
@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
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?
Before you start breaking wall tiles with your bare fists, ask yourself first - do you truly need it?
#13
Posted 05 September 2008 - 11:22 PM
Quote
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...
Reply to this topic

1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users













