4:58 PM
@genaray A loot system in a game I worked on used logic very similar to what's been recommended above. We had a large library of "preconditions" which were plain old data objects that described a single test that could evaluate to true or false, like "Is in Region X" or "Is in Time of Day Range Y" or "Was Killed by Element Z"...
We could also have compound preconditions that would string together other preconditions into boolean expressions. So we could make more complex conditions like "Minor enemy was killed at night by gunfire from a player of level > 10" out of these building blocks.
Then in our loot system, each item in a pool could specify a precondition to check to see if it was valid. And a weight.
When executing a loot roll, we'd run through all the items in the pool and evaluate their preconditions. Ones that passed would be added into the potential selection according to their weight, and ones that failed would be skipped.
Then we'd do a weighted random selection from those surviving items.
That worked quite well for our purposes. The polymorphism of different precondition types wasn't a problem, because evaluating a loot roll - like spawning an entity - isn't something we did hundreds or thousands of times a frame. It's something we did a handful of times with seconds or minutes between iterations.
So, remember you don't get any points for "ECS purity". Players don't see that. The "rules" of an ECS help with performance when you're doing the same thing hundreds or thousands of times in a frame, and with flexibility of composing entities modularly.
If you're not in a situation where you need those benefits, then over-complicating your own development efficiency just to meet those guidelines anyway is not good development practice. It's just superstition.
Use ECS for what it's good at and what you need it for. Don't wear it like shackles.