(BG1) Spells that create magical items have issues when concluding w Opcodes 111,122
I'm not able to articulate it better, so I'll direct quote from @Galactygon:
OBSERVED:
EXPECTED:Galactygon said:Opcodes 111 (create magical weapon) and 122 (create inventory item) with durations create items and then remove them by internally applying opcodes 122 (remove item) and 123 (remove inventory item). This way of handling things has the following issues:
1. You may not refresh spells that create items because opcode 122 will be applied prematurely from the previous casting. For example, if you cast Flame Blade that lasts for 10 rounds and you try to refresh the spell after 8 rounds, the new casting will only last for 2 rounds because the .itm will be removed by virtue of the previous casting
2. In case of opcode 122 you may give the .itm to another .cre or drop it on the ground or in a container and the .itm will not disappear because at expiry it will attempt to remove the .itm from the .cre on which it was created
3. There is this default sound (EFF_M02) that is hardcoded, which would be nice to softcode or eliminate somehow
4. The created magical items are not dispellable (but this is fixed in ToBEx)
Opcode 255 (create inventory item (days)) on the other hand removes the item by applying an internal timer to the .itm which is stored on the inventory of the .cre. This is a much better way to to handle magically created items, and would fix all the issues if this method would be used by opcodes 111 and 122.
I would even go as far to suggest an alternative to the current ToBEx implementation to use the extra space at 0x10 and 0x11 of inventory items header of the .cre for a "dispellable" flag and bytes at 0x12 and 0x13 to store the casting level of the caster who created the item.
-Galactygon
Comments
1. You may not refresh spells that create items because opcode 122 will be applied prematurely from the previous casting. For example, if you cast Flame Blade that lasts for 10 rounds and you try to refresh the spell after 8 rounds, the new casting will only last for 2 rounds because the .itm will be removed by virtue of the previous casting
2. In case of opcode 122 you may give the .itm to another .cre or drop it on the ground or in a container and the .itm will not disappear because at expiry it will attempt to remove the .itm from the .cre on which it was created
3. There is this default sound (EFF_M02) that is hardcoded, which would be nice to softcode or eliminate somehow
4. The created magical items are not dispellable (but this is fixed in ToBEx)
Opcode 255 (create inventory item (days)) on the other hand removes the item by applying an internal timer to the .itm which is stored on the inventory of the .cre. This is a much better way to to handle magically created items, and would fix all the issues if this method would be used by opcodes 111 and 122.
I would even go as far to suggest an alternative to the current ToBEx implementation to use the extra space at 0x10 and 0x11 of inventory items header of the .cre for a "dispellable" flag and bytes at 0x12 and 0x13 to store the casting level of the caster who created the item.
-Galactygon
I'd like to elaborate on the last part of my suggested solution. There is an inconsistency between game time (kept track as a long) and the expiry values in the itm header of the .cre and .are formats (stored as two bytes at 0x08 and 0x09).
I propose that the absolute game time value for item expiry is stored as a long that "jumps" from 0x08, 0x09 to 0x12, 0x13. The caster level (normally stored as a short) is then truncated to a single byte at 0x11 since it's unlikely to go above 255, and the item flags are stored at 0x10.
This isn't a clean solution, but this doesn't change the size of the file format and should prevent existing mods from breaking.
-Galactygon
That sounds about right, but I suppose I wouldn't know. There is an example in @Galactygon's quote above though regarding the spell Flame Blade and whether you can extend its duration by re-casting the spell (apparently you can't). I'm not sure what spell-created limited-duration ITMs are supposed to auto-delete which you can also drop before expiration, though maybe it can be spawned?
-Galactygon
Shillelagh and flame blade are also known by her.
Just memorize 2 flame blades. Cast one, then cast another midway expiration.
If the item is refreshed - good. Then just wait till the end of expiration.
So spells like Chill Touch, Vampiric Touch, Shocking Grasp all rely on creating temporary items? Is that true also for Polymorph that adds squirrel paws? In those cases though there's nothing the player could remove from inventory to test for the other element of duration expiring despite the created ITM not remaining in the caster's inventory.
Oh where's @Igneous who knows the spell angles so well?
-Galactygon
Potentially fixed - Summoned weapons and items now die at the appropriate times without using a timed destroy effect. This allows weapons to be refreshed.
And come to think of it, I've probably just turned it into create item so i can see what it looks like before it goes poof....
Tested this in three ways:
1. As a level 6 Druid I casted Flame Blade and then waited 24 seconds before casting it again. The second Flame Blade lasted 42 seconds, consistent with the description of the spell.
2. As a level 6 Druid I casted Flame Blade, waited 10 seconds, casted a successful Dispel that dispelled Flame Blade, and then recast Flame Blade. The second Flame Blade lasted 42 seconds, consistent with the description of the spell.
3. Used Cause Serious Wounds and observed that the spell lasted for 15 seconds. Used a Cleric to cast Cause Serious Wounds, used it immediately on a target and then immediately recasted Cause Serious Wounds and it lasted 15 seconds.
[edit]
Actually no, i changed goodberries to use duration. They vanish from inventory properly, but once dropped and taken, m_wear vanishes. I will bug that separately.