public void Cast(Unit caster, SkillCaster casterCaster, BaseUnit target, SkillCastTarget targetCaster, SkillObject skillObject) { caster.SkillTask = null; caster.BroadcastPacket(new SCSkillFiredPacket(Id, TlId, casterCaster, targetCaster, this, skillObject), true); if (Template.ChannelingTime > 0) { if (Template.ChannelingBuffId != 0) { var buff = SkillManager.Instance.GetBuffTemplate(Template.ChannelingBuffId); buff.Apply(caster, casterCaster, target, targetCaster, new CastSkill(Template.Id, TlId), this, skillObject, DateTime.Now); } caster.SkillTask = new ChannelingTask(this, caster, casterCaster, target, targetCaster, skillObject); TaskManager.Instance.Schedule(caster.SkillTask, TimeSpan.FromMilliseconds(Template.ChannelingTime)); } else { Channeling(caster, casterCaster, target, targetCaster, skillObject); } }
public void Use(Unit caster, SkillCaster casterCaster, SkillCastTarget targetCaster, SkillObject skillObject = null) { if (skillObject == null) { skillObject = new SkillObject(); } var effects = caster.Effects.GetEffectsByType(typeof(BuffTemplate)); foreach (var effect in effects) { if (((BuffTemplate)effect.Template).RemoveOnStartSkill || ((BuffTemplate)effect.Template).RemoveOnUseSkill) { effect.Exit(); } } effects = caster.Effects.GetEffectsByType(typeof(BuffEffect)); foreach (var effect in effects) { if (((BuffEffect)effect.Template).Buff.RemoveOnStartSkill || ((BuffEffect)effect.Template).Buff.RemoveOnUseSkill) { effect.Exit(); } } var target = (BaseUnit)caster; if (Template.TargetType == SkillTargetType.Self) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { targetCaster.ObjId = target.ObjId; } } else if (Template.TargetType == SkillTargetType.Friendly) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } if (caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Friendly) { return; //TODO отправлять ошибку? } } else if (Template.TargetType == SkillTargetType.Hostile) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } if (caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Hostile) { return; //TODO отправлять ошибку? } } else if (Template.TargetType == SkillTargetType.AnyUnit) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } } else if (Template.TargetType == SkillTargetType.Doodad) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } } else if (Template.TargetType == SkillTargetType.Item) { // TODO ... } else if (Template.TargetType == SkillTargetType.Others) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } if (caster.ObjId == target.ObjId) { return; //TODO отправлять ошибку? } } else if (Template.TargetType == SkillTargetType.FriendlyOthers) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } if (caster.ObjId == target.ObjId) { return; //TODO отправлять ошибку? } if (caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Friendly) { return; //TODO отправлять ошибку? } } else if (Template.TargetType == SkillTargetType.Building) { if (targetCaster.Type == SkillCastTargetType.Unit || targetCaster.Type == SkillCastTargetType.Doodad) { target = targetCaster.ObjId > 0 ? WorldManager.Instance.GetBaseUnit(targetCaster.ObjId) : caster; targetCaster.ObjId = target.ObjId; } else { // TODO ... } if (caster.ObjId == target.ObjId) { return; //TODO отправлять ошибку? } } else if (Template.TargetType == SkillTargetType.Pos) { var positionTarget = (SkillCastPositionTarget)targetCaster; var positionUnit = new BaseUnit(); positionUnit.Position = new Point(positionTarget.PosX, positionTarget.PosY, positionTarget.PosZ); positionUnit.Position.ZoneId = caster.Position.ZoneId; positionUnit.Position.WorldId = caster.Position.WorldId; positionUnit.Region = caster.Region; target = positionUnit; } else { // TODO ... } TlId = (ushort)TlIdManager.Instance.GetNextId(); if (Template.Plot != null) { var eventTemplate = Template.Plot.EventTemplate; var step = new PlotStep(); step.Event = eventTemplate; step.Flag = 2; if (!eventTemplate.СheckСonditions(caster, casterCaster, target, targetCaster, skillObject)) { step.Flag = 0; } var res = true; if (step.Flag != 0) { foreach (var evnt in eventTemplate.NextEvents) { res = res && BuildPlot(caster, casterCaster, target, targetCaster, skillObject, evnt, step); } } ParsePlot(caster, casterCaster, target, targetCaster, skillObject, step); if (!res) { return; } TlIdManager.Instance.ReleaseId(TlId); TlId = 0; } else { if (Template.CastingTime > 0) { caster.BroadcastPacket(new SCSkillStartedPacket(Id, TlId, casterCaster, targetCaster, this, skillObject), true); caster.SkillTask = new CastTask(this, caster, casterCaster, target, targetCaster, skillObject); TaskManager.Instance.Schedule(caster.SkillTask, TimeSpan.FromMilliseconds(Template.CastingTime)); } else { Cast(caster, casterCaster, target, targetCaster, skillObject); } } }
public void Apply(Unit caster, SkillCaster casterCaster, BaseUnit targetSelf, SkillCastTarget targetCaster, SkillObject skillObject) { var targets = new List <BaseUnit>(); // TODO crutches if (Template.TargetAreaRadius > 0) { var obj = WorldManager.Instance.GetAround <BaseUnit>(targetSelf, Template.TargetAreaRadius); targets.AddRange(obj); } else { targets.Add(targetSelf); } foreach (var effect in Template.Effects) { foreach (var target in targets) { if (effect.StartLevel > caster.Level || effect.EndLevel < caster.Level) { continue; } if (effect.Friendly && !effect.NonFriendly && caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Friendly) { continue; } if (!effect.Friendly && effect.NonFriendly && caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Hostile) { continue; } if (effect.Front && !effect.Back && !MathUtil.IsFront(caster, target)) { continue; } if (!effect.Front && effect.Back && MathUtil.IsFront(caster, target)) { continue; } if (effect.SourceBuffTagId > 0 && !caster.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.SourceBuffTagId))) { continue; } if (effect.SourceNoBuffTagId > 0 && caster.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.SourceNoBuffTagId))) { continue; } if (effect.TargetBuffTagId > 0 && !target.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.TargetBuffTagId))) { continue; } if (effect.TargetNoBuffTagId > 0 && target.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.TargetNoBuffTagId))) { continue; } if (effect.Chance < 100 && Rand.Next(100) > effect.Chance) { continue; } effect.Template?.Apply(caster, casterCaster, target, targetCaster, new CastSkill(Template.Id, TlId), this, skillObject, DateTime.Now); } } if (Template.ConsumeLaborPower > 0) { if (caster is Character character) { character.ChangeLabor((short)-Template.ConsumeLaborPower, Template.ActabilityGroupId); } } caster.BroadcastPacket(new SCSkillEndedPacket(TlId), true); TlIdManager.Instance.ReleaseId(TlId); TlId = 0; }
public void Channeling(Unit caster, SkillCaster casterCaster, BaseUnit target, SkillCastTarget targetCaster, SkillObject skillObject) { caster.SkillTask = null; if (Template.ChannelingBuffId != 0) { caster.Effects.RemoveEffect(Template.ChannelingBuffId, Template.Id); } if (Template.ToggleBuffId != 0) { var buff = SkillManager.Instance.GetBuffTemplate(Template.ToggleBuffId); buff.Apply(caster, casterCaster, target, targetCaster, new CastSkill(Template.Id, TlId), this, skillObject, DateTime.Now); } if (Template.EffectDelay > 0) { TaskManager.Instance.Schedule(new ApplySkillTask(this, caster, casterCaster, target, targetCaster, skillObject), TimeSpan.FromMilliseconds(Template.EffectDelay)); } else { Apply(caster, casterCaster, target, targetCaster, skillObject); } }
public void ParsePlot(Unit caster, SkillCaster casterCaster, BaseUnit target, SkillCastTarget targetCaster, SkillObject skillObject, PlotStep step) { if (step.Flag != 0) { foreach (var eff in step.Event.Effects) { var template = SkillManager.Instance.GetEffectTemplate(eff.ActualId, eff.ActualType); if (template is BuffEffect) { step.Flag = 6; } template.Apply(caster, casterCaster, target, targetCaster, new CastPlot(step.Event.PlotId, TlId, step.Event.Id, Template.Id), this, skillObject, DateTime.Now); } } var time = (ushort)(step.Flag != 0 ? step.Delay / 10 : 0); var unkId = step.Casting || step.Channeling ? caster.ObjId : 0; caster.BroadcastPacket( new SCPlotEventPacket(TlId, step.Event.Id, Template.Id, caster.ObjId, target.ObjId, unkId, time, step.Flag), true); foreach (var st in step.Steps) { ParsePlot(caster, casterCaster, target, targetCaster, skillObject, st); } }
public bool BuildPlot(Unit caster, SkillCaster casterCaster, BaseUnit target, SkillCastTarget targetCaster, SkillObject skillObject, PlotNextEvent nextEvent, PlotStep baseStep) { if (nextEvent.Delay > 0) { baseStep.Delay = nextEvent.Delay; caster.SkillTask = new PlotTask(this, caster, casterCaster, target, targetCaster, skillObject, nextEvent); TaskManager.Instance.Schedule(caster.SkillTask, TimeSpan.FromMilliseconds(nextEvent.Delay)); return(false); } if (nextEvent.Speed > 0) { baseStep.Speed = nextEvent.Speed; caster.SkillTask = new PlotTask(this, caster, casterCaster, target, targetCaster, skillObject, nextEvent); TaskManager.Instance.Schedule(caster.SkillTask, TimeSpan.FromMilliseconds(nextEvent.Speed * 40)); // TODO зависит от расстояния, найти формулу return(false); } var step = new PlotStep(); step.Event = nextEvent.Event; step.Flag = 2; step.Casting = nextEvent.Casting; step.Channeling = nextEvent.Channeling; foreach (var condition in nextEvent.Event.Conditions) { if (condition.Condition.Check(caster, casterCaster, target, targetCaster, skillObject)) { continue; } step.Flag = 0; break; } baseStep.Steps.AddLast(step); if (step.Flag == 0) { return(true); } var res = true; foreach (var e in nextEvent.Event.NextEvents) { res = res && BuildPlot(caster, casterCaster, target, targetCaster, skillObject, e, step); } return(res); }
public void Apply(Unit caster, SkillCaster casterCaster, BaseUnit targetSelf, SkillCastTarget targetCaster, SkillObject skillObject) { var targets = new List <BaseUnit>(); // TODO crutches if (Template.TargetAreaRadius > 0) { var obj = WorldManager.Instance.GetAround <BaseUnit>(targetSelf, Template.TargetAreaRadius); targets.AddRange(obj); } else { targets.Add(targetSelf); } foreach (var effect in Template.Effects) { foreach (var target in targets) { if (effect.StartLevel > caster.Level || effect.EndLevel < caster.Level) { continue; } if (effect.Friendly && !effect.NonFriendly && caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Friendly) { continue; } if (!effect.Friendly && effect.NonFriendly && caster.Faction.GetRelationState(target.Faction.Id) != RelationState.Hostile) { continue; } if (effect.Front && !effect.Back && !MathUtil.IsFront(caster, target)) { continue; } if (!effect.Front && effect.Back && MathUtil.IsFront(caster, target)) { continue; } if (effect.SourceBuffTagId > 0 && !caster.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.SourceBuffTagId))) { continue; } if (effect.SourceNoBuffTagId > 0 && caster.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.SourceNoBuffTagId))) { continue; } if (effect.TargetBuffTagId > 0 && !target.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.TargetBuffTagId))) { continue; } if (effect.TargetNoBuffTagId > 0 && target.Effects.CheckBuffs(SkillManager.Instance.GetBuffsByTagId(effect.TargetNoBuffTagId))) { continue; } if (effect.Chance < 100 && Rand.Next(100) > effect.Chance) { continue; } if (caster is Character character && effect.ConsumeItemId != 0 && effect.ConsumeItemCount > 0) { if (effect.ConsumeSourceItem) { var item = ItemManager.Instance.Create(effect.ConsumeItemId, effect.ConsumeItemCount, 0); var res = character.Inventory.AddItem(item); if (res == null) { ItemIdManager.Instance.ReleaseId((uint)res.Id); continue; } var tasks = new List <ItemTask>(); if (res.Id != item.Id) { tasks.Add(new ItemCountUpdate(res, item.Count)); } else { tasks.Add(new ItemAdd(item)); } character.SendPacket( new SCItemTaskSuccessPacket(ItemTaskType.SkillEffectConsumption, tasks, new List <ulong>()) ); } else { var inventory = character.Inventory.CheckItems(SlotType.Inventory, effect.ConsumeItemId, effect.ConsumeItemCount); var equipment = character.Inventory.CheckItems(SlotType.Equipment, effect.ConsumeItemId, effect.ConsumeItemCount); if (!(inventory || equipment)) { continue; } var tasks = new List <ItemTask>(); if (inventory) { var items = character.Inventory.RemoveItem(effect.ConsumeItemId, effect.ConsumeItemCount); foreach (var(item, count) in items) { if (item.Count == 0) { tasks.Add(new ItemRemove(item)); } else { tasks.Add(new ItemCountUpdate(item, -count)); } } } else if (equipment) { var item = character.Inventory.GetItemByTemplateId(effect.ConsumeItemId); character.Inventory.RemoveItem(item, true); tasks.Add(new ItemRemove(item)); } character.SendPacket( new SCItemTaskSuccessPacket(ItemTaskType.SkillEffectConsumption, tasks, new List <ulong>()) ); } } effect.Template?.Apply(caster, casterCaster, target, targetCaster, new CastSkill(Template.Id, TlId), this, skillObject, DateTime.Now); } } if (Template.ConsumeLaborPower > 0 && caster is Character chart) { chart.ChangeLabor((short)-Template.ConsumeLaborPower, Template.ActabilityGroupId); } caster.BroadcastPacket(new SCSkillEndedPacket(TlId), true); TlIdManager.Instance.ReleaseId(TlId); TlId = 0; }
public bool BuildPlot(Unit caster, SkillCaster casterCaster, BaseUnit target, SkillCastTarget targetCaster, SkillObject skillObject, PlotNextEvent nextEvent, PlotStep baseStep, Dictionary <uint, int> counter) { if (counter.ContainsKey(nextEvent.Event.Id)) { var nextCount = counter[nextEvent.Event.Id] + 1; if (nextCount > nextEvent.Event.Tickets) { return(true); } counter[nextEvent.Event.Id] = nextCount; } else { counter.Add(nextEvent.Event.Id, 1); } if (nextEvent.Delay > 0) { baseStep.Delay = nextEvent.Delay; caster.SkillTask = new PlotTask(this, caster, casterCaster, target, targetCaster, skillObject, nextEvent, counter); TaskManager.Instance.Schedule(caster.SkillTask, TimeSpan.FromMilliseconds(nextEvent.Delay)); return(false); } if (nextEvent.Speed > 0) { baseStep.Speed = nextEvent.Speed; caster.SkillTask = new PlotTask(this, caster, casterCaster, target, targetCaster, skillObject, nextEvent, counter); var dist = MathUtil.CalculateDistance(caster.Position, target.Position, true); TaskManager.Instance.Schedule(caster.SkillTask, TimeSpan.FromSeconds(dist / nextEvent.Speed)); return(false); } var step = new PlotStep(); step.Event = nextEvent.Event; step.Flag = 2; step.Casting = nextEvent.Casting; step.Channeling = nextEvent.Channeling; foreach (var condition in nextEvent.Event.Conditions) { if (condition.Condition.Check(caster, casterCaster, target, targetCaster, skillObject)) { continue; } step.Flag = 0; break; } baseStep.Steps.AddLast(step); if (step.Flag == 0) { return(true); } var res = true; foreach (var e in nextEvent.Event.NextEvents) { res = res && BuildPlot(caster, casterCaster, target, targetCaster, skillObject, e, step, counter); } return(res); }