Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 37 additions & 10 deletions src/Imlight.Setup/SpellSupport.Describe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,16 @@ private static string Requirement(Requirement? requirement) {
var you = requirement is ConditionalSpellEffectRequirement { m_targetType: RequirementTarget.RT_Caster };
var who = you ? "you" : "the target";
var has = you ? (not ? "you have no" : "you have") : (not ? "the target has no" : "the target has");
var doesNotHave = you ? "you don't have" : "the target doesn't have";
// "has no blades" reads right, "has no at least 2 blades" doesn't: a count that is not met is "fewer than".
string Count(int min, int max, string one, string many)
=> min > 1 && max >= min && max != min ? $"{min} to {max} {many}" : min > 1 ? $"at least {min} {many}" : (not ? many : "a " + one);
=> min > 1 && max >= min && max != min ? $"{min} to {max} {many}"
: min > 1 ? (not ? $"fewer than {min} {many}" : $"at least {min} {many}")
: (not ? many : "a " + one);

return requirement switch {
ReqIsSchool isSchool => $"{who} {(you ? "are" : "is")}{(not ? " not" : "")} {isSchool.m_magicSchoolName}",
ReqIsSecondarySchool => $"{who} {(you ? "have" : "has")}{(not ? " not" : "")} the right second school",
ReqIsSecondarySchool => $"{(not ? doesNotHave : you ? "you have" : "the target has")} the right second school",
ReqHangingWard ward => $"{has} {Count(ward.m_minCount, ward.m_maxCount, Kind(ward.m_disposition, "shield", "trap", "ward"), Kind(ward.m_disposition, "shields", "traps", "wards"))}",
ReqHangingCharm charm => $"{has} {Count(charm.m_minCount, charm.m_maxCount, Kind(charm.m_disposition, "blade", "weakness", "charm"), Kind(charm.m_disposition, "blades", "weaknesses", "charms"))}",
ReqHangingOverTime overTime => $"{has} {Count(overTime.m_minCount, overTime.m_maxCount, Kind(overTime.m_disposition, "heal over time", "damage over time", "over-time effect"), Kind(overTime.m_disposition, "heals over time", "damage-over-time effects", "over-time effects"))}",
Expand All @@ -383,7 +387,9 @@ string Count(int min, int max, string one, string many)
},
ReqCombatHealth health => $"{who}{(you ? "r" : "'s")} health is{(not ? " not" : "")} between {health.m_fMinPercent * 100:0}% and {health.m_fMaxPercent * 100:0}%",
ReqCombatStatus status => $"{who} {(you ? "are" : "is")}{(not ? " not" : "")} {(status.m_status == kStatusEffect.kConfused ? "confused" : "stunned")}",
ReqPipCount pips => $"{who} {(you ? "have" : "has")}{(not ? " not" : "")} {pips.m_minPips}{(pips.m_maxPips > pips.m_minPips ? $" to {pips.m_maxPips}" : " or more")} pips",
ReqPipCount pips => pips.m_maxPips > pips.m_minPips
? $"{(not ? doesNotHave : you ? "you have" : "the target has")} {pips.m_minPips} to {pips.m_maxPips} pips"
: $"{who} {(you ? "have" : "has")} {(not ? $"fewer than {pips.m_minPips}" : $"{pips.m_minPips} or more")} pips",
ReqShadowPipCount => $"{who} {(you ? "have" : "has")}{(not ? " no" : "")} shadow pips",
_ => "a condition is met",
};
Expand Down Expand Up @@ -487,6 +493,10 @@ private static string Number(int low, int high) {
var next = rounds > 0 ? "" : "next ";
var many = rounds > 0 ? "s" : "";
var their = who == "you" ? "your" : "their";
// "all enemies take", "one enemy takes", "you take".
var plural = who is "you" or "all enemies" or "several enemies" or "several allies";
string Verb(string single, string multiple) => plural ? multiple : single;
var them = who == "you" ? "you" : "them";

Clause Say(string text, string suffix = "") => new(text, suffix);

Expand Down Expand Up @@ -535,7 +545,7 @@ private static string Number(int low, int high) {
return Say($"{sign} damage on {whose} {next}{hit}attack{many}{forRounds}");
case kSpellEffects.kModifyIncomingDamage:
if (rounds > 0) {
return Say($"{sign}% to the {hit}damage {who} take{(who == "you" ? "" : "s")} for {Rounds(rounds)}");
return Say($"{sign}% to the {hit}damage {who} {Verb("takes", "take")} for {Rounds(rounds)}");
}

return Say(high < 0 || low < 0 ? $"{sign}% to the next {hit}attack{on}" : $"{sign}% to the next {hit}hit{on}");
Expand Down Expand Up @@ -650,12 +660,12 @@ private static string Number(int low, int high) {
case kSpellEffects.kModifyHate:
return Say($"Changes how much monsters go after {who}");
case kSpellEffects.kAfterlife:
return Say($"If {who} {(who == "you" ? "are" : "is")} defeated{(rounds > 0 ? $" in the next {Rounds(rounds)}" : "")}, brings them back");
return Say($"If {who} {Verb("is", "are")} defeated{(rounds > 0 ? $" in the next {Rounds(rounds)}" : "")}, brings {them} back");
case kSpellEffects.kConfusion:
return Say($"Confuses {who}{forRounds}: {n}% chance each turn that their spell hits a random target");
return Say($"Confuses {who}{forRounds}: {n}% chance each turn that {their} spell hits a random target");
// Beguile and Spy keep their rounds in m_effectParam.
case kSpellEffects.kMindControl:
return Say($"Beguiles {who} so it fights for your side for {Rounds(effect.m_effectParam)}");
return Say($"Beguiles {who} so {Verb("it fights", "they fight")} for your side for {Rounds(effect.m_effectParam)}");
case kSpellEffects.kClue:
return Say($"Spies on {who} for {Rounds(effect.m_effectParam)}");
case kSpellEffects.kAddSpellToHand:
Expand All @@ -678,7 +688,7 @@ private static string Number(int low, int high) {
case kSpellEffects.kModifyPipRoundRate:
return Say($"{(high >= 0 ? "+" : "-")}{n} pip{(n == "1" ? "" : "s")} each round for {who}{forRounds}");
case kSpellEffects.kHealByWard:
return Say($"Heals {who} for {n} health for each ward on them{forRounds}");
return Say($"Heals {who} for {n} health for each ward on {them}{forRounds}");
case kSpellEffects.kAddCombatTriggerList:
return Say($"Sets up battle triggers on {who}");
case kSpellEffects.kRemoveCombatTriggerList:
Expand All @@ -690,7 +700,7 @@ private static string Number(int low, int high) {
case kSpellEffects.kVanish:
return Say($"Makes {who} vanish from the battle{forRounds}");
case kSpellEffects.kAutoPass:
return Say($"Makes {who} pass {(who == "you" ? "your" : "their")} turns{forRounds}");
return Say($"Makes {who} pass {their} turns{forRounds}");
case kSpellEffects.kExitCombat:
return Say($"Takes {who} out of the battle");
case kSpellEffects.kCollectEssence:
Expand Down Expand Up @@ -719,9 +729,26 @@ private static string Number(int low, int high) {
case kSpellEffects.kModifyCardCloak:
return Say("Cloaks the card, so the enemy can't see it");
case kSpellEffects.kModifyCardRank:
return Say($"{sign} pip{(n == "1" ? "" : "s")} on the card's rank");
return Say(high >= 0 ? $"Makes the card cost {n} more pip{(n == "1" ? "" : "s")}" : $"Makes the card cost {n} fewer pip{(n == "1" ? "" : "s")}");
case kSpellEffects.kModifyCardMutation:
return Say("Changes the card into a stronger one");
case kSpellEffects.kRevealCloak:
return Say($"Reveals the hidden charms and wards on {who}");
case kSpellEffects.kStopVanish:
return Say($"Brings {who} back from vanishing");
case kSpellEffects.kStopAutoPass:
return Say($"Lets {who} pick {their} own turns again");
case kSpellEffects.kMakeTargetable:
case kSpellEffects.kForceTargetable:
return Say($"Makes {who} targetable again");
case kSpellEffects.kSuspendPips:
return Say($"Stops {whose} pips from coming in{forRounds}");
case kSpellEffects.kResumePips:
return Say($"Lets {whose} pips come in again");
case kSpellEffects.kBacklashDamage:
return Say("Deals Shadow backlash damage", to);
case kSpellEffects.kAbsorbHeal:
return Say($"Gives {who} a shield that soaks up the next {n} healing{forRounds}");
case kSpellEffects.kProtectCardBeneficial:
case kSpellEffects.kProtectCardHarmful:
return Say("Protects what the card puts on from being removed");
Expand Down
2 changes: 1 addition & 1 deletion src/Imlight.Setup/SpellSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ kSpellEffects.kUntargetable or kSpellEffects.kMakeTargetable or kSpellEffects.kF
kSpellEffects.kDelayCast => "a delayed cast",
kSpellEffects.kAbsorbHeal => "absorbing heals",
kSpellEffects.kRevealCloak => "revealing cloaked effects",
kSpellEffects.kClue => "a clue",
kSpellEffects.kClue => "spy",
_ => Words(type.ToString()).ToLowerInvariant(),
};

Expand Down