Ejemplo n.º 1
0
 private static IBattleEffect WithLogging(Func <BattleCharacter, string> description, IBattleEffect fx)
 {
     return(new WithLogging(BattleLog.Instance, description, fx));
 }
Ejemplo n.º 2
0
 /// <summary>
 /// 接受战斗效果
 /// </summary>
 /// <param name="ef"></param>
 public virtual void TakeBattleEffect(IBattleEffect ef)
 {
     this.bfList.Add(ef);
     ef.Execute(this);
 }
Ejemplo n.º 3
0
 public WithLogging(ILog log, Func <BattleCharacter, string> description, IBattleEffect effect)
 {
     _log         = log;
     _description = description;
     _effect      = effect;
 }
Ejemplo n.º 4
0
        public AdventureStatus ProcessPlayer(long playerid)
        {
            IBattleEntity attacker;
            IBattleEntity target;

            lock (actors) {
                if (actors.Count < 2)
                {
                    return(AdventureStatus.Exploration);
                }

                foreach (IBattleEntity entity in actors)
                {
                    entity.Refresh();
                }


                attacker = actors[actor];
                actor    = (actor + 1) % actors.Count;
                target   = actors[actor];
            }

            RPGMessageBuilder message = messages?.Create();

            foreach (IBattleEffect effect in attacker.Effects.Where(t => t is IBattleEffect && ((IBattleEffect)t).Type == BattleEffectType.Persistent).Cast <IBattleEffect>())
            {
                EffectResult result = effect.ProcessEffect(attacker, target);
                if (result.Type == EffectResultType.CancelAttack)
                {
                    return(AdventureStatus.MonsterBattle);
                }

                AdventureStatus status = ProcessEffectResult(result, attacker, target, message);
                if (status != AdventureStatus.MonsterBattle)
                {
                    message?.Send();
                    attacker.CleanUp();
                    target.CleanUp();
                    return(status);
                }
            }

            MonsterSkill skill = (attacker as MonsterBattleEntity)?.DetermineSkill();

            if (skill != null)
            {
                skill.Process(attacker, target);
                AdventureStatus status = CheckStatus(attacker, target, message);
                message?.Send();
                return(status);
            }

            float           hitprobability = MathCore.Sigmoid(attacker.Dexterity - target.Dexterity, 1.1f, 0.7f);
            float           dice           = RNG.XORShift64.NextFloat();
            AdventureStatus returnstatus   = AdventureStatus.MonsterBattle;

            if (dice < hitprobability)
            {
                bool hit = true;
                foreach (IBattleEffect effect in target.Effects.Where(t => (t as IBattleEffect)?.Type == BattleEffectType.Defense).Cast <IBattleEffect>())
                {
                    if (effect.ProcessEffect(attacker, target).Type == EffectResultType.CancelAttack)
                    {
                        hit = false;
                        break;
                    }
                }

                if (hit)
                {
                    bool damagecritical = attacker.WeaponOptimum > 0 && RNG.XORShift64.NextFloat() < (float)attacker.Luck / attacker.WeaponOptimum;
                    bool armorcritical  = target.ArmorOptimum > 0 && RNG.XORShift64.NextFloat() < (float)target.Luck / target.ArmorOptimum;

                    int power = damagecritical ? attacker.Power * 2 : attacker.Power;
                    int armor = armorcritical ? target.Defense * 2 : target.Defense;

                    int damage = (int)Math.Max(0, (power - armor) * (0.5f + 0.5f * dice / hitprobability));
                    if (damage <= 0)
                    {
                        message?.BattleActor(target);
                        if (armorcritical)
                        {
                            message?.Bold();
                        }

                        message?.Text(" deflects ").Reset().BattleActor(attacker).Text("'s attack.");
                        target.Hit(0);
                    }
                    else
                    {
                        message?.BattleActor(attacker);
                        if (damagecritical)
                        {
                            message?.Bold();
                        }

                        message?.Text(armorcritical ? " clashes with " : " hits ");
                        message?.Reset().BattleActor(target).Text(" for ").Damage(damage).Text(".");

                        IBattleEffect effect = attacker.Effects.FirstOrDefault(e => e is ShittyWeaponEffect) as IBattleEffect;
                        ProcessEffectResult(effect?.ProcessEffect(attacker, target), attacker, target, message);

                        target.Hit(damage);
                        returnstatus = CheckStatus(attacker, target, message);
                        if (returnstatus == AdventureStatus.MonsterBattle)
                        {
                            if (target is PlayerBattleEntity)
                            {
                                message?.Text(" ").BattleActor(target).Text(" has ").Health(target.HP).Text(" left.");
                            }
                        }
                        else
                        {
                            attacker.CleanUp();
                            target.CleanUp();
                        }
                    }
                }
            }
            else
            {
                message?.BattleActor(attacker).Text(" attacks ").BattleActor(target).Text(" but ").Color(AdventureColors.Miss).Text("misses").Reset().Text(".");
            }

            message?.Send();
            return(returnstatus);
        }