foul-magics/Mage/src/main/java/mage/abilities/keyword/EchoAbility.java
Alex Vasile a2162ec3e7
Refactor: private fields and performance tweaks (#9625)
1a. Make `costs`, `manaCosts`, and `manaCostsToPay` private in `AbilityImpl` with access through getters/setters 
1b. fix cost adjuster for imprinted cards affected by the above

2a. Lazy instantiation for rarely used `data` field in `TargetPointerImpl`

3a. Pre-allocate certain array sizes in `Modes` and `CostsImpl`

4a. Make `manaTemplate` private in `BasicManaEffect`, copy when passing outside the class 
4b. Don't copy `manaTemplate` in copy constructor since it doesn't change 
4c. Add comments explaining copy usage for `manaTemplate` 
4d. Remove redundant variable assignment and make fields final 

---------

Co-authored-by: xenohedron <xenohedron@users.noreply.github.com>
2023-08-27 17:58:19 -04:00

126 lines
4 KiB
Java

package mage.abilities.keyword;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.keyword.EchoEffect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
/**
* @author Backfir3
*/
public class EchoAbility extends TriggeredAbilityImpl {
protected UUID lastController;
protected boolean echoPaid;
protected Costs<Cost> echoCosts = new CostsImpl<>();
private boolean manaEcho = true;
private DynamicValue amount;
private String rule;
public EchoAbility(String manaString) {
super(Zone.BATTLEFIELD, new EchoEffect(new ManaCostsImpl<>(manaString)), false);
this.echoPaid = false;
this.echoCosts.add(new ManaCostsImpl<>(manaString));
this.lastController = null;
this.rule = null;
}
public EchoAbility(DynamicValue amount, String rule) {
super(Zone.BATTLEFIELD, new EchoEffect(amount), false);
this.amount = amount;
this.echoPaid = false;
this.echoCosts.add(getCosts());
this.lastController = null;
this.manaEcho = true;
this.rule = rule;
}
public EchoAbility(Cost echoCost) {
super(Zone.BATTLEFIELD, new EchoEffect(echoCost), false);
this.echoPaid = false;
this.echoCosts.add(echoCost);
this.manaEcho = false;
this.lastController = null;
this.rule = null;
}
protected EchoAbility(final EchoAbility ability) {
super(ability);
this.echoPaid = ability.echoPaid;
this.echoCosts = ability.echoCosts.copy();
this.manaEcho = ability.manaEcho;
this.lastController = ability.lastController;
this.amount = ability.amount;
this.rule = ability.rule;
}
@Override
public EchoAbility copy() {
return new EchoAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD
|| event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
// reset the echo paid state back, if creature enters the battlefield
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD
&& event.getTargetId().equals(this.getSourceId())) {
this.echoPaid = false;
}
if (event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE) {
if (lastController != null) {
if (!lastController.equals(this.controllerId)) {
this.echoPaid = false;
}
}
// remember the last controller
lastController = this.getControllerId();
// if echo not paid yet, controller has to pay
if (event.getPlayerId().equals(this.controllerId)
&& lastController.equals(this.controllerId)
&& !this.echoPaid) {
this.echoPaid = true;
return true;
}
}
return false;
}
@Override
public String getRule() {
StringBuilder sb = new StringBuilder();
if (rule != null) {
sb.append(rule);
} else {
sb = new StringBuilder("Echo");
if (manaEcho) {
sb.append(' ');
} else {
sb.append("&mdash;");
}
if (echoCosts != null) {
sb.append(echoCosts.getText());
}
if (!manaEcho) {
sb.append('.');
}
}
sb.append(" <i>(At the beginning of your upkeep, if this came under your control since the beginning of your last upkeep, sacrifice it unless you pay its echo cost.)</i>");
return sb.toString();
}
}