Expanded the {name} syntax to work in many more effect types, and added additional culture icon replacement as well.

This commit is contained in:
Christian 'ketura' McCarty
2022-08-11 19:26:02 -05:00
parent 49290403db
commit b8ee9b5610
11 changed files with 92 additions and 36 deletions

View File

@@ -42,4 +42,13 @@ public enum Culture implements Filterable {
}
return null;
}
public static Culture findCulture(String name) {
String nameCaps = name.toUpperCase().replace(' ', '_').replace('-', '_');
for (Culture culture : values()) {
if (culture.getHumanReadable().equals(name) || culture.toString().equals(nameCaps))
return culture;
}
return null;
}
}

View File

@@ -3,6 +3,7 @@ package com.gempukku.lotro.cards.build.field.effect;
import com.gempukku.lotro.cards.build.ActionContext;
import com.gempukku.lotro.cards.build.ActionSource;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import java.util.LinkedList;
@@ -54,7 +55,7 @@ public class DefaultActionSource implements ActionSource {
@Override
public void createAction(CostToEffectAction action, ActionContext actionContext) {
if (text != null)
action.setText(text);
action.setText(GameUtils.SubstituteText(text, actionContext));
for (EffectAppender cost : costs)
cost.appendEffect(true, action, actionContext);

View File

@@ -6,6 +6,7 @@ import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.decisions.IntegerAwaitingDecision;
@@ -34,7 +35,7 @@ public class ChooseANumber implements EffectAppenderProducer {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
return new PlayoutDecisionEffect(actionContext.getPerformingPlayer(),
new IntegerAwaitingDecision(1, displayText,
new IntegerAwaitingDecision(1, GameUtils.SubstituteText(displayText, actionContext),
fromSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null),
toSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null))
{

View File

@@ -20,7 +20,7 @@ public class ChooseCardsFromDiscard implements EffectAppenderProducer {
final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize");
if (memorize == null)
throw new InvalidCardDefinitionException("You need to define what memory to use to store chosen cards");
final String text = FieldUtils.getString(effectObject.get("text"), "text");
final String text = FieldUtils.getString(effectObject.get("text"), "text", "Choose cards from discard.");
if (text == null)
throw new InvalidCardDefinitionException("You need to define text to show");

View File

@@ -9,6 +9,7 @@ import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.common.Filterable;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.decisions.IntegerAwaitingDecision;
@@ -36,7 +37,7 @@ public class ChooseHowManyToSpot implements EffectAppenderProducer {
final Filterable filterable = filterableSource.getFilterable(actionContext);
final int count = Filters.countSpottable(actionContext.getGame(), filterable);
return new PlayoutDecisionEffect(actionContext.getPerformingPlayer(),
new IntegerAwaitingDecision(1, text, 0, count, count) {
new IntegerAwaitingDecision(1, GameUtils.SubstituteText(text, actionContext), 0, count, count) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
final int spotCount = getValidatedResult(result);

View File

@@ -8,6 +8,7 @@ import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.decisions.YesNoDecision;
import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect;
@@ -31,15 +32,15 @@ public class ChooseYesOrNo implements EffectAppenderProducer {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
return new PlayoutDecisionEffect(playerSource.getPlayer(actionContext),
new YesNoDecision(text) {
new YesNoDecision(GameUtils.SubstituteText(text, actionContext)) {
@Override
protected void yes() {
actionContext.setValueToMemory(memorize, yesAnswer);
actionContext.setValueToMemory(memorize, GameUtils.SubstituteText(yesAnswer, actionContext));
}
@Override
protected void no() {
actionContext.setValueToMemory(memorize, noAnswer);
actionContext.setValueToMemory(memorize, GameUtils.SubstituteText(noAnswer, actionContext));
}
});
}

View File

@@ -5,6 +5,7 @@ import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.actions.SubAction;
import com.gempukku.lotro.logic.decisions.YesNoDecision;
@@ -35,7 +36,7 @@ public class Optional implements EffectAppenderProducer {
SubAction subAction = new SubAction(action);
subAction.appendCost(
new PlayoutDecisionEffect(choosingPlayer,
new YesNoDecision(text) {
new YesNoDecision(GameUtils.SubstituteText(text, actionContext)) {
@Override
protected void yes() {
ActionContext delegate = new DelegateActionContext(actionContext,

View File

@@ -41,16 +41,7 @@ public class PreventableAppenderProducer implements EffectAppenderProducer {
if (areCostsPlayable(actionContext)) {
final String preventingPlayer = preventingPlayerSource.getPlayer(actionContext);
String textToUse = text;
while (textToUse.contains("{")) {
int startIndex = textToUse.indexOf("{");
int endIndex = textToUse.indexOf("}");
String memory = textToUse.substring(startIndex + 1, endIndex);
final String cardNames = GameUtils.getAppendedNames(actionContext.getCardsFromMemory(memory));
textToUse = textToUse.replace("{" + memory + "}", cardNames);
}
String textToUse = GameUtils.SubstituteText(text, actionContext);
SubAction subAction = new SubAction(action);
subAction.appendEffect(

View File

@@ -58,7 +58,7 @@ public class CardResolver {
@Override
public String getText(LotroGame game) {
return choiceText;
return GameUtils.SubstituteText(choiceText, actionContext);
}
};
};
@@ -121,12 +121,12 @@ public class CardResolver {
@Override
public String getText(LotroGame game) {
return choiceText;
return GameUtils.SubstituteText(choiceText, actionContext);
}
};
} else {
List<? extends PhysicalCard> cardsInHand = actionContext.getGame().getGameState().getHand(handId);
return new ChooseArbitraryCardsEffect(choicePlayerId, choiceText, cardsInHand, Filters.in(possibleCards), min, max, false) {
return new ChooseArbitraryCardsEffect(choicePlayerId, GameUtils.SubstituteText(choiceText, actionContext), cardsInHand, Filters.in(possibleCards), min, max, false) {
@Override
protected void cardsSelected(LotroGame game, Collection<PhysicalCard> selectedCards) {
actionContext.setCardMemory(memory, selectedCards);
@@ -173,7 +173,7 @@ public class CardResolver {
@Override
public String getText(LotroGame game) {
return choiceText;
return GameUtils.SubstituteText(choiceText, actionContext);
}
};
};
@@ -212,7 +212,7 @@ public class CardResolver {
@Override
public String getText(LotroGame game) {
return choiceText;
return GameUtils.SubstituteText(choiceText, actionContext);
}
};
};
@@ -295,7 +295,7 @@ public class CardResolver {
final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment);
ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> {
String choicePlayerId = playerSource.getPlayer(actionContext);
return new ChooseActiveCardsEffect(actionContext.getSource(), choicePlayerId, choiceText, min, max, Filters.in(possibleCards)) {
return new ChooseActiveCardsEffect(actionContext.getSource(), choicePlayerId, GameUtils.SubstituteText(choiceText, actionContext), min, max, Filters.in(possibleCards)) {
@Override
protected void cardsSelected(LotroGame game, Collection<PhysicalCard> cards) {
actionContext.setCardMemory(memory, cards);

View File

@@ -129,15 +129,25 @@ public class ValueResolver {
return actionContext -> new MultiplyEvaluator(multiplier, new ForEachBurdenEvaluator());
} else if (type.equalsIgnoreCase("forEachWound")) {
FieldUtils.validateAllowedFields(object, "filter", "multiplier");
final String filter = FieldUtils.getString(object.get("filter"), "filter");
final String filter = FieldUtils.getString(object.get("filter"), "filter", "any");
final int multiplier = FieldUtils.getInteger(object.get("multiplier"), "multiplier", 1);
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
return (actionContext) -> (Evaluator) (game, cardAffected) -> {
int wounds = 0;
for (PhysicalCard physicalCard : Filters.filterActive(actionContext.getGame(), filterableSource.getFilterable(actionContext))) {
wounds += actionContext.getGame().getGameState().getWounds(physicalCard);
return (actionContext) -> {
if (filter.equals("any")) {
return new MultiplyEvaluator(multiplier,
(game, cardAffected) -> actionContext.getGame().getGameState().getWounds(cardAffected));
} else {
return new MultiplyEvaluator(multiplier,
(game, cardAffected) -> {
final Filterable filterable = filterableSource.getFilterable(actionContext);
int wounds = 0;
for (PhysicalCard physicalCard : Filters.filterActive(game, filterable)) {
wounds += actionContext.getGame().getGameState().getWounds(physicalCard);
}
return wounds;
});
}
return multiplier * wounds;
};
} else if (type.equalsIgnoreCase("forEachKeyword")) {
FieldUtils.validateAllowedFields(object, "filter", "keyword");

View File

@@ -1,5 +1,6 @@
package com.gempukku.lotro.logic;
import com.gempukku.lotro.cards.build.ActionContext;
import com.gempukku.lotro.common.Culture;
import com.gempukku.lotro.common.Filterable;
import com.gempukku.lotro.common.Side;
@@ -118,6 +119,19 @@ public class GameUtils {
return "<div class='cardHint' value='" + blueprintId + "'>" + (blueprint.isUnique() ? "·" : "") + GameUtils.getFullName(blueprint) + "</div>";
}
public static String getCultureImage(String cultureName) {
Culture culture = Culture.findCulture(cultureName);
if(culture == null)
return null;
return getCultureImage(culture);
}
public static String getCultureImage(Culture culture) {
return "<span class='cultureHint' value='" + culture.toString() + "'><img src='images/cultures/" + culture.toString().toLowerCase() + ".png'> "
+ culture.getHumanReadable() + "</span>";
}
public static String getAppendedTextNames(Collection<? extends PhysicalCard> cards) {
StringBuilder sb = new StringBuilder();
for (PhysicalCard card : cards)
@@ -130,14 +144,41 @@ public class GameUtils {
}
public static String getAppendedNames(Collection<? extends PhysicalCard> cards) {
StringBuilder sb = new StringBuilder();
for (PhysicalCard card : cards)
sb.append(GameUtils.getCardLink(card) + ", ");
ArrayList<String> cardStrings = new ArrayList<>();
for (PhysicalCard card : cards) {
cardStrings.add(GameUtils.getCardLink(card));
}
if (sb.length() == 0)
if (cardStrings.size() == 0)
return "none";
else
return sb.substring(0, sb.length() - 2);
return String.join(", ", cardStrings);
}
public static String SubstituteText(String text)
{
return SubstituteText(text, null);
}
public static String SubstituteText(String text, ActionContext context)
{
String result = text;
while (result.contains("{")) {
int startIndex = result.indexOf("{");
int endIndex = result.indexOf("}");
String memory = result.substring(startIndex + 1, endIndex);
String culture = getCultureImage(memory);
if(culture != null) {
result = result.replace("{" + memory + "}", culture);
}
else if(context != null){
final String cardNames = GameUtils.getAppendedNames(context.getCardsFromMemory(memory));
result = result.replace("{" + memory + "}", cardNames);
}
}
return result;
}
public static int getSpottableTokensTotal(LotroGame game, Token token) {