meiskam / PlayerHeads

Bukkit Plugin - Drops a player's head when s/he dies, also mob heads
https://dev.bukkit.org/projects/player-heads
Other
17 stars 39 forks source link

How to modify the drop rate ? #27

Closed MeowRay closed 3 years ago

MeowRay commented 3 years ago

plugin version : latest How can I modify the drop rate through the API? Can you add a drop rate preprocessing event?

HeadRollEvent Only getter, but no setter.. image

crashdemons commented 3 years ago

HeadRollevent occurs after internal droprates have already been calculated. At this stage, only the success value is used after this event is fired (you will notice the success value has a setter).

If you want to add additional factors to the droprate yourself, you will unfortunately have to do some additional calculation/RNG and set the success value yourself (taking into account the existing droprate and success). The droprates provided by the event are meant to be informative as to how you set the success. That is, using the right formula - you can override the droprate calculation of PH entirely and calculate it with the same or different variables.

Aside: forcing droprate recalculation and droprate modifiers API that worked inside of PH (with different options like multiplicative/additive/proportional) were a planned feature (and even coded) for the now-tabled version 5.3 [which included a lot of other features like custom head extensions, etc], but the project got to be too large and difficult to maintain, so it never was stable enough to release. Since then, I haven't had a lot of time to dedicate toward new advancements (with some small exceptions), but instead I've been trying to focus on stability and maintenance.

crashdemons commented 3 years ago

That is, using the right formula - you can override the droprate calculation of PH entirely and calculate it with the same or different variables.

To help with this, in the following example you can replicate and modify the PH droprate.

//double myModifier = 1 + rate * level; // where rate is a value 0.0-1.0 and level multiplies the effect (for instance, luck level)
// the following modifiers are available from event getters.

double droprate = droprateOriginal * lootingModifier * slimeModifier * chargedcreeperModifier; /* add "*myModifier" to modify the rate further */
OR
double droprate = droprateEffective; /* from the event getter - add "*myModifier" to modify the rate further */

double dropchance = event.getEffectiveDropRoll();// OR prng.nextDouble();  - effective roll only differs from random when "alwaysbehead" is set, which changes it to 0.0 (guaranteed success on positive droprates)
boolean headDropSuccess = dropchance < droprate; //where the PRNG is uniform 0.0-1.0 and the droprate of 1.0+ is 100%
event.setDropSuccess​( headDropSuccess );

I have an example project that modifies rates to include Luck in the calculation by doing a similar process: https://github.com/crashdemons/TrophyLuckModifier although it does so for both PlayerHeads and MiningTrophies.

recalculation with luck https://github.com/crashdemons/TrophyLuckModifier/blob/master/src/main/java/com/github/crashdemons/trophyluckmodifier/TrophyLuckModifier.java#L121

overwriting success https://github.com/crashdemons/TrophyLuckModifier/blob/master/src/main/java/com/github/crashdemons/trophyluckmodifier/TrophyLuckModifier.java#L124 https://github.com/crashdemons/TrophyLuckModifier/blob/master/src/main/java/com/github/crashdemons/trophyluckmodifier/PHListener.java#L30

My main nag with this process (which was going to be addressed in 5.3 originally) is that it makes you recalculate things yourself, and that it leaves other plugins "out of the loop" that further modification occurred.

MeowRay commented 3 years ago

That is, using the right formula - you can override the droprate calculation of PH entirely and calculate it with the same or different variables.

To help with this, in the following example you can replicate and modify the PH droprate.

//double myModifier = 1 + rate * level; // where rate is a value 0.0-1.0 and level multiplies the effect (for instance, luck level)
// the following modifiers are available from event getters.

double droprate = droprateOriginal * lootingModifier * slimeModifier * chargedcreeperModifier; /* add "*myModifier" to modify the rate further */
OR
double droprate = droprateEffective; /* from the event getter - add "*myModifier" to modify the rate further */

double dropchance = event.getEffectiveDropRoll();// OR prng.nextDouble();  - effective roll only differs from random when "alwaysbehead" is set, which changes it to 0.0 (guaranteed success on positive droprates)
boolean headDropSuccess = dropchance < droprate; //where the PRNG is uniform 0.0-1.0 and the droprate of 1.0+ is 100%
event.setDropSuccess​( headDropSuccess );

I have an example project that modifies rates to include Luck in the calculation by doing a similar process: https://github.com/crashdemons/TrophyLuckModifier although it does so for both PlayerHeads and MiningTrophies.

recalculation with luck https://github.com/crashdemons/TrophyLuckModifier/blob/master/src/main/java/com/github/crashdemons/trophyluckmodifier/TrophyLuckModifier.java#L121

overwriting success https://github.com/crashdemons/TrophyLuckModifier/blob/master/src/main/java/com/github/crashdemons/trophyluckmodifier/TrophyLuckModifier.java#L124 https://github.com/crashdemons/TrophyLuckModifier/blob/master/src/main/java/com/github/crashdemons/trophyluckmodifier/PHListener.java#L30

My main nag with this process (which was going to be addressed in 5.3 originally) is that it makes you recalculate things yourself, and that it leaves other plugins "out of the loop" that further modification occurred.

I solved the problem by adding pre event and rebuilding the project. Thank you