示例#1
0
    public static async Task ActAsync(SelfCtx ctx)
    {
        // Your presence may count as badlands and beast.
        int PresenceAsToken(GameState _, Space space) => ctx.Self.Presence.CountOn(space);

        ctx.GameState.Tokens.RegisterDynamic(PresenceAsToken, TokenType.Badlands, false);
        ctx.GameState.Tokens.RegisterDynamic(PresenceAsToken, TokenType.Beast, false);
        // (Decide per presence, per action) ... Not doing this bit exactly, both are always present, but can't be destroyed.

        // your presence cannot move.
        // !!! not implemented

        // if you have 2 plant 3 animal:
        if (await ctx.YouHave("2 plant,3 animal"))
        {
            // 2 fear and
            ctx.AddFear(2);
            // 2 damamge in one of your lands.
            var space = await ctx.Decision(new Select.Space("2 damage", ctx.Self.Presence.Spaces, Present.Always));

            if (space != null)
            {
                await ctx.Target(space).DamageInvaders(2);
            }
        }
    }
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        if (ctx.Self is not FracturedDaysSplitTheSky fracturedDays)
        {
            return;
        }

        var minor = fracturedDays.DtnwMinor;
        var major = fracturedDays.DtnwMajor;

        PowerCard card = await ctx.Self.SelectPowerCard("Gain Power Card from Days That Never Were", minor.Union(major), CardUse.AddToHand, Present.Always);

        if (card == null)
        {
            return;                      // in case both hands are empty.
        }
        fracturedDays.AddCardToHand(card);
        if (minor.Contains(card))
        {
            minor.Remove(card);
        }
        else
        {
            major.Remove(card);
            await fracturedDays.ForgetPowerCard_UserChoice(Present.Always);
        }
    }
示例#3
0
    static async Task TargetActions(SelfCtx ctx, bool bringCityAndBlight)
    {
        // target spirit gets +2 range with all Powers.
        ctx.GameState.TimePasses_ThisRound.Push(new PowerApiRestorer(ctx.Self).Restore);
        ctx.Self.RangeCalc = new TargetLandApi_ExtendRange(2, ctx.Self.RangeCalc);


        // Target spirit may push 1 of their presence to an adjacent land
        var(src, destination) = await ctx.Presence.PushUpTo1();

        var mover = new TokenPusher_FixedDestination(ctx.Target(src), destination);

        // bringing up to 2 explorers, 2 towns and 2 dahan along with it.
        mover.AddGroup(2, Invader.Explorer);
        mover.AddGroup(2, Invader.Town);
        mover.AddGroup(2, TokenType.Dahan);

        // if you hvae 2 air, 2 water, the moved presence may also bring along up to 2 cities and up to 2 blight.
        if (bringCityAndBlight)
        {
            mover.AddGroup(2, Invader.City);
            mover.AddGroup(2, TokenType.Blight);
        }

        await mover.MoveUpToN();
    }
示例#4
0
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        var options = ctx.Self.Presence.Spaces.SelectMany(p => p.Range(2)).Distinct();
        var to      = await ctx.Decision(new Select.Space("Gather beast to", options, Present.Always));

        await ctx.Target(to).GatherUpTo(1, TokenType.Beast);
    }
示例#5
0
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        var element = ElementOptions.Length == 1 ? ElementOptions[0]
                        : await ctx.Self.SelectElementEx("Gain element", ElementOptions);

        ctx.Self.Elements[element]++;
    }
    static async Task DestroyBoard(SelfCtx ctx, Board board)
    {
        // destroy the board containing target land and everything on that board.
        // All destroyed blight is removed from the game instead of being returned to the blight card.
        await DestroyTokens(ctx, board);

        if (!ctx.Self.Text.StartsWith("Bringer"))            // !!! Maybe Api should have method called "Destroy Space" or "DestroyBoard"

        // destroy presence
        {
            foreach (var spirit in ctx.GameState.Spirits)
            {
                foreach (var p in spirit.Presence.Placed.Where(p => p.Board == board).ToArray())
                {
                    await spirit.Presence.Destroy(p, ctx.GameState, DestoryPresenceCause.SpiritPower);
                }
            }

            // destroy board - spaces
            foreach (var space in board.Spaces.ToArray())
            {
                board.Remove(space);
            }

            ctx.GameState.Island.RemoveBoard(board);
        }
    }
示例#7
0
    public static async Task ActAsync(SelfCtx ctx)
    {
        // Gain a Minor Power.
        // If you have 4 moon, You may gain a Major Power instead of a Minor Power.
        if (await ctx.YouHave("4 moon"))
        {
            await ctx.Draw();
        }
        else
        {
            await ctx.DrawMinor();
        }

        // You may Forget this Power Card to gain 3 Energy.
        var thisCard = ctx.Self.InPlay.SingleOrDefault(x => x.Name == ShapeTheSelfAnew.Name);

        if (thisCard != null &&      // might have already been forgotten when picking a major card.
            await ctx.Self.UserSelectsFirstText("Forget this card for +3 energy.", "Yes, forget it.", "no thanks.")
            )
        {
            // Forget this Power Card
            ctx.Self.Forget(thisCard);

            // gain 3 energy
            ctx.Self.Energy += 3;
        }
    }
示例#8
0
    public async Task <bool> ResolveAction(Phase speed, Present present, SelfCtx ctx)
    {
        // -------------
        // Select Actions to resolve
        // -------------
        IActionFactory[] options = this.GetAvailableActions(speed).ToArray();
        IActionFactory   option  = await this.SelectFactory("Select " + speed + " to resolve:", options, present);

        if (option == null)
        {
            return(false);
        }

        // if user clicked a slow card that was made fast, // slow card won't be in the options
        if (!options.Contains(option))
        {
            // find the fast version of the slow card that was clicked
            option = options.Cast <IActionFactory>()
                     .First(factory => factory == option);
        }

        if (!options.Contains(option))
        {
            throw new Exception("Dude! - You selected something that wasn't an option");
        }

        await TakeAction(option, ctx);

        return(true);
    }
    // ! Can't used normal PlacePresence, because it must be range-1, range 0 not allowed.
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        var options = ctx.Self.Presence.Spaces.First().Adjacent;
        var space   = await ctx.Decision(new Select.Space("Add presence to", options, Present.Always));

        ctx.Presence.PlaceOn(space);
    }
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        List <Space> gatherSpaces = ctx.Self.Presence.Spaces
                                    .Where(p => p.IsCoastal)
                                    .Select(p => p.Adjacent.Single(o => o.IsOcean))
                                    .Distinct()
                                    .ToList();

        while (0 < gatherSpaces.Count)
        {
            Space currentTarget = gatherSpaces[0];
            Space source        = await ctx.Decision(new Select.Space(
                                                         $"Select source of Presence to Gather into {currentTarget}"
                                                         , currentTarget.Adjacent
                                                         .Where(ctx.Self.Presence.Spaces.Contains)
                                                         .ToArray()
                                                         , Present.Always
                                                         ));

            // apply...
            ctx.Presence.Move(source, currentTarget);

            // next
            gatherSpaces.RemoveAt(0);
        }         // while
    }
示例#11
0
    public bool RunAfterGrowthResult => false;     // no dependencies

    public override async Task ActivateAsync(SelfCtx ctx)
    {
        if (ctx.Self is ShiftingMemoryOfAges smoa)
        {
            await smoa.PrepareElement(context);
        }
    }
示例#12
0
    public override async Task <object> GetTargetCtx(string powerName, SelfCtx ctx, TargettingFrom _)
    {
        Spirit target = ctx.GameState.Spirits.Length == 1 ? ctx.Self
                        : await ctx.Decision(new Select.Spirit(powerName, ctx.GameState.Spirits));

        return(ctx.TargetSpirit(target));
    }
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        repeater.BeginAction();
        await Inner.ActivateAsync(ctx);

        repeater.EndAction(ctx.Self);
    }
示例#14
0
 public override async Task ActivateAsync(SelfCtx ctx)
 {
     for (int i = 0; i < count; ++i)
     {
         await ctx.Self.Draw(ctx.GameState);
     }
 }
示例#15
0
 public override async Task ActivateAsync(SelfCtx ctx)
 {
     if (ctx.Self is FracturedDaysSplitTheSky fracturedDays)
     {
         await fracturedDays.GainTime(delta, ctx.GameState);
     }
 }
    private static MultiSpace JoinSpaces(SelfCtx originatorCtx, Space space, Space other)
    {
        var gameState = originatorCtx.GameState;

        var multi = new MultiSpace(space, other);

        MoveAllItemsOnSpace(gameState, other, multi);
        MoveAllItemsOnSpace(gameState, space, multi);

        // Pick Board
        var board = space.Board;         // !!! this is not correct when we start having multiple boards.

        // Disconnect space
        var spaceAdjacents = board.Remove(space);
        var otherAdjacents = board.Remove(other);

        // it has the terrain and land # of both lands.
        board.Add(multi, spaceAdjacents.Union(otherAdjacents).Distinct().ToArray());

        // When this effect expires
        gameState.TimePasses_ThisRound.Push(async(gs) => {
            MoveAllItemsOnSpace(gs, multi, space);
            board.Remove(multi);
            board.Add(other, otherAdjacents);
            board.Add(space, spaceAdjacents);

            // divide pieces as you wish.
            await DistributePresence(space, other, gs);
            await DistributeTokens(originatorCtx, space, other, gs);
        });

        return(multi);
    }
 public StopPresenceDestructionFromBlightOrEvents(SelfCtx ctx)
 {
     this.spirit      = ctx.Self;
     this.oldBehavior = ctx.GameState.Destroy1PresenceFromBlightCard;
     ctx.GameState.Destroy1PresenceFromBlightCard = this.DestroyPresenceDirectlyFromBlight;
     ctx.GameState.TimePasses_ThisRound.Push(Restore);
 }
示例#18
0
    static async Task PlayCardByPayingHalfCostOrForgetting(PowerCard card, SelfCtx ctx)
    {
        // target spirit may now play the major power they keep by:
        //    * paying half its cost (round up) OR
        int cost = (card.Cost + card.Cost % 2) / 2;
        var payingHalfCostOption = new SelfAction(
            $"paying {cost}",
            ctx => ctx.Self.PlayCard(card, cost)
            ).Matches(x => cost <= x.Self.Energy);

        //    * forgetting it at the end of turn.
        var forgettingCardOption = new SelfAction(
            $"forgetting at end of turn",
            ctx => {
            ctx.Self.PlayCard(card, 0);
            ctx.GameState.TimePasses_ThisRound.Push((gs) => {
                ctx.Self.Forget(card); return(Task.CompletedTask);                          // this must run befire cards are moved to discard, or it will be forgotten for Shifting Memories
            });
        }
            );

        // !!! It gains all elmemental thresholds.  - implement!

        await ctx.SelectAction_Optional($"Play {card.Name} now by:",
                                        payingHalfCostOption,
                                        forgettingCardOption
                                        );
    }
示例#19
0
    public bool RunAfterGrowthResult => true;     // uses growth-earned energy;

    public override async Task ActivateAsync(SelfCtx ctx)
    {
        if (2 <= ctx.Self.Energy && await ctx.Self.UserSelectsFirstText("Draw Power Card?", "Yes, pay 2 energy", "No, thank you."))
        {
            ctx.Self.Energy -= 2;
            await ctx.Draw();
        }
    }
示例#20
0
 protected override PowerCard[] GetCardOptions(SelfCtx ctx)
 {
     return(base.GetCardOptions(ctx)
            .GroupBy(pc => pc.Cost)
            .OrderBy(grp => grp.Key)
            .First()          // group with lowest cost
            .ToArray());      // all cards in group
 }
示例#21
0
    public override Task ActivateAsync(SelfCtx ctx)
    {
        var oceanSpaces = ctx.GameState.Island.Boards
                          .Select(b => b.Spaces.Single(s => s.IsOcean))
                          .ToArray();

        return(ctx.Presence.Place(oceanSpaces));
    }
    public static async Task AssignNewElementToTrack(SelfCtx ctx, Track track)
    {
        var el = await ctx.Self.SelectElementEx("Select permanent element for this slot.", ElementList.AllElements);

        track.Elements = new Element[] { el };
        ctx.Self.Elements[el]++;
        track.Icon.ContentImg = el.GetTokenImg();
    }
 public PayEnergyToTakeFromCard(SelfCtx ctx, int cost)
 {
     this.spirit      = ctx.Self;
     this.cost        = cost;
     this.oldBehavior = ctx.GameState.TakeFromBlightSouce;
     ctx.GameState.TakeFromBlightSouce = this.AddBlight;
     ctx.GameState.TimePasses_ThisRound.Push(Restore);
 }
示例#24
0
    static async Task Replace1PresenceWith1Disease(SelfCtx ctx)
    {
        var space = await ctx.Presence.SelectDeployed("Replace Presence with 1 disease");

        await ctx.Presence.RemoveFrom(space);

        await ctx.Target(space).Disease.Add(1);
    }
示例#25
0
    public override Task ActivateAsync(SelfCtx ctx)
    {
        var spirit = ctx.Self;

        spirit.Hand.AddRange(spirit.DiscardPile);
        spirit.DiscardPile.Clear();
        return(Task.CompletedTask);
    }
    public override async Task ActivateAsync(SelfCtx ctx)
    {
        var gameState = ctx.GameState;
        var options   = gameState.Island.AllSpaces.Where(space => gameState.Tokens[space].Beasts.Any);
        var space     = await ctx.Decision(new Select.Space("Add presence to", options, Present.Always));

        ctx.Presence.PlaceOn(space);
    }
示例#27
0
    public bool RunAfterGrowthResult => true;     // might receive additional presence

    public override async Task ActivateAsync(SelfCtx ctx)
    {
        var src = await ctx.Decision(Select.DeployedPresence.All("Move presence from:", ctx.Self, Present.Always));

        var dstOptions = src.Range(Range).Where(s => !s.IsOcean);
        var dst        = await ctx.Decision(Select.Space.ForAdjacent("Move preseence to:", src, Select.AdjacentDirection.Outgoing, dstOptions, Present.Always));

        ctx.Presence.Move(src, dst);
    }
 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 override Task ActivateAsync(SelfCtx ctx)
 {
     if (!ran)
     {
         ctx.Self.Energy++;
         ran = true;
     }
     return(Task.CompletedTask);
 }
示例#30
0
    static public async Task Option1(SelfCtx ctx)
    {
        var          deck    = ctx.GameState.InvaderDeck.unrevealedCards;
        IInvaderCard topCard = deck[0];
        await ctx.Self.SelectText(topCard.Text, new string[] { "Shuffle with next top card." }, Present.Always);

        deck.RemoveAt(0);
        InsertIntoTop2(deck, topCard);
    }