And I wonder... what's the best way to separate animation and collision so that they won't depend too much on each other? Any ideas?
I don't know what the best way is, but the way I'd do it is have animation frames associated with an attack geometry class. The class would describe the initial size of the collision geometry (a rect for example), and then keys for size and rotation, which would be interpolated over the frames until the end frame (which could default to the animated end, or be specified). It would have an entityID associated with it.
I'd do basically the same thing for the hitboxes. Then I'd sort them based on which quadrant (or some smaller factor) they're in. There would be a similar sort for the collision geometry. When any collision geometry was active, it would then check against the hitboxes in it's same quadrant. If it hits, the event system would tell the attacker it hit, and the one attacked that it was hit...and then those entities would handle their own behavior.
That's my very straightforward approach. I'm not really sure how well it would work, my own game is turn-based, so the animations themselves don't determine if something is hit or not, that's determined beforehand. I tried to keep it fairly generic since I don't know how you have your game set up. Anyway, don't know if you'll use any of those ideas, but maybe it will inspire something cleverer.