Jump to content

Scriptable Spells v3


Recommended Posts

If you need proof of that, I can provide it.

 

Yeah, there's quite a few mods that thought it would be a good idea to dump a few hundred lines of item checks into Baldur.bcs - it never works out well and I just delete that kind of stuff on sight now :rant:

 

Five or six items in a NPC only script would make no noticible difference though, that's for sure :)

Link to comment

If you could (dis)prove it, then it should be written in the IESDP to clarify the masses (myself included).

 

One thing is certain, as I already mentioned, it takes more work to reference the item than a single stat (not in executing scripts, but when the game loads all the data of all the creatures). So the game does slow down a bit. I hope this is a bit more clear.

 

-Galactygon

Link to comment

The number of fake bivalent states you'll get with this method and HasItemSlot() is given by:

 

(the number of items you use) raised to the power of (the number of slots that you use). With six items and one slot, you get 6 states, with 2 slots you get 36. Use 10 items and 2 slots and you get 100....

 

Stats are still preferable, because they take an additional argument (you have to use 256 of these fake item states just to replicate what RESIST_FIRE can do do) so you'd obviously be wanting to use them only to detect stuff that can be neatly represented as an on/off state.

 

If there really are only about six additional things that you need to check for, they might be better served by working them into the normal package :rant:

Link to comment
(the number of items you use) raised to the power of (the number of slots that you use). With six items and one slot, you get 6 states, with 2 slots you get 36. Use 10 items and 2 slots and you get 100....

 

Stats are still preferable, because they take an additional argument (you have to use 256 of these fake item states just to replicate what RESIST_FIRE can do do) so you'd obviously be wanting to use them only to detect stuff that can be neatly represented as an on/off state.

 

True/false states are what I am really after, although replicating RESIST_FIRE would simply be a matter of creating 100 instances of that item in an single slot and using the NumItems() to check for the "state". This hasn't been verified, but I am assuming it would work.

 

-Galactygon

Link to comment

Can't help thinking this would be better in a finished and distributable condition than consigned to The Inescapable Mire of Waiting for Someone Else to do something, so I coded about half of what I surmise to be the last nearly consensual version so I can finish some scripts that have been idling for too long. It's meant for personal use (though I'm happy to share if someone else wants it).

 

Some questions for anyone else who's interested:

 

Is 134 LEVEL_DRAINED really necessary? I know 200 LEVELDRAIN doesn't work by itself, but adding a modifying-stat-200 effect to level draining stuff makes it work just fine, and I can't see the point of squandering another stat to do that and leaving this one to rot - they're at a premium and we're only getting one byte's worth.

 

Speaking of stats, I'm adding the following:

REPLACE_TEXTUALLY ~^172 +.+~ ~172 TITLERECORDS~
REPLACE_TEXTUALLY ~^173 +.+~ ~173 TITLEVARIOUS~
REPLACE_TEXTUALLY ~^186 +.+~ ~186 NOCHUNKYDEATH~
REPLACE_TEXTUALLY ~^187 +.+~ ~187 IMMUNITYTURN~
REPLACE_TEXTUALLY ~^190 +.+~ ~190 NPCBUMP~
REPLACE_TEXTUALLY ~^194 +.+~ ~194 SPELLFAILUREINNATE~
REPLACE_TEXTUALLY ~^195 +.+~ ~195 IMMUNITYTRACKING~
REPLACE_TEXTUALLY ~^196 +.+~ ~196 DEADMAGICZONE~ 
REPLACE_TEXTUALLY ~^201 +.+~ ~201 DONOTDRAW~

because they're already used by the engine and there's not much we can do with them. If the Commitee for Officially Designating Names comes up with something else for them, that's fine with me, though these are based on my vague memories of what devSin pulled out of the mac .exe awhile back.

 

I'm not at all keen on adding underscores to the stat names, particularly when none of the existing stats have any such character and it's more typing - I'd rather have ASSASSINATION than ALWAYS_BACKSTAB. With that said, I'm never going to remember whether it's BACKSTAB_ALWAYS or ALWAYS_BACKSTAB or ASSASINATION or ASSASSINATION or whatever without having stats.ids open so I'm just going to call it 192 anyway ???

 

Anyone want to name 184, 185, 188, 193, and 198?

 

I'm just setting the value for INSIDE_OF_CLOUD to the spell's level for now, no idea how parameter one was being determined before :(

Link to comment

There is no consensus. I don't think there's an appropriate resolution here (the time for this stuff having any effect on future mods is likely long past).

 

As for the stats, this is my list:

APPEND STATS.IDS "166 MELEETHAC0BONUS"
APPEND STATS.IDS "167 MELEEDAMAGEBONUS"
APPEND STATS.IDS "168 MISSILEDAMAGEBONUS"
APPEND STATS.IDS "169 NOCIRCLE"
APPEND STATS.IDS "170 FISTTHAC0BONUS"
APPEND STATS.IDS "171 FISTDAMAGEBONUS"
APPEND STATS.IDS "172 TITLE1"
APPEND STATS.IDS "173 TITLE2"
APPEND STATS.IDS "174 NOVISUALS"
APPEND STATS.IDS "175 BACKSTABIMMUNITY"
APPEND STATS.IDS "183 NODEFERAI"
APPEND STATS.IDS "186 NOPERMANENTDEATH"
APPEND STATS.IDS "187 TURNUNDEADIMMUNITY"
APPEND STATS.IDS "189 WILDSURGEMOD"
APPEND STATS.IDS "190 NPCBUMP"
APPEND STATS.IDS "191 USEANYITEM"
APPEND STATS.IDS "192 ASSASSINATION"
APPEND STATS.IDS "194 SPELLFAILUREINNATE"
APPEND STATS.IDS "195 TRACKINGIMMUNITY"
APPEND STATS.IDS "196 DEADMAGIC"
APPEND STATS.IDS "197 TIMESTOPIMMUNITY"
APPEND STATS.IDS "201 DONOTDRAW"

Link to comment

Nythrun, if you've got a working version, go for it. I had been working on the update with cirerrek, but between spending most of December out of town and then pushing out a new version of Fixpack, I've gotten approximately zero done. The hold up, for me at least, was figuring our which spells should be assigned what stats. If we have a finalized stats list, I don't think it should be too hard to solicit input from the interested modders here to sort it out.

Link to comment

I don't know that there is a finalized stats list, which is problematic inasmuch as the number of people who are going to use detectable effects is asymptotically approaching zero.

 

I'd set up stats.ids thusly:

COPY_EXISTING ~stats.ids~ ~override~
PATCH_IF SOURCE_SIZE THEN BEGIN
 READ_BYTE 0x0 "fj_check"
 PATCH_IF (("fj_check" = 0xd) OR ("fj_check" = 0xa)) THEN BEGIN
   INSERT_BYTES 0x0 0x3
   WRITE_ASCII  0x0 ~IDS~
 END
 COUNT_2DA_ROWS 0x2 "fj_r_2da"
 FOR ("fj_1_idx" = 0x0; "fj_1_idx" < "fj_r_2da"; "fj_1_idx" += 1) BEGIN
   READ_2DA_ENTRY "fj_1_idx" 0x0 0x2 "fj_2_idx"
   PATCH_IF (("fj_1_idx" != "fj_2_idx") AND ("fj_1_idx" < "fj_r_2da")) THEN BEGIN
     SET "fj_1_ssn" = (("fj_1_idx" - 0x9b) > 0x0) ? ("fj_1_idx" - 0x9b) : ("fj_1_idx" + 0x64)
     INSERT_2DA_ROW "fj_1_idx" 0x2 ~%fj_1_idx% SCRIPTINGSTATE%fj_1_ssn%~
     SET "fj_r_2da" += 0x1
   END
 END
 WHILE ("fj_r_2da" < 0x101) BEGIN
   SET "fj_1_ssn" = ("fj_r_2da" - 0x9b)
   INSERT_2DA_ROW "fj_r_2da" 0x2 ~%fj_r_2da% SCRIPTINGSTATE%fj_1_ssn%~
   SET "fj_r_2da" += 0x1
 END
 FOR ("fj_1_idx" = 0x101; "fj_1_idx" < "fj_r_2da"; "fj_1_idx" += 1) BEGIN
   READ_2DA_ENTRY "fj_1_idx" 0x0 0x2 "fj_2_idx"
   PATCH_IF ("fj_2_idx" < 0x101) THEN BEGIN
     SET_2DA_ENTRY "fj_1_idx" 0x1 0x2 ~Unused0~
     SET_2DA_ENTRY "fj_1_idx" 0x0 0x2 ~0~
   END
 END
 REPLACE_TEXTUALLY ~^0 .+~ ~~
 REPLACE_TEXTUALLY ~^109 +.+~ ~109 IMMUNITY_ENCHANTMENT~
 REPLACE_TEXTUALLY ~^110 +.+~ ~110 WEAPON_ENCHANTMENT~
 /*
 REPLACE_TEXTUALLY ~^111 +.+~ ~111 PROFICIENCY2HANDED~
 REPLACE_TEXTUALLY ~^112 +.+~ ~112 PROFICIENCYSWORDANDSHIELD~
 REPLACE_TEXTUALLY ~^113 +.+~ ~113 PROFICIENCYSINGLEWEAPON~
 REPLACE_TEXTUALLY ~^114 +.+~ ~114 PROFICIENCY2WEAPON~
 */

 REPLACE_TEXTUALLY ~^115 +.+~ ~115 PROFICIENCYCLUB~

 REPLACE_TEXTUALLY ~^116 +.+~ ~116 SPELL_DEFLECTION~
 REPLACE_TEXTUALLY ~^117 +.+~ ~117 PROTECTION_ALIGNMENT~
 REPLACE_TEXTUALLY ~^118 +.+~ ~118 TRUE_SIGHT~
 REPLACE_TEXTUALLY ~^119 +.+~ ~119 MIND_SHIELD~
 REPLACE_TEXTUALLY ~^120 +.+~ ~120 PROTECTION_SPELL_LEVEL~
 REPLACE_TEXTUALLY ~^121 +.+~ ~121 IMMUNITY_NECROMANCY~
 REPLACE_TEXTUALLY ~^122 +.+~ ~122 PHYSICAL_MIRROR~
 REPLACE_TEXTUALLY ~^123 +.+~ ~123 IMMUNITY_ABJURATION~
 REPLACE_TEXTUALLY ~^124 +.+~ ~124 REGENERATION~
 REPLACE_TEXTUALLY ~^125 +.+~ ~125 FIRE_SHIELD~
 REPLACE_TEXTUALLY ~^126 +.+~ ~126 IMMUNITY_ALTERATION~
 REPLACE_TEXTUALLY ~^127 +.+~ ~127 IMMUNITY_CONJURATION~
 REPLACE_TEXTUALLY ~^128 +.+~ ~128 PROTECTION_MAGIC_WEAPONS~
 REPLACE_TEXTUALLY ~^129 +.+~ ~129 SPELL_TURNING~
 REPLACE_TEXTUALLY ~^130 +.+~ ~130 IMMUNITY_DIVINATION~
 REPLACE_TEXTUALLY ~^131 +.+~ ~131 FREE_ACTION~
 REPLACE_TEXTUALLY ~^132 +.+~ ~132 KHELBENS_WARDING_WHIP~
 REPLACE_TEXTUALLY ~^133 +.+~ ~133 IMMUNITY_ILLUSION~
 REPLACE_TEXTUALLY ~^134 +.+~ ~134 LEVEL_DRAINED~
 /*
 REPLACE_TEXTUALLY ~^135 +.+~ ~135 HIDEINSHADOWS~
 REPLACE_TEXTUALLY ~^136 +.+~ ~136 DETECTILLUSIONS~
 REPLACE_TEXTUALLY ~^137 +.+~ ~137 SETTRAPS~
 REPLACE_TEXTUALLY ~^138 +.+~ ~138 PUPPETMASTERID~
 REPLACE_TEXTUALLY ~^139 +.+~ ~139 PUPPETMASTERTYPE~
 REPLACE_TEXTUALLY ~^140 +.+~ ~140 PUPPETTYPE~
 REPLACE_TEXTUALLY ~^141 +.+~ ~141 PUPPETID~
 REPLACE_TEXTUALLY ~^142 +.+~ ~142 CHECKFORBERSERK~
 REPLACE_TEXTUALLY ~^143 +.+~ ~143 BERSERKSTAGE1~
 REPLACE_TEXTUALLY ~^144 +.+~ ~144 BERSERKSTAGE2~
 REPLACE_TEXTUALLY ~^145 +.+~ ~145 DAMAGELUCK~
 REPLACE_TEXTUALLY ~^146 +.+~ ~146 CRITICALHITBONUS~
 REPLACE_TEXTUALLY ~^147 +.+~ ~147 VISUALRANGE~
 REPLACE_TEXTUALLY ~^148 +.+~ ~148 EXPLORE~
 REPLACE_TEXTUALLY ~^149 +.+~ ~149 THRULLCHARM~
 REPLACE_TEXTUALLY ~^150 +.+~ ~150 SUMMONDISABLE~
 REPLACE_TEXTUALLY ~^151 +.+~ ~151 HITBONUS~
 REPLACE_TEXTUALLY ~^152 +.+~ ~152 KIT~
 REPLACE_TEXTUALLY ~^153 +.+~ ~153 FORCESURGE~
 REPLACE_TEXTUALLY ~^154 +.+~ ~154 SURGEMOD~
 REPLACE_TEXTUALLY ~^155 +.+~ ~155 IMPROVEDHASTE~
 REPLACE_TEXTUALLY ~^156 +.+~ ~156 SCRIPTINGSTATE1~
 */
 REPLACE_TEXTUALLY ~^157 +.+~ ~157 DEATH_WARD~
 REPLACE_TEXTUALLY ~^158 +.+~ ~158 NEGATIVE_PLANE_PROTECTION~
 REPLACE_TEXTUALLY ~^159 +.+~ ~159 COMBAT_BUFF~
 REPLACE_TEXTUALLY ~^160 +.+~ ~160 ARMOR_SPELL~
 REPLACE_TEXTUALLY ~^161 +.+~ ~161 STRENGTH_BUFF~
 REPLACE_TEXTUALLY ~^162 +.+~ ~162 IMMUNITY_INVOCATION~
 REPLACE_TEXTUALLY ~^163 +.+~ ~163 NEEDS_BREACH~
 REPLACE_TEXTUALLY ~^164 +.+~ ~164 SPELL_TRAP~
 REPLACE_TEXTUALLY ~^165 +.+~ ~165 BLADE_BARRIER~
 REPLACE_TEXTUALLY ~^166 +.+~ ~166 MELEE_THAC0~
 REPLACE_TEXTUALLY ~^167 +.+~ ~167 MELEE_DAMAGE~
 REPLACE_TEXTUALLY ~^168 +.+~ ~168 MISSILE_DAMAGE~
 REPLACE_TEXTUALLY ~^169 +.+~ ~169 NO_CIRCLE~
 REPLACE_TEXTUALLY ~^170 +.+~ ~170 FIST_THAC0~
 REPLACE_TEXTUALLY ~^171 +.+~ ~171 FIST_DAMAGE~
 REPLACE_TEXTUALLY ~^172 +.+~ ~172 TITLERECORDS~
 REPLACE_TEXTUALLY ~^173 +.+~ ~173 TITLEVARIOUS~
 REPLACE_TEXTUALLY ~^174 +.+~ ~174 DISABLE_OVERLAY~
 REPLACE_TEXTUALLY ~^175 +.+~ ~175 IMMUNE_TO_BACKSTAB~
 REPLACE_TEXTUALLY ~^176 +.+~ ~176 GAZE_REFLECTION~
 REPLACE_TEXTUALLY ~^177 +.+~ ~177 SPELL_SHIELD~
 REPLACE_TEXTUALLY ~^178 +.+~ ~178 RESIST_FEAR~
 REPLACE_TEXTUALLY ~^179 +.+~ ~179 DISPEL_BAD~
 REPLACE_TEXTUALLY ~^180 +.+~ ~180 INSIDE_OF_CLOUD~
 REPLACE_TEXTUALLY ~^181 +.+~ ~181 PROTECTION_NORMAL_WEAPONS~
 REPLACE_TEXTUALLY ~^182 +.+~ ~182 DISPEL_GOOD~
 REPLACE_TEXTUALLY ~^183 +.+~ ~183 OFFSCREEN_AI~
 /*
 REPLACE_TEXTUALLY ~^184 +.+~ ~184 SCRIPTINGSTATE28~
 REPLACE_TEXTUALLY ~^185 +.+~ ~185 SCRIPTINGSTATE29~
 */
 REPLACE_TEXTUALLY ~^186 +.+~ ~186 NOCHUNKYDEATH~
 REPLACE_TEXTUALLY ~^187 +.+~ ~187 IMMUNITYTURN~
 /*
 REPLACE_TEXTUALLY ~^188 +.+~ ~188 SCRIPTINGSTATE32~
 */
 REPLACE_TEXTUALLY ~^189 +.+~ ~189 CHAOS_SHIELD~
 REPLACE_TEXTUALLY ~^190 +.+~ ~190 NPCBUMP~
 REPLACE_TEXTUALLY ~^191 +.+~ ~191 USE_ANY_ITEM~
 REPLACE_TEXTUALLY ~^192 +.+~ ~192 ALWAYS_BACKSTAB~
 /*
 REPLACE_TEXTUALLY ~^193 +.+~ ~193 SCRIPTINGSTATE37~
 */
 REPLACE_TEXTUALLY ~^194 +.+~ ~194 SPELLFAILUREINNATE~
 REPLACE_TEXTUALLY ~^195 +.+~ ~195 IMMUNITYTRACKING~
 REPLACE_TEXTUALLY ~^196 +.+~ ~196 DEADMAGICZONE~
 REPLACE_TEXTUALLY ~^197 +.+~ ~197 IMMUNE_TO_TIMESTOP~
 /*
 REPLACE_TEXTUALLY ~^198 +.+~ ~198 SCRIPTINGSTATE42~
 */
 /*
 REPLACE_TEXTUALLY ~^199 +.+~ ~199 STONESKINGOLEM~
 REPLACE_TEXTUALLY ~^200 +.+~ ~200 LEVELDRAIN~
 */
 REPLACE_TEXTUALLY ~^201 +.+~ ~201 DONOTDRAW~
END
BUT_ONLY

CLEAR_IDS_MAP

INCLUDE ~detectable_effects/macros/detectable_effects.tph~

COPY_EXISTING_REGEXP GLOB ~^[^. ][^. ]?[^. ]?[^. ]?[^. ]?[^. ]?[^. ]?[^. ]?\.\(spl\|itm\)$~ ~override~
 PATCH_IF 1 THEN BEGIN
   LAUNCH_PATCH_MACRO ~detectable_effects~
 END
BUT_ONLY

Link to comment

And then done the effect modification via regexp and arithmetic rather than an explicit lookup table (I'm sorry, but no one wants to add the ~= 700 entries needed to fix up WEAPON_ENCHANTMENT to a table ??? ) Opcode list trimmed for brevity (and there's a hundred more I've yet to go through, it's only half done)

DEFINE_PATCH_MACRO ~detectable_effects~ BEGIN
 PATCH_IF          (NOT ~%SOURCE_FILE%~ STRING_CONTAINS_REGEXP ~\.spl~) THEN BEGIN
   SET "hs" = 0x28
 END ELSE PATCH_IF (NOT ~%SOURCE_FILE%~ STRING_CONTAINS_REGEXP ~\.itm~) THEN BEGIN
   SET "hs" = 0x38
 END
 PATCH_IF (SOURCE_SIZE > 0x71) THEN BEGIN
   PATCH_IF ("hs" = 0x28) THEN BEGIN
     READ_LONG 0x18 "fs"
   END
   PATCH_IF ("hs" = 0x38) THEN BEGIN
     READ_SHORT 0x1c "it"
     READ_LONG  0x60 "el"
   END
   READ_LONG  0x64 "ho"
   READ_SHORT 0x68 "hc"
   READ_LONG  0x6a "eo"
   FOR ("i1" = 0x0; "i1" < (("hc" + 0x1) * "hs"); "i1" += "hs") BEGIN
     SPRINT ~tm~ ~~ // Template
     SPRINT ~te~ ~~ // Template: detectable Effect
     SET "ad" = 0x0 // Added Effects
     SET "dg" = 0x0 // Duration: dispel Good
     SET "db" = 0x0 // Duration: dispel Bad
     SET "dp" = 0x0 // Duration: Projectile
     INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
       INSERT_BYTES 0x00 0x30
       WRITE_SHORT  0x00 0xe9
       WRITE_BYTE   0x12 0x64
     END
     PATCH_IF ("i1" = 0x0) THEN BEGIN
       READ_SHORT  0x6e "ei"
       READ_SHORT  0x70 "ec"
     END ELSE BEGIN
       READ_SHORT  ("ho" + ("i1" - "hs") + 0x1e) "ec"
       WRITE_SHORT ("ho" + ("i1" - "hs") + 0x20) "ei"
     END
     PATCH_IF (("hs" = 0x28) AND ("i1" != 0x0) AND (("fs" & 0x400) != 0x0)) THEN BEGIN
       READ_SHORT  ("ho" + ("i1" - "hs") + 0x26) "pi"
       LOOKUP_IDS_SYMBOL_OF_INT ~pn~ ~projectl~ "pi"
       PATCH_IF (FILE_EXISTS_IN_GAME ~%pn%.pro~) THEN BEGIN
         INNER_PATCH_FILE ~%pn%.pro~ BEGIN
           READ_SHORT 0x200 "fp" ELSE 0xc0
           PATCH_IF NOT (("fp" & 0xc0) = 0xc0) THEN BEGIN
             READ_BYTE 0x216 "dp" ELSE 0x0
           END
         END
       END
     END
     FOR ("i2" = ("ei" * 0x30); "i2" < (("ei" + "ec") * 0x30); "i2" += 0x30) BEGIN
       READ_ASCII ("eo" + "i2" + 0x00) ~tm~ (0x30)
       INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
         WRITE_SHORT  0x00 0xe9
         WRITE_ASCIIT 0x14 ~~
       END
       READ_SHORT ("eo" + "i2" + 0x00) "op"
       READ_BYTE  ("eo" + "i2" + 0x03) "pw"
       READ_LONG  ("eo" + "i2" + 0x04) "p1"
       READ_LONG  ("eo" + "i2" + 0x08) "p2"
       READ_BYTE  ("eo" + "i2" + 0x0d) "ds"
       READ_LONG  ("eo" + "i2" + 0x0e) "dd"

       PATCH_IF          ("op" = 0x000) THEN BEGIN
       END ELSE PATCH_IF ("op" = 0x001) THEN BEGIN
       END ELSE PATCH_IF ("op" = 0x066) THEN BEGIN // immunity to spell level
         PATCH_IF (("ds" & 0x1) = 0x1) THEN BEGIN
           SET "dg" = ("dd" > "dg") ? "dd" : "dg"
         END
         INNER_PATCH_SAVE ~te~ ~%te%~ BEGIN
           FOR ("i3" = ("ad" * 0x30); "i3" > 0x0; "i3" -= 0x30) BEGIN
             READ_LONG ("i3" - 0x28) "px"
             PATCH_IF ("px" = IDS_OF_SYMBOL (~stats~ ~PROTECTION_SPELL_LEVEL~)) THEN BEGIN
               READ_BYTE  ("i3" - 0x2c) "py"
               PATCH_IF ("py" < "p1") THEN BEGIN
                 WRITE_BYTE ("i3" - 0x2c) "p1"
                 SET "p1" = 0x0
               END ELSE BEGIN
                 SET "p1" = 0x0
               END
             END
           END
         END
         PATCH_IF ("p1" > 0x0) THEN BEGIN
           INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
             WRITE_LONG   0x04 "p1"
             WRITE_LONG   0x08 IDS_OF_SYMBOL (~stats~ ~PROTECTION_SPELL_LEVEL~)
           END
           SPRINT ~te~ ~%tm%%te%~
           SET "ad" += 0x1
         END
       END ELSE PATCH_IF ("op" = 0x067) THEN BEGIN
       END ELSE PATCH_IF ("op" = 0x135) THEN BEGIN // Script: Set/Modify Variable
       END ELSE PATCH_IF ("op" = 0x136) THEN BEGIN // Protection: from Timestop
         PATCH_IF (("ds" & 0x1) = 0x1) THEN BEGIN
           SET "dg" = ("dd" > "dg") ? "dd" : "dg"
         END
         INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
           WRITE_LONG   0x04 0x1
           WRITE_LONG   0x08 IDS_OF_SYMBOL (~stats~ ~IMMUNE_TO_TIMESTOP~)
         END
         SPRINT ~te~ ~%tm%%te%~
         SET "ad" += 0x1
       END ELSE PATCH_IF ("op" = 0x137) THEN BEGIN // Spell: Random Wish Spell
       END ELSE PATCH_IF ("op" = 0x13d) THEN BEGIN // State: Haste 2
       END
     END
     PATCH_IF (("hs" = 0x38) AND ("i1" = 0x0)) THEN BEGIN
       PATCH_IF (("el" > 0x0) AND ("it" > 0x0d) AND ("it" < 0x1f)) THEN BEGIN
         INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
           WRITE_SHORT  0x00 0xe9
           WRITE_BYTE   0x02 0x1
           WRITE_LONG   0x04 "el"
           WRITE_LONG   0x08 IDS_OF_SYMBOL (~stats~ ~WEAPON_ENCHANTMENT~)
           WRITE_BYTE   0x0c 0x2
           WRITE_BYTE   0x12 0x64
         END
         SPRINT ~te~ ~%tm%%te%~
         SET "ad" += 0x1
       END
     END
     PATCH_IF ("dg" > 0x0) THEN BEGIN
       INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
         WRITE_LONG   0x04 ("pw" > 0x0) ? "pw" : 0x1
         WRITE_LONG   0x08 IDS_OF_SYMBOL (~stats~ ~DISPEL_GOOD~)
         WRITE_LONG   0x0e "dg"
       END
       SPRINT ~te~ ~%tm%%te%~
       SET "ad" += 0x1
     END
     PATCH_IF ("db" > 0x0) THEN BEGIN
       INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
         WRITE_LONG   0x04 ("pw" > 0x0) ? "pw" : 0x1
         WRITE_LONG   0x08 IDS_OF_SYMBOL (~stats~ ~DISPEL_BAD~)
         WRITE_LONG   0x0e "db"
       END
       SPRINT ~te~ ~%tm%%te%~
       SET "ad" += 0x1
     END
     PATCH_IF ("dp" > 0x1) THEN BEGIN
       INNER_PATCH_SAVE ~tm~ ~%tm%~ BEGIN
         INSERT_BYTES 0x00 0x30
         WRITE_ASCIIE 0x00 ~%tm%~
         WRITE_LONG   0x04 ("pw" > 0x0) ? "pw" : 0x1
         WRITE_LONG   0x08 IDS_OF_SYMBOL (~stats~ ~INSIDE_OF_CLOUD~)
         WRITE_BYTE   0x0c 0x0
         WRITE_LONG   0x0e 0x6
         WRITE_BYTE   0x12 0x64
         WRITE_BYTE   0x13 0x0
         WRITE_LONG   0x24 0x0
         WRITE_LONG   0x28 0x0
         WRITE_LONG   0x34 ("pw" > 0x0) ? "pw" : 0x1
         WRITE_LONG   0x38 IDS_OF_SYMBOL (~stats~ ~INSIDE_OF_CLOUD~)
         WRITE_BYTE   0x3c 0x3
         WRITE_LONG   0x3e 0x6
         WRITE_BYTE   0x42 0x64
         WRITE_BYTE   0x43 0x0
         WRITE_LONG   0x54 0x0
         WRITE_LONG   0x58 0x0
       END
       SPRINT ~te~ ~%tm%%te%~
       SET "ad" += 0x2
     END
     FOR ("i2" = ("ei" * 0x30); "i2" < (("ei" + "ec") * 0x30); "i2" += 0x30) BEGIN
       READ_ASCII ("eo" + "i2" + 0x00) ~t1~ (0xc)
       INNER_PATCH_SAVE ~%te%~ ~te~ BEGIN
         FOR ("i3" = ("ad" * 0x30); "i3" > 0x0; "i3" -= 0x30) BEGIN
           READ_ASCII ("i3" - 0x30) ~t2~ (0xc)
           PATCH_IF NOT (~%t2%~ STR_CMP ~%t1%~) THEN BEGIN
             DELETE_BYTES ("i3" - 0x30) 0x30
             SET "ad" -= 0x1
           END
         END
       END
     END
     PATCH_IF ((~%te%~ STR_CMP ~~) AND ("ad" > 0x0)) THEN BEGIN
       INSERT_BYTES ("eo" + (("ei" + "ec") * 0x30)) (0x30 * "ad")
       WRITE_ASCIIE ("eo" + (("ei" + "ec") * 0x30)) ~%te%~
       WRITE_SHORT ("i1" > 0x0 ? ("ho" + ("i1" - "hs") + 0x1e) : 0x70) ("ec" + "ad")
       SET "ei" += ("ec" + "ad")
     END
   END
 END
END

 

I'd like to finish at least a personal use version for weekend after this (no time at the moment, but it'll happen)

Link to comment

And the a few more unsolicited observations:

  1. 109 IMMUNITY_ENCHANTMENT - Bivalent, no issues
  2. 110 WEAPON_ENCHANTMENT - Including launchers will often produce skewed results. Not including them will make this stat a glorified MostDamagingMelee check. Which is worse?
  3. 116 SPELL_DEFLECTION - Presumably it's the maximum level of deflected spell?
  4. 117 PROTECTION_ALIGNMENT - Bivalent?
  5. 118 TRUE_SIGHT - Bivalent, no issues
  6. 119 MIND_SHIELD - Bivalent, no issues other than how many effects need to be present to invoke the state.
  7. 120 PROTECTION_SPELL_LEVEL - Simple counter, no issues
  8. 121 IMMUNITY_NECROMANCY - Bivalent
  9. 122 PHYSICAL_MIRROR - Bivalent, no issues
  10. 123 IMMUNITY_ABJURATION - Bivalent, no issues
  11. 124 REGENERATION - Since there's three modes of regeneration, this isn't going to be perfectly accurate as a representation of regeneration rates - but a thumbnail hp/turn would probably suffice
  12. 125 FIRE_SHIELD - Implementing this as cast spell on condition if the triggered spell has the hostility flag set.
  13. 126 IMMUNITY_ALTERATION - Bivalent, no issues
  14. 127 IMMUNITY_CONJURATION - Bivalent, no issues
  15. 128 PROTECTION_MAGIC_WEAPONS - Have the spell Protection from Magical Weapons set the stat to 255?
  16. 129 SPELL_TURNING - Maximum level of spell turned?
  17. 130 IMMUNITY_DIVINATION - Bivalent, no issues
  18. 131 FREE_ACTION - Bivalent, only question is how many effects need to be present to invoke the state.
  19. 132 KHELBENS_WARDING_WHIP - Add three .effs to the spell I suppose
  20. 133 IMMUNITY_ILLUSION - Bivalent, no issues
  21. 134 LEVEL_DRAINED - Redundantly redundant
  22. 157 DEATH_WARD - just a rename
  23. 158 NEGATIVE_PLANE_PROTECTION - just a rename
  24. 159 COMBAT_BUFF - this is going to be a mess, not sure how to handle it yet.
  25. 160 ARMOR_SPELL - as above, and the various set/increment modes make this stat not so useful
  26. 161 STRENGTH_BUFF - as above but more so: still going to need LOCALS or this won't be well handled. This one is probably not going to be useful, but we'll see what can be done.
  27. 162 IMMUNITY_INVOCATION - Bivalent, no issues
  28. 163 NEEDS_BREACH - Probably bivalent, though higher level buffs can have a higher value too.
  29. 164 SPELL_TRAP - Highest level absorbed?
  30. 165 BLADE_BARRIER - would presumably include Aura of Flaming Scat and its ilk
  31. 166 MELEE_THAC0 - used by engine, not really negotiable
  32. 167 MELEE_DAMAGE - vide infra
  33. 168 MISSILE_DAMAGE - vide infra
  34. 169 NO_CIRCLE - vide infra
  35. 170 FIST_THAC0 - vide infra
  36. 171 FIST_DAMAGE - vide infra
  37. 174 DISABLE_OVERLAY - vide infra some more
  38. 175 IMMUNE_TO_BACKSTAB -
  39. 176 GAZE_REFLECTION - this is reflect projectile, perhaps?
  40. 177 SPELL_SHIELD - Could be bivalent, but I'd prefer more info stuck into parameter one
  41. 178 RESIST_FEAR - yep
  42. 179 DISPEL_BAD - huge stat, setting parameter one to the power of the agent spell
  43. 180 INSIDE_OF_CLOUD - this is going to be messy, should probably be handled by a once-per-six-second eff call, the teleport field opcode might be better excluded.
  44. 181 PROTECTION_NORMAL_WEAPONS - Bivalent, no issues
  45. 182 DISPEL_GOOD - Other than being enormous, no issues.
  46. 183 OFFSCREEN_AI - Bivalent, used by engine
  47. 189 CHAOS_SHIELD - Used by engine, I'd prefer SURGEMOD but the stat itself is quite spoken for
  48. 191 USE_ANY_ITEM - Hee.
  49. 192 ALWAYS_BACKSTAB -not much to do here
  50. 197 IMMUNE_TO_TIMESTOP-or here

Dunno if any of the stats not yet accounted for are in any way usable, it's possible, but would have to check them all.

Link to comment

Archived

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

×
×
  • Create New...