Jump to content

getting the IWDEE spells into BGEE


subtledoctor

Recommended Posts

Hey guys, I have just been reading about IWD-in-EET. I am working on a mod called Faiths & Powers... it has a bunch of new divine-class kits, revised cleric item usability, a facility to choose a deity by dialogue instead of the kits menu, and a sphere system with 21 spheres.

 

You can read about the mod here:

http://gibberlings3.net/forums/index.php?showtopic=27627

https://forums.beamdog.com/discussion/43174/faiths-and-powers-gods-of-the-realms-kitpack-and-divine-caster-spell-tweaks#latest

 

One of the notorious things about the DR sphere system was that some spheres were more or less empty of spells, at some levels anyway. For our mod, in order to fill out 21 spheres with 7-14 spells each, we did a few things: 1) borrow some wizard spells; 2) make some brand new spells; and 3) use the IWD spells from either IWDEE or IWDification.

 

We want to stop relying on IWDification, and just add in all of the IWDEE spells ourselves... but, doing so will be incredibly time-consuming, to export each one from NI and copy over the name and description text. It appears that you guys have already done this... so, getting to the point of this message, would you care to contribute some code, or techniques, or even just advice, to help us get it done faster?

 

(Beamdog says it's okay to copy the IWDEE spells over to the BG games, so there are no legal issues with doing this, and no need to check whether the player already has IWDEE on the computer.)

Link to comment

The IWD-in-EET code can't be used as it is for this task because the mod imports (and on the fly patches if needed) every single resource from the game, so it doesn't need to worry about identifying spell related resources or exporting just particular TRA references - that is handled automatically like any other resource. You could use spell.ids parser that can prepare a code for ADD_SPELL (it's also in EET.tp2, so feel free to use it). In order to export things only related to spells you would need to adopt the code existing in macros.tph file to loop through all references existing in these spells to get their names (or do it manually), than do the same with with those referenced files and again until nothing else is found. You would also need to identify offsets that needs to be updated after ADD_SPELL is used. Patch spells after ADD_PROJECTILE is used, if needed. On top of that a custom code to generate TRA files for different languages with only spell description and spell effects strings used there (the code for it could be easily adopted from "EET_expand_tlk" function also available within EET macros.tph file).

 

Overall it would be pretty time consuming. Probably it's a better idea to use IWDification work as a base, to save yourself time. Additional benefit would be compatibility with vanilla engines considering IWD:EE spells uses a lot of EE exclusive spell effects that doesn't exist in vanilla BG2. If that's out of the question than at least wait for Siege of Dragonspear to see what's the situation with spells post 1.4 patch. Beamdog guys mentioned during stream that there will be some new spells, so who knows.

Some advices regarding compatibility with other mods (including IWDification, IWD-in-EET and SCS if it ever receives proper update to support IWD:EE content):
- use ADD_SPELL with symbolic name exactly the same as in IWD/IWD:EE (for example CLERIC_IMPERVIOUS_SANCTITY_OF_MIND and not let's say SD#CLERIC_IMPERVIOUS_SANCTITY),
- don't change the level that particular spell is assigned to,
- mention in the readme that your mod should be installed after IWD-in-EET (if someone wants to use both mods).

Link to comment

I am also working on that mod.

 

I just want to check: when we effectively change a spell to a different level, we are planning to do this:

 

Add the spell in question to hidspl.2da.

 

Create a new spell at the desired level that uses 146 or 148 as appropriate (I.e. the cast spell opcodes) to cast the original spell.

 

Addspell this new spell at the desired level.

 

Alter scrolls as appropriate to cast (or teach) the new spell.

 

Alter any joinable npcs as necessary in terms of known spells.

 

This means that enemies will still have the spell at the original level. Not consistant, but it won't mess up any scripts at least (I don't think). Any mods that patch, or even overwrite the original spell will still be compatible (though still at the modified level).

 

Will this be okay as far as compatibility is concerned (perhaps with a warning?)

 

Edit: we aren't using addspell at the moment for the mod because the sphere system in place doesn't really need it...

 

I'm actually thinking of two different mods. In fnp, we aren't really using addspell, but otherwise I think we are doing this (or planning to)

Link to comment

Yeah, adding old spell to HIDESPL.2DA and updating old references with new ones in places that are noticeable by player (scrolls and known spells) would be enough to make it work. But why not just buff or nerf the spell instead of messing with levels? I don't think even Spell Revisions changes spell levels.

Link to comment

We're changing levels because we need to fill out 21 spheres.

 

Say the sphere of Vigor has 7 spells, but instead of having one at each level, it has none at 1st level and two at 2nd level (Slow Poison and Unfailing Endurance). We want a priest with access to the Vigor Sphere to be able to cast a 1st level spell from this dphere that his deity focuses on. So we drop Unfailing Endurance down to 1st level. This way every sphere has at least one spell at every level. And we rebalance things in the meantime. (E.g. DUHM is so absurdly good that it moves to 3rd level; Unfailing Endurance is almost useless, so it drops to 1st level. Etc.)

 

Changing the level of priest spells is actually pretty easy. I think you can just WRITE_SHORT 0x34 1 and leave everything else the same. The IDS name is unchanged, and the IDS number (which is used by IDS scripts) still points to the same file, so AI scripts should work just fine. Of course the mismatch between the spell's level, and the digit in its IDS number corresponding to level, will screw up its appearance in spell choice/memorization menus... but then again we are removing all spells from those menus anyway, so it doesn't matter! And we don't even need to use hidespl.2da! :)

 

(Changing the level of wizard spells is a tougher nut to crack... I've just about cracked it in TnB but it is definitely a more delicate proposition.)

 

If we get around to doing all this work to port over the IWDEE spells, we will indeed use ADD_SPELL, and we will use the exact same IDS names... because the sphere system is based on an associative array linking spheres to spells via their IDS name. Feed the IDS name of a spell to the array (any spell, including wizard spells and innate abilities) and tell it which sphere to put it in and what level it should be... my system will convert it to a priest spell (if necessary) of the desired level (if different) and add it via CLAB to every priest kit with access to that sphere.

 

And because it's all based on an array with 3 simple columns (IDS name, spell level, sphere), anyone can easily go in and tweak things to their liking. Want to move DUHM back to 2nd level? Sure. Want to make Wail of the Banshee a 3rd level spell in the sphere of Life? Go crazy. The system will adapt to your preferences. :)

 

Further benefit: the system can very easily be compatible with any spell mod out there that uses ADD_SPELL (or otherwise gives IDS names to its new spells). We will comb through such mods, gathering the IDS names of the spells they add, and add them to the array. If the mod is installed before ours, those spells will automatically be included in the sphere system. If the spells are not present in SPELL.IDS, those entries in the array will simply be ignored.

Link to comment

I don't think even Spell Revisions changes spell levels.

It does, mostly for the cure wounds line (which in that case is mostly about renaming the spells). Changing spell levels can sort of be done with ADD_SPELL, but it's kind of ugly.

 

I just want to check: when we effectively change a spell to a different level, we are planning to do this:

 

Add the spell in question to hidspl.2da.

 

Create a new spell at the desired level that uses 146 or 148 as appropriate (I.e. the cast spell opcodes) to cast the original spell.

 

Addspell this new spell at the desired level.

 

Alter scrolls as appropriate to cast (or teach) the new spell.

 

Alter any joinable npcs as necessary in terms of known spells.

 

This means that enemies will still have the spell at the original level. Not consistant, but it won't mess up any scripts at least (I don't think). Any mods that patch, or even overwrite the original spell will still be compatible (though still at the modified level).

 

Will this be okay as far as compatibility is concerned (perhaps with a warning?)

That could mess up some scripts. If enemies use HaveSpell() to check if they have the spell or any of the Spell() variants to cast a spell using the IDS name, it will be checking to see if they have the new spell, not the old one.

Link to comment

Just to clarify, I think AI scripts are safe.

 

- Priest spells will not be ADD_SPELL'd or added to hidespl2da. They are simply clone spells that cast the normal spell via opcode 146/148. Enemy priests are unchanged - they have the original spells and their scripts can still reference them by IDS name or IDS number using HaveSpell. Game scripts that check for conditions like SpellCastOnMe (or whatever that trigger is) will still work, because our clones are casting the real spells with opcode 146/148.

 

It's not 100% perfect but I think it covers everything that scripts need covered.

 

Wizard spells, on the other hand (this is TnB now) we change their level by

- cloning the spell

- ADD_SPELLing the clone with a *new* IDS name (like WIZARD_SHAPECHANGE_TNB)

- edit scrolls to learn/cast the new spell instead of the original

- add the original to hidespl.2da

 

So here again, AI casters simply use the original spells that happen to already be in their spellbooks. But the player learns new spells with a different level, either from scrolls or from spell selection menus.

Link to comment

Has there been any progress on this awesome idea? :borg:

 

Which? Getting divine IWDEE spells into BG2? A beta is here, thanks to the excellent and tireless work of Grammarsalad:

https://forums.beamdog.com/discussion/59668/iwd-divine-spells-in-bgee-sod-and-bg2ee

 

The broader sphere system/divine class overhaul mod (which will include those IWDEE divine spells)? It's not ready yet, but there has indeed been a lot of progress. We are getting pretty near to release.

Link to comment

The IWD-in-EET code can't be used as it is for this task because the mod imports (and on the fly patches if needed) every single resource from the game, so it doesn't need to worry about identifying spell related resources or exporting just particular TRA references - that is handled automatically like any other resource. You could use spell.ids parser that can prepare a code for ADD_SPELL (it's also in EET.tp2, so feel free to use it). In order to export things only related to spells you would need to adopt the code existing in macros.tph file to loop through all references existing in these spells to get their names (or do it manually), than do the same with with those referenced files and again until nothing else is found. You would also need to identify offsets that needs to be updated after ADD_SPELL is used. Patch spells after ADD_PROJECTILE is used, if needed. On top of that a custom code to generate TRA files for different languages with only spell description and spell effects strings used there (the code for it could be easily adopted from "EET_expand_tlk" function also available within EET macros.tph file).

 

Overall it would be pretty time consuming. Probably it's a better idea to use IWDification work as a base, to save yourself time. Additional benefit would be compatibility with vanilla engines considering IWD:EE spells uses a lot of EE exclusive spell effects that doesn't exist in vanilla BG2. If that's out of the question than at least wait for Siege of Dragonspear to see what's the situation with spells post 1.4 patch. Beamdog guys mentioned during stream that there will be some new spells, so who knows.

 

Some advices regarding compatibility with other mods (including IWDification, IWD-in-EET and SCS if it ever receives proper update to support IWD:EE content):

- use ADD_SPELL with symbolic name exactly the same as in IWD/IWD:EE (for example CLERIC_IMPERVIOUS_SANCTITY_OF_MIND and not let's say SD#CLERIC_IMPERVIOUS_SANCTITY),

- don't change the level that particular spell is assigned to,

- mention in the readme that your mod should be installed after IWD-in-EET (if someone wants to use both mods).

I have a question about this process.

 

One of the most pita things about converting IWD spells to the other games in my opinion involves opcode 267: protection from specific string. Many of the stringrefs do not match across games. I still find errors, and I am going to just have to go notification by notification and recheck everything to make sure that the spells are protecting against the right strings in the right engine.

 

Now, I'm confident that when IWD-in-EET imports IWD spells, all of this will be handled dynamically. Now, do you know at this point which engine will act as the 'base' (presumably BG2EE or IWDEE?) By 'base" i mean the 'main' game engine that will host the files from the other games. Though I obviously won't have to import IWD spells/resources into this new engine, I'll still be creating new spells that will need to protect from the game's text notifications, and I am hoping to get an idea of which games text notifications I should plan to protect from.

 

(Of course, I still have to install and test in EET. Right now I check for EET whenever I check for BG2EE for this purpose, and I have a given spell protect from BG2EE spell text refs in EET. Again, I totally admit that I have to recheck to ensure that this is the right policy--I feel fairly confident doing it this way atm as it appears that BG2EE is the 'base'. It is certainly possible that this is just a bad strategy :D Guess work is no substitute for empirical investigation, I know.)

Link to comment

You are indeed correct that it's handled automatically but the current implementation is not perfect by any means. I'm planning to write a code that automatically exports all disabled messages from Icewindification mod and apply them during installation if not yet present, because their implementation made by hand is probably the most accurate one. For now we are using these systems to get at least some of the messages handled:
- installer is able to automatically update opcode 'Remove effects by resource' which handles a lot of messages
- few messages are matched with this table (most of these are unused though):

 

ACTION_DEFINE_ASSOCIATIVE_ARRAY table_traify_strOldstrNew BEGIN //IWD => BG2
    //STATDESC.2DA
    "STAT0" , "37601" => "17391" //Charm
    "STAT1" , "37602" => "17392" //Dire Charm
    "STAT2" , "37603" => "17393" //Rigid Thinking
    "STAT3" , "37604" => "17394" //Confused
    "STAT4" , "37605" => "17395" //Berserk
    "STAT5" , "37606" => "17396" //Intoxicated
    "STAT6" , "37607" => "17397" //Poisoned
    "STAT7" , "35593" => "54337" //Diseased
    "STAT8" , "37608" => "17399" //Blind
    "STAT9" , "37609" => "17400" //Protection From Evil
    "STAT10" , "37610" => "17401" //Protection From Petrification
    "STAT11" , "37611" => "17402" //Protection From Missiles
    "STAT12" , "37612" => "17403" //Magic Armor
    "STAT13" , "35606" => "17404" //Held
    "STAT14" , "37613" => "17405" //Sleep
    "STAT15" , "37614" => "17406" //Shielded
    "STAT16" , "37615" => "17407" //Protection From Fire
    "STAT17" , "37616" => "17408" //Blessed
    "STAT18" , "37617" => "17409" //Chant
    "STAT19" , "37618" => "17410" //Free Action
    "STAT20" , "37619" => "17411" //Barkskin
    "STAT21" , "37620" => "17412" //Strength
    "STAT22" , "37621" => "17413" //Heroism
    "STAT23" , "37622" => "17414" //Invulnerable
    "STAT24" , "37623" => "17415" //Protection From Acid
    "STAT25" , "37624" => "17416" //Protection From Cold
    "STAT26" , "37625" => "17417" //Resist Fire/Cold
    "STAT27" , "37626" => "17418" //Protection From Electricity
    "STAT28" , "37627" => "17419" //Protection From Magic
    "STAT29" , "37628" => "17420" //Protection From Undead
    "STAT30" , "37629" => "17421" //Protection From Poison
    "STAT31" , "37630" => "17422" //Non-detectable
    "STAT32" , "37631" => "17423" //Good Luck
    "STAT33" , "37632" => "17424" //Bad Luck
    "STAT34" , "37633" => "17425" //Silenced
    "STAT35" , "37634" => "17426" //Cursed
    "STAT36" , "35484" => "17427" //Panic
    "STAT37" , "35985" => "10953" //Resist Fear
    "STAT38" , "37635" => "10954" //Haste
    "STAT39" , "37636" => "11330" //Fatigue
    "STAT40" , "37637" => "11798" //Bard Song
    "STAT41" , "37638" => "11799" //Slow
    "STAT43" , "37640" => "23739" //Domination
    "STAT44" , "37641" => "23740" //Hopelessness
    "STAT45" , "37642" => "23741" //Greater Malison
    "STAT46" , "37643" => "23742" //Spirit Armor
    "STAT47" , "37644" => "23743" //Chaos
    "STAT48" , "37645" => "23744" //Feebleminded
    "STAT49" , "37646" => "23745" //Defensive Harmony
    "STAT50" , "37647" => "23746" //Champion's Strength
    "STAT51" , "37648" => "23747" //Dying
    "STAT52" , "37649" => "23748" //Mind Shield
    "STAT53" , "37650" => "23779" //Energy Drain
    "STAT54" , "37651" => "23780" //Polymorph Self
    "STAT55" , "35567" => "14043" //Stun
    //"STAT56" , "" => "14091" //Regeneration (no entry in IWD:EE)
    "STAT57" , "37653" => "32877" //Perception
    "STAT58" , "37654" => "32878" //Master Thievery
    "STAT59" , "37655" => "8266" //Energy Drain
    "STAT60" , "37656" => "8267" //Holy Power
    "STAT61" , "37657" => "8268" //Cloak of Fear
    "STAT62" , "37658" => "8270" //Iron Skins
    "STAT63" , "37659" => "8271" //Magic Resistance
    "STAT64" , "37660" => "8272" //Righteous Magic
    "STAT65" , "37661" => "8273" //Spell Turning
    //"STAT66" , "37662" => "8275" //Repulsing Undead (no entry in IWD:EE)
    "STAT67" , "37663" => "8276" //Spell Deflection
    "STAT68" , "37664" => "8277" //Fireshield Red => Fire Shield Red
    "STAT69" , "37665" => "8279" //Fireshield Blue => Fire Shield Blue
    "STAT70" , "37666" => "8280" //Protection from Normal Weapon => Protection From Normal Weapons
    "STAT71" , "37667" => "8282" //Protection from Magic Weapon => Protection From Magical Weapons
    "STAT72" , "37668" => "8284" //Tenser's Transformation
    "STAT73" , "36633" => "26228" //Spell Shield
    "STAT74" , "37669" => "8291" //Mislead
    "STAT75" , "37670" => "8292" //Contingency Active
    "STAT76" , "37671" => "8293" //Protected from the Elements
    "STAT77" , "37672" => "8296" //Projected Image
    "STAT78" , "36720" => "18141" //Maze
    "STAT79" , "37673" => "8299" //Imprisonment
    "STAT80" , "37674" => "8300" //Stoneskin
    "STAT81" , "37675" => "8303" //KAI
    "STAT82" , "37676" => "8306" //Called Shot
    "STAT83" , "37677" => "8307" //Spell Failure
    "STAT84" , "37678" => "8308" //Offensive Spin
    "STAT85" , "37679" => "8309" //Defensive Spin
    "STAT86" , "37680" => "8311" //Intelligence drained by mind flayer
    "STAT87" , "37681" => "8313" //Regenerating
    "STAT88" , "37682" => "8315" //In Dialog
    "STAT89" , "37683" => "8316" //In Store
    "STAT90" , "37684" => "8318" //Negative Plane Protection
    "STAT91" , "37685" => "8320" //Ability Score Drained
    "STAT92" , "37686" => "8322" //Spell Sequencer Active
    "STAT93" , "2419" => "8324" //Antimagic Shell => Protected from Energy
    //"STAT94" , "37688" => "8325" //Magnetized (no entry in IWD:EE)
    "STAT95" , "37689" => "8326" //Able to Poison Weapons
    "STAT96" , "37690" => "8329" //Setting Trap
    "STAT97" , "37691" => "779" //Glass Dust
    "STAT98" , "37692" => "829" //Blade Barrier
    "STAT99" , "36313" => "5789" //Death Ward
    "STAT100" , "36230" => "3351" //Doom
    "STAT101" , "37693" => "34569" //Decaying
    "STAT102" , "37694" => "34570" //Acid
    "STAT103" , "36520" => "12079" //Vocalize
    "STAT104" , "37695" => "34571" //Mantle
    "STAT105" , "37696" => "54303" //Miscast Magic
    "STAT106" , "36434" => "14790" //Magic Resistance Lowered
    "STAT107" , "37697" => "54307" //Spell Immunity
    "STAT108" , "37698" => "54309" //True Seeing
    "STAT109" , "37699" => "50699" //Detecting Traps
    "STAT110" , "37700" => "54312" //Improved Haste
    "STAT111" , "37701" => "54315" //Spell Trigger
    "STAT112" , "35952" => "54318" //Deaf
    "STAT113" , "36525" => "7924" //Enfeebled
    "STAT114" , "36480" => "14060" //Infravision
    "STAT115" , "36471" => "12046" //Friends
    "STAT116" , "35964" => "11014" //Shield of the Archons
    "STAT117" , "36729" => "26304" //Spell Trap
    "STAT118" , "36732" => "7619" //Absolute Immunity
    "STAT119" , "36713" => "7617" //Improved Mantle
    "STAT120" , "36323" => "38133" //Farsight
    "STAT121" , "36651" => "23791" //Globe of Invulnerability
    "STAT122" , "36559" => "12029" //Minor Globe Of Invulnerability
    "STAT123" , "37702" => "8286" //Protected from Magical Energy
    "STAT124" , "37703" => "54332" //Polymorphed
    "STAT125" , "36570" => "22177" //Otiluke's Resilient Sphere
    "STAT126" , "37704" => "17398" //Nauseated
    "STAT127" , "36548" => "12129" //Ghost Armor
    "STAT128" , "36529" => "38594" //Glitterdust
    "STAT129" , "37705" => "54331" //Webbed
    "STAT130" , "37340" => "20438" //Unconscious
    "STAT131" , "37706" => "54333" //Mental Combat
    "STAT132" , "36375" => "38577" //Physical Mirror
    "STAT133" , "36346" => "2365" //Repulse Undead
    "STAT134" , "36334" => "22903" //Chaotic Commands
    "STAT135" , "36263" => "12108" //Draw Upon Holy Might
    "STAT136" , "36287" => "12125" //Strength of One
    "STAT137" , "37707" => "54335" //Bleeding
    "STAT138" , "35994" => "42870" //Rage => Barbarian Rage
    "STAT139" , "36061" => "34800" //Boon of Lathander
    "STAT140" , "36056" => "34768" //Storm Shield
    "STAT141" , "37708" => "54336" //Enraged
    "STAT142" , "36064" => "42865" //Stunning Blow
    "STAT143" , "36066" => "42857" //Quivering Palm
    "STAT144" , "37709" => "47835" //Entangled
    "STAT145" , "36459" => "12030" //Grease
    "STAT146" , "36086" => "65598" //Smite
    "STAT147" , "36082" => "63953" //Hardiness
    "STAT148" , "36080" => "63941" //Power Attack
    "STAT149" , "36068" => "63902" //Whirlwind Attack
    "STAT150" , "36070" => "63904" //Greater Whirlwind Attack
    //"STAT151" , "" => "70297" //Magic Flute (no entry in IWD:EE)
    "STAT152" , "36078" => "65434" //Critical Strike
    "STAT153" , "36074" => "63938" //Greater Deathblow
    "STAT154" , "36072" => "63922" //Deathblow
    "STAT155" , "36102" => "64001" //Avoid Death
    "STAT156" , "36100" => "65438" //Assassination
    "STAT157" , "36094" => "63992" //Evasion
    "STAT158" , "36096" => "63993" //Greater Evasion
    "STAT159" , "36748" => "63217" //Improved Alacrity
    "STAT160" , "36426" => "63842" //Aura of Flaming Death
    "STAT161" , "36420" => "63801" //Globe of Blades
    "STAT162" , "36705" => "64324" //Improved Chaos Shield => Improved Chaos Shield*
    "STAT163" , "36526" => "64319" //Chaos Shield => Chaos Shield*
    //"STAT164" , "36428" => "63873" //Fire Elemental Transformation (no entry in IWD:EE)
    //"STAT165" , "36430" => "63882" //Earth Elemental Transformation (no entry in IWD:EE)
    //below this line goes entries added during installation
    //above this line goes entries added during installation
END

 


- for the rest of messages SAY weidu command is used and we're hoping for the best with weidu automatic TLK matching feature (which is not really accurate most of the time)

 

A thing not implemented yet but planned is finding missing strings using OHSMODE1.SPL as a base since that one protects against many negative messages. Also some other spells could be used as a base for matching opcode and than automatically assigning all related message protections. It would be a matter of preapering 1 array that lists all strings appropriate to particular opcode. Once such common table is created everything would be sorted with simple weidu code and you wouldn't need to do it by hand, Grammarsalad (if anyone is interested in prearranging such table than that would be a huge help).

Example how such table would look like (opcode on the left, BG2:EE string number on the right - IWD:EE string numbers are not really needed for this since that would be universal implementation unrelated to what was used previously):

//Cure stun
46 => 14043
46 => 1280

and so forth.

 

BG2:EE strings numbers are used as a base in everything related to EET.

 

edit: confused 'Immunity to spell and message' opcode with 'Remove effects by resource'

Link to comment

Archived

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

×
×
  • Create New...