호출 방법
Functions.forecast.calculate(platform, history, window, noheals, nodmg, now)
Functions.forecast.calculate(이)라는 이름의 의존성으로 기록한 뒤(자동 완성을 수락하면 이렇게 됩니다) 그 이름으로 호출하세요.
하는 일
명시적인 유한 구간과 시각으로 검증된 생명력 기록 변화율을 계산합니다. 순서 있는 가중치, 행별 실시간 표준 반올림, 건너뛴 스트림, 배열 빈칸, 소수 키, 마지막으로 방문한 경과 시간을 보존합니다. 고정된 4096단위 예산이 두 스트림의 방문 행과 누적 구간을 모두 포함하며, 초과하거나 잘못된 계산은 부분 추정이나 제한값이 아니라 사용할 수 없음을 반환합니다. 이 새 API는 자체 원본 식별자를 가지며, 기존 추세 함수는 바뀌지 않습니다.
인수
| 이름 | 유형 | 하는 일 |
|---|---|---|
platform | RMPlatform | 사용하는 값의 읽기 가능 여부 판정 기준. |
history | table | 시간/값 행으로 된 피해/치유 배열. 선택한 스트림만 사용합니다. |
window | number | 명시적인 유한 가중치 구간. 프로필 대체값이나 제한이 없습니다. |
noheals | boolean | true면 치유 스트림에 전혀 접근하지 않습니다. |
nodmg | boolean | true면 피해 스트림에 전혀 접근하지 않습니다. |
now | number | 명시적인 유한 시각 스냅샷. 부호 있는 값과 소수도 유효합니다. |
반환값
| 1 | number | nil | 유한한 부호 있는 합계 변화율. 계산을 사용할 수 없으면 nil. |
|---|---|---|
| 2 | number | nil | 유한한 최종 스트림 경과 시간. 사용할 수 없으면 nil. |
| 3 | string | nil | nil인 변화율/경과 시간에 대한 작업 한도, 데이터 또는 산술 사용 불가 이유. |
버전
기본 제공 도우미는 모든 버전에 등록됩니다. 다른 점은 읽는 게임 API이며, API가 없으면 도우미는 대체 동작을 하거나 이유와 함께 nil을 반환합니다.
게임 API를 직접 읽지 않습니다.
비공개 값 (Retail과 Forever)
Retail과 Forever에서는 게임이 애드온에 비공개 값을 넘깁니다. 이 도우미는 읽는 값을 확인하고(addon.Platform:CanReadValue), 비교할 수 없는 비공개 값 대신 restricted-value 같은 이유와 함께 nil을 반환합니다. nil은 거짓이 아니라 사용할 수 없음으로 취급하세요.
예시
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 < 0의존성
finite→Functions.forecast.finitereadField→Functions.forecast.readField
소스
Functions/forecast.lua, 61번째 줄. 게임에서는 읽기 전용이며, 복제하면 편집 가능한 사본이 생깁니다.
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