subtledoctor Posted January 31, 2016 Share Posted January 31, 2016 I am trying to turn Spell Thrust into an innate ability. Here is my code: ADD_SPELL ~innate_magic/wizard/spwi321.spl~ 4 1 WIZARD_SPELL_THRUST SAY NAME1 @6053 SAY UNIDENTIFIED_DESC @6054 COPY_EXISTING_REGEXP GLOB ~^.+\.cre$~ ~override~ PATCH_IF (SOURCE_SIZE > 0x2d3) BEGIN READ_BYTE 0x273 class PATCH_IF (class == 1 || class == 13 || class == 14 || class == 7 || class == 10 || class == 17) BEGIN // wizards ADD_KNOWN_SPELL ~%thrust_res%~ #0 ~innate~ ADD_MEMORIZED_SPELL ~%thrust_res%~ #0 ~innate~ END END BUT_ONLY COPY ~innate_magic/wizard/spwi321.spl~ ~override~ SAY NAME1 @6053 SAY UNIDENTIFIED_DESC @6054 Basically, my mod has an innate version of Spell Thrust; I use ADD_SPELL to add it as an spclxxx.spl file linked to the IDS name WIZARD_SPELL_THRUST in spell.ids. Then I give the ability to every wizard in the game. Then I copy my innate version into /override as spwi321.spl. This .spl file is no longer linked to anything in the IDS table, but it is there. So: any script that uses HaveSpell(WIZARD_SPELL_THRUST) will find my innate version, and scripts that use HaveSpellRES(spwi321) will find my leftover version of spwi321.spl. This way, scripts should work with my innate version of the spell... and because it is a self-renewing ability, AI mages should be able to use it at will. BUT: after I run the code above, existing BCS scripts in the game *change.* When I inspect AI scripts in Near Infinity, scripts that use to say HaveSpell(WIZARD_SPELL_THRUST) now say HaveSpell(2321) And of course, the IDS number of the old Spell Thrust spell now points to nothing, because ADD_SPELL changed the IDS number of WIZARD_SPELL_THRUST to something like 4107. Why is this happening? How is this happening? I don't want to change any scripts - I want to look at them, and work with them as they already are! How can I account for how existing scripts work when my own code seems to change them? Can this be avoided? Or am I going to have to run something like this at the end of the mod: LAF RES_NUM_OF_SPELL_NAME STR_VAR spell_name = ~WIZARD_SPELL_THRUST~ RET spell_num END OUTER_SET thrust_num %spell_num% COPY_EXISTING_REGEXP_GLOB ~^.+\.bcs$~ ~override~ DECOMPILE_BCS_TO_BAF REPLACE_TEXTUALLY EVAL ~2321~ ~%thrust_num%~ COMPILE_BAF_TO_BCS ...Because, with SCS scripts weighing in at ~30,000 lines each, decompiling and compiling them all to make a simple text change could take a looooong time... Any ideas? Link to comment
Jarno Mikkola Posted January 31, 2016 Share Posted January 31, 2016 Why is this happening? Any ideas? Well, because the .bcs scripts are already compiled scripts. Aka the numbers are already set in them ... the scripts you thing you are watching with Near Infinity are the source .baf's aka text file made out of them. for debug'ging.. So yeah, you need to recompile the scripts again. And instead of DECOMPILE_BCS_TO_BAF --- COMPILE_BAF_TO_BCS , use the DECOMPILE_AND_PATCH BEGIN --- END routine. Link to comment
subtledoctor Posted January 31, 2016 Author Share Posted January 31, 2016 Yeah but why would NI show me different BAF text for an AI BCS script before and after I ADD_SPELL a spell? Is the BCS content in fact changed by the later mod? If the BCS script content is static, then what is actually referenced in them? If I can't trust NI to tell me, does anyone know the answer? What should I be targeting with my mod? The IDS number? Link to comment
Jarno Mikkola Posted January 31, 2016 Share Posted January 31, 2016 If the BCS script content is static, then what is actually referenced in them? If I can't trust NI to tell me...Well the thing is, the NI shows you the Script source(decompiled) which is the .baf code, when it's decoded by the games current libraries, but you can also view the Script code which is the actual files content. And I don't think you wish to touch that. Link to comment
subtledoctor Posted January 31, 2016 Author Share Posted January 31, 2016 yeah I still don't understand why the displayed decompiled .BAF source seems to change when I ADD_SPELL a new version of WIZARD_SPELL_THRUST. Link to comment
argent77 Posted February 1, 2016 Share Posted February 1, 2016 BCS byte code stores the numeric value of the respective spells. The IDS file is only used to translate the number into a symbolic name when NI or WeiDU decompiles the script into the BAF source or vice versa. If you change the spell from SPWI321 into SPCL101 (or whatever ADD_SPELL is returning) then you have to change all instances of "2321" into "4101" in all existing BCS files of the game if they should use your new spell instead of the original one.You can easily inspect the BCS byte code in NI by switching to the "Script code" tab. As an example, the trigger "HaveSpell(WIZARD_SPELL_THRUST)" is translated into TR 16433 2321 0 0 0 "" "" OB 0 0 0 0 0 0 0 0 0 0 0 0 ""OB TR in an unmodded game. 16433 is the trigger ID of "HaveSpell()" and 2321 is the function argument which translates into WIZARD_SPELL_THRUST via SPELL.IDS. When you change the value assigned to WIZARD_SPELL_THRUST in SPELL.IDS from 2321 to any other value then the decompiler can't resolve the number from the byte code above into a symbolic name. It will fall back to display the raw number instead. Link to comment
subtledoctor Posted February 1, 2016 Author Share Posted February 1, 2016 @argent77 - thank you for the explanation. So it looks like in order to "fool" AI scripts into using my alternate version of Spell Thrust, I have to target the IDS number instead of the name. Which may be difficult or even impossible... And separate issue, it means that it would be difficult or impossible to change the level of any spell without breaking scripts. Meaning, possibly, that the only answer is indeed to DECOMPILE_AND_PATCH every .bcs script in the game...? Ouch. ... Alternatively: I could just make Spell Thrust self-renewing as a wizard spell. The Wondrous Recall opcode can do this, but it only works for the earliest spell that is memorized and already cast. I.e. the furthest to the left in the spell screen when looking at your spellbook. Does anyone know how the organization of known spells in the .cre file translates to being earliest or latest in the spellbook screen? Is there any way to make it so that AI wizard .CREs get Spell Thrust as the "earliest" 3rd level spell? Can I do something with this code to make sure of it, and therefore make sure that any application of the Wondrous Recall opcode will always restore Spell Thrust? COPY_EXISTING_REGEXP GLOB ~^.+\.cre$~ ~override~ PATCH_IF (SOURCE_SIZE > 0x2d3) BEGIN READ_BYTE 0x273 class PATCH_IF (class == 1 || class == 13 || class == 14 || class == 7 || class == 10 || class == 17) BEGIN // wizards ADD_KNOWN_SPELL ~%thrust_res%~ #0 ~innate~ ADD_MEMORIZED_SPELL ~%thrust_res%~ #0 ~innate~ END END BUT_ONLY Link to comment
Jarno Mikkola Posted February 1, 2016 Share Posted February 1, 2016 Can I do something with this code to make sure of it, and therefore make sure that any application of the Wondrous Recall opcode will always restore Spell Thrust?Well unless you rearrange their spell memorization table. In theory you could do that. But then what happens when the player get's fireballs instead of spell thrusts. Link to comment
subtledoctor Posted February 1, 2016 Author Share Posted February 1, 2016 what happens when the player get's fireballs instead of spell thrusts. That's precisely the issue. A possible plan is to split this into using two different methods: 1) The PC and joinable NPCs will get an innate ability at level 5 that is self-renewing via opcode 171 2) Non-joinable NPCs will have Spell Thrust as a normal wizard spell, but it will be patched to use opcode 261 to renew itself upon casting. They could be given a bonus to 3rd-level spell slots to make up for using up one of them on Spell Thrust. That could work perfectly in-game (every wizard can cast Spell Thrust at will) *as long as* the spell tables of the non-joinable .CREs can be edited such that Spell Thrust is the first memorized 3rd-level spell, and thus will always be renewed when the .CRE is affected by Wondrous Recall. It's that last part I have no idea how to do. But I want to see if it's possible, before deciding to decompile and patch every BCS script. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.