public void AddElements(ElementCounts elements) { foreach (var part in parts) { part.AddElements(elements); } }
protected ElementCounts actionElements; // null unless we are in the middle of an action public override async Task <bool> HasElements(ElementCounts subset) { if (actionElements == null) { actionElements = Elements.Clone(); } if (actionElements.Contains(subset)) { return(true); } // Check if we have prepared element markers to fill the missing elements if (PreparedElements.Any()) { var missing = subset.Except(actionElements); if (PreparedElements.Contains(missing) && await this.UserSelectsFirstText($"Meet elemental threshold:" + subset.BuildElementString(), "Yes, use prepared elements", "No, I'll pass.")) { foreach (var pair in missing) { PreparedElements[pair.Key] -= pair.Value; actionElements[pair.Key] += pair.Value; // assign to this action so next check recognizes them } return(true); } } return(false); }
/// <summary> /// Checks elements available, and commits them (like the 'Any' element) /// </summary> public virtual async Task <bool> HasElements(ElementCounts subset) { // For normal spirits without Prepared Elements, this is the same as Could Have Elements if (Elements.Contains(subset)) { return(true); } int wildCount = Elements[Element.Any]; if (wildCount == 0) { return(false); } // We have some wild cards var missing = subset.Except(Elements); if (missing.Count > wildCount) { return(false); } if (await this.UserSelectsFirstText("Activate: " + subset.BuildElementString() + "?", $"Yes, use {missing.Count} 'Any' elments", "No thanks")) { foreach (var p in missing) { Elements[p.Key] += p.Value; } Elements[Element.Any] -= missing.Count; return(true); } return(false); }
public void AddElements(ElementCounts elements) { foreach (var r in Revealed) { r.AddElement(elements); } }
protected CardAttribute(string name, int cost, PowerType type, ElementCounts elements) { this.Name = name; this.Cost = cost; this.PowerType = type; this.Elements = elements; }
public override bool CouldHaveElements(ElementCounts subset) { var els = PreparedElements.Any() ? Elements.Union(PreparedElements) : Elements; return(els.Contains(subset)); }
/// <summary> /// Checks all elements that are available to spirit. /// </summary> public virtual bool CouldHaveElements(ElementCounts subset) { // For normal spirits without Prepared Elements, this is only the normal Elements int wildCount = Elements[Element.Any]; return(wildCount == 0 ? Elements.Contains(subset) // no 'wild-card' elements, Elements must contain subset : subset.Except(Elements).Count <= wildCount); // Find missing elements and count if they are less than our 'wild-card' elements }
public override async Task TakeAction(IActionFactory factory, SelfCtx ctx) { actionElements = null; // make sure these are cleared out for every action try { await base.TakeAction(factory, ctx); } finally { actionElements = null; } }
public ElementCounts AddElements(ElementCounts elements = null) { if (elements == null) { elements = new ElementCounts(); } Energy.AddElements(elements); CardPlays.AddElements(elements); return(elements); }
public new ElementCounts Clone() { var clone = new ElementCounts(); foreach (var invader in Keys) { clone[invader] = this[invader]; } return(clone); }
public override async Task <ElementCounts> SelectInnateToActivate(IEnumerable <IDrawableInnateOption> innateOptions) { var elementOptions = innateOptions.Select(x => x.Elements); // Init the elements that are active for this action only. if (actionElements == null) { actionElements = Elements.Clone(); } var highestAlreadyMatch = innateOptions .OrderByDescending(e => e.Elements.Total) .FirstOrDefault(x => actionElements.Contains(x.Elements)); var canMeetWithPrepared = innateOptions // .Elements .Where(x => !actionElements.Contains(x.Elements) && PreparedElements.Contains(x.Elements.Except(actionElements))) .ToArray(); // If we can't extend with prepared, just return what we can if (canMeetWithPrepared.Length > 0) { // if we CAN meet something with Prepared, return string prompt = highestAlreadyMatch != null ? "Extend element threshold? (current: " + highestAlreadyMatch.Elements.BuildElementString() + ")" : "Meet element threshold?"; // Select which Extened we want to meet. var options = canMeetWithPrepared .OrderBy(e => e.Elements.Total) // smallest first .ToList(); if (highestAlreadyMatch != null) { options.Insert(0, highestAlreadyMatch); } Present present = highestAlreadyMatch != null ? Present.Always : Present.Done; IDrawableInnateOption extendedOption = await this.Select <IDrawableInnateOption>(prompt, options.ToArray(), present); if (extendedOption != null) { // Apply necessary prepared elements to the action Elements. var preparedElementsToConsume = extendedOption.Elements.Except(actionElements); foreach (var consumeEl in preparedElementsToConsume) { PreparedElements[consumeEl.Key] -= consumeEl.Value; actionElements[consumeEl.Key] += consumeEl.Value; } return(extendedOption.Elements); } } return(highestAlreadyMatch?.Elements); }
void DrawActivatedElements(Graphics graphics, ElementCounts elements, ElementLayout elLayout, int skip = 0) { var orderedElements = elements.Keys.OrderBy(el => (int)el); int idx = skip; foreach (var element in orderedElements) { var rect = elLayout.Rect(idx++); graphics.DrawImage(GetElementImage(element), rect); graphics.DrawCountIfHigherThan(rect, elements[element]); } }
public virtual async Task <ElementCounts> SelectInnateToActivate(IEnumerable <IDrawableInnateOption> innateOptions) { IEnumerable <ElementCounts> elementOptions = innateOptions.Select(x => x.Elements); ElementCounts match = null; foreach (ElementCounts elements in elementOptions.OrderBy(els => els.Total)) { if (await HasElements(elements)) { match = elements; } } return(match); }
public void DrawFromLayout(Graphics graphics, CachedImageDrawer imageDrawer, ElementCounts activatedElements, InnatePower[] innateOptions, IDrawableInnateOption[] innateGroupOptions ) { if (backgroundCache == null) { this.imageDrawer = imageDrawer; using var boldFont = layout.BuildBoldFont(); DrawBackgroundImage(boldFont); InitOverlayCache(boldFont); } // Background Layer graphics.DrawImage(backgroundCache, layout.Bounds); this.graphics = graphics; // Middle Layer - Available foreach (WrappingText_InnateOptions wrappintText in layout.Options) { if (activatedElements.Contains(wrappintText.GroupOption.Elements)) { graphics.FillRectangle(Brushes.PeachPuff, wrappintText.Bounds); } } // Overlay text / images graphics.DrawImage(overlayCache, layout.Bounds); // Selected Innate Power if (innateOptions.Contains(power)) { using Pen highlightPen = new(Color.Red, 2f); graphics.DrawRectangle(highlightPen, layout.Bounds); } // Selected Innat Option Group foreach (var x in layout.Options) { if (innateGroupOptions.Contains(x.GroupOption)) { using Pen highlightPen = new(Color.Red, 2f); graphics.DrawRectangle(highlightPen, x.Bounds); } } }
public async Task <ElementCounts> DiscardElements(int totalNumToRemove, string effect) { var discarded = new ElementCounts(); int index = 0; while (index++ < totalNumToRemove) { Element el = await this.SelectElementEx($"Select element to discard for {effect} ({index} of {totalNumToRemove})", PreparedElements.Keys, Present.Done); if (el == default) { break; } PreparedElements[el]--; discarded[el]++; } return(discarded); }
async Task <List <MethodInfo> > GetLastActivatedMethodsOfEachGroup(SelfCtx spiritCtx) { // Not using LINQ because of the AWAIT in the loop. var lastMethods = new List <MethodInfo>(); foreach (MethodTuple[] grp in executionGroups) { // Ask spirit which methods they can activate ElementCounts match = await spiritCtx.Self.SelectInnateToActivate(grp.Select(g => g.Attr)); // Find matching method and it to execute-list MethodInfo method = grp.FirstOrDefault(g => g.Elements == match)?.Method; if (method != null) { lastMethods.Add(method); } } return(lastMethods); }
public DrawableInnateOption(string thresholds, string description) { Elements = ElementCounts.Parse(thresholds); Description = description; }
public Task <bool> YouHave(string elementString) => Self.HasElements(ElementCounts.Parse(elementString));
public MinorCardAttribute(string name, int cost, string elementString) : base(name, cost, PowerType.Minor, ElementCounts.Parse(elementString)) { }
public SlowButFastIfAttribute(string triggerElements) : base(Phase.Slow) { this.triggerElements = ElementCounts.Parse(triggerElements); }
public InnateOptionAttribute(string elementText, string description, int group = 0) { Elements = ElementCounts.Parse(elementText); Description = description; Group = group; }
public FastButSlowIfAttribute(string triggerElements) : base(Phase.Fast) { this.triggerElements = ElementCounts.Parse(triggerElements); }
/// <summary> /// Non-executable. Called from dirived class /// </summary> protected InnateOptionAttribute(string elementText, string description) { Elements = ElementCounts.Parse(elementText); Description = description; Group = null; }