Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add warband currency support #5229

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Boneshockx
Copy link
Contributor

@Boneshockx Boneshockx commented Jul 16, 2024

Description

TWW brings warband currencies that can be transferred over to other characters within your warband.
The C_CurrencyInfo API contains currencyData for all warband characters, and so we're able to create a cloning trigger that shows currency info for each character in the warband.

This is a full rework of the currency trigger prototype as this needs to use statesParameter = "full".

Several state values for account wide currencies have been added:

  • accountQuantity (sum of all account characters' quantity)
  • realAccountQuantity (total account quantity after transferring everything to your current character and paying the transfer cost)
  • realCharacterQuantity (remaining quantity if all this character's currency was transfered and paid the transfer cost)
  • transferPercentage (transfer cost %)
  • unitName (comes from currency API)
  • unitGUID (comes from currency API)
  • mainCharacter (bool value to check for the character you are currently playing on)

Example

image

!WA:2!vI1(ZTXv1FRikDy7dSLBstAsBvCE0MKwxhx7usN4o41psCX12zLSDzOG2v7EL2BYQDV9URSJDBhAfbW88lJPq4nfXB(2cfbL3qbZJodZKzoJg(damu6WRbM8paCU3DLLT1QqW)G0Q7EUN3NpNZXjMlLF)JswivPuwPSw5(vlY9wuD0PNFQ1Z7XTiCvdZZBX9ySovDOlVSb3kDwppNakJFHPluWNeCM3CLx7F)0D0rh8LACWt(YYdQuKtTYUeJ0J2Ovlu2Xzek30HOR5Zmmjxh3WmG656Fcn)adEGs(cuxQVTIk(vGsLaoTyrc3)2omp6X3tvls(Yfkiyj)mJn5mJp7KQb4p0mkZn6VIpJ44mHLVY6(LZtwG4gKbPMEHA5gz4mzZLj7WAzvlJmppZXyjcxZ1OeXxrtsA(ZqmCcS34QZWj4v1YmZyto5QLDJubLAMEoLl5MrybjZZnSOL9V4nUQHlTKHWAobCJJVgXWNKjGtClgyF9q3QUEUK6wOokOiNqJ5(etpxl)kcsf2dCq1sgu3XHdGxaoiCi4WWDHFFtB)endhArx1jhB8S1kWrdafKrGrso6efAyIQOfOrkk8Sk5994bt7YnTnClsSuD8mSgpFGHdAG7sRuzmoQOIUnZDb9ROz6y47lEs1NUmr8qvZY(bELYGCH9Qfk7kdy3TX9Ko)rusJ)rlK2OxUuy9IYpG0l1k9qdLUNrkZrZ3CPSe)G0dBA6HEW0Zz4uM43tA5v94PZ))8vL3mWM4kFq8hNeuM7MUGHJprEiX1sztVyBQ3cc(K(udTDzlpxbVB98rj8J454XF4KjtotY(6DWv9jofMXJI5bzNEgHZNhgYj21clucPprIej18nrhCYQMOtMWL5)tQLpKk7QHFpMvrcRRmpEzdoj94yPr65TPbKv9diSHDl6qUZicZGrIRtZHwIgCdRAWnNuMuDXDv3OCGThFAwqyGgZMkqlQun0QecDnRLW8BQjwrxMTo(E0sDdghl68451gE0jMntLY(KjfS2ETqPfwa)gWCmMTrYQbEMlGPQid3DIx4f7HAX6CEdEEdxR0nIsvq8IWIHvfv7ZtTcSVHRy4AIk34I0tHQKpZiAJn2uxHkCiUgoZfY0l1FzQvnsXjM5CNK)wkmXSrUYjCrLiPQi3nFycyTqgkda5hzSPYoMwvr9dn06RrDl4Xdlavqnkq(uIuMhDLJuLIeMXRm3KSVoQzyDoKHeRhX4c7O5pOU7aU(eWBdES6Mi4ML3IUzwKYi6R14NI4LnCdy1TcCtkWnRaVXB(WqNRCywxOpmxrIlHtnZy7T40U6SUfNzeM6E2YOxNgSKnRBoIWm8wpnfMzjqTMc9ujUI4ALmUqZRKsYirvSeE6r8Si6WUGBLDlBISCEiEIbgvt9qWER0iWSQ4Qi0G551RkE00bbH81LhlZ2TxVjZLmMDhcfCeBdbWmH3c77zOHGDd7HLoYYAiPwj8HgILwWCejYxOcbrwTOOXVGOwXpqNT3n5L2oV0z3ABEt)3FF9PjnG(pEF9X292CZBrB7csb3McIEUB2TkewmbaB42H7O2M8M93pY1DgRNqDGbp(Bs61mJuQjS0xxQlnf7PgQ(wYgw3x(1irjs1L(LgHCDyNkIIWCIUs6vBY2r5S90qJBrpSz7lglPzAWPUY2CkANOVh4K9b3PcRlrp3fizd7Mjc7pFhWSx6kNNG4oIgbbAIAhBOhrJST3m6U)V3EcBr7BeiA1H1l37dVlO76ywGauvGd5ATY9XsfqUqqoFBd0F8OHiojy7rEO8JWs5C(rpahC1nEx9d9ehVxHV60ZoXOpf7(A5sTl1SbRy90YvAYWOtulwwG0TjTSj2olDl3)X3UmUs4BPxGech(mXCPJ3llxaTej63jyhSfsIiWHu0WezUJNh3MT)RM6BkutyGQsaqswKi1PMEQXQkj3Sr)SKBja8wJca1LNTiI)op3Gvz(OhwtE8cuFAECWn2UJrlJKA9OtXHUWww7NDK2zqrTLYfyZjyTHJ1sSd3E)Zwn)9edtJC7pBSCzdFJr(8CYcurA56HMFJg6QdpB2PzDlpeBQ6jAJykdCQdJ)m0diAuqlSe8yXebyBI5c47Uy3v7YlBnF82VQSZMDG27AyCIjv0hnzm(fZneb0nhRafVlgHfcETH2CvDHcmNs5eZmR5IJiZz7nwDl8rnHkAfB5wK6xYZkNaMqF1nYCyDooNUCA0lzjMPnD2SX6FAQiWlfLmhoFquY8ozhR9InM0V93Uu1ME46Hcyd4Qo3KuLzr1MEwCOKCAtC6ZKLDhTJHnQ2p61wQAy2u62XTn8G13I5NOzPOCtjuZMCIPgBLbH1sa)FycXhHT)dH(J03Tann2omp1rGvrc)OWZcFmjUh8XXFEPNb(ejypym6E8doKNwmNB5s5j8ikzDRIuE(zztAWlsMs(kF4tbdaFA4ZaFwj6e85saFE45GVGESzJcj1sve8HtaFX9dFPLGFd8kX0vODky4RxvLwmuxGpPn8LTHxob8vql)xPd)C4xaFn4RdFd4)h(zjHVjkQFDc4f6cEXKTb0QfBg(TS7jgkdIgfAgcxSNGrXMvHW3bReV29YwyoAjdNnLSc)y4LWEY1GFi8JGFGo8tWE8)0LGVlE6Zdpg89GldFBumFlB4RAd)YUGQWa)56fD8wCCo5Xll6BoZRRVE7FWqKdXlwdNf50orncTRiosKAvpF5Gap3PrWaCH6QIJd3pzN1ep3iFC1InUQmcVM4NJgTnCsjLnQRKArwBQ55Xzv9tkVyg52uQIhTLhmjfFzxsPPgUuvEBcTODWzH(MtoFReEYgoUyfwya5N3V8ZbfFY6ePz4Oz)LRcydzGSB)yQRnCgvX2dWFshEhkW4kWjXga3sJDcenyhL6BGDgTSH5Qn4PN8bgP)hD5PMFe1L98kLaE9jGPBS50TVL9A3imMEe5C5WXsctLuBrrBNZkh7VXaJ4mAAIAC40kCQRyDmITwZM5rBOl0L(vuuG3UsLg6N96mUxreLZpC9NJUVo2Xkdd67RduXQzr9f)xqexKrBSvNCn7hmnIoSTgwkdxqOSnYAtBItWlPlMbrdXvAnb)Po0Hos0AwS0Bs8TbJ8(IHKyLxJcNlhTF2nlwrJ1t7LWg4MWhWwesHpOTQaTeRw6Bo4p0(eNtgRkftPCmOa13YaVjH)Oi7suFdVQDywcMaGb5QnhC8I3ioYCGdMUdVcKFh13YeByu0uN1zZW)Sml0MG9U(whIbrUcxv9aaAWfSHf7FW(6dStauB4CYTjHZl2CeCGs6aM0Jt)Z0HNbQi2DkqhkdlalBlxMAf49j2Mcwk1PGlQdftnOyJqWxhEAKfVtD4jGNexPrStf8U0H39OC49IVqSriU9b8(F(oyhlwFyBMp6YSd3(W4wgne(xI07O1we7JGRLSP1w22j3ulNCV3gUQc8HGF)zH1TR0ym29WoX1K6gt8g(R6W)0M9GxZzXX154yT36BDog4Vh2a1yhW)yhiAf7aT)2BQzbcUn7LQ0yYF454nM19OWF5ScKR9Ev(pYHWElEUjk5FeT5OdmGafdrsHxlbR3R1sLnkE)B2S9gRchrX3V22xgdb7e4Yw2Pw439O)Nd

@Boneshockx Boneshockx force-pushed the feature/currency branch 3 times, most recently from ee62f78 to 995a03c Compare July 29, 2024 22:51
@Boneshockx Boneshockx marked this pull request as ready for review July 29, 2024 23:09
WeakAuras/Prototypes.lua Outdated Show resolved Hide resolved
Comment on lines +11227 to +11228
"ACCOUNT_CHARACTER_CURRENCY_DATA_RECEIVED",
"CURRENCY_TRANSFER_LOG_UPDATE",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was expecting this to error on cataclysm, but it didn't

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-retail flavors don't have currencyInfo.isAccountTransferable which is what is gatekeeping any retail code from running on cata.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do call RegisterEvent() on all of these evenrs, but the RegisterEvents is in a xpcall:

xpcall(frame.RegisterEvent, trueFunction, frame, event)

WeakAuras/Prototypes.lua Outdated Show resolved Hide resolved
@Boneshockx
Copy link
Contributor Author

  • Added sharedStateValues which are applied to main state and clone states.
  • Removed the CopyTable from main state to clones as per result of the above
  • unitName and unitGUID renamed to characterName and characterGUID which is what the WoW API calls them too.
  • hide existing clones if primary checks fail (bugfix)

Comment on lines +11227 to +11228
"ACCOUNT_CHARACTER_CURRENCY_DATA_RECEIVED",
"CURRENCY_TRANSFER_LOG_UPDATE",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do call RegisterEvent() on all of these evenrs, but the RegisterEvents is in a xpcall:

xpcall(frame.RegisterEvent, trueFunction, frame, event)

return Private.AccountCurrencyData[currencyId]
end

Private.AccountCurrencyData[currencyId] = C_CurrencyInfo.FetchCurrencyDataFromAccountCharacters(currencyId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you need this caching? Did you measure whether C_CurrencyInfo.FetchCurrencyDataFromAccountCharacter is actually expensive.

Also note that the way you implemented caching is currently faulty, because:

  • Multiple triggers for the same currency, will receive the same CURRENCY_TRANSFER_LOG_UPDATE event and thus refresh. (That's probably not a problem.)
  • Relying on the trigger receiving the event does not work with auras loading/unloading, that is:
    ** Assume an aura only loaded in say the capital city
    ** The aura is initially loaded, the AccountCurrencyData is updated
    ** The user leaves that zone, the aura unloads
    ** The user transfers currency, resulting in CURRENCY_TRANSFER_LOG_UPDATE, but no aura is loaded so no cache update happens
    ** The user reenters the capital city, the trigger receives WA_DELAYED_PLAYER_ENTERING_WORLD, WA_DELAYED_PLAYER_ENTERING_WORLD doesn't get the cache updated, so old stale data is used.

(I didn't test that scenario, but I think that's how it works, or rather doesn't.)

Imho check first whether we need the caching, I suspect we don't.

end
end
else
C_CurrencyInfo.RequestCurrencyDataForAccountCharacters()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes each trigger call C_CurrencyInfo.RequestCurrencyDataForAccountCharacters(). I think you should move the handling of the api to an outside system in GenericTrigger.lua, which handles that for every trigger.

quantityEarnedThisWeek = %q,
totalEarned = %q
}
local discovered = %q
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using %q for these seems wrong, %s should be the better choice, %q should only be used for strings.

state.show = active
state.value = currencyInfo.quantity
state.realCharacterQuantity = currencyInfo.realCharacterQuantity
state.capped = currencyInfo.maxQuantity and currencyInfo.maxQuantity > 0 and currencyInfo.quantity >= currencyInfo.maxQuantity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These capped calculation is duplicated above in the checkTriState calls, the code above would be much easier to read if you calculated it just once.


ret = ret .. [=[
-- Gather currency data for account characters
if currencyInfo and currencyInfo.isAccountTransferable then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this whole code probably should check for "clone" somewhere

trigger.use_maxQuantity and trigger.maxQuantity_operator or "<",
trigger.use_quantityEarnedThisWeek and trigger.quantityEarnedThisWeek_operator or "<",
trigger.use_totalEarned and trigger.totalEarned_operator or "<",
trigger.use_discovered ~= nil and (trigger.use_discovered and "true" or "false") or "nil",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using something like "trigger.use_discovered and "true" or "false" " is fine, if the check is not set at all, we can treat it as "false".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually you are right here, this is a tristate value, which is the stupid kind of unreadable code we sometimes create.

state.mainCharacter = true

if clone then
for i, currencyData in ipairs(accountCurrencyData) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transfering everything from a character doesn't correctly update the trigger, the clone for the character who know has 0 is still displayed.

I think this because this loop here runs over accountCurrencyData which no longer contains any data for that character, so the existing state is kept unmodified even though it should have been dropped.

local primaryCheckFailed = false

-- Check quantity-related values
for attribute, triggerValue in pairs(triggerQuantities) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be rewritten so that checking the triggerValue happens at function creation time, not every time the trigger runs.

So the looping should be outside of the string, and the string should only include a check if the triggerValue is not nil. This makes the resulting function much smaller in the usual case that there's no or one check.

checkTristate(discovered, currencyInfo.discovered, true, true)
checkTristate(capped, currencyInfo.quantity >= (currencyInfo.maxQuantity or 0), currencyInfo.maxQuantity and currencyInfo.maxQuantity > 0, false)
checkTristate(seasonCapped, currencyInfo.totalEarned >= (currencyInfo.maxQuantity or 0), currencyInfo.useTotalEarnedForMaxQty and currencyInfo.maxQuantity and currencyInfo.maxQuantity > 0, true)
checkTristate(weeklyCapped, currencyInfo.quantityEarnedThisWeek >= (currencyInfo.maxWeeklyQuantity or 0), currencyInfo.maxWeeklyQuantity and currencyInfo.maxWeeklyQuantity > 0, true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, the checking whether to include the check for discovered/capped/seasonCapped/weeklyCapped should probably be done at function creation time.

@Boneshockx Boneshockx marked this pull request as draft August 26, 2024 17:46
@Boneshockx
Copy link
Contributor Author

I still plan on updating this with the feedback from code review, but I'm just enjoying playing the game a bit too much right now :D

@InfusOnWoW
Copy link
Contributor

That's not a problem. I can also take a look at some of the changes I suggested, but similarly not now..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants