mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 13:32:06 -08:00
* GUI: added auto-choose for replacement effects (remember answer in dialog + reset answer in popup menu + new option in preferences; #4360, #328, #4219, #6676, #7914);
This commit is contained in:
parent
c081d3fa33
commit
c9ab896d24
11 changed files with 311 additions and 77 deletions
|
|
@ -189,7 +189,7 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
logger.error("No abilities for continuous effect: " + effect.toString());
|
||||
logger.error("No abilities for continuous effect: " + effect);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1282,7 +1282,7 @@ public class ContinuousEffects implements Serializable {
|
|||
logger.error("Effect is null: " + source.toString());
|
||||
return;
|
||||
} else if (source == null) {
|
||||
logger.warn("Adding effect without ability : " + effect.toString());
|
||||
logger.warn("Adding effect without ability : " + effect);
|
||||
}
|
||||
switch (effect.getEffectType()) {
|
||||
case REPLACEMENT:
|
||||
|
|
@ -1369,6 +1369,8 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
|
||||
public Map<String, String> getReplacementEffectsTexts(Map<ReplacementEffect, Set<Ability>> rEffects, Game game) {
|
||||
// warning, autoSelectReplacementEffects uses [object id] in texts as different settings,
|
||||
// so if you change keys or texts logic then don't forget to change auto-choose too
|
||||
Map<String, String> texts = new LinkedHashMap<>();
|
||||
for (Map.Entry<ReplacementEffect, Set<Ability>> entry : rEffects.entrySet()) {
|
||||
if (entry.getValue() != null) {
|
||||
|
|
|
|||
|
|
@ -1,55 +1,92 @@
|
|||
|
||||
|
||||
package mage.choices;
|
||||
|
||||
import mage.util.Copyable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||
*/
|
||||
public interface Choice {
|
||||
public interface Choice extends Serializable, Copyable<Choice> {
|
||||
|
||||
String getMessage();
|
||||
|
||||
void setMessage(String message);
|
||||
|
||||
String getSubMessage();
|
||||
|
||||
void setSubMessage(String subMessage);
|
||||
|
||||
void clearChoice();
|
||||
|
||||
boolean isChosen();
|
||||
|
||||
boolean isChosenSpecial();
|
||||
|
||||
boolean isRequired();
|
||||
|
||||
Choice copy();
|
||||
// special mode for all choices
|
||||
void setSpecial(boolean enabled, boolean canBeEmpty, String text, String hint);
|
||||
|
||||
boolean isSpecialEnabled();
|
||||
|
||||
boolean isSpecialCanBeEmpty();
|
||||
|
||||
String getSpecialText();
|
||||
|
||||
String getSpecialHint();
|
||||
|
||||
// string choice
|
||||
void setChoices(Set<String> choices);
|
||||
|
||||
Set<String> getChoices();
|
||||
void setChoice(String choice);
|
||||
|
||||
void setChoice(String choice, boolean isSpecial);
|
||||
|
||||
String getChoice();
|
||||
|
||||
default void setChoice(String choice) {
|
||||
setChoice(choice, false);
|
||||
}
|
||||
|
||||
// key-value choice
|
||||
boolean isKeyChoice();
|
||||
|
||||
void setKeyChoices(Map<String, String> choices);
|
||||
Map<String,String> getKeyChoices();
|
||||
void setChoiceByKey(String choiceKey);
|
||||
|
||||
Map<String, String> getKeyChoices();
|
||||
|
||||
void setChoiceByKey(String choiceKey, boolean isSpecial);
|
||||
|
||||
String getChoiceKey();
|
||||
|
||||
String getChoiceValue();
|
||||
|
||||
default void setChoiceByKey(String choiceKey) {
|
||||
setChoiceByKey(choiceKey, false);
|
||||
}
|
||||
|
||||
// search
|
||||
boolean isSearchEnabled();
|
||||
|
||||
void setSearchEnabled(boolean isEnabled);
|
||||
|
||||
void setSearchText(String searchText);
|
||||
|
||||
String getSearchText();
|
||||
|
||||
// sorting
|
||||
boolean isSortEnabled();
|
||||
|
||||
void setSortData(Map<String, Integer> sortData);
|
||||
|
||||
Map<String, Integer> getSortData();
|
||||
|
||||
// random choice
|
||||
// random choice (for AI usage)
|
||||
void setRandomChoice();
|
||||
|
||||
boolean setChoiceByAnswers(List<String> answers, boolean removeSelectAnswerFromList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ package mage.choices;
|
|||
|
||||
import mage.util.RandomUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||
*/
|
||||
public class ChoiceImpl implements Choice, Serializable {
|
||||
public class ChoiceImpl implements Choice {
|
||||
|
||||
protected boolean chosen;
|
||||
protected boolean chosenNormal;
|
||||
protected boolean chosenSpecial;
|
||||
protected final boolean required;
|
||||
protected String choice;
|
||||
protected String choiceKey;
|
||||
|
|
@ -22,6 +22,13 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
protected boolean searchEnabled = true; // enable for all windows by default
|
||||
protected String searchText;
|
||||
|
||||
// special button with #-answer
|
||||
// warning, only for human's GUI, not AI
|
||||
protected boolean specialEnabled = false;
|
||||
protected boolean specialCanBeEmpty = false; // enable if you want to select "nothing", but not cancel
|
||||
protected String specialText = "";
|
||||
protected String specialHint = "";
|
||||
|
||||
public ChoiceImpl() {
|
||||
this(false);
|
||||
}
|
||||
|
|
@ -30,9 +37,10 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
this.required = required;
|
||||
}
|
||||
|
||||
public ChoiceImpl(ChoiceImpl choice) {
|
||||
public ChoiceImpl(final ChoiceImpl choice) {
|
||||
this.choice = choice.choice;
|
||||
this.chosen = choice.chosen;
|
||||
this.chosenNormal = choice.chosenNormal;
|
||||
this.chosenSpecial = choice.chosenSpecial;
|
||||
this.required = choice.required;
|
||||
this.message = choice.message;
|
||||
this.subMessage = choice.subMessage;
|
||||
|
|
@ -42,18 +50,28 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
this.choiceKey = choice.choiceKey;
|
||||
this.keyChoices = choice.keyChoices; // list should never change for the same object so copy by reference TODO: check errors with that, it that ok? Color list is static
|
||||
this.sortData = choice.sortData;
|
||||
this.specialEnabled = choice.specialEnabled;
|
||||
this.specialCanBeEmpty = choice.specialCanBeEmpty;
|
||||
this.specialText = choice.specialText;
|
||||
this.specialHint = choice.specialHint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChosen() {
|
||||
return chosen;
|
||||
return chosenNormal || chosenSpecial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChosenSpecial() {
|
||||
return chosenSpecial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearChoice() {
|
||||
choice = null;
|
||||
choiceKey = null;
|
||||
chosen = false;
|
||||
this.choice = null;
|
||||
this.choiceKey = null;
|
||||
this.chosenNormal = false;
|
||||
this.chosenSpecial = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -92,10 +110,17 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setChoice(String choice) {
|
||||
public void setChoice(String choice, boolean isSpecial) {
|
||||
if (choices.contains(choice)) {
|
||||
this.choice = choice;
|
||||
this.chosen = true;
|
||||
this.chosenNormal = true;
|
||||
this.chosenSpecial = isSpecial;
|
||||
}
|
||||
|
||||
if (isSpecial && this.specialCanBeEmpty && (choice == null || choice.isEmpty())) {
|
||||
clearChoice();
|
||||
this.chosenNormal = false;
|
||||
this.chosenSpecial = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -134,12 +159,19 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setChoiceByKey(String choiceKey) {
|
||||
public void setChoiceByKey(String choiceKey, boolean isSpecial) {
|
||||
String choiceToSet = keyChoices.get(choiceKey);
|
||||
if (choiceToSet != null) {
|
||||
this.choice = choiceToSet;
|
||||
this.choiceKey = choiceKey;
|
||||
this.chosen = true;
|
||||
this.chosenNormal = true;
|
||||
this.chosenSpecial = isSpecial;
|
||||
}
|
||||
|
||||
if (isSpecial && this.specialCanBeEmpty && (choiceKey == null || choiceKey.isEmpty())) {
|
||||
clearChoice();
|
||||
this.chosenNormal = false;
|
||||
this.chosenSpecial = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,14 +223,14 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
String[] vals = this.getKeyChoices().keySet().toArray(new String[0]);
|
||||
if (vals.length > 0) {
|
||||
int choiceNum = RandomUtil.nextInt(vals.length);
|
||||
this.setChoiceByKey(vals[choiceNum]);
|
||||
this.setChoiceByKey(vals[choiceNum], false);
|
||||
}
|
||||
} else {
|
||||
// string mode
|
||||
String[] vals = this.getChoices().toArray(new String[0]);
|
||||
if (vals.length > 0) {
|
||||
int choiceNum = RandomUtil.nextInt(vals.length);
|
||||
this.setChoice(vals[choiceNum]);
|
||||
this.setChoice(vals[choiceNum], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -211,18 +243,18 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
for (String needChoice : answers) {
|
||||
for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) {
|
||||
if (currentChoice.getKey().equals(needChoice)) {
|
||||
this.setChoiceByKey(needChoice);
|
||||
this.setChoiceByKey(needChoice, false);
|
||||
answers.remove(needChoice);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// no key answer found, try to macht by text starting with
|
||||
// no key answer found, try to match by text starting with
|
||||
for (String needChoice : answers) {
|
||||
for (Map.Entry<String, String> currentChoice : this.getKeyChoices().entrySet()) {
|
||||
if (currentChoice.getValue().startsWith(needChoice)) {
|
||||
this.setChoiceByKey(currentChoice.getKey());
|
||||
this.setChoiceByKey(currentChoice.getKey(), false);
|
||||
answers.remove(needChoice);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -233,7 +265,7 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
for (String needChoice : answers) {
|
||||
for (String currentChoice : this.getChoices()) {
|
||||
if (currentChoice.equals(needChoice)) {
|
||||
this.setChoice(needChoice);
|
||||
this.setChoice(needChoice, false);
|
||||
answers.remove(needChoice);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -242,4 +274,32 @@ public class ChoiceImpl implements Choice, Serializable {
|
|||
}
|
||||
return false; // can't find answer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpecial(boolean enabled, boolean canBeEmpty, String text, String hint) {
|
||||
this.specialEnabled = enabled;
|
||||
this.specialCanBeEmpty = canBeEmpty;
|
||||
this.specialText = text;
|
||||
this.specialHint = hint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecialEnabled() {
|
||||
return this.specialEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecialCanBeEmpty() {
|
||||
return this.specialCanBeEmpty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpecialText() {
|
||||
return this.specialText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpecialHint() {
|
||||
return this.specialHint;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class UserData implements Serializable {
|
|||
protected boolean passPriorityCast;
|
||||
protected boolean passPriorityActivation;
|
||||
protected boolean autoOrderTrigger;
|
||||
protected boolean useSameSettingsForReplacementEffects;
|
||||
protected boolean useFirstManaAbility = false;
|
||||
private String userIdStr;
|
||||
protected Map<UUID, Set<UUID>> requestedHandPlayersList; // game -> players list
|
||||
|
|
@ -36,10 +37,22 @@ public class UserData implements Serializable {
|
|||
private int constructedRating;
|
||||
private int limitedRating;
|
||||
|
||||
public UserData(UserGroup userGroup, int avatarId, boolean showAbilityPickerForced,
|
||||
boolean allowRequestShowHandCards, boolean confirmEmptyManaPool, UserSkipPrioritySteps userSkipPrioritySteps,
|
||||
String flagName, boolean askMoveToGraveOrder, boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted,
|
||||
boolean passPriorityCast, boolean passPriorityActivation, boolean autoOrderTrigger, boolean useFirstManaAbility, String userIdStr) {
|
||||
public UserData(UserGroup userGroup,
|
||||
int avatarId,
|
||||
boolean showAbilityPickerForced,
|
||||
boolean allowRequestShowHandCards,
|
||||
boolean confirmEmptyManaPool,
|
||||
UserSkipPrioritySteps userSkipPrioritySteps,
|
||||
String flagName,
|
||||
boolean askMoveToGraveOrder,
|
||||
boolean manaPoolAutomatic,
|
||||
boolean manaPoolAutomaticRestricted,
|
||||
boolean passPriorityCast,
|
||||
boolean passPriorityActivation,
|
||||
boolean autoOrderTrigger,
|
||||
boolean useSameSettingsForReplacementEffects,
|
||||
boolean useFirstManaAbility,
|
||||
String userIdStr) {
|
||||
this.groupId = userGroup.getGroupId();
|
||||
this.avatarId = avatarId;
|
||||
this.showAbilityPickerForced = showAbilityPickerForced;
|
||||
|
|
@ -53,6 +66,7 @@ public class UserData implements Serializable {
|
|||
this.passPriorityCast = passPriorityCast;
|
||||
this.passPriorityActivation = passPriorityActivation;
|
||||
this.autoOrderTrigger = autoOrderTrigger;
|
||||
this.useSameSettingsForReplacementEffects = useSameSettingsForReplacementEffects;
|
||||
this.useFirstManaAbility = useFirstManaAbility;
|
||||
this.matchHistory = "";
|
||||
this.matchQuitRatio = 0;
|
||||
|
|
@ -76,13 +90,31 @@ public class UserData implements Serializable {
|
|||
this.passPriorityCast = userData.passPriorityCast;
|
||||
this.passPriorityActivation = userData.passPriorityActivation;
|
||||
this.autoOrderTrigger = userData.autoOrderTrigger;
|
||||
this.useSameSettingsForReplacementEffects = userData.useSameSettingsForReplacementEffects;
|
||||
this.useFirstManaAbility = userData.useFirstManaAbility;
|
||||
this.userIdStr = userData.userIdStr;
|
||||
// todo: why we don't update user stats here? => can't be updated from client side
|
||||
}
|
||||
|
||||
public static UserData getDefaultUserDataView() {
|
||||
return new UserData(UserGroup.DEFAULT, 0, false, false, true, new UserSkipPrioritySteps(), getDefaultFlagName(), false, true, true, false, false, false, false, "");
|
||||
return new UserData(
|
||||
UserGroup.DEFAULT,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
new UserSkipPrioritySteps(),
|
||||
getDefaultFlagName(),
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
public void setGroupId(int groupId) {
|
||||
|
|
@ -115,10 +147,7 @@ public class UserData implements Serializable {
|
|||
|
||||
public boolean isAllowRequestHandToPlayer(UUID gameId, UUID requesterPlayerId) {
|
||||
// once per game
|
||||
boolean allowToPlayer = true;
|
||||
if (requestedHandPlayersList.containsKey(gameId) && requestedHandPlayersList.get(gameId).contains(requesterPlayerId)) {
|
||||
allowToPlayer = false;
|
||||
}
|
||||
boolean allowToPlayer = !requestedHandPlayersList.containsKey(gameId) || !requestedHandPlayersList.get(gameId).contains(requesterPlayerId);
|
||||
return isAllowRequestHandToAll() && allowToPlayer;
|
||||
}
|
||||
|
||||
|
|
@ -206,6 +235,10 @@ public class UserData implements Serializable {
|
|||
return autoOrderTrigger;
|
||||
}
|
||||
|
||||
public boolean isUseSameSettingsForReplacementEffects() {
|
||||
return useSameSettingsForReplacementEffects;
|
||||
}
|
||||
|
||||
public void setAutoOrderTrigger(boolean autoOrderTrigger) {
|
||||
this.autoOrderTrigger = autoOrderTrigger;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue