Exemplo n.º 1
0
        public OffensiveSpell ApplySpell(LivingEntity caster, SpellSource spellSource)
        {
            var spell = spellSource.CreateSpell(caster);

            if (!gm.UtylizeSpellSource(caster, spellSource, spell))
            {
                return(null);
            }

            if (spell is OffensiveSpell ps)
            {
                if (ps is SkeletonSpell skeletonSpell)
                {
                    gm.AddAlly(skeletonSpell.Ally);
                }
                if (caster is Hero)
                {
                    HandleHeroActionDone();
                }

                return(ps);
            }
            else
            {
                gm.Logger.LogError("!OffensiveSpell " + spellSource);
                gm.ReportFailure("");
            }

            return(null);
        }
Exemplo n.º 2
0
        public PassiveSpell ApplyPassiveSpell(LivingEntity caster, SpellSource spellSource, Point?destPoint = null)
        {
            var    spell         = spellSource.CreateSpell(caster);
            string preventReason = "";

            if (!gm.Context.CanUseScroll(caster, spellSource, spell, ref preventReason))
            {
                gm.ReportFailure(preventReason);
                return(null);
            }

            if (spell is PassiveSpell ps)
            {
                if (ps.Kind == SpellKind.Teleport)
                {
                    if (destPoint != null)
                    {
                        var currentTile   = gm.CurrentNode.GetTile(destPoint.Value);
                        var teleportSpell = ps as TeleportSpell;
                        if (teleportSpell.Range < gm.Hero.DistanceFrom(currentTile))
                        {
                            gm.ReportFailure("Range of spell is too small (max:" + teleportSpell.Range + ")");
                            return(null);
                        }

                        if (currentTile.IsEmpty || currentTile is Loot)
                        {
                            gm.CurrentNode.SetTile(gm.Hero, destPoint.Value);
                        }
                        else
                        {
                            gm.ReportFailure("Can not cast on the pointed tile");
                            return(null);
                        }
                    }
                }
                else
                {
                    caster.ApplyPassiveSpell(ps);
                }

                gm.UtylizeSpellSource(caster, spellSource, spell);
                gm.AppendAction <LivingEntityAction>((LivingEntityAction ac) =>
                                                     { ac.Kind = LivingEntityActionKind.Teleported; ac.Info = gm.Hero.Name + " used " + spellSource.Kind.ToDescription() + " scroll"; ac.InvolvedEntity = caster; });

                if (caster is Hero)
                {
                    HandleHeroActionDone();
                }

                return(ps);
            }
            else
            {
                gm.Logger.LogError("!PassiveSpell " + spellSource);
                gm.ReportFailure("");
            }

            return(null);
        }
Exemplo n.º 3
0
        public PassiveSpell ApplyPassiveSpell(LivingEntity caster, SpellSource spellSource, Point?destPoint = null)
        {
            var    spell         = spellSource.CreateSpell(caster);
            string preventReason = "";

            if (!gm.Context.CanUseScroll(caster, spellSource, spell, ref preventReason))
            {
                gm.ReportFailure(preventReason);
                return(null);
            }

            if (spell is PassiveSpell ps)
            {
                if (ps.Kind == SpellKind.Teleport)
                {
                    if (destPoint != null)
                    {
                        var currentTile   = gm.CurrentNode.GetTile(destPoint.Value);
                        var teleportSpell = ps as TeleportSpell;
                        if (teleportSpell.Range < gm.Hero.DistanceFrom(currentTile))
                        {
                            gm.ReportFailure("Range of spell is too small (max:" + teleportSpell.Range + ")");
                            return(null);
                        }

                        if (currentTile.IsEmpty || currentTile is Loot)
                        {
                            gm.CurrentNode.SetTile(gm.Hero, destPoint.Value);
                        }
                        else
                        {
                            gm.ReportFailure("Can not cast on the pointed tile");
                            return(null);
                        }
                    }
                }
                else if (ps.Kind == SpellKind.Dziewanna)
                {
                    int maxApples = 1;
                    if (RandHelper.GetRandomDouble() > 0.5)
                    {
                        maxApples += 1;
                    }
                    for (int appleIndex = 0; appleIndex < maxApples; appleIndex++)
                    {
                        var  enemies = gm.CurrentNode.GetNeighborTiles <Enemy>(gm.Hero);
                        bool added   = false;
                        foreach (var en in enemies)
                        {
                            var emptyOnes = gm.CurrentNode.GetEmptyNeighborhoodTiles(en, false);
                            if (emptyOnes.Any())
                            {
                                AddApple(emptyOnes.First());
                                added = true;
                                break;
                            }
                        }
                        if (!added)
                        {
                            var emp = gm.CurrentNode.GetClosestEmpty(gm.Hero);
                            AddApple(emp);
                        }
                    }
                }
                else
                {
                    caster.ApplyPassiveSpell(ps);
                }

                gm.UtylizeSpellSource(caster, spellSource, spell);
                gm.AppendAction <LivingEntityAction>((LivingEntityAction ac) =>
                                                     { ac.Kind = LivingEntityActionKind.Teleported; ac.Info = gm.Hero.Name + " used " + spellSource.Kind.ToDescription() + " scroll"; ac.InvolvedEntity = caster; });

                if (caster is Hero)
                {
                    HandleHeroActionDone();
                }

                return(ps);
            }
            else
            {
                gm.Logger.LogError("!PassiveSpell " + spellSource);
                gm.ReportFailure("");
            }

            return(null);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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);
        }