Amiibo drops: Difference between revisions

From ZeldaMods (Breath of the Wild)
Jump to navigation Jump to search
imported>Leoetlino
No edit summary
 
(45 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{stub}}
<languages/>
== Drop tables ==
<translate>
 
<!--T:1-->
{{lowercase}}
 
== Drop tables == <!--T:2-->
 
<!--T:3-->
{|class="wikitable"
{|class="wikitable"
! Idx || Name !! Description
! Idx || Name !! Description
Line 6: Line 13:
| 0 || Normal ||
| 0 || Normal ||
|-
|-
| 1 || Normal2 ||
| 1 || Normal2 || Unused.
|-
|-
| 2 || SmallHit ||
| 2 || SmallHit ||
|-
|-
| 3 || SmallHit2 ||
| 3 || SmallHit2 || Unused.
|-
|-
| 4 || BigHit ||
| 4 || BigHit ||
|-
|-
| 5 || BigHit2 ||
| 5 || BigHit2 || Unused.
|-
|-
| 6 || GreatHit ||
| 6 || GreatHit ||
|-
|-
| 7 || GreatHit2 ||
| 7 || GreatHit2 || Unused.
|}
|}


== Notes on AmiiboMgr ==
== amiibo registering == <!--T:4-->
*amiibo code ([[AIDef:Action/CreateEpona]], [[AIDef:Action/ItemAmiiboSelectDropTable]], [[AIDef:AI/WolfLinkAmiibo]]) call [[AmiiboMgr]]::updateHistoryFlags{{un}}<ref>0x710064B564 on Switch 1.5.0</ref> every time an amiibo is used.
 
**First, AmiiboMgr determines if it should reset its daily amiibo use history (stored in the AmiiboTouchHistory flag)<ref>0x710064B3C8</ref>.
<!--T:5-->
***If less than 86400 seconds (1 day) have elapsed since the game was launched, don't do anything.{{check}}
amiibo are registered<ref>0x710064B564 on Switch 1.5.0</ref> every time an amiibo is used.
***AmiiboMgr then computes <code>10000 * now.year + 100 * now.month + now.day</code>. If the value is different from AmiiboLastTouchDate (which would mean that a day has elapsed), the AmiiboTouchHistory array is cleared.
* [[AIDef:Action/CreateEpona]] does so after Epona has been spawned.
**AmiiboTouchHistoryTotal (which stores the last 200 used amiibos) is updated too. Exactly what happens is currently unknown.
* [[AIDef:AI/WolfLinkAmiibo]] does it after spawning Wolf Link.
**Finally, AmiiboLastTouchDate is set to <code>10000 * now.year + 100 * now.month + now.day</code>.
* [[AIDef:Action/ItemAmiiboSelectDropTable]] registers an amiibo as soon as it is scanned, even before spawning the drops.
 
<!--T:6-->
Whenever an amiibo is registered:
*AmiiboMgr determines if it should reset its daily amiibo use history (stored in the AmiiboTouchHistory flag)<ref>0x710064B3C8</ref>.
**If less than 86400 seconds (1 day) have elapsed since the game was launched, don't do anything.{{check}}
**AmiiboMgr then computes <code>10000 * now.year + 100 * now.month + now.day</code>. If the value is different from AmiiboLastTouchDate (which would mean that a day has elapsed), the AmiiboTouchHistory array is cleared.
*An entry for the scanned amiibo is inserted into AmiiboTouchHistory. Only the last 100 entries are kept.
*For a first time scan, a new entry is inserted into AmiiboTouchHistoryTotal (only the last 200 entries are kept). Otherwise, the scan count is incremented by updating the existing entry.
*Finally, AmiiboLastTouchDate is set to the current date.
 
<!--T:7-->
The format for AmiiboTouchHistory and AmiiboTouchHistoryTotal entries is "%s_%d_%d_%d" (amiibo UID, amiibo value 1, amiibo value 2, scan count) 
 
== Logic == <!--T:8-->
 
<!--T:9-->
A SmallHit happens 20% of the time.
 
<!--T:10-->
If the amiibo has been scanned 0, 1, 2, 3 or 4 times, you'll get a GreatHit 20% of the time. If you didn't get a GreatHit, the game will ensure you get a BigHit.
 
<!--T:11-->
If the amiibo has been scanned 5 times or more, you'll always get a GreatHit. In this case, the BigHit table is ignored.
 
<!--T:12-->
For BigHits and GreatHits, the game uses the 'Remain' tables if Find_4Relic_1stClear is set, 'Parasail' if IsGet_PlayerStole2, and 'Normal' otherwise.
 
<!--T:13-->
The game then determines the number of drops from each table<ref>[[AIDef:Action/ItemAmiiboCreateFromDropTable]]</ref>:
* For a GreatHit:
** GreatHit drops: random number between RepeatNumMin and RepeatNumMax for GreatHit
** SmallHit drops: same, but for SmallHit (if there is a SmallHit).
** Normal drops: random number between RepeatNumMin and RepeatNumMax for Normal, minus the GreatHit drop num
* For a BigHit:
** BigHit drops: random number between RepeatNumMin and RepeatNumMax for BigHit
** SmallHit drops: same, but for SmallHit (if there is a SmallHit).
** Normal drops: random number between RepeatNumMin and RepeatNumMax for the Normal table, minus the BigHit drop num
 
<!--T:14-->
After a GreatHit, the amiibo's scan count for the amiibo is reset to 0 (0x710064AC8C).
 
<!--T:15-->
Dropped items receive the '''IsAmiibo''' actor parameter.
 
=== Special cases === <!--T:16-->
 
==== Items with the AmiiboArmorItem tag ==== <!--T:17-->
 
<!--T:18-->
If the player hasn't received the complete armor set from an amiibo, armor pieces that they have already received will not be spawned.
 
==== Items with the Important tag ==== <!--T:19-->
 
<!--T:20-->
The IsGet_ flag for Important items must be false; otherwise they will not spawn.
 
==== Items with the AmiiboTreasure tag ==== <!--T:21-->
 
<!--T:22-->
Items with the AmiiboTreasure tag are spawned inside of a treasure chest (TBox_Field_Iron).
 
<!--T:23-->
The chest's "SharpWeaponJudgeType" parameter is set to 2, which causes [[difficulty scaling#Weapon bonuses|different weapon bonuses]] and guarantees the weapon will have at least a blue/white modifier.
 
<!--T:24-->
Exceptions:
* bdrop resource is Actor/DropTable/Item_Amiibo_DropTable_012 (Daruk), drop name starts with "Item_Ore_" and is not Item_Ore_A (Diamond)
* bdrop resource is Actor/DropTable/Item_Amiibo_DropTable_013 (Revali), drop name starts with "Obj_BombArrow"
* bdrop resource is Actor/DropTable/Item_Amiibo_DropTable_015 (Urbosa), drop name starts with "Obj_ElectricArrow"
 
==== Items with a name that starts with GameRomHorse ==== <!--T:25-->
 
<!--T:26-->
If it is the first time you are scanning an amiibo that can drop horse equipment (if IsAmiiboDrop_GameRomHorseItem isn't set), the game will always spawn GameRomHorseSaddle_01 and GameRomHorseReins_01.
 
<!--T:27-->
If you have already received those items, they will not spawn consistently anymore (or not at all{{check}}).
 
==== Items that are marked as amiibo drops ==== <!--T:28-->
 
<!--T:29-->
Items that are marked as amiibo drops -- i.e. actors for which the "Amiibo" key exists in the "drops" dictionary in their [[ActorInfo]] entry -- receive an additional '''DropTable''' actor parameter. It is set to "Amiibo" for normal drop lists and "Amiibo_After" for Parasail/Remain lists.
 
==== Ancient arrows ==== <!--T:30-->
 
<!--T:31-->
Obj_AncientArrow_A_01 and Obj_AncientArrow_C_01 can only spawn if you have already received Ancient Arrows at some point (if IsGet_AncientArrow is set).


== Logic ==
==== Divine Beast helms (Armor_181_Head, Armor_182_Head, Armor_183_Head, Armor_184_Head) ==== <!--T:32-->
[[AIDef:Action/ItemAmiiboCreateFromDropTable]] (the action that is responsible for determining the drop table and spawning the drops) follows the following process:


*Get the number of times the amiibo has been scanned for the current day (using AmiiboTouchHistory): $scanCount
<!--T:33-->
*Get the number of times the amiibo has been scanned (using AmiiboTouchHistoryTotal): $$scanCountTotal
When scanning a Champion amiibo, if you've completed any Divine Beast '''and''' received a Great Hit, '''and''' if you haven't already received the corresponding helm<ref>If the corresponding IsGet flag is false</ref>, the chest is guaranteed to contain the Divine Helm.


*Determine the drop table category to use.
=== Code === <!--T:34-->
**''Remain'' if Find_4Relic_1stClear is set
**''Parasail'' if IsGet_PlayerStole2 is set
**''Normal'' otherwise


*Calculate the "adjust rate"
<!--T:35-->
**When the amiibo has been scanned 0 to $HitRateAdjustStart times, the adjust rate is 0%.
Unless otherwise indicated, all member function names below are unofficial. (Only the class name is official.)
**This value increases linearly and reaches its maximum (100%) when the amiibo scan count is >= $HitRateAdjustEnd.
**In practice, because HitRateAdjustStart and HitRateAdjustEnd are both set to the same value (5), the formula can be simplified: the rate is 100% if $$scanCountTotal >= $HitRateAdjustEnd and 0% otherwise.


*Determine if there should be a Great Hit (RNG)
==== action::ItemAmiiboCreateFromDropTable::getOneDrop ==== <!--T:36-->
**If $scanCount is <2, use GreatHitRate1st as the probability of getting a Great Hit.
**If $scanCount is 2, use GreatHitRate2nd.
**If $scanCount is 3, use GreatHitRate3rd.
**In these three cases, if the great hit rate is >0.0, add <code>adjustRate * (100.0 - greatHitRate)</code> to the great hit rate.
**Otherwise, if $scanCount is >3, the great hit rate is 0%.


*If there was no Great Hit, determine if there should be a Big Hit (RNG)
<!--T:37-->
**If $scanCount <= 3, a Big Hit is guaranteed.
This function is responsible for choosing a drop to be spawned.
**If $scanCount >= 4, a Big Hit will never happen.


*Determine if there should be a Small Hit (RNG)
<!--T:38-->
**If $scanCount is <2, use SmallHitRate1st.
https://gist.github.com/leoetlino/a67a874111c1bd97805239f8678e0d00
**If $scanCount is 2, use SmallHitRate2nd.
**If $scanCount is 3, use SmallHitRate3rd.
**Otherwise, if $scanCount is >3, the great hit rate is 0%.


*Determine the drop num rate
==== action::ItemAmiiboCreateFromDropTable::doSpawn ==== <!--T:39-->
**If $scanCount is <2, use DropNumRate1st.
**If $scanCount is 2, use DropNumRate2nd.
**If $scanCount is 3, use DropNumRate3rd.
**Otherwise, if $scanCount is >3, the drop num rate is 0%.


*For each [[#Drop tables|drop table]] ({Normal,SmallHit,BigHit,GreatHit}{,2}), calculate the actual drop num.
<!--T:40-->
**0 if the table doesn't exist in the [[bdrop]]
This function is responsible for spawning a drop.
**<code>max(1, (dropNumRate * repeatNum) / 100.0)</code> otherwise
**'''Note:''' For BigHit and GreatHit tables, (Remain), (Parasail) or (Normal) are appended to the table name.


*Fix the drop nums based on the RNG results
<!--T:41-->
**Tables that won't be used (for example GreatHit tables if you didn't get any Great Hit) have their drop num forced to 0.{{check}}
https://gist.github.com/leoetlino/ff246cb5c16b12c5af14a899d1cd8ffd
</translate>


== References ==
== References ==
<references/>
<references/>
[[Category:Internals]]
 
[[Category:Game mechanics]]
[[Category:Internals{{#translation:}}]]
[[Category:Game mechanics{{#translation:}}]]

Latest revision as of 12:05, 28 May 2020

Other languages:

Drop tables

Idx Name Description
0 Normal
1 Normal2 Unused.
2 SmallHit
3 SmallHit2 Unused.
4 BigHit
5 BigHit2 Unused.
6 GreatHit
7 GreatHit2 Unused.

amiibo registering

amiibo are registered[1] every time an amiibo is used.

Whenever an amiibo is registered:

  • AmiiboMgr determines if it should reset its daily amiibo use history (stored in the AmiiboTouchHistory flag)[2].
    • If less than 86400 seconds (1 day) have elapsed since the game was launched, don't do anything.[check]
    • AmiiboMgr then computes 10000 * now.year + 100 * now.month + now.day. If the value is different from AmiiboLastTouchDate (which would mean that a day has elapsed), the AmiiboTouchHistory array is cleared.
  • An entry for the scanned amiibo is inserted into AmiiboTouchHistory. Only the last 100 entries are kept.
  • For a first time scan, a new entry is inserted into AmiiboTouchHistoryTotal (only the last 200 entries are kept). Otherwise, the scan count is incremented by updating the existing entry.
  • Finally, AmiiboLastTouchDate is set to the current date.

The format for AmiiboTouchHistory and AmiiboTouchHistoryTotal entries is "%s_%d_%d_%d" (amiibo UID, amiibo value 1, amiibo value 2, scan count) 

Logic

A SmallHit happens 20% of the time.

If the amiibo has been scanned 0, 1, 2, 3 or 4 times, you'll get a GreatHit 20% of the time. If you didn't get a GreatHit, the game will ensure you get a BigHit.

If the amiibo has been scanned 5 times or more, you'll always get a GreatHit. In this case, the BigHit table is ignored.

For BigHits and GreatHits, the game uses the 'Remain' tables if Find_4Relic_1stClear is set, 'Parasail' if IsGet_PlayerStole2, and 'Normal' otherwise.

The game then determines the number of drops from each table[3]:

  • For a GreatHit:
    • GreatHit drops: random number between RepeatNumMin and RepeatNumMax for GreatHit
    • SmallHit drops: same, but for SmallHit (if there is a SmallHit).
    • Normal drops: random number between RepeatNumMin and RepeatNumMax for Normal, minus the GreatHit drop num
  • For a BigHit:
    • BigHit drops: random number between RepeatNumMin and RepeatNumMax for BigHit
    • SmallHit drops: same, but for SmallHit (if there is a SmallHit).
    • Normal drops: random number between RepeatNumMin and RepeatNumMax for the Normal table, minus the BigHit drop num

After a GreatHit, the amiibo's scan count for the amiibo is reset to 0 (0x710064AC8C).

Dropped items receive the IsAmiibo actor parameter.

Special cases

Items with the AmiiboArmorItem tag

If the player hasn't received the complete armor set from an amiibo, armor pieces that they have already received will not be spawned.

Items with the Important tag

The IsGet_ flag for Important items must be false; otherwise they will not spawn.

Items with the AmiiboTreasure tag

Items with the AmiiboTreasure tag are spawned inside of a treasure chest (TBox_Field_Iron).

The chest's "SharpWeaponJudgeType" parameter is set to 2, which causes different weapon bonuses and guarantees the weapon will have at least a blue/white modifier.

Exceptions:

  • bdrop resource is Actor/DropTable/Item_Amiibo_DropTable_012 (Daruk), drop name starts with "Item_Ore_" and is not Item_Ore_A (Diamond)
  • bdrop resource is Actor/DropTable/Item_Amiibo_DropTable_013 (Revali), drop name starts with "Obj_BombArrow"
  • bdrop resource is Actor/DropTable/Item_Amiibo_DropTable_015 (Urbosa), drop name starts with "Obj_ElectricArrow"

Items with a name that starts with GameRomHorse

If it is the first time you are scanning an amiibo that can drop horse equipment (if IsAmiiboDrop_GameRomHorseItem isn't set), the game will always spawn GameRomHorseSaddle_01 and GameRomHorseReins_01.

If you have already received those items, they will not spawn consistently anymore (or not at all[check]).

Items that are marked as amiibo drops

Items that are marked as amiibo drops -- i.e. actors for which the "Amiibo" key exists in the "drops" dictionary in their ActorInfo.product.sbyml entry -- receive an additional DropTable actor parameter. It is set to "Amiibo" for normal drop lists and "Amiibo_After" for Parasail/Remain lists.

Ancient arrows

Obj_AncientArrow_A_01 and Obj_AncientArrow_C_01 can only spawn if you have already received Ancient Arrows at some point (if IsGet_AncientArrow is set).

Divine Beast helms (Armor_181_Head, Armor_182_Head, Armor_183_Head, Armor_184_Head)

When scanning a Champion amiibo, if you've completed any Divine Beast and received a Great Hit, and if you haven't already received the corresponding helm[4], the chest is guaranteed to contain the Divine Helm.

Code

Unless otherwise indicated, all member function names below are unofficial. (Only the class name is official.)

action::ItemAmiiboCreateFromDropTable::getOneDrop

This function is responsible for choosing a drop to be spawned.

https://gist.github.com/leoetlino/a67a874111c1bd97805239f8678e0d00

action::ItemAmiiboCreateFromDropTable::doSpawn

This function is responsible for spawning a drop.

https://gist.github.com/leoetlino/ff246cb5c16b12c5af14a899d1cd8ffd

References

  1. 0x710064B564 on Switch 1.5.0
  2. 0x710064B3C8
  3. AIDef:Action/ItemAmiiboCreateFromDropTable
  4. If the corresponding IsGet flag is false