Sorry for a late reply, was sitting in a car with a pissed off cat for 20 hours yesterday coming home...
1. Attach a trigger volume around the tree. Anything which enters the volume triggers an event which can be piped to functions or other components.
2. Attach the trigger event to a 'filter' which only passes the event if it is caused by the player object. Could be another component or a customized event/message proxy system.
3. Attach the filtered event to a spawner. Set the spawner to spawn a squirrel when triggered. Attach this to the tree also and route the event to trigger this spawner.
So, your "logic" is built up from simple concepts which can be reused and combined in many ways for other things. You have avoided putting any of this case specific logic into the player, so it gets to remain a nice focused object. You have attached the trigger to a static item so it is actually pretty low cost (moving trigger volumes are considerably more expensive). And the squirrel is the only "specific" item in the whole solution. Obviously to "spawn" a squirrel, you need a squirrel to spawn.
So basically I will have like 100+ events specified in a very generic way? Then I set up some observer / listener messaging system so that every object only registers for certain events and then respond on it? I must say thinking about this in such an abstract way seems alright but I guess it will be a nightmare to implement in reality :/
I do this considerably differently which doesn't require a bunch of intermediate structures and message "crackers" etc. I actually use std::bind and wrap that in a generic functor so there is no translation. All the work of figuring out what data to send gets wrapped up in the bound function and/or with the case of compositing you can basically write a little script of things to do and not just a single emitted event. If you can't tell, I love std::bind flexibility, understanding it can be a bit of a pain though.
Anyway, "event" is just a descriptive term, whatever you use is up to you. It can be messages, bound functions, or like my system bound functions sent as "messages" but they simply call functions when you actually 'dispatch' them.