/// <summary> /// Calculates the combat for an AI /// </summary> /// <param name="delta">Passed time in milliseconds since last tick</param> private Task CalculateCombat(float delta) { if (!Enabled || !DestructibleComponent.Alive || QuickBuildComponent != default && QuickBuildComponent.State != RebuildState.Completed) { return(Task.CompletedTask); } if (Cooldown <= 0) { AbilityDowntime = false; var elapsedCooldown = FrozenCooldown; Cooldown = 1000f; FrozenCooldown = Cooldown; foreach (var entry in SkillEntries) { entry.Cooldown -= elapsedCooldown; if (entry.Cooldown > 0 || AbilityDowntime) { continue; } var time = SkillComponent.CalculateSkill(entry.Tree, (int)entry.SkillId); if (time == 0) { continue; } AbilityDowntime = true; entry.Cooldown = entry.AbilityCooldown + time; Cooldown += time; FrozenCooldown = Cooldown; } } Cooldown -= delta; return(Task.CompletedTask); }
public BaseCombatAiComponent() { Listen(OnStart, () => { SkillEntries = new List <NpcSkillEntry>(); Listen(GameObject.OnStart, async() => { SkillComponent = GameObject.GetComponent <SkillComponent>(); DestructibleComponent = GameObject.GetComponent <DestructibleComponent>(); QuickBuildComponent = GameObject.GetComponent <QuickBuildComponent>(); Stats = GameObject.GetComponent <DestroyableComponent>(); foreach (var skillEntry in SkillComponent.DefaultSkillSet) { await using var ctx = new CdClientContext(); var skillInfo = await ctx.SkillBehaviorTable.FirstAsync( s => s.SkillID == skillEntry.SkillId ); await SkillComponent.CalculateSkillAsync((int)skillEntry.SkillId, true); SkillEntries.Add(new NpcSkillEntry { SkillId = skillEntry.SkillId, Cooldown = false, AbilityCooldown = skillInfo.Cooldown ?? 1 }); } Zone.Update(GameObject, async delta => { await CalculateCombat(delta); }, 1); });