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

Unbound Flourishing's X doubling should be a triggered ability (and related refactors) #12597

Merged
merged 16 commits into from
Aug 22, 2024

Conversation

ssk97
Copy link
Contributor

@ssk97 ssk97 commented Jul 23, 2024

Note the "Whenever" in the rules text, it's a triggered ability and not a replacement effect.

Since Unbound Flourishing was the only card to use the X_MANA_ANNOUNCE event and all the associated multiplier code, that should probably all also be removed as well? Leaving this as a draft while I figure out what should be removed there.

edit: now also include a rework of "copy that ability" effects to use the stack/LKI instead of a saved object

Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.isPermanent(game)) {
if (spell.getSpellAbility().getManaCostsToPay().containsX()) {
game.getState().setValue(this.getSourceId() + UnboundFlourishing.needPrefix, spell);
Copy link
Member

Choose a reason for hiding this comment

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

Make sure it support multiple triggers/spells. Current code save only one spell per Unbound Flourishing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I copied it from the copy spell/ability trigger, both of them need to be fixed in that manner.

Copy link
Member

Choose a reason for hiding this comment

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

Also don't forget about flourishing ZCC in setValue. So blinked Unbound Flourishing will ignore outdated spell data.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A better solution is to not use the global game state, and instead use target pointers or the effect value map.

@ssk97 ssk97 changed the title Unbound Flourishing's X doubling should be a triggered ability Unbound Flourishing's X doubling should be a triggered ability (and related refactors) Jul 27, 2024
@ssk97
Copy link
Contributor Author

ssk97 commented Jul 27, 2024

Haven't done as much testing with the changes as I'd like so probably best not to merge quite yet, but I think this is all good now.

@ssk97 ssk97 marked this pull request as ready for review July 27, 2024 07:24
@@ -82,6 +83,7 @@ public boolean counter(UUID objectId, Ability source, Game game, PutCards putCar
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, source, stackObject.getControllerId()))) {
if (!(stackObject instanceof Spell)) { // spells are removed from stack by the card movement
this.remove(stackObject, game);
game.rememberLKI(Zone.STACK, stackObject);
Copy link
Contributor

Choose a reason for hiding this comment

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

interesting

Copy link
Contributor Author

@ssk97 ssk97 Aug 13, 2024

Choose a reason for hiding this comment

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

This is required by the test I added - previously it was storing the entire object inside the effect which made it ok to not store it in LKI, but now that I changed it to use a FixedTarget I needed the LKI there.

if (ability.checkEventType(event, game) && ability.checkTrigger(event, game)) {
toRet = true;
}
ability.getEffects().clear(); //Remove afterwards, ensures that they remain synced even with copying
Copy link
Contributor

Choose a reason for hiding this comment

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

Though this feels a bit weird, I think I see what this is trying to do and why it can't be done otherwise

Copy link
Member

@JayDi85 JayDi85 Aug 22, 2024

Choose a reason for hiding this comment

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

That’s code with effects copy must be removed 100%. Conditional abilities from “or” parts must have all real effects. If something put effects in “or” ability (e.g. abilities container) then that’s wrong logic/design.

Copy link
Contributor Author

@ssk97 ssk97 Aug 22, 2024

Choose a reason for hiding this comment

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

Any triggered ability that has SetTargetPointer needs this code to function correctly, as otherwise that inner ability has no access to the effects it's trying to set the target pointers of.

edit: It's also important to note that this isn't copying the effects, it's sharing the effects that are currently inside the OrTriggeredAbility.

Copy link
Member

Choose a reason for hiding this comment

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

It’s weird. Whole OrTriggeredAbility is big workaround with potentially buggy code (example: if something clear/reset data inside triggered ability or init something then it will be broken with that “container”). Must be reworked/removed someday to simple ability with multiple conditionals.

So new part for temporary add/remove is “fine” here — it’s a fix for existing logic.

IMG_0705

Copy link
Contributor

Choose a reason for hiding this comment

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

Only 53 usages of OrTriggeredAbility. How many of them need target pointers set in order to function? Seems like the sort of thing that could be excluded from scope, with those few usages getting cleaner custom implementations

@ssk97 ssk97 merged commit b70638a into magefree:master Aug 22, 2024
4 checks passed
Copy link
Member

@JayDi85 JayDi85 left a comment

Choose a reason for hiding this comment

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

@ssk97 must be improved, also contains suspected code (see comments).

if (ability.checkEventType(event, game) && ability.checkTrigger(event, game)) {
toRet = true;
}
ability.getEffects().clear(); //Remove afterwards, ensures that they remain synced even with copying
Copy link
Member

@JayDi85 JayDi85 Aug 22, 2024

Choose a reason for hiding this comment

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

That’s code with effects copy must be removed 100%. Conditional abilities from “or” parts must have all real effects. If something put effects in “or” ability (e.g. abilities container) then that’s wrong logic/design.

if (!(input instanceof Ability)) {
return false;
}
return !((Ability) input).isManaAbility();
Copy link
Member

Choose a reason for hiding this comment

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

Looks strange. Mana abilities never goes to stack due mtg rules. So it’s useless to search stack objects for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh, that's a good point. If I understand correctly, that means that FilterActivatedOrTriggeredAbility just automatically includes the "not a mana ability" clause by its very design?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, before this it was only being used for targeting

@ssk97
Copy link
Contributor Author

ssk97 commented Aug 22, 2024

Github's not letting me reply to #12597 (comment), but the purpose of that is that the abilities have code inside of them where the effects' TargetPointer gets set based on what triggered the ability. edit:figured it out

Conditional abilities from “or” parts must have all real effects

The abilities normally will not have any effects, the OrTriggeredAbility has them. However, shortly above that removal, I temporarily add those effects to the ability so that they can set any target pointers necessary.

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

Successfully merging this pull request may close these issues.

3 participants