mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
* Reworked calculation of available mana that can be a source of heavy server load.
This commit is contained in:
parent
8a6a615250
commit
e0b17eacc7
3 changed files with 129 additions and 14 deletions
|
@ -170,6 +170,10 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
public int count() {
|
||||
return red + green + blue + white + black + colorless + any;
|
||||
}
|
||||
|
||||
public int countColored() {
|
||||
return red + green + blue + white + black + any;
|
||||
}
|
||||
|
||||
public int count(FilterMana filter) {
|
||||
if (filter == null) {
|
||||
|
@ -506,4 +510,74 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
|||
return flag;
|
||||
}
|
||||
|
||||
public void setToMana(Mana mana) {
|
||||
this.any = mana.any;
|
||||
this.red = mana.red;
|
||||
this.green = mana.green;
|
||||
this.white = mana.white;
|
||||
this.blue = mana.blue;
|
||||
this.black = mana.black;
|
||||
this.colorless = mana.colorless;
|
||||
}
|
||||
|
||||
public boolean equalManaValue(Mana mana) {
|
||||
return this.any == mana.any &&
|
||||
this.red == mana.red &&
|
||||
this.green == mana.green &&
|
||||
this.white == mana.white &&
|
||||
this.blue == mana.blue &&
|
||||
this.black == mana.black &&
|
||||
this.colorless == mana.colorless;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't takes any mana into account to be usable in calculating available mana
|
||||
* @param mana
|
||||
* @return
|
||||
*/
|
||||
public boolean includesMana(Mana mana) {
|
||||
return this.green >= mana.green &&
|
||||
this.blue >= mana.blue &&
|
||||
this.white >= mana.white &&
|
||||
this.black >= mana.black &&
|
||||
this.red >= mana.red &&
|
||||
(
|
||||
this.colorless >= mana.colorless ||
|
||||
this.countColored() >= mana.countColored() + mana.colorless
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mana that is more colored but does not contain
|
||||
* one less mana in any color but colorless
|
||||
* if you call with {1}{W}{R} and {G}{W}{R} you get back {G}{W}{R}
|
||||
* if you call with {G}{W}{R} and {G}{W}{R} you get back {G}{W}{R}
|
||||
* if you call with {G}{W}{B} and {G}{W}{R} you get back null
|
||||
*
|
||||
* @param mana1
|
||||
* @param mana2
|
||||
* @return
|
||||
*/
|
||||
public static Mana getMoreValuableMana(Mana mana1, Mana mana2) {
|
||||
Mana moreMana;
|
||||
Mana lessMana;
|
||||
if (mana2.count() > mana1.count() || mana2.getAny() > mana1.getAny() || mana2.getColorless() < mana1.getColorless()) {
|
||||
moreMana = mana2;
|
||||
lessMana = mana1;
|
||||
} else {
|
||||
moreMana = mana1;
|
||||
lessMana = mana2;
|
||||
}
|
||||
if (lessMana.getWhite() > moreMana.getWhite() ||
|
||||
lessMana.getRed() > moreMana.getRed() ||
|
||||
lessMana.getGreen() > moreMana.getGreen() ||
|
||||
lessMana.getBlue() > moreMana.getBlue() ||
|
||||
lessMana.getBlack() > moreMana.getBlack() ||
|
||||
lessMana.getAny() > moreMana.getAny()
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return moreMana;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,10 +82,22 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
this.clear();
|
||||
for (ManaAbility ability: abilities) {
|
||||
for (Mana netMana: ability.getNetMana(game)) {
|
||||
SkipAddMana:
|
||||
for (Mana mana: copy) {
|
||||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
for(Mana existingMana: this) {
|
||||
if (existingMana.equalManaValue(newMana)) {
|
||||
continue SkipAddMana;
|
||||
}
|
||||
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
|
||||
if (moreValuable != null) {
|
||||
// only keep the more valuable mana
|
||||
existingMana.setToMana(newMana);
|
||||
continue SkipAddMana;
|
||||
}
|
||||
}
|
||||
this.add(newMana);
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +115,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
//if there is only one mana option available add it to all the existing options
|
||||
ManaAbility ability = abilities.get(0);
|
||||
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
||||
// no mana costs
|
||||
if (ability.getManaCosts().isEmpty()) {
|
||||
if (netManas.size() == 1) {
|
||||
addMana(netManas.get(0));
|
||||
|
@ -121,7 +134,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
}
|
||||
else {
|
||||
if (netManas.size() == 1) {
|
||||
addMana(ability.getManaCosts().getMana(), netManas.get(0));
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netManas.get(0), ability.getCosts().isEmpty());
|
||||
} else {
|
||||
List<Mana> copy = copy();
|
||||
this.clear();
|
||||
|
@ -130,7 +143,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
Mana newMana = new Mana();
|
||||
newMana.add(mana);
|
||||
newMana.add(netMana);
|
||||
addMana(ability.getManaCosts().getMana(), netMana);
|
||||
subtractCostAddMana(ability.getManaCosts().getMana(), netMana, ability.getCosts().isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,14 +221,21 @@ public class ManaOptions extends ArrayList<Mana> {
|
|||
return new ManaOptions(this);
|
||||
}
|
||||
|
||||
public void addMana(Mana cost, Mana addMana) {
|
||||
public void subtractCostAddMana(Mana cost, Mana addMana, boolean onlyManaCosts) {
|
||||
if (isEmpty()) {
|
||||
this.add(new Mana());
|
||||
}
|
||||
boolean addAny = false;
|
||||
if (addMana.getAny() == 1 && addMana.count() == 1) {
|
||||
addAny = true; // only replace to any will be repeated
|
||||
}
|
||||
for (Mana mana: this) {
|
||||
if (mana.contains(cost)) {
|
||||
while (mana.includesMana(cost)) {
|
||||
mana.subtract(cost);
|
||||
mana.add(addMana);
|
||||
if (!addAny) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2099,14 +2099,35 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
protected ManaOptions getManaAvailable(Game game) {
|
||||
ManaOptions available = new ManaOptions();
|
||||
|
||||
List<Permanent> manaPerms = this.getAvailableManaProducers(game);
|
||||
for (Permanent perm: manaPerms) {
|
||||
available.addMana(perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game), game);
|
||||
List<Abilities<ManaAbility>> sourceWithoutCosts = new ArrayList<>();
|
||||
List<Abilities<ManaAbility>> sourceWithCosts = new ArrayList<>();
|
||||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
boolean canAdd = false;
|
||||
boolean withCost = false;
|
||||
Abilities<ManaAbility> manaAbilities = permanent.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game);
|
||||
for (ManaAbility ability: manaAbilities) {
|
||||
if (ability.canActivate(playerId, game)) {
|
||||
canAdd = true;
|
||||
if (!ability.getManaCosts().isEmpty()) {
|
||||
withCost = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canAdd) {
|
||||
if (withCost) {
|
||||
sourceWithCosts.add(manaAbilities);
|
||||
} else {
|
||||
sourceWithoutCosts.add(manaAbilities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Permanent> manaPermsWithCost = this.getAvailableManaProducersWithCost(game);
|
||||
for (Permanent perm: manaPermsWithCost) {
|
||||
available.addManaWithCost(perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game), game);
|
||||
for (Abilities<ManaAbility> manaAbilities: sourceWithoutCosts) {
|
||||
available.addMana(manaAbilities, game);
|
||||
}
|
||||
for (Abilities<ManaAbility> manaAbilities: sourceWithCosts) {
|
||||
available.addManaWithCost(manaAbilities, game);
|
||||
}
|
||||
return available;
|
||||
}
|
||||
|
@ -2117,13 +2138,13 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) {
|
||||
boolean canAdd = false;
|
||||
for (ManaAbility ability: permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
|
||||
if (ability.canActivate(playerId, game)) {
|
||||
canAdd = true;
|
||||
}
|
||||
if (!ability.getManaCosts().isEmpty()) {
|
||||
canAdd = false;
|
||||
break;
|
||||
}
|
||||
if (ability.canActivate(playerId, game)) {
|
||||
canAdd = true;
|
||||
}
|
||||
}
|
||||
if (canAdd) {
|
||||
result.add(permanent);
|
||||
|
@ -2203,7 +2224,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
|
||||
protected boolean canPlayCardByAlternateCost(Card sourceObject, ManaOptions available, Ability ability, Game game) {
|
||||
if (!(sourceObject instanceof Permanent)) {
|
||||
if (sourceObject != null && !(sourceObject instanceof Permanent)) {
|
||||
for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (alternateSourceCostsAbility instanceof AlternativeSourceCosts) {
|
||||
|
|
Loading…
Reference in a new issue