2.0 - exclusive doesn't work
Zarius opened this issue ยท 10 comments
STONE: #1
- drop: STONE
- chance: 50
drop: DIAMOND
exclusive: 1
Stone still drops when the diamond does.
Issue confirmed but not yet investigated.
It grew from just being "exclusive: true" meaning that if this one drops nothing does. I added the numbers (or strings) so that you could have groups of items that might be able to drop together (whilst blocking any drops without that exclusive string).
Having the numbers (or strings) probably confuses the matter, perhaps exclusive could just be a flag? We could then use dropgroups for "grouped" exclusives - this does take away the power of having two differenct dropgroups with the same exclusive value though...
Well, I do like the concept of exclusive's current behaviour; it's just not the same concept of its behaviour that you had. I don't actually think there's an easy way to implement your version as it currently stands unless we sort the drops list so that the ones with no exclusivity are at the end. (That said, such sorting shouldn't be difficult to accomplish.) I think the groups aspect of what you described is better done as a dropgroup, but we could add "unique: true" or "flags: unique" to mean that if the drop occurs then no other drop will occur?
I'm fairly sure exclusive will work if every drop has it, and if some drops don't have it I would think it's because they're not supposed to be exclusive.
The stone is not supposed to be exclusive, but the diamond is - what this means is that if the diamond drops then nothing else should (unless it also has the exclusive: 1 tag).
Another example:
STONE: #1
- drop: STONE
- drop: APPLE
chance: 25
- drop: DIAMOND
chance: 50
exclusive: 1
In this case if an apple drops I would still expect stone to drop, but if the diamond drops then nothing else should.
Hm, this sounds a bit different from what I thought exclusive was supposed to do. Currently in 2.0, exclusive means "only one drop with this key can drop".
Well, it has the same use as "drop: {x, y, z}", except that x, y, and z can be drop groups. So, for example, if you wanted sand to have a chance of dropping either a compass and watch together or a specific map, you could do it using the current behaviour of exclusive. I don't think there's currently another way to do that.
It can also be used inside drop groups, for example if you want a map and either a compass or a watch but never with neither.
Hmm... can you give some examples of how you see the current behaviour is useful? I'm not doubting it - just can't see it yet.
Here's how I would have written the examples you gave in OtherBlocks 1.x -
# sand will drop sand & an apple however if the mapcompass group is "rolled" then it
# will only drop a map&compass, and if the MAP@9 is subsequently rolled it will override
# all other drops (as there are no other "exclusive: 2" drops).
SAND:
- drop: SAND
- drop: APPLE
- dropgroup: mapcompass
chance: 10%
exclusive: 1
drops:
- drop: COMPASS
- drop: WATCH
- drop: MAP@9/10%
exclusive: 2
Second example -
# inside a dropgroup: I thought of the below but it wont work... hmm.
SAND:
- dropgroup: mapcompass
chance: 10%
drops:
- drop: MAP
exclusive: 1
- drop: COMPASS
exclusive: 1
- drop: WATCH
exclusive: 2
Who would have thought the exclusive options/unique flag would be so tricky :D My previous use of "exclusive" could almost be done entirely by dropgroups (could be completely done if dropgroups could contain dropgroups) though so your interpretation is probably more powerful, just need to document a few examples.
This made me think of drops containing drops using aliases which works fine with lists "[ ]" but not hashes "{ }" - see example:
aliases:
- &mapcompass
dropgroup: mapcompass
chance: 10%
exclusive: 1
drops:
- drop: COMPASS
- drop: WATCH
- &map9
drop: MAP@9/10%
exclusive: 2
event: LIGHTNING
biome: FOREST
otherdrops:
SAND:
- drop: SAND
- drop: APPLE
- drops: {*mapcompass, *map9} # unfortunately dict objects are unhashable
- drops: [*mapcompass, *map9] # this works
Wow, a lot to say here.
Your first example does seem to be basically identical to what I described if you assume that a drop with an exclusive key dropping means all subsequent drops are ignored.
Your second example would I think do what I described in 2.0, though the exclusive: 2 is redundant.
My previous use of "exclusive" could almost be done entirely by dropgroups (could be completely done if dropgroups could contain dropgroups)
I don't have any strong objection to dropgroups containing dropgroups; it wouldn't even be too difficult to make it possible (would mostly amount to removing the check that a drop in a dropgroup is not itself a drop group, though that's not quite all).
- drops: {*mapcompass, *map9} # unfortunately dict objects are unhashable
This I believe is actually a flaw in PyYAML, one which SnakeYAML does not share. Maps as keys are perfectly valid in YAML, so this line is itself valid YAML. However, it won't work for a different reason. Unlike "drop", the "drops" key is not set up to handle the { } syntax. It would certainly be possible to change this, giving rise to the following notation:
otherdrops:
SAND:
- drop: SAND
- drop: APPLE
- dropgroup: stuff
drops:
? drop: MAP@9/10%
event: LIGHTNING
biome: FOREST
? dropgroup: mapcompass
chance: 10%
drops:
- drop: COMPASS
- drop: WATCH
This would have roughly the same effect as what you intended with your third example. However, I'm not convinced it's worth it since the same effect is obtainable (in 2.0) like this:
otherdrops:
SAND:
- drop: SAND
- drop: APPLE
- dropgroup: stuff
drops:
- drop: MAP@9/10%
event: LIGHTNING
biome: FOREST
exclusive: 1
- dropgroup: mapcompass
chance: 10%
exclusive: 1
drops:
- drop: COMPASS
- drop: WATCH
Also, I should note that you need to be careful with YAML aliases, since I believe they can be used to create genuinely recursive structures. That is, I think when you use an alias, it references the anchor rather than inserting a copy of it. (Using it with <<: may eliminate this danger though, not sure.)