That looks good. You made an interesting choice for your delegate naming strategy, basing the names on the signature as opposed to the delegate semantics (in other words, what it means for the object). I had gone that way in my own code originally and soon got tired of generic parameters. It *does* probably allow fewer delegate definitions in the long run if many delegates are used!

(I might reconsider that choice in my own code.)
You could probably come up with a nice concise convention, like "Delegate_N_type", where "N" is the number of arguments and "type" is the return type (if there is one). So a delegate taking two params and returning a string could be "Delegate_2_string". Something like that... That's basically what you did in a more verbose way.
Edit: one downside to using the signature (param/type) naming is if you later need to (say) add a parameter to an existing delegate that you're using. Let's say you have a delegate in use across many objects (e.g. every room in your game) and you decide you need to add a parameter for a special case that has come up. If you have named your delegate based on functional use, where you have a unique name for that *behavior*, then you can simply go to the delegate definition for that usage, add the new parameter, and you're done. If you have based the delegate name on the number of parameters used, then you must go to each object and change each type usage individually.