コード例 #1
0
ファイル: StormSwath.cs プロジェクト: rettigcd/spiritisland
 static async Task <Space> SelectLandAdjacentToBoth(TargetSpaceCtx ctx, Space origin)
 {
     return(await ctx.Decision(new Select.Space(
                                   "Select land for 1 damge to each invader",
                                   ctx.Adjacent
                                   .Intersect(ctx.Target(origin).Adjacent)
                                   .Where(s => ctx.Target(s).IsInPlay(default)),
コード例 #2
0
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // add 2 disease
        var disease = ctx.Disease;
        await disease.Add(2);

        // for each disease in target land, defend 1 in target and all adjacent lands
        ctx.Defend(disease.Count);
        foreach (var adjacent in ctx.Adjacent)
        {
            ctx.Target(adjacent).Defend(disease.Count);
        }

        // if you have 2 earthn 4 animal:
        if (await ctx.YouHave("2 earth,4 animal"))
        {
            // 2 fear.
            ctx.AddFear(2);
            // For each disease in target land, do 1 damage in target or adjacent land
            int damage = disease.Count;
            var space  = await ctx.Decision(new Select.Space($"Select space to apply {damage} damage", ctx.Range(1), Present.Always));             // can we wrap this and make it easier to call?

            await ctx.Target(space).DamageInvaders(damage);
        }
    }
コード例 #3
0
ファイル: StormSwath.cs プロジェクト: rettigcd/spiritisland
    public static async Task ActAsync(TargetSpaceCtx ctx)
    {
        // 2 fear.
        ctx.AddFear(2);

        // in both origin land and target land: 1 damage to each invader.
        var origin = await FindOriginLand_SS(ctx, 1);

        await ctx.DamageEachInvader(1);

        await ctx.Target(origin).DamageEachInvader(1);

        // if you have 2 fire 3 air 2 water:
        if (await ctx.YouHave("2 fire,3 air,2 water"))
        {
            // +1 fear.
            ctx.AddFear(1);

            // This Power has +1 range. (see attribute)

            // in a land adjacent to both origin and target
            Space thirdSpace = await SelectLandAdjacentToBoth(ctx, origin);

            // 1 damage to each invader.
            await ctx.Target(thirdSpace).DamageEachInvader(1);

            // in lands where you did Damage, Destroy 1 town
            foreach (var space in new[] { ctx.Space, origin, thirdSpace }.Distinct())
            {
                await ctx.Target(space).Invaders.Destroy(1, Invader.Town);
            }
        }
    }
コード例 #4
0
    static async Task RemoveBlightFromLandOrAdjacent(TargetSpaceCtx ctx)
    {
        // remove 1 blight from target or adjacent land
        var blightedLands = ctx.Space.Range(1).Where(s => ctx.Target(s).HasBlight).ToArray();
        var unblightLand  = await ctx.Decision(new Select.Space("Remove 1 blight from", blightedLands, Present.Always));

        if (unblightLand != null)
        {
            await ctx.Target(unblightLand).RemoveBlight();
        }
    }
コード例 #5
0
    public static async Task ActAsync(TargetSpaceCtx ctx)
    {
        // target land and a land adjacent to it become a single land for this turn.
        var other = (await ctx.SelectAdjacentLand($"Join {ctx.Space.Label} to.")).Space;

        MultiSpace multi = JoinSpaces(ctx, ctx.Space, other);

        // if you have 4 air:
        if (await ctx.YouHave("4 air"))
        {
            // isolate the joined land.
            var joinedCtx = ctx.Target(multi);
            joinedCtx.Isolate();
            // If it has invaders,
            if (joinedCtx.HasInvaders)
            {
                // 2 fear,
                joinedCtx.AddFear(2);
                // and Remove up to 2 invaders
                await joinedCtx.Invaders.Remove();

                await joinedCtx.Invaders.Remove();
            }
        }
    }
コード例 #6
0
    static public async Task ActAsymc(TargetSpaceCtx ctx)
    {
        // 1 fear if invaders are present.
        if (ctx.HasInvaders)
        {
            ctx.AddFear(1);
        }

        var beastSources = ctx.Adjacent.Where(s => ctx.Target(s).Beasts.Any).ToArray();

        // If you can gather 1 beast,
        if (beastSources.Length > 0)
        {
            // do so,
            await ctx.Gather(1, TokenType.Beast);

            // then push 1 explorer.
            await ctx.Push(1, Invader.Explorer);
        }
        else
        {
            // othersie, add 1 beast
            await ctx.Beasts.Add(1);
        }
    }
コード例 #7
0
    static async Task DamageLandWithinRange(TargetSpaceCtx ctx, int range)
    {
        // !!! could make this a single SpaceToken step.
        var space = await ctx.Decision(new Select.Space("Select land for 1 Damage", ctx.Range(range), Present.Always));

        await ctx.Target(space).DamageInvaders(1);
    }
コード例 #8
0
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // destroy all explorers.
        await ctx.Invaders.Destroy(int.MaxValue, Invader.Explorer);

        // Add 1 wilds.
        await ctx.Wilds.Add(1);

        // Add 1 wilds in the originating Sands.
        // !! won't find original if this was picked using a range-extender - would need to capture that info during the targetting process
        var originatingOptions = ctx.Range(1)
                                 .Where(a => ctx.Self.Presence.Spaces.Contains(a) && a.IsSand)
                                 .ToArray();
        var originalCtx = await ctx.SelectSpace("Select origination space", originatingOptions, Present.AutoSelectSingle);

        if (originalCtx != null)
        {
            await originalCtx.Wilds.Add(1);
        }

        // 1 damage per wilds in / adjacent to target land.
        int wildsDamage = ctx.Space.Range(1).Sum(s => ctx.Target(s).Wilds.Count);

        // if you have 2 fire, 3 plant: // +1 damage per wilds in / adjacent to target land.
        if (await ctx.YouHave("2 fire,3 plant"))
        {
            wildsDamage += wildsDamage;
        }

        await ctx.DamageInvaders(wildsDamage);
    }
コード例 #9
0
    static async Task ActAsync(TargetSpaceCtx ctx, int damage)
    {
        // Destroy 1 dahan
        await ctx.DestroyDahan(1);

        // 4 plant  split this power's damage however desired between target land and another 1 of your lands
        int damageToTarget = ctx.Self.Elements[Element.Plant] < 4 && ctx.Self.Presence.Spaces.Count() > 1
                        ? damage
                        : await ctx.Self.SelectNumber("Damage to apply to " + ctx.Space.Label, damage);

        await ctx.DamageInvaders(damage);

        int remainingDamage = damage - damageToTarget;

        if (remainingDamage > 0)
        {
            var secondaryTarget = await ctx.Decision(new Select.Space(
                                                         $"Apply {remainingDamage} reamaining damage"
                                                         , ctx.Self.Presence.Spaces
                                                         , Present.Always
                                                         ));

            await ctx.Target(secondaryTarget).DamageInvaders(remainingDamage);
        }
    }
コード例 #10
0
ファイル: DahanHelper.cs プロジェクト: rettigcd/spiritisland
    public static async Task BoostDahanHealthForRound(TargetSpaceCtx ctx, int boost)
    {
        // Boost ALL Dahan in land
        await ctx.Dahan.AdjustHealthOfAll(boost);

        // Move(,) triggers 'Add' and 'Remove' events also

        // This covers simple-add AND move-in
        ctx.GameState.Tokens.TokenAdded.ForRound.Add(async args => {
            if (args.Token.Class == TokenType.Dahan && args.Space == ctx.Space)
            {
                await ctx.Dahan.AdjustHealthOf((HealthToken)args.Token, boost, args.Count);
            }
        });


        // Move out
        ctx.GameState.Tokens.TokenMoved.ForRound.Add(async args => {
            // if removing dahan from this space
            if (args.Token.Class == TokenType.Dahan && args.RemovedFrom == ctx.Space)
            {
                // In the destination space
                await ctx.Target(args.AddedTo)
                // reduce the health by boost amount
                .Dahan.AdjustHealthOf((HealthToken)args.Token, -boost, args.Count);
            }
        });

        // Add handler to restore ALL at end of round.
        ctx.GameState.TimePasses_ThisRound.Push(async gs => {
            // Ensure the dahan are healed before we restore their health.
            ctx.GameState.Healer.HealSpace(ctx.Tokens);
            await ctx.Dahan.AdjustHealthOfAll(-boost);
        });
    }
コード例 #11
0
    public static async Task ActAsync(TargetSpaceCtx ctx)
    {
        // 6 damage.
        await ctx.DamageInvaders(6);

        // Add 2 badlands/strife
        var addBadlandsOrStrife = Cmd.Pick1("Add badlands/strife", Cmd.AddBadlands(1), Cmd.AddStrife(1));
        await addBadlandsOrStrife.Repeat(2).Execute(ctx);

        // and 1 blight.
        await ctx.AddBlight(1);

        await TakeActionInUpToNLands(ctx
                                     // In up to 3 adjacent lands with blight
                                     , 3, ctx.Adjacent.Where(s => ctx.Target(s).HasBlight)
                                     // add 1 badland/strife.
                                     , addBadlandsOrStrife
                                     );

        // if you have 3 fire 3 water:
        if (await ctx.YouHave("3 fire,3 water"))
        {
            await TakeActionInUpToNLands(ctx
                                         // in up to 3 adjacent lands,
                                         , 3, ctx.Adjacent
                                         // 1 damage to each invader.
                                         , new SpaceAction("1 damage to each invader", ctx => ctx.DamageEachInvader(1))
                                         );
        }
    }
コード例 #12
0
ファイル: FireAndFlood.cs プロジェクト: rettigcd/spiritisland
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // == Pick 2nd target - range 2 from same SS ==
        var spiritSS = ctx.Self.Presence.SacredSites.ToArray();
        var possibleSacredSiteSourcesForThisSpace = ctx.Space.Range(1).Where(s => spiritSS.Contains(s)).ToArray();

        // IEnumerable<Space> secondTargetOptions = ctx.Presence.GetValidDestinationOptionsFromPresence( 2, Target.Any, possibleSacredSiteSourcesForThisSpace );
        IEnumerable <Space> secondTargetOptions = ctx.Self.RangeCalc.GetTargetOptionsFromKnownSource(ctx.Self, ctx.GameState, TargettingFrom.PowerCard, possibleSacredSiteSourcesForThisSpace, new TargetCriteria(2));

        var secondTarget = await ctx.Decision(new Select.Space("Select space to target.", secondTargetOptions, Present.Always));


        // 4 damage in each target land  (range must be measured from same SS)
        await ctx.DamageInvaders(4);

        await ctx.Target(secondTarget).DamageInvaders(4);

        // if 3 fire
        if (await ctx.YouHave("3 fire"))
        {
            await Apply3DamageInOneOfThese(ctx, secondTarget, "fire");
        }

        // if 3 water
        if (await ctx.YouHave("3 water"))
        {
            await Apply3DamageInOneOfThese(ctx, secondTarget, "water");
        }
    }
コード例 #13
0
 static void Given_NoSuroundingTowns(TargetSpaceCtx spaceCtx)
 {
     // Simplifies power card because it has a Gather-Towns we don't want to deal with.
     foreach (var adj in spaceCtx.Adjacent)
     {
         spaceCtx.Target(adj).Tokens.InitDefault(Invader.Town, 0);
     }
 }
コード例 #14
0
 static void Given_NoSuroundingDahan(TargetSpaceCtx spaceCtx)
 {
     // Simplifies power card because it has a Gather-dahan we don't want to deal with.
     foreach (var adj in spaceCtx.Adjacent)
     {
         var dahan = spaceCtx.Target(adj).Tokens.Dahan;
         dahan.Init(0);
     }
 }
コード例 #15
0
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // For each adjacent land with your presence, 1 Damage to a different Invader.
        int count = ctx.Space.Adjacent.Count(s => ctx.Target(s).Presence.IsHere);
        await ctx.Apply1DamageToDifferentInvaders(count);

        // Push 2 dahan
        await ctx.PushDahan(2);
    }
コード例 #16
0
        static Task DamageLandFromBlight(TargetSpaceCtx ctx)
        {
            // 2 damage per blight in target land
            int damage = ctx.BlightOnSpace * 2
                         // +1 damage per blight in adjacent lands
                         + ctx.Adjacent.Sum(x => ctx.Target(x).BlightOnSpace);

            return(ctx.DamageInvaders(damage));
        }
コード例 #17
0
    // A Real Flair for Discord
    // After one of your Powers adds strife in a land, you may pay 1 Energy to add 1 strife within Range-1 of that land."
    public override async Task AddStrife(TargetSpaceCtx ctx, Token invader)
    {
        await base.AddStrife(ctx, invader);

        if (Energy == 0)
        {
            return;
        }
        var nearbyInvaders = ctx.Space.Range(1)
                             .SelectMany(s => ctx.Target(s).Tokens.Invaders().Select(t => new SpaceToken(s, t)))
                             .ToArray();
        var invader2 = await Action.Decision(new Select.TokenFromManySpaces("Add additional strife for 1 energy", nearbyInvaders, Present.Done));

        if (invader2 == null)
        {
            return;
        }
        Energy--;
        await base.AddStrife(ctx.Target(invader2.Space), invader2.Token);
    }
コード例 #18
0
    static async Task DistributeDamageToLands(TargetSpaceCtx ctx, List <Space> newDamageLands, int additionalDamage)
    {
        Space[] targetLandOptions;
        while (additionalDamage > 0 &&
               (targetLandOptions = newDamageLands.Where(s => ctx.Target(s).HasInvaders).ToArray()).Length > 0
               )
        {
            var newLand = await ctx.Decision(new Select.Space($"Apply up to {additionalDamage} vengeanance damage in:", targetLandOptions, Present.Always));

            if (newLand == null)
            {
                break;
            }
            int damage = await ctx.Self.SelectNumber("How many damage to apply?", additionalDamage, 0);

            await ctx.Target(newLand).DamageInvaders(damage);

            additionalDamage -= damage;
        }
    }
コード例 #19
0
ファイル: FireStorm.cs プロジェクト: rettigcd/spiritisland
    static public async Task Option4(TargetSpaceCtx ctx)
    {
        // In a land with blight and presence  (Select a space, not necessarily the one you targetted with power (I guess...)
        var spacesWithPresenceAndBlight = ctx.Self.Presence.Spaces
                                          .Where(s => ctx.Target(s).HasBlight);
        var space = await ctx.Decision(new Select.Space($"Push all dahan, destroy invaders and beast, 1 blight", spacesWithPresenceAndBlight, Present.Always));

        var spaceCtx = ctx.Target(space);

        // Push all Dahan
        await spaceCtx.PushDahan(int.MaxValue);

        // Destroy all invaders and Beasts
        var beasts = spaceCtx.Beasts;
        await beasts.Destroy(beasts.Count);

        await spaceCtx.Invaders.DestroyAny(int.MaxValue, Invader.Explorer, Invader.Town, Invader.City);

        // Add 1 blight
        await ctx.AddBlight(1);
    }
コード例 #20
0
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // 2 fear
        ctx.AddFear(2);

        // +8 damage
        await ctx.DamageInvaders(8);

        // destroy 2 dahan
        await ctx.DestroyDahan(2);

        if (await ctx.YouHave("3 water,2 earth"))
        {
            var otherCoastalsOnSameBoard = ctx.Space.Board
                                           .Spaces.Where(s => s != ctx.Space && ctx.Target(s).IsCoastal)
                                           .ToArray();

            foreach (var otherCoast in otherCoastalsOnSameBoard)
            {
                await DamageOtherCoast(ctx.Target(otherCoast));
            }
        }
    }
コード例 #21
0
    static public async Task ActionAsync(TargetSpaceCtx ctx)
    {
        // Push up to 2 dahan.
        var destinationSpaces = await ctx.PushUpToNDahan(2);

        // if pushed dahan into town or city
        bool pushedToBuildingSpace = destinationSpaces
                                     .Any(neighbor => ctx.Target(neighbor).Tokens.HasAny(Invader.Town, Invader.City));

        if (pushedToBuildingSpace)
        {
            ctx.AddFear(1);
        }
    }
コード例 #22
0
ファイル: FireStorm.cs プロジェクト: rettigcd/spiritisland
    private static async Task DoFireDamageToMultipleTargets(TargetSpaceCtx ctx, int fireDamage)
    {
        await ctx.DamageInvaders(1);           // because they targetted a land, only select invaders from that land.

        --fireDamage;

        var spacesWithPresenceAndBlight = ctx.Self.Presence.Spaces
                                          .Select(s => ctx.Target(s))
                                          .Where(x => x.HasBlight)
                                          .ToArray();

        // ! don't .ToArray() this because we want it to re-execute each time.
        var invaderTokens = spacesWithPresenceAndBlight
                            .SelectMany(ctx => ctx.Tokens.Invaders().Select(t => new SpaceToken(ctx.Space, t)));

        while (fireDamage > 0 && invaderTokens.Any())
        {
            SpaceToken token = await ctx.Decision(new Select.TokenFromManySpaces($"Apply fire damage. ({fireDamage} remaining)", invaderTokens, Present.Always));

            await ctx.Target(token.Space).Invaders.ApplyDamageTo1(1, (HealthToken)token.Token);

            --fireDamage;
        }
    }
コード例 #23
0
    public static async Task ActAsync(TargetSpaceCtx ctx)
    {
        // 2 damage per dahan in target land
        await ctx.DamageInvaders(2 *ctx.Dahan.Count);

        if (await ctx.YouHave("3 sun,2 animal"))
        {
            // you may push up to 2 dahan.
            var pushedToLands = await ctx.PushUpToNDahan(2);

            // 2 damage per dahan
            foreach (var neighbor in pushedToLands.Distinct())
            {
                await DahanDeal2DamageEach(ctx.Target(neighbor));
            }
        }
    }
コード例 #24
0
    static public async Task ActionAsync(TargetSpaceCtx ctx)
    {
        // 3 fear
        ctx.AddFear(3);

        // 5 damage
        await ctx.DamageInvaders(5);

        if (await ctx.YouHave("3 fire,3 air"))
        {
            // destroy 1 town in each adjacent land
            foreach (var neighbor in ctx.Space.Adjacent)
            {
                await ctx.Target(neighbor).Invaders.Destroy(1, Invader.Town);
            }
        }
    }
コード例 #25
0
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // if you have 2 sun, 2 air, 2 animal, // First Gather up to 3 dahan
        if (await ctx.YouHave("2 sun,2 air,2 animal"))
        {
            await ctx.GatherUpToNDahan(3);
        }

        // move up to 5 dahan from target land to any land.
        Space destination = await ctx.MoveTokensOut(max : 5, TokenType.Dahan, range : 100);

        // defend 5 in that land
        if (destination != null)
        {
            ctx.Target(destination).Defend(5);
        }
    }
コード例 #26
0
    static public async Task ActAsync(TargetSpaceCtx ctx)
    {
        // 1 fear.
        ctx.AddFear(1);
        // 1 damage.
        await ctx.DamageInvaders(1);

        // You may pay 1 Energy to deal 1 Damage in an adjacent land.
        if (1 <= ctx.Self.Energy && await ctx.Self.UserSelectsFirstText("Pay 1 energy to deal 1 Damage in an adjacent land?", "Yes, pay 1 energy for 1 damage", "No, thank you"))
        {
            ctx.Self.Energy--;

            var adjInvaders = ctx.Adjacent.SelectMany(s => ctx.GameState.Tokens[s].Invaders().Select(t => new SpaceToken(s, t))).ToArray();
            var adjInvader  = await ctx.Decision(new Select.TokenFromManySpaces("Select invader for 1 damage", adjInvaders, Present.Always));

            await ctx.Target(adjInvader.Space).Invaders.ApplyDamageTo1(1, (HealthToken)adjInvader.Token);
        }
    }
コード例 #27
0
    static public async Task Option3Async(TargetSpaceCtx ctx)
    {
        await Option2Async(ctx);

        if (7 <= ctx.Self.Energy && await ctx.Self.UserSelectsFirstText("Activate Teir 3?", "Pay 7 to cause damage from presence", "skip"))
        {
            // -7 Energy.
            ctx.Self.Energy -= 7;
            // In every land in the game: X Damage, where X is the number of presence you have in and adjacent to that land.
            var invaderLands = ctx.AllSpaces.Where(space => ctx.Target(space).HasInvaders).ToArray();
            foreach (var land in invaderLands)
            {
                var landsCreatingDamage = new HashSet <Space>(land.Range(1));
                int damage = ctx.Self.Presence.Placed.Count(landsCreatingDamage.Contains);
                await ctx.DamageInvaders(damage);
            }
        }
    }
コード例 #28
0
    public static Task ActAsync(TargetSpaceCtx ctx)
    {
        // defend 2 in target land and all adjacent lands.
        int defense = 2;         // Defense 2

        // For every presence on your Deep Slumber track, Defend 1 in target land and all adjacent lands.
        if (ctx.Self.Presence is SerpentPresence sp)              // don't crash if card was gifted to someone else
        {
            defense += sp.AbsorbedPresences.Count;
        }

        ctx.Defend(defense);
        foreach (var adj in ctx.Adjacent)
        {
            ctx.Target(adj).Defend(defense);
        }

        return(Task.CompletedTask);
    }
コード例 #29
0
    public static async Task ActAsync(TargetSpaceCtx ctx)
    {
        // 2 fear. 2 damage.
        ctx.AddFear(2);
        await ctx.DamageInvaders(2);

        // if no beasts are present, add beast.
        if (!ctx.Beasts.Any)
        {
            await ctx.Beasts.Add(1);
        }
        else
        {
            // otherwise, +2 Damage,
            await ctx.DamageInvaders(2);

            // and Push up to 1 beast.
            await ctx.PushUpTo(1, TokenType.Beast);
        }

        if (await ctx.YouHave("2 fire,3 animal"))
        {
            // 1 fear and
            ctx.AddFear(1);
            // destroy 1 explorer/town in an adjacent land with beast
            var tokens = ctx.Adjacent
                         .Select(ctx.Target)
                         .Where(x => x.Beasts.Any)
                         .SelectMany(x => x.Tokens.OfType(Invader.Explorer)
                                     .Select(t => new SpaceToken(x.Space, t))
                                     )
                         .ToArray();
            var st = await ctx.Decision(new Select.TokenFromManySpaces("Destroy Explorer", tokens, Present.Always));

            if (st != null)
            {
                await ctx.Target(st.Space).Invaders.Destroy(1, (HealthToken)st.Token);
            }
        }
    }
コード例 #30
0
    static public async Task ActionAsync(TargetSpaceCtx ctx)
    {
        // for each dahan in target land, 1 damage and defend 2

        // -- damage --
        await ctx.DamageInvaders(ctx.Dahan.Count);

        // if you have 2 sun, 2 earth, 2 plant
        if (await ctx.YouHave("2 sun, 2 earth, 2 plant"))
        {
            // you may push up to 2 dahan
            Space[] dest = await ctx.PushUpToNDahan(2);

            // defend pushed
            foreach (var d in dest)
            {
                ctx.Target(d).Defend(2);
            }
        }

        // -- defend remaining --
        ctx.Defend(ctx.Dahan.Count * 2);
    }