Difference between revisions of "User:Epictaru/Sandbox/Treasure Hunter Demystified"
m (→Treasure Hunter - Drop Calculations) |
m (→Treasure Hunter - Drop Calculations) |
||
(One intermediate revision by the same user not shown) | |||
Line 106: | Line 106: | ||
* Treasure Hunter 5: 3 drop chances. | * Treasure Hunter 5: 3 drop chances. | ||
− | As you can see, after Treasure Hunter 2, you <u>do not</u> affect how many times an item has a chance to drop | + | As you can see, after Treasure Hunter 2, you <u>do not</u> affect how many times an item has a chance to drop. But it <u>does</u> effect the "bonus" applied to the actual drop rate. |
− | /u> effect the "bonus" applied to the actual drop rate. | ||
The drop "bonus" is applied to the actual items drop rate. For example, let's look at the Ridill. Fafnir drops this at a rate of 6%. | The drop "bonus" is applied to the actual items drop rate. For example, let's look at the Ridill. Fafnir drops this at a rate of 6%. |
Revision as of 17:39, 29 May 2023
This was originally posted on the LegionDark forums by Atom0s on Wednesday, Oct 26, 2016 3:50 am
This has been modified by EpicTaru to reformat it into a wiki article, to increase clarity in some sections, to change any mentions of the LegionDark name with HomepointXI, to add the link to the Q&A that SE did recently to further explain some specifics of Treasure Hunter on retail, and to add the comment explaining drop slots.
Contents
Treasure Hunter Demystified
This post is meant to cover how Treasure Hunter (TH) works on HomepointXI (and the DarkStar private server code base in general). Please note that Treasure Hunter on private servers using the stock Dark Star Project (DSP) core does not work like retail. There are very major differences in the way that TH functions here (and on other DSP private servers) than on retail. This post is going to help clear up those differences and explain how TH is actually working for you here.
At the time of making this post, HomepointXI DOES NOT have any custom code effecting how Treasure Hunter works. This may change in the future, but for now this information is valid on HomepointXI and DSP stock private servers. As of 2022, the code for Treasure Hunter hasn't changed in the currently active codebase (LandSandBoat) aside from function name changes.
Intro To Treasure Hunter
Before I begin, I want to point people to information pertaining to Treasure Hunter on retail so you can get a jist of what it is, what it does and how it is supposed to work. A lot of information surrounding Treasure Hunter is assumptions and guess work, along with user-based testing and theory crafting. Square Enix has never come out and said how every part of TH works, instead they have only given us tid-bits of information throughout the years. Some of the more recent updates to retail have also given some more clues as to how it is supposed to work.
https://www.bg-wiki.com/bg/Treasure_Hunter
http://forum.square-enix.com/ffxi/threads/56550
http://forum.square-enix.com/ffxi/threads/40657-Mar-18-2014-%28JST%29-Version-Update?p=498469&viewfull=1#post498469
http://forum.square-enix.com/ffxi/threads/27974-TH-Procing?p=377001&viewfull=1#post377001
https://www.bluegartr.com/threads/112776-Dev-Tracker-Findings-Posts-(NO-DISCUSSION)?p=5469894&viewfull=1#post5469894
https://www.reddit.com/r/ffxi/comments/4ulgh1/official_ffxi_developer_ama_with_producer_akihiko/d5qsvi2/
For those interested in seeing how DSP handles Treasure Hunter, you can find that information here:
Where Treasure Hunter is applied to a mob:
https://github.com/DarkstarProject/darkstar/blob/master/src/map/enmity_container.cpp#L150
Where treasure hunter is handled for drops:
https://github.com/DarkstarProject/darkstar/blob/master/src/map/map/entities/mobentity.cpp#L779
Treasure Hunter - Retail vs. DSP
While I am not going to get into too many specifics about this, I do want to point out some major differences between Treasure Hunter on retail and Treasure Hunter on DSP servers. They work differently and should not be assumed to work alike unless the server you play on has modified it otherwise.
While on retail, Treasure Hunter's effectiveness is applied as a debuff to the target you are attacking. Your effective Treasure Hunter amount is based on your TH level compared to the current TH level debuff applied to the target. On retail, you will see an animation and receive a message when your Treasure Hunter procs on a mob. However, on DSP, this is not the case. Instead, Treasure Hunter is applied, in full, each time you hit a target.
On retail, swapping out of TH gear can hinder your effective Treasure Hunter against the target preventing it from increasing anymore. On DSP, this is not the case and the max TH of the gear you have equipped is applied and used, regardless of if you switch gear afterward. This means that, for example, say you are fighting Fafnir with Treasure Hunter +10. If you hit Fafnir at the start of the fight with your TH +10 gear then kill it in TH +0 gear, you will still be granted with TH +10 on the drops. You do not need to keep your gear on. I will go into these better below.
Treasure Hunter - Understanding How It Works On DSP
Since DSP implements Treasure Hunter "incorrectly" to how retail does, some people are left to assume how it works here. This often leads to speculations that are incorrect and misinformation spreads around on how it works. I'm making this post to help clear up that misinformation and to assist players in understanding how Treasure Hunter works, and how to best and effectively utilize it.
Treasure Hunter is only applied on aggressive actions. This means that when your enmity is updated, you must be doing something that aggressively pisses off the target. Casting Cure on someone WILL NOT apply Treasure Hunter. Meaning that if you are THF/WHM, you cannot apply Treasure Hunter by simply curing someone that has hate. Even if you pull hate from curing, it will not apply your Treasure Hunter.
Treasure Hunter is applied, in full, when an aggressive action is taken. This means that if you are a Thief with TH+15, when you hit a mob, steal from it, mug it, etc. your full TH+15 is applied immediately. There is no ramp up of effectiveness, no "proccing", like on retail.
Treasure Hunter will remain on the mob if the thief drops party. The thief does not have to be in the party after they have hit the target for their Treasure Hunter to work. As long as they do not die and remain in range of the target when it dies, their Treasure Hunter will still be applied. This means you can kick that useless Thief from party after they have hit the mob!
Treasure Hunter gear does not have to remain equipped after being applied. Once you have hit a mob once with your full Treasure Hunter gear, you can swap out of it and use whatever you want. You do not have to be wearing your Treasure Hunter gear while the mob dies. You also do not have to keep it on to remain the highest Treasure Hunter level on the mob. One and done boys, hit it and quit it.
Treasure Hunter uses the highest overall Treasure Hunter applied during the fight. When the mob dies, it will use the highest Treasure Hunter that hit it to do the drop calculations. This means that if you have, for example, two Thiefs with different Treasure Hunter levels, it does not matter which one has the last hit, which one has their max TH on when the mob dies etc. The highest overall TH between the two will be used for the calculation (keep in mind the player with the highest Treasure Hunter does have to be alive, on the hate list, and in range for it to work!)
Treasure Hunter is not removed if you go out of range and come back. If you leave range of the fight (far enough that you will not receive exp etc. when it dies) your Treasure Hunter is not erased from the mob's list. But, you MUST be within range when the mob dies for your TH to be used. This means you can move away from the mob to stay safe and come back just before it dies to ensure your Treasure Hunter is applied.
Treasure Hunter - Drop Calculations
Now that we have the methods of how Treasure Hunter is applied and handled, lets discuss how it affects drops. Item drops have a two-stage system in how they are handled. The first stage is determining if the the drop can happen at all, the second stage is if the item should drop. The first stage is referred to a "roll". And the second is the rate.
When a mob dies, the following steps are taken for how drops are handled:
The max Treasure Hunter value is pulled from the mob's enmity list at the time of death.
The Treasure Hunter value is pulled from this enmity container and is only valid if the player is alive and within enmity range of the dying mob.
The mob's drop list is loaded.
Each item in the drop list is looped through the below calculations.
An amount of "rolls" are applied to let the item drop.
If a roll is successful, the item drops to the treasure pool.
On stock DSP servers, these calculations are done like this:
Note that:
m_THLvl = the highest Treasure Hunter pulled from the mob's enmity container at the time of death.
https://github.com/DarkstarProject/darkstar/blob/master/src/map/entities/mobentity.cpp#L795-L796
maxRolls = 1 + (m_THLvl > 2 ? 2 : m_THLvl); bonus = (m_THLvl > 2 ? (m_THLvl - 2) * 10 : 0);
If we look at how this is applied, we see:
https://github.com/DarkstarProject/darkstar/blob/master/src/map/entities/mobentity.cpp#L824-L835
for (const DropItem_t& item : DropList->Items) { for (int16 roll = 0; roll < maxRolls; ++roll) { if (item.DropRate > 0 && dsprand::GetRandomNumber(1000) < item.DropRate * map_config.drop_rate_multiplier + bonus) { if (AddItemToPool(item.ItemID, ++dropCount)) return; break; } } }
This means that an item has a maximum of 3 tries to drop depending on the amount of Treasure Hunter that is being used in the calculation.
For example, this is how drops would be up to Treasure Hunter +5:
- Treasure Hunter 0: 1 drop chance.
- Treasure Hunter 1: 2 drop chances.
- Treasure Hunter 2: 3 drop chances.
- Treasure Hunter 3: 3 drop chances.
- Treasure Hunter 4: 3 drop chances.
- Treasure Hunter 5: 3 drop chances.
As you can see, after Treasure Hunter 2, you do not affect how many times an item has a chance to drop. But it does effect the "bonus" applied to the actual drop rate.
The drop "bonus" is applied to the actual items drop rate. For example, let's look at the Ridill. Fafnir drops this at a rate of 6%.
http://homepointxi.com/db/items/16555/ridill
So this means that at Treasure Hunter 0, you have 1 chance for this item to drop at the listed 6%.
Each Treasure Hunter level after that will add a bonus to the roll being done. This would look like this:
- Treasure Hunter 0 Bonus: 0
- Treasure Hunter 1 Bonus: 0
- Treasure Hunter 2 Bonus: 0
- Treasure Hunter 3 Bonus: 10
- Treasure Hunter 4 Bonus: 20
- Treasure Hunter 5 Bonus: 30
And so on, incrementing at 10 per level of Treasure Hunter.
DSP handles the drop rate and attempt via this line:
https://github.com/DarkstarProject/darkstar/blob/master/src/map/entities/mobentity.cpp#L828
if (item.DropRate > 0 && dsprand::GetRandomNumber(1000) < item.DropRate * map_config.drop_rate_multiplier + bonus)
The beginning portion of the above line says that: if the drop rate is greater than 0 (meaning it can actually drop the item) then roll a random number between 0 and 1000. If that number is less than our calculated drop rate, the item will drop.
The calculated item drop rate is done via the ending portion of the above line:
item.DropRate * map_config.drop_rate_multiplier + bonus)
- item.DropRate is the item's set drop rate from the database. The Ridill is set to 60 in the database, i.e. 6% drop rate.
- map_config.drop_rate_multiplier is a server based configuration that can multiply the drop rate. HomepointXI has this set to 1.0, which means the drop rates are not multiplied or affected as a whole. (So 6% means 6%)
- bonus is our calculated bonus added to the drop during its calculation.
Let's say for example you have Treasure Hunter +13. This means that the following would happen:
- You would have 3 tries for the Ridill to drop.
- Each try would have 6% (60) + 11% (110) bonus to drop.
So this means that a random number between 0 and 1000 will be rolled 3 times. Each time the server will compare that rolled number to: (60 * 1.0 + 110)
This means that with Treasure Hunter +13, you change the drop rate of Ridill from 6% to 17%.
If you have any questions regarding this, let me know. I will gladly answer them.
Additional comment from TeoTwawki
TeoTwawki
Re: Treasure Hunter Demystified
Thu Oct 27, 2016 11:25 am
atom0s touched on this and I want to emphasize it: anything that fully removes the THF from the mob's hate list, will remove that THF's TH. So while you can be out of range for most of the battle and not lose TH, zoning will normally remove you from the mob's hate list resulting in lost TH. So your THF friend can't come hit it once then zone out, barring unintended bugs.
@atom0s: if I remember right retail caps TH and DSP is missing that cap too, isn't it?
Additonal comment from Epictaru regarding drop slots
When someone refers to a mob having an item that is a "drop slot" drop, what that means is that the item is a strict chance at it's weighted value being chosen for being used in the drop slot. Treasure Hunter has zero effect on drop slot items.
Let's use King Behemoth and the oh so coveted Defending Ring as an example of a drop slot item. The Defending Ring (Item ID 13566) is in a drop slot group along with the Pixie Earring (Item ID 13415), this is defined in mob_droplist.sql as:
https://github.com/DarkstarProject/darkstar/blob/master/sql/mob_droplist.sql#L7579-L7580
INSERT INTO `mob_droplist` VALUES (1450,1,1,1000,13415,950); INSERT INTO `mob_droplist` VALUES (1450,1,1,1000,13566,50);
Here is the code that explains how items in drop slots are calculated to be chosen to drop or not:
https://github.com/DarkstarProject/darkstar/blob/master/src/map/entities/mobentity.cpp#L802-L820
//Determine if this group should drop an item if (group.GroupRate > 0 && dsprand::GetRandomNumber(1000) < group.GroupRate * map_config.drop_rate_multiplier + bonus) { //Each item in the group is given its own weight range which is the previous value to the previous value + item.DropRate //Such as 2 items with drop rates of 200 and 800 would be 0-199 and 200-999 respectively uint16 previousRateValue = 0; uint16 itemRoll = dsprand::GetRandomNumber(1000); for (const DropItem_t& item : group.Items) { if (previousRateValue + item.DropRate > itemRoll) { if (AddItemToPool(item.ItemID, ++dropCount)) return; break; } previousRateValue += item.DropRate; } break; }