-
Notifications
You must be signed in to change notification settings - Fork 232
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
item.roll() does not preserve the item in most cases, causing counter-intuitive results and errors #1049
Comments
Originally in GitLab by @akrigline Thank you for this super detailed issue regarding a potential change in how the system works! Some more things to think about:
Spitballing: |
Originally in GitLab by @caewok mentioned in issue tposney/midi-qol#307 |
Originally in GitLab by @caewok I would have thought that each item with a unique id is stored separately in the database. So the chat data actually just links to the underlying unique item and so resources used would be minimal. Maybe someone with more experience with the data storage part of Foundry can weigh in. The impact may change if one were to repeatedly create unique temporary items, in which case I see several possibilities:
In any event, a good short-term fix for at least part of this issue would be to accept a flag on the item that marks it as temporary and required to save in the chat. Presumably, most items would not enable the flag so impact on chat data should remain minimal. |
Originally in GitLab by @akrigline
Either way, doesn't this plan create an extra copy of the Item in the database? I'm not sure if there's much in the way of "timing out" data, but that's definitely a solution. It would lead to other potentially unexpected issues ("Any button I click in my chat history errors out!" vs "Any button whose item is missing..."). It would be interesting to profile some iterations of this and compare the impact. If you intend all chat buttons to snapshot their item's values for things like attack rolls and damage rolls that'll obviously have a higher impact than if you limit it only to chat cards which are allowed to pop out (as an arbitrary rule of thumb). |
Originally in GitLab by @caewok Right, so assume for the moment that you run some tests and there is enough of a resource impact to warrant something more complicated than just storing every item in its respective chat message. In the short term, I think it is still worth adding a flag to the item indicating that the item is "temporary" and therefore must be attached to the chat message data. This is just an extension of the current practice of storing item data if the item is going to be consumed. Because the flag has to be enabled for the item to be stored in that manner, the resource impact is likely comparable to that of consumed items. This would make it much easier for macros/modules to manipulate certain item data in a one-off manner. For example, sorcerer metamagic, magic weapons that allow for occasional additional damage, or class features that give occasional modifications to attack/damage/weapon characteristics. In the long term, consider approaching the item storage problem with something like this: Create a Within the This type of |
Originally in GitLab by @caewok mentioned in issue tposney/midi-qol#342 |
Originally in GitLab by @caewok
Setup
Foundry 0.7.9, dnd5e 1.2.4, no modules enabled
Server: Docker on a Vultr 1 gig cloud server. https://github.com/felddy/foundryvtt-docker (shouldn't matter for this issue)
Browser: Firefox 86.0.1 on Mac OS X 10.15.7 (also shouldn't matter for this issue)
Issue
When rolling an item such as a weapon or a spell, the resulting chat card usually links back to the item in the actor, instead of storing a copy of the item. (The exceptions I can see are (1) if the item is consumed on roll; and (2) if spell level is increased, spell slot level increases are preserved but not the rest of the item rolled.)
This causes at least three problems:
If the item is rolled, but then subsequently changed in the actor, clicking on the attack/damage for the item pulls the changed item data and not the original. Reasonable minds can differ on this, but I view this as a counterintuitive and unwanted result. In my view, once an actor uses an item and the card shows up in chat, the expectation is that the use is frozen in time based on the item at that time. If I wanted to modify the weapon or spell after the initial roll, I would expect to have to re-roll with the new item. Accessing the previous roll in the chat should take me back to the item as it was when it was rolled and displayed into chat. (Compare to dragging the item to the macro bar, where I would expect the macro to access the current version of the item, acting like a shortcut for rolling the item.)
If the item is rolled and then subsequently deleted in the actor, the chat buttons for that roll no longer work and throw an error, because the actor's item is not found. This is a more extreme version of (1).
Modifying a weapon or spell in a macro and then rolling using that temporary item does not work, because the resulting chat message buttons will instead look up the original version of the item. This is particularly problematic for certain use cases, such as using a macro to allow the user to temporarily change the damage type or other aspects of a spell. (See sorcerer metamagic for some examples of why one might want to do this.)
Details
displayCard
in entity.js only embeds the item rolled if it is consumable and the actor no longer owns the item:While this is a correct check, it is not the only situation in which one might want to embed the item. Following that, clicking attack, damage, or create template buttons in the resulting chat message for the rolled item results in a call to
_onChatCardAction
in entity.js._onChatCardAction
looks up the stored data flag, and if the item is not stored, pulls the current version of the item from the actor using the item id. Spell level is handled as a unique case:Proposed Solution
The easy fix for Issue (3) would be to add a way for
item.roll()
to pass through a storeData flag that causes displayCard to store the data. Basically, we just need another check along with the consumable item check that causesdisplayCard
to set the "dnd5e.itemData" flag. This could be done using a flag in the item itself, such as a temporary flag that tells the subsequent functions to store it and not rely on the actor version of the item.A relatively easy fix for Issue (2) would be to always store the item data in chat and in
_onChatCardAction
, first check if the item still exists in the actor and fall back on the stored data if the item is no longer found. This would obviate the need for a consumable item check indisplayCard
.I believe that to fix Issue (1) would require always storing the item data and never pulling it from the actor after the chat message has been created. This would be a user-facing change from past practice, so if you agree that it is the correct result, it should probably be done on a major version change with some notice of the change.
Presumably, storing item data in chat is not resource-intensive because the item data will typically be linked to a single item and the chat can be deleted or archived as necessary.
Replication
For weapons, simply roll a weapon so that attack and damage buttons appear in the chat. For Issue (1), after the roll, change the weapon damage and then click the damage button to see that it the damage is now changed. For Issue (2), after the roll, delete the weapon from the actor and then click attack or damage buttons in the chat.
For spells and Issue 3, the following macro might help show one use case. To use, select a token that has Burning Hands. Note that I have tried two ways to create the upgraded temporary Burning Hands spell, but both ways fail to work properly with the resulting chat buttons.
The text was updated successfully, but these errors were encountered: