Another approach, somewhat outside the box, depending on how complex and versatile this has to be, I’d built it with a number of game objects.
1) Make a parent game object, Event Manager that has two children, Pool A and Pool B. Pool A has three children, called Events.
Event Manager
— Pool A
—— Event 1
—— Event 2
—— Event 3
— Pool B
The parent gets a FSM that draws a random child from Pool A, and parents the child to Pool B. If no child is in Pool A, then rename Pool A to Pool B, and vice versa and continue. So what it does, it draws events and puts it into the other pool. If you put types of events into it, it should process them nicely in a random order and until all are depleted, then shuffle them back, and repeat.
2) Next, put an identical FSM on each Event object. It listens to a global event, say “DOEVENT” and then sends out a desired event of a specific type to a target FSM. This specific event type is the only thing you need to adjust. Say, Event 1 sends event1, Event 2 sends event2 etc. and to wherever you want it.
3) Now, you only need to go to the FSM in Event Manager and after it grabs one random child, also send the DOEVENT of that child. All put together, it will grab a random child, start the FSM routine inside which sends out a special event. Then puts the child into the discarded pool B. By simply duplicating the events of each type, you can control exactly how many there are of each type.
You probably don’t want to do this like that, since there are more direct methods with weights on the events, but it all depends on what you try to do overall.