Appel
Functions.forecast.calculate(platform, history, window, noheals, nodmg, now)
Enregistrez-la comme dépendance nommée Functions.forecast.calculate (accepter la complétion le fait pour vous), puis appelez-la sous ce nom.
Ce qu'elle fait
Calcule un taux contrôlé d'historique des points de vie à partir d'une fenêtre et d'une horloge finies explicites. Conserve la pondération ordonnée, l'arrondi canonique en direct ligne par ligne, les flux ignorés, les trous de tableau, les clés fractionnaires et les âges finaux visités. Un budget fixe de 4096 unités couvre les lignes visitées et les intervalles d'accumulation des deux flux ; tout dépassement ou calcul consommé invalide renvoie « indisponible », jamais une estimation partielle ni une valeur bornée. Cette nouvelle API a sa propre identité de source ; les fonctions de tendance historiques restent inchangées.
Arguments
| Nom | Type | Ce qu'elle fait |
|---|---|---|
platform | RMPlatform | Autorité de lisibilité pour les valeurs consommées. |
history | table | Tableaux damage/heals de lignes temps/valeur ; seuls les flux sélectionnés sont consommés. |
window | number | Fenêtre de pondération finie explicite ; sans repli sur le profil ni bornage. |
noheals | boolean | true ignore tout accès au flux de soins. |
nodmg | boolean | true ignore tout accès au flux de dégâts. |
now | number | Instantané d'horloge fini explicite ; les valeurs signées et fractionnaires restent valides. |
Retours
| 1 | number | nil | Taux combiné signé fini, ou nil si le calcul est indisponible. |
|---|---|---|
| 2 | number | nil | Âge final fini du flux, ou nil si indisponible. |
| 3 | string | nil | Motif de disponibilité (limite de travail, données ou calcul) pour un taux ou un âge nil. |
Éditions
Les fonctions utilitaires intégrées sont enregistrées sur toutes les éditions. Ce qui diffère, c'est l'API du jeu qu'elles lisent ; quand l'une manque, la fonction utilitaire se rabat sur une alternative ou renvoie nil avec une raison.
Elle ne lit directement aucune API du jeu.
Valeurs secrètes (Retail et Forever)
Sur Retail et Forever, le jeu transmet aux addons des valeurs secrètes. Cette fonction utilitaire vérifie ce qu'elle lit (addon.Platform:CanReadValue) et renvoie nil avec une raison telle que restricted-value au lieu d'une valeur secrète qu'elle ne peut pas comparer. Traitez nil comme indisponible, pas comme false.
Exemple
local guid = UnitGUID("player")
local history = guid and addon.damageHistory[guid]
if not history then return nil, "no-history" end
local rate, age, reason = Functions.forecast.calculate(addon.Platform, history, 5, false, false, GetTime())
if rate == nil then return nil, reason end
return age >= 2 and rate < 0Dépendances
finite→Functions.forecast.finitereadField→Functions.forecast.readField
Source
Functions/forecast.lua, ligne 61. En lecture seule dans le jeu ; Dupliquer crée une copie modifiable.
Functions.forecast.calculate(platform, history, window, noheals, nodmg, now)
if type(platform)~='table' or type(platform.CanReadValue)~='function' then return nil,nil,'invalid-forecast-platform' end
if not platform:CanReadValue(history) or not platform:CanReadValue(noheals) or not platform:CanReadValue(nodmg) then return nil,nil,'restricted-value' end
if type(history)~='table' then return nil,nil,'invalid-forecast-history' end
if type(noheals)~='boolean' or type(nodmg)~='boolean' then return nil,nil,'invalid-forecast-mode' end
local valid,reason=finite(platform,window)
if not valid then return nil,nil,reason end
valid,reason=finite(platform,now)
if not valid then return nil,nil,reason end
local work=0
local function scan(name,skip)
if skip then return 0,0,0 end
local rows,why=readField(platform,history,name)
if why then return nil,nil,nil,why end
if type(rows)~='table' then return nil,nil,nil,'invalid-forecast-stream' end
local maxoffs,data=0,{}
for _,row in ipairs(rows) do
work=work+1
if work>4096 then return nil,nil,nil,'forecast-work-budget' end
local time,problem=readField(platform,row,'time')
if problem then return nil,nil,nil,problem end
local good,numberReason=finite(platform,time)
if not good then return nil,nil,nil,numberReason end
local diff=now-time
good,numberReason=finite(platform,diff)
if not good then return nil,nil,nil,numberReason end
local scale=window-diff
local functions,namespaceReason=readField(platform,addon,'Functions')
if namespaceReason then return nil,nil,nil,namespaceReason end
if type(functions)~='table' then return nil,nil,nil,'forecast-round-unavailable' end
local values
values,namespaceReason=readField(platform,functions,'values')
if namespaceReason then return nil,nil,nil,namespaceReason end
if type(values)~='table' then return nil,nil,nil,'forecast-round-unavailable' end
local round
round,namespaceReason=readField(platform,values,'round')
if namespaceReason then return nil,nil,nil,namespaceReason end
if type(round)~='function' then return nil,nil,nil,'forecast-round-unavailable' end
local ok,rounded=pcall(round,diff)
if not ok then return nil,nil,nil,'forecast-round-error' end
good,numberReason=finite(platform,rounded)
if not good then return nil,nil,nil,numberReason end
maxoffs=rounded
if maxoffs>window then break end
local amount,amountReason=readField(platform,row,'value')
if amountReason then return nil,nil,nil,amountReason end
if amount~=nil and amount~=false then
good,numberReason=finite(platform,amount)
if not good then return nil,nil,nil,numberReason end
good,numberReason=finite(platform,scale)
if not good then return nil,nil,nil,numberReason end
local product=amount*scale
good,numberReason=finite(platform,product)
if not good then return nil,nil,nil,numberReason end
local value=(data[maxoffs] or 0)+product
good,numberReason=finite(platform,value)
if not good then return nil,nil,nil,numberReason end
data[maxoffs]=value
end
end
local bins=maxoffs<0 and 0 or math.floor(maxoffs)+1
if bins>4096-work then return nil,nil,nil,'forecast-work-budget' end
work=work+bins
local total,count=0,0
for i=0,maxoffs do
total=total+(data[i] or 0)
local good,numberReason=finite(platform,total)
if not good then return nil,nil,nil,numberReason end
local scale=window-i
good,numberReason=finite(platform,scale)
if not good then return nil,nil,nil,numberReason end
count=count+scale
good,numberReason=finite(platform,count)
if not good then return nil,nil,nil,numberReason end
end
return total,count,maxoffs
end
local damageTotal,damageCount,damageSeconds,damageReason=scan('damage',nodmg)
if damageReason then return nil,nil,damageReason end
local healTotal,healCount,healSeconds,healReason=scan('heals',noheals)
if healReason then return nil,nil,healReason end
local damageRate=damageCount>0 and -damageTotal/damageCount or 0
valid,reason=finite(platform,damageRate)
if not valid then return nil,nil,reason end
local healRate=healCount>0 and healTotal/healCount or 0
valid,reason=finite(platform,healRate)
if not valid then return nil,nil,reason end
local rate=damageRate+healRate
valid,reason=finite(platform,rate)
if not valid then return nil,nil,reason end
return rate,damageSeconds>healSeconds and damageSeconds or healSeconds