예제 #1
0
        public bool ApplyAttackPolicy
        (
            LivingEntity caster,//hero, enemy, ally
            Tiles.Abstract.IObstacle target,
            SpellSource spellSource,
            Action <Policy> BeforeApply = null,
            Action <Policy> AfterApply  = null,
            bool looped = false
        )
        {
            if (!looped)
            {
                applyingBulk = false;
            }
            var spell = spellSource.CreateSpell(caster) as IProjectileSpell;

            if (spell != null)
            {
                if (!caster.IsInProjectileReach(spell, target.Position))
                {
                    this.gm.SoundManager.PlayBeepSound();
                    this.gm.AppendAction(new GameEvent()
                    {
                        Info = "Target out of range"
                    });
                    return(false);
                }
            }

            if (!looped && !gm.UtylizeSpellSource(caster, spellSource, spell))
            {
                return(false);
            }

            var policy = Container.GetInstance <ProjectileCastPolicy>();

            policy.Target             = target as Dungeons.Tiles.Tile;
            policy.ProjectilesFactory = Container.GetInstance <IProjectilesFactory>();
            policy.Projectile         = spellSource.CreateSpell(caster) as IProjectileSpell;
            if (BeforeApply != null)
            {
                BeforeApply(policy);
            }

            policy.OnApplied += (s, e) =>
            {
                var le = policy.TargetDestroyable is LivingEntity;
                if (!le)//le is handled specially
                {
                    this.gm.LootManager.TryAddForLootSource(policy.Target as ILootSource);
                    //dest.Destroyed = true;
                }


                if (looped)
                {
                    return;
                }
                if (!applyingBulk)
                {
                    var repeatOK = caster.IsStatRandomlyTrue(EntityStatKind.ChanceToRepeatElementalProjectileAttack);
                    if (repeatOK)
                    {
                        ApplyAttackPolicy(caster, target, spellSource, BeforeApply, AfterApply, true);
                    }
                }

                if (caster is Hero)
                {
                    OnHeroPolicyApplied(policy);
                }

                if (AfterApply != null)
                {
                    AfterApply(policy);
                }
            };

            policy.Apply(caster);

            var bulkOK = false;

            if (target is Enemy en && spellSource is WeaponSpellSource)
            {
                bulkOK = HandleBulk(en, EntityStatKind.ChanceToElementalProjectileBulkAttack, (Enemy en1) => {
                    applyingBulk = true;
                    ApplyAttackPolicy(caster, en1, spellSource, BeforeApply, AfterApply, true);
                });
            }

            return(true);
        }
예제 #2
0
        public ApplyAttackPolicyResult ApplyAttackPolicy
        (
            LivingEntity caster,//hero, enemy, ally
            Tiles.Abstract.IObstacle target,
            SpellSource spellSource,
            Action <Policy> BeforeApply = null,
            Action <Policy> AfterApply  = null,
            bool looped = false
        )
        {
            if (!looped)
            {
                applyingBulk = false;
            }
            var spell = spellSource.CreateSpell(caster) as IProjectileSpell;

            if (spell != null)
            {
                if (!caster.IsInProjectileReach(spell, target.Position))
                {
                    this.gm.SoundManager.PlayBeepSound();
                    this.gm.AppendAction(new GameEvent()
                    {
                        Info = "Target out of range"
                    });
                    return(ApplyAttackPolicyResult.OutOfRange);
                }
            }

            if (!looped && !gm.UtylizeSpellSource(caster, spellSource, spell))
            {
                return(ApplyAttackPolicyResult.NotEnoughResources);
            }

            var policy = Container.GetInstance <ProjectileCastPolicy>();

            policy.AddTarget(target);
            policy.ProjectilesFactory = Container.GetInstance <IProjectilesFactory>();
            policy.Projectile         = spellSource.CreateSpell(caster) as IProjectileSpell;
            if (BeforeApply != null)
            {
                BeforeApply(policy);
            }

            policy.OnApplied += (s, e) =>
            {
                gm.CallTryAddForLootSource(policy.Targets.First());

                if (looped)
                {
                    return;
                }
                if (!applyingBulk)
                {
                    var repeatOK = caster.IsStatRandomlyTrue(EntityStatKind.ChanceToRepeatElementalProjectileAttack);
                    if (repeatOK)
                    {
                        ApplyAttackPolicy(caster, target, spellSource, BeforeApply, AfterApply, true);
                    }
                }

                gm.FinishPolicyApplied(caster, AfterApply, policy);
            };

            policy.Apply(caster);

            var bulkOK = false;

            if (target is Enemy en && spellSource is WeaponSpellSource)
            {
                bulkOK = HandleBulk(en, EntityStatKind.ChanceToElementalProjectileBulkAttack, (Enemy en1) => {
                    applyingBulk = true;
                    ApplyAttackPolicy(caster, en1, spellSource, BeforeApply, AfterApply, true);
                    gm.AppendAction(caster.Name + " used Projectile Bulk Attack", ActionLevel.Important);
                });
            }

            return(ApplyAttackPolicyResult.OK);
        }