コード例 #1
0
ファイル: TestHitStrategy.cs プロジェクト: atom-chen/SimCivil
        public async Task <ImmutableDictionary <BodyPartIndex, Wound> > HitCalculateAsync(
            Immutable <IEntity> attacker,
            Immutable <IEntity> defender,
            Immutable <IEntity> injurant,
            HitMethod hitMethod)
        {
            switch (hitMethod)
            {
            case HitMethod.Fist:
            case HitMethod.Foot:
            {
                if (injurant.Value == null)
                {
                    return(await HitCalculateWithoutInjurantAsync(attacker.Value, defender.Value, hitMethod));
                }

                throw new NotSupportedException();
            }

            case HitMethod.Melee:
            case HitMethod.Magic:
            case HitMethod.Projectile:
            case HitMethod.Temperature:
            case HitMethod.Trap:
                throw new NotSupportedException();

            default:
                throw new ArgumentOutOfRangeException(nameof(hitMethod), hitMethod, null);
            }
        }
コード例 #2
0
        public async Task <AttackResult> Attack(IEntity target, IEntity injurant, HitMethod hitMethod)
        {
            // TODO check distance
            var attackResult = await _hitStrategy.HitCalculateAsync(
                GrainFactory.GetEntity(this).AsImmutable(),
                target.AsImmutable(),
                injurant.AsImmutable(),
                hitMethod);

            return(attackResult.IsEmpty ? AttackResult.Miss() : AttackResult.Hit(attackResult));
        }
コード例 #3
0
ファイル: TestHitStrategy.cs プロジェクト: atom-chen/SimCivil
        private async Task <ImmutableDictionary <BodyPartIndex, Wound> > HitCalculateWithoutInjurantAsync(
            IEntity attacker,
            IEntity defender,
            HitMethod hitMethod)
        {
            UnitState attackerState = await GrainFactory.Get <IUnit>(attacker).GetData();

            UnitState defenderState = await GrainFactory.Get <IUnit>(defender).GetData();

            UnitProperty hitRate;
            UnitProperty dodgeRate = defenderState.DodgeRate;
            UnitProperty attackEfficiency;

            switch (hitMethod)
            {
            case HitMethod.Fist:
                hitRate          = attackerState.UpperAttackHitRate;
                attackEfficiency = attackerState.UpperAttackEfficiency;

                break;

            case HitMethod.Foot:
                hitRate          = attackerState.LowerAttackHitRate;
                attackEfficiency = attackerState.LowerAttackEfficiency;

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(hitMethod), hitMethod, null);
            }

            double hitP = 1 - Math.Exp(hitRate / dodgeRate);

            if (Rand.NextDouble() > hitP)
            {
                return(ImmutableDictionary <BodyPartIndex, Wound> .Empty);
            }

            var attackResult = new Dictionary <BodyPartIndex, Wound>();

            for (var i = 0; i < (int)BodyPartIndex.BodyPartCount; i++)
            {
                if (Options.BodyHitBaseProbability[i] > Rand.NextDouble())
                {
                    attackResult.Add((BodyPartIndex)i, new Wound((uint)attackEfficiency, WoundType.Bruise));
                }
            }

            return(attackResult.ToImmutableDictionary());
        }