示例#1
0
    /// <returns>(city-dead,town-dead,explorer-dead)</returns>
    public async Task DamageAttackers(int damageFromDefenders)
    {
        @event.attackerDamageFromDefenders = damageFromDefenders;
        if (damageFromDefenders == 0)
        {
            return;
        }

        @event.attackerDamageFromBadlands = BadLandsCount;
        int remainingDamageToApply = damageFromDefenders + BadLandsCount;

        // ! must use current Attackers counts, because some have lost their strife so tokens are different than when they started.
        var remaningAttackers = currentAttackers.Clone();

        while (remainingDamageToApply > 0 && remaningAttackers.Any())
        {
            HealthToken attackerToDamage = PickSmartInvaderToDamage(remaningAttackers, remainingDamageToApply);

            // Apply real damage
            var(damageInflicted, _) = await grp.ApplyDamageTo1(remainingDamageToApply, attackerToDamage, true);

            remainingDamageToApply -= damageInflicted;

            // Apply tracking damage
            --remaningAttackers[attackerToDamage];
            var damagedAttacker = attackerToDamage.AddDamage(damageInflicted);
            if (damagedAttacker.RemainingHealth > 0)
            {
                ++remaningAttackers[damagedAttacker];
            }
        }
        @event.endingAttackers = remaningAttackers;
    }
示例#2
0
    public static async Task Downgrade(TargetSpaceCtx ctx, params HealthTokenClass[] groups)
    {
        var         options    = ctx.Tokens.OfAnyType(groups);
        HealthToken oldInvader = (HealthToken)await ctx.Self.Action.Decision(Select.Invader.ToReplace("downgrade", ctx.Space, options));

        if (oldInvader == null)
        {
            return;
        }

        // remove old invader
        ctx.Tokens.Adjust(oldInvader, -1);

        // Add new
        var newInvaderClass = oldInvader.Class == Invader.City ? Invader.Town : Invader.Explorer;

        var newTokenWithoutDamage = ctx.Tokens.GetDefault(newInvaderClass).AddStrife(oldInvader.StrifeCount);
        var newTokenWithDamage    = newTokenWithoutDamage.AddDamage(oldInvader.Damage);

        if (!newTokenWithDamage.IsDestroyed)
        {
            ctx.Tokens.Adjust(newTokenWithDamage, 1);
        }
        else if (newInvaderClass != Invader.Explorer)
        {
            // add the non-damaged token, and destory it.
            ctx.Tokens.Adjust(newTokenWithoutDamage, 1);
            await ctx.Invaders.Destroy(1, newTokenWithoutDamage);
        }
    }
示例#3
0
 static async Task DefaultDestroyDahan(DahanGroupBinding dahan, int count, HealthToken token)
 {
     if (count <= 0)
     {
         return;
     }
     await dahan.Destroy(count, token);
 }
示例#4
0
    public async Task Destroy(int count, HealthToken original)
    {
        if (Frozen)
        {
            return;
        }

        await _tokens.Remove(original, count, _destroyReason);
    }
示例#5
0
    public async Task <int> Destroy(int countToDestroy, HealthToken invaderToDestroy)
    {
        int numToDestroy = Math.Min(countToDestroy, this[invaderToDestroy]);

        for (int i = 0; i < numToDestroy; ++i)
        {
            await DestroyStrategy.OnInvaderDestroyed(Space, invaderToDestroy, false);
        }
        return(numToDestroy);
    }
 public override async Task OnInvaderDestroyed(Space space, HealthToken token, bool fromRavage)
 {
     if (token.Class == Invader.City)
     {
         AddFear(space, 5, false);               // not actually destroying towns/cities
     }
     else
     {
         if (token.Class == Invader.Town)
         {
             AddFear(space, 2, false);                   // not actually destroying towns/cities
         }
         await BringerPushNInvaders(space, 1, token.Class);
     }
 }
示例#7
0
    public void AddingStrife()
    {
        int         expected = 0;
        HealthToken inv      = city;

        void Add(int delta)
        {
            expected += delta;
            inv       = inv.AddStrife(delta);
            inv.StrifeCount.ShouldBe(expected);
        }

        Add(1);
        Add(3);
        Add(-2);
    }
    public virtual async Task OnInvaderDestroyed(Space space, HealthToken token, bool fromRavage)
    {
        var reason = fromRavage ? RemoveReason.DestroyedInBattle : RemoveReason.Destroyed;

        await gs.Tokens[space].Destroy(token, 1);

        // !!! see if we can invoke this through the Token-Publish API instead - so we can make TokenRemovedArgs internal to Island_Tokens class
        await gs.Tokens.TokenRemoved.InvokeAsync(new TokenRemovedArgs( gs, token, reason ) {
            Space = space,
            Count = 1,
        });

        // Don't assert token is destroyed (from damage) because it is possible to destory healthy tokens

        AddFear(space, token.Class.FearGeneratedWhenDestroyed, true);
    }
示例#9
0
    /// <summary> Not Badland-aware </summary>
    /// <returns>(damage inflicted,damagedInvader)</returns>
    public async Task <(int, Token)> ApplyDamageTo1(int availableDamage, HealthToken invaderToken, bool fromRavage = false)       // !! change Token to HealthToken
    {
        var damagedInvader = invaderToken.AddDamage(availableDamage);

        if (!damagedInvader.IsDestroyed)
        {
            Tokens.Adjust(invaderToken, -1);
            Tokens.Adjust(damagedInvader, 1);
        }
        else
        {
            await DestroyStrategy.OnInvaderDestroyed(Space, invaderToken, fromRavage);
        }

        int damageInflicted = invaderToken.RemainingHealth - damagedInvader.RemainingHealth;

        return(damageInflicted, damagedInvader);         // damage inflicted
    }
示例#10
0
    static async Task DamageInvaderHealthByItsOwnStrife(TokenCountDictionary tokens, HealthToken originalInvader)
    {
        var newInvader = originalInvader.AddDamage(originalInvader.StrifeCount);

        if (newInvader == originalInvader)
        {
            return;
        }

        if (newInvader.IsDestroyed)
        {
            await tokens.Destroy(originalInvader, tokens[originalInvader]);
        }
        else
        {
            tokens.Adjust(newInvader, tokens[originalInvader]);
            tokens.Init(originalInvader, 0);
        }
    }
示例#11
0
    public async Task AdjustHealthOf(HealthToken token, int delta, int count)
    {
        count = Math.Min(_tokens[token], count);
        if (count == 0)
        {
            return;
        }

        var newToken = token.AddHealth(delta);

        if (newToken.IsDestroyed)
        {
            await this.Destroy(count, token);
        }
        else
        {
            _tokens.Adjust(token, -count);
            _tokens.Adjust(newToken, count);
        }
    }
示例#12
0
    public async Task <int> ApplyDamageToToken(int damageToDahan, HealthToken token)
    {
        // Destroy what can be destroyed
        if (token.RemainingHealth <= damageToDahan)
        {
            int destroyed = damageToDahan / token.RemainingHealth;
            await Destroy(destroyed, token);

            damageToDahan -= destroyed * token.RemainingHealth;
        }
        // if we can apply partial damage
        if (0 < damageToDahan && 0 < _tokens[token])
        {
            _tokens.Adjust(token, -1);
            _tokens.Adjust(token.AddDamage(damageToDahan), 1);
            damageToDahan = 0;             // damage should be used up
        }

        return(damageToDahan);
    }
示例#13
0
    static async Task ReduceInvaderHealthByItsOwnStrife(TokenCountDictionary tokens, HealthToken originalInvader, int minimum)
    {
        int newHealth  = Math.Min(minimum, originalInvader.FullHealth - originalInvader.StrifeCount);
        var newInvader = new HealthToken(originalInvader.Class, newHealth, originalInvader.Damage, originalInvader.StrifeCount);

        if (newInvader == originalInvader)
        {
            return;
        }

        if (newInvader.IsDestroyed)
        {
            await tokens.Destroy(originalInvader, tokens[originalInvader]);
        }
        else
        {
            tokens.Adjust(newInvader, tokens[originalInvader]);
            tokens.Init(originalInvader, 0);
            // !!! Need something at end of turn to restore health.
        }
    }
示例#14
0
 public Strife_Tests()
 {
     city        = Tokens.City;
     strifedCity = Tokens.City.HavingStrife(1);
 }
示例#15
0
 static int DefaultDamageFromInvader(HealthToken invader) => invader.Class.Attack;
示例#16
0
 static (int, HealthToken) GetDamageFromInvader(TokenCountDictionary tokens, HealthToken invader)
 {
     return(0 < invader.StrifeCount
                     ? (0, tokens.RemoveStrife(invader, 1))
                     : (invader.Class.Attack, invader));
 }