DEFINE_ACTION_FUNCTION ADD_SPLSTATE STR_VAR label = ~~ RET new_ids BEGIN
OUTER_SET new_ids = ~-1~
ACTION_IF FILE_CONTAINS_EVALUATED (~SPLSTATE.IDS~ ~^.+[ %TAB%]%label%\b~) BEGIN
COPY_EXISTING ~SPLSTATE.IDS~ override
COUNT_2DA_ROWS 2 rows
FOR (i = 0; i < rows; ++i) BEGIN
READ_2DA_ENTRY i 1 2 state_label
PATCH_IF ~%state_label%~ STRING_EQUAL_CASE ~%label%~ BEGIN
READ_2DA_ENTRY i 0 2 state_id
SET new_ids = state_id
END
END
BUT_ONLY
END ELSE BEGIN
OUTER_FOR (i = 0; i < 256; ++i) BEGIN
OUTER_SET $occupied_spell_state(~%i%~) = 0
END
ACTION_IF (~%label%~ STRING_EQUAL ~~) BEGIN FAIL ~Missing Spell State label~ END ELSE BEGIN
ACTION_IF ((~%label%~ STRING_CONTAINS_REGEXP ~ ~) = 0) BEGIN FAIL ~Spell State lable cannot have spaces~ END ELSE BEGIN
COPY_EXISTING ~SPLSTATE.IDS~ override
COUNT_2DA_ROWS 2 rows
FOR (i = 0; i < rows; ++i) BEGIN
READ_2DA_ENTRY i 0 2 state_id
SET $occupied_spell_state(~%state_id%~) = 1
END
FOR (i = 0; i < 256; ++i) BEGIN
PATCH_IF $occupied_spell_state(~%i%~) = 0 BEGIN
SET new_ids = i
SET i = 256
PATCH_IF new_ids <= rows BEGIN
INSERT_2DA_ROW new_ids 2 ~%new_ids% %label%~
END ELSE BEGIN
INSERT_2DA_ROW new_ids 2 ~%new_ids% %label%~
END
END
END
PATCH_IF (new_ids = ~-1~) BEGIN PATCH_FAIL ~No available Spell States~ END
BUT_ONLY
END
END
END
END
LAF ADD_SPLSTATE STR_VAR label = ~CUSTOM_STATE~ RET new_ids END
I have coded a function for my Golem Construction mod which adds new entries to free slots in IDS files, including SPLSTATE.IDS. Just note that (as already mentioned) values > 255 may not work correctly (or at all), so a heavily modded game will run out of free slots rather quickly.
Detectable Spells' version, which tries to look up the name in specified .ids file, otherwise adds it to unoccupied slot. Can be invoked by LAF ds_resolve_stat INT_VAR ids=1 STR_VAR id= CUSTOM_SPELLSTATE_NAME RET stat_ind=stat_ind END Where "stat_ind" variable it returns is the corresponding .ids value the stat/state got assigned.
Incidentally any thoughts on which weapons this should affect, other than the Zerth Blade? I already have a list of all the +spells weapons in IWDEE... are there any more in BG2 I'm not thinking of? Or in prominent mods?
Loop through weapons and read the opcodes they're using. That way you'll catch everything.
But if the character already has a permanent 232 effect with the "hp<102%" condition (say, from a mod adding new stat bonuses), will this one fail?</p>
As long as opcode 232 is called through opcode 177 in an external eff, by default you can stack as many as you want.
Setting the fields at 0x90 and/or 0x94 in the EFF is what will cause multiples to fail - parent resource type and resref, but there is no limit when the fields are empty.
@subtledoctor I had an idea for another way to implement items such as this.
Require Binding them to the character to get the full benefits, by making them undroppable & unstealable. You could toggle the effect with the converse button, a dialog file, and 2 spell files.
Two subspells: %resref%B.spl = remove effects of "%resref%R", extra spell slot effects (Timing=9), set LOCAL %resref% = 1. %resref%R.spl = remove effects of "%resref%B", set LOCAL %resref% = 0.
Remove the extra spell slot effects from the item itself.
An entry in "itemdial.2da": "itemres strref dlgres". strref would be the "converse" button label.
While the item is bound, it cannot be moved from its slot, and you get the full benefit of its effects - the extra spell slots. You would still be able to switch to and out the other weapon slots.
While the item is unbound, it can be freely moved around, but you would not get the extra spell slots.
You would need to remove the effect whenever items are forcibly destroyed: SoA start, Black Dragon Bribe, some Black Pits event. Or just flag them as "Critical Item" so they cannot be destroyed.
You could do this with any item type, or not even require the item be equipped, just kept in the inventory.
@subtledoctor, They can be used in items, yes, you can even use the same EFF for both a spell and an item - the timing mode listed in the EFF is irrelevant. I can only say to check the basics, because something is off, or upload them for another set of eyes.
Comments
Still sucks that values above 255 are unstable.
Can be invoked by
LAF ds_resolve_stat INT_VAR ids=1 STR_VAR id= CUSTOM_SPELLSTATE_NAME RET stat_ind=stat_ind END
Where "stat_ind" variable it returns is the corresponding .ids value the stat/state got assigned.
Setting the fields at 0x90 and/or 0x94 in the EFF is what will cause multiples to fail - parent resource type and resref, but there is no limit when the fields are empty.
Require Binding them to the character to get the full benefits, by making them undroppable & unstealable.
You could toggle the effect with the converse button, a dialog file, and 2 spell files.
The dialog would need 3 states: Two subspells:
%resref%B.spl = remove effects of "%resref%R", extra spell slot effects (Timing=9), set LOCAL %resref% = 1.
%resref%R.spl = remove effects of "%resref%B", set LOCAL %resref% = 0.
Remove the extra spell slot effects from the item itself.
An entry in "itemdial.2da": "itemres strref dlgres". strref would be the "converse" button label.
While the item is bound, it cannot be moved from its slot, and you get the full benefit of its effects - the extra spell slots. You would still be able to switch to and out the other weapon slots.
While the item is unbound, it can be freely moved around, but you would not get the extra spell slots.
You would need to remove the effect whenever items are forcibly destroyed: SoA start, Black Dragon Bribe, some Black Pits event. Or just flag them as "Critical Item" so they cannot be destroyed.
You could do this with any item type, or not even require the item be equipped, just kept in the inventory.