/// <summary> /// Calculate a server preformed skill /// </summary> /// <param name="associate">Executioner</param> /// <param name="writer">Data to be sent to clients</param> /// <param name="skillId">Skill to execute</param> /// <param name="syncId">Sync Id</param> /// <param name="calculatingPosition">Where position calculations are done from</param> /// <param name="target">Explicit target</param> /// <returns>Context</returns> public async Task <NpcExecutionContext> CalculateAsync(GameObject associate, BitWriter writer, int skillId, uint syncId, Vector3 calculatingPosition, GameObject target = default) { target ??= associate; var context = new NpcExecutionContext(target, writer, skillId, syncId, calculatingPosition); if (!SkillRoots.TryGetValue(skillId, out var root)) { Logger.Debug($"Failed to find skill: {skillId}"); return(context); } context.Root = root; var branchContext = new ExecutionBranchContext(target); try { await root.CalculateAsync(context, branchContext); } catch (Exception e) { Logger.Error(e); } return(context); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { context.Associate.Transform.LookAt(branchContext.Target.Transform.Position); await branchContext.Target.NetFavorAsync(); context.Writer.Align(); context.Writer.Write <ushort>(0); context.Writer.WriteBit(false); context.Writer.WriteBit(false); context.Writer.WriteBit(true); context.Writer.Write(0); var success = context.IsValidTarget(branchContext.Target) && context.Alive; var damage = (uint)(success ? MinDamage : 0); context.Writer.Write(damage); context.Writer.WriteBit(success); if (success) { await PlayFxAsync("onhit", branchContext.Target, 1000); var stats = branchContext.Target.GetComponent <Stats>(); stats.Damage(damage, context.Associate, EffectHandler); await OnSuccess.CalculateAsync(context, branchContext); } }
public override Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { var syncId = context.Associate.GetComponent <SkillComponent>().ClaimSyncId(); context.Writer.Write(syncId); if (branchContext.Target is Player player) { player.SendChatMessage($"Delay. [{context.SkillSyncId}] [{syncId}]"); } Task.Run(async() => { await Task.Delay(Delay); context = context.Copy(); await Action.CalculateAsync(context, branchContext); context.Sync(syncId); if (branchContext.Target is Player sPlayer) { sPlayer.SendChatMessage($"Sync. [{context.SkillSyncId}] [{syncId}]"); } }); return(Task.CompletedTask); }
public override BehaviorExecutionParameters SerializeStart(BitWriter writer, NpcExecutionContext context, ExecutionBranchContext branchContext) { writer.WriteBit(false); if (branchContext.Target is Player target) { var targetDirection = context.Associate.Transform.Position - target.Transform.Position; var rotation = targetDirection.QuaternionLookRotation(Vector3.UnitY); // Forward, currently unused _ = rotation.VectorMultiply(Vector3.UnitX); // Handled in the background Task.Run(() => { target.Message(new KnockbackMessage { Associate = target, Caster = context.Associate, Originator = context.Associate, KnockbackTime = 0, Vector = Vector3.UnitY * Strength }); }); } return(base.SerializeStart(writer, context, branchContext)); }
/// <summary> /// Wrapper to call the generic typed version of this method /// </summary> /// <param name="context">The global context to use</param> /// <param name="branchContext">The branch context to use</param> /// <returns><c>BehaviorExecutionParameters</c> gained by serializing the start skill</returns> public override BehaviorExecutionParameters SerializeStart(BitWriter writer, NpcExecutionContext context, ExecutionBranchContext branchContext) { var behaviorExecutionParameters = CreateInstance(context, branchContext); SerializeStart(writer, behaviorExecutionParameters); return(behaviorExecutionParameters); }
public override BehaviorExecutionParameters SerializeStart(NpcExecutionContext context, ExecutionBranchContext branchContext) { if (StunCaster != 1) { context.Writer.WriteBit(false); } return(base.SerializeStart(context, branchContext)); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { context.MinRange = MinRange; context.MaxRange = MaxRange; context.SkillTime = SkillTime; await Behavior.CalculateAsync(context, branchContext); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { // TODO context.Writer.Write(1); await Behaviors[1 - 1].CalculateAsync(context, branchContext); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { if (StunCaster == 1) { return; } context.Writer.WriteBit(false); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { if (branchContext.Target is Player player) { player.SendChatMessage($"Verified: [{Action.Id}] {Action.BehaviorId}"); } await Action.CalculateAsync(context, branchContext); }
/// <summary> /// Wrapper to call the generic typed version of this method /// </summary> /// <param name="context">The global context to use</param> /// <param name="branchContext">The branch context to use</param> /// <returns><c>BehaviorExecutionParameters</c> gained by serializing the start skill</returns> public override BehaviorExecutionParameters SerializeStart(NpcExecutionContext context, ExecutionBranchContext branchContext) { var behaviorExecutionParameters = new T { Context = context, BranchContext = branchContext }; SerializeStart(behaviorExecutionParameters); return(behaviorExecutionParameters); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { context.Writer.Write(branchContext.Target); var count = ProjectileCount == 0 ? 1 : ProjectileCount; for (var i = 0; i < count; i++) { CalculateProjectile(context, branchContext.Target); } }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { if (branchContext.Target != context.Associate) { context.Writer.WriteBit(false); } if (InterruptBlock == 0) { context.Writer.WriteBit(false); } context.Writer.WriteBit(false); }
public override BehaviorExecutionParameters SerializeStart(BitWriter writer, NpcExecutionContext context, ExecutionBranchContext branchContext) { if (branchContext.Target != context.Associate) { writer.WriteBit(false); } if (InterruptBlock == 0) { writer.WriteBit(false); } writer.WriteBit(false); return(base.SerializeStart(writer, context, branchContext)); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { if (!context.Associate.TryGetComponent <BaseCombatAiComponent>(out var baseCombatAiComponent)) { return; } var validTarget = baseCombatAiComponent.SeekValidTargets(); var sourcePosition = context.CalculatingPosition; var targets = validTarget.Where(target => { var transform = target.Transform; var distance = Vector3.Distance(transform.Position, sourcePosition); var valid = distance <= Radius; return(valid); }).ToArray(); foreach (var target in targets) { if (target is Player player) { player.SendChatMessage("You are a AOE target!"); } } if (targets.Length > 0) { context.FoundTarget = true; } context.Writer.Write((uint)targets.Length); foreach (var target in targets) { context.Writer.Write(target); } foreach (var target in targets) { await Action.CalculateAsync(context, new ExecutionBranchContext(target)); } }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { /* * var syncId = context.Associate.GetComponent<SkillComponent>().ClaimSyncId(); * * context.Writer.Write(syncId); */ // TODO var state = true; if (Imagination > 0 || !IsEnemyFaction) { state = branchContext.Target != default && context.Alive; context.Writer.WriteBit(state); } if (state) { await ActionTrue.CalculateAsync(context, branchContext); } else { await ActionFalse.CalculateAsync(context, branchContext); } /* * var _ = Task.Run(async () => * { * context = context.Copy(); * * await Action.CalculateAsync(context, branchContext); * * context.Sync(syncId); * }); */ }
/// <summary> /// Locates all targets within range of a context and returns a list of them /// </summary> /// <param name="context">The NPC context to find targets for</param> /// <returns>A list of targets if they were found, otherwise an empty list</returns> private List <GameObject> LocateTargets(NpcExecutionContext context) { if (!context.Associate.TryGetComponent <BaseCombatAiComponent>(out var baseCombatAiComponent)) { return(new List <GameObject>()); } var validTargets = baseCombatAiComponent.SeekValidTargets(); var sourcePosition = context.CalculatingPosition; // Change back to author position? var targets = validTargets.Where(target => { var transform = target.Transform; if (transform == null) { return(false); } var distance = Vector3.Distance(transform.Position, sourcePosition); return(distance <= context.MaxRange && context.MinRange <= distance); }).ToList(); targets.ToList().Sort((g1, g2) => { var distance1 = Vector3.Distance(g1.Transform.Position, sourcePosition); var distance2 = Vector3.Distance(g2.Transform.Position, sourcePosition); return((int)(distance1 - distance2)); }); var selectedTargets = new List <GameObject>(); for (var i = 0; i < targets.Count && i < MaxTargets; i++) { selectedTargets.Add(targets[i]); } return(selectedTargets); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { context.Writer.WriteBit(false); if (!(branchContext.Target is Player target)) { return; } var targetDirection = context.Associate.Transform.Position - target.Transform.Position; var rotation = targetDirection.QuaternionLookRotation(Vector3.UnitY); var forward = rotation.VectorMultiply(Vector3.UnitX); target.Message(new KnockbackMessage { Associate = target, Caster = context.Associate, Originator = context.Associate, KnockbackTime = 0, Vector = Vector3.UnitY * Strength }); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { branchContext.Duration = ActionDuration * 1000; await Action.CalculateAsync(context, branchContext); }
public virtual Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { return(Task.CompletedTask); }
public override async Task CalculateAsync(NpcExecutionContext context, ExecutionBranchContext branchContext) { if (!context.Associate.TryGetComponent <BaseCombatAiComponent>(out var baseCombatAiComponent)) { return; } var validTarget = baseCombatAiComponent.SeekValidTargets(); var sourcePosition = context.CalculatingPosition; // Change back to author position? var targets = validTarget.Where(target => { var transform = target.Transform; var distance = Vector3.Distance(transform.Position, sourcePosition); return(distance <= context.MaxRange && context.MinRange <= distance); }).ToList(); targets.ToList().Sort((g1, g2) => { var distance1 = Vector3.Distance(g1.Transform.Position, sourcePosition); var distance2 = Vector3.Distance(g2.Transform.Position, sourcePosition); return((int)(distance1 - distance2)); }); var selectedTargets = new List <GameObject>(); foreach (var target in targets) { if (selectedTargets.Count < MaxTargets) { selectedTargets.Add(target); } } if (!context.Alive) { selectedTargets.Clear(); // No targeting if dead } var any = selectedTargets.Any(); context.Writer.WriteBit(any); // Hit if (any) { baseCombatAiComponent.Target = selectedTargets.First(); context.FoundTarget = true; if (CheckEnvironment) { // TODO context.Writer.WriteBit(false); } context.Writer.Write((uint)selectedTargets.Count); foreach (var target in selectedTargets) { context.Writer.Write(target.Id); } foreach (var target in selectedTargets) { if (!(target is Player player)) { continue; } player.SendChatMessage($"You are a target! [{context.SkillSyncId}]"); } foreach (var target in selectedTargets) { var branch = new ExecutionBranchContext(target) { Duration = branchContext.Duration }; await ActionBehavior.CalculateAsync(context, branch); } } else { if (Blocked) { // TODO context.Writer.WriteBit(false); } else { await MissBehavior.CalculateAsync(context, branchContext); } } }