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); }
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); }