I've looked pretty thoroughly through the code now, and I think I know exactly what's going on. Some of this might help you fix the VGA bug, because it's probably the exact same thing going on there.
It's not effecting all spells in the rooms you've identified. It's not even actually causing problems in all the rooms you fixed, so you can scale back your fixes a bit. That said, I think your fix is the best way to do so. The basic problem is exactly as you found -- the (switch spell) is happening after (CastSpell spell).
The basic order of things is that in Main, the glory::handleEvent procedure runs constantly, and for speechEvents (of which typing "Cast anything" is one) it tells the specific room to do what it needs to do first:
(super handleEvent: event)
If the room code has done what it needs to do, it will set (event claimed: TRUE). I.e. it did the job, stop there.
So, what should be happening is that the room specific stuff should check only for spells that do something unique in that room, and if so cast the spell (via (CastSpell), do the animations, whatever, and claim the event.
Instead, what's happening is that those buggy rooms are casting the spells first thing with a (CastSpell) call -- that improves your skill with the spell, drains your mana, and flags the event as claimed, so nothing else will try to claim the spell -- then it's checking if it should actually do anything specific with the spell. If so, do that animation, show that text, otherwise if it's a spell we're not doing anything special with reset the event claimed flag back to FALSE, so the main script can deal with it.
But we're already cast the spell... so we're casting it twice. Once in secret, then finally with the animation and text.
There's two ways to fix it... one, as you've already done is to swap around the switch statement and the CastSpell statement. So you check to see which spell the player typed in, and only CastSpell if it's one this room recognizes... otherwise, leave the claimed flag as false and let the main script handle it. You can see the original programmers already did this in some rooms, like the Stags in Rooms 77 and 78.
The other way is to add cases for all 7 spells, and don't let the main script handle any of that. That's actually the approach done in the RandomEncounter.sc script. So that room you didn't actually need to switch the order around, because it's not leaving the event unclaimed for the main script to handle. It's not my favorite approach though, because it means needlessly copying code into all the rooms. Something the original programmers did a fair bit... there's like 5 places where they handle the Zap spell, and it does the exact same thing in each... scratch that, almost the exact same thing. They slightly changed the text for when you're not holding a weapon in all but the Main script.
Best I can figure, there were 31 separate instances that check if the user tried to cast a spell (calls to the SaidCast function), not counting the one in Main. So to be sure, I think you'd need to check each of those rooms, and see if they're casting the spell first, then accounting for a fraction of the spells then flagging the event as not claimed. Those would be your problems rooms, and I suspect it'll be the exact same in the VGA version.