/// <summary> /// Gets the next skill ID from the skill to update, returns 0 if none is found. /// </summary> public static uint GetCommonAttack(SRTypes.Weapon type) { List <NameValueCollection> result = Database.GetResultFromQuery("SELECT id FROM skills WHERE (weapon_first = " + ((byte)type) + " or weapon_second = " + ((byte)type) + ") and group_name LIKE '%_BASE'"); if (result.Count > 0) { return(uint.Parse(result[0]["id"])); } return(0); }
private void AttackLoop() { Window w = Window.Get; SRCoord myPosition, trainingPosition; int trainingRadius; bool doMovement = true; while (true) { // Check attacking params trainingPosition = w.TrainingArea_GetPosition(); if (trainingPosition == null) { w.Log("Training area it's not activated"); Stop(); return; } myPosition = InfoManager.Character.GetRealtimePosition(); trainingRadius = w.TrainingArea_GetRadius(); // Check movement if (doMovement) { // Avoid getting far away from training area if (myPosition.DistanceTo(trainingPosition) - trainingRadius < 50) { // Default time walking int timeTraveling = 3000; // Try to make a training movement if (w.Training_cbxWalkToCenter.Checked) { if (!myPosition.Equals(trainingPosition)) { // Move and wait timeTraveling = myPosition.TimeTo(trainingPosition, InfoManager.Character.GetMovementSpeed()); MoveTo(trainingPosition); w.LogProcess("Walking to center (" + timeTraveling + "ms)..."); WaitHandle.WaitAny(new WaitHandle[] { InfoManager.MonitorMobSpawnChanged, InfoManager.MonitorBuffRemoved }, timeTraveling); } } else { // Random walk int random = rand.Next(-trainingRadius, trainingRadius); // Take care about where am I SRCoord newPosition; if (trainingPosition.inDungeon()) { newPosition = new SRCoord(trainingPosition.PosX + random, trainingPosition.PosY + random, trainingPosition.Region, trainingPosition.Z); } else { newPosition = new SRCoord(trainingPosition.PosX + random, trainingPosition.PosY + random); } // Move and wait timeTraveling = myPosition.TimeTo(trainingPosition, InfoManager.Character.GetMovementSpeed()); MoveTo(newPosition); w.LogProcess("Walking randomly (" + timeTraveling + "ms)..."); WaitHandle.WaitAny(new WaitHandle[] { InfoManager.MonitorMobSpawnChanged, InfoManager.MonitorBuffRemoved }, timeTraveling); } doMovement = false; } else { // Too far away from training area w.Log("Attacking stopped, too far away from training area"); w.LogProcess("Far away from training area"); return; } } // Check buffs BuffLoop(); if (trainingRadius > 0) { // Attacking List <SRMob> mobs = InfoManager.Mobs.FindAll(m => trainingPosition.DistanceTo(m.GetRealtimePosition()) <= trainingRadius); SRMob mob = GetMobFiltered(mobs); if (mob == null) { // No mob to attack w.LogProcess("No mobs around to attack"); doMovement = true; continue; } else { // Load skills and iterate it SRSkill[] skillshots = w.Skills_GetSkillShots(mob.MobType); if (skillshots != null && skillshots.Length != 0) { // Try to select mob if (WaitSelectEntity(mob.UniqueID, 2, 250, "Selecting " + mob.Name + " (" + mob.MobType + ")...")) { // Iterate skills for (int k = 0; k <= skillshots.Length; k++) { // loop control if (k == skillshots.Length) { k = 0; } SRSkill skillshot = skillshots[k]; // Check if skill is enabled if (!skillshot.isCastingEnabled) { continue; } // Check and fix the weapon used for this skillshot SRTypes.Weapon myWeapon = GetWeaponUsed(); if (skillshot.ID == 1) { // Common attack, fix the basic skill if (myWeapon != SRTypes.Weapon.None) { skillshot = new SRSkill(DataManager.GetCommonAttack(myWeapon)); skillshot.Name = "Common Attack"; } } else { // Check the required weapon SRTypes.Weapon weaponRequired = skillshot.RequiredWeaponPrimary; w.LogProcess("Checking weapon required (" + weaponRequired + ")..."); while (myWeapon != weaponRequired) { // Check the first 4 slots from inventory int slotInventory = InfoManager.Character.Inventory.FindIndex(item => item.ID2 == 1 && item.ID3 == 6 && item.ID3 == (byte)weaponRequired, 13, 16); if (slotInventory != -1) { w.LogProcess("Changing weapon (" + myWeapon + ")..."); // Try to change it byte maxWeaponChangeAttempts = 5; // Check max. 4 times to skip the mob (max. 1 seconds actually) while (myWeapon != weaponRequired && maxWeaponChangeAttempts > 0) { PacketBuilder.MoveItem((byte)slotInventory, 6, SRTypes.InventoryItemMovement.InventoryToInventory); maxWeaponChangeAttempts--; InfoManager.MonitorWeaponChanged.WaitOne(250); myWeapon = GetWeaponUsed(); } if (maxWeaponChangeAttempts == 0) { w.LogProcess("Weapon changing failed!"); continue; } } else { w.LogProcess("Weapon required not found (" + myWeapon + ")..."); continue; } InfoManager.MonitorWeaponChanged.WaitOne(250); myWeapon = GetWeaponUsed(); } } // Check if mob is alive if (InfoManager.Mobs.ContainsKey(mob.UniqueID)) { w.LogProcess("Casting skill " + skillshot.Name + " (" + skillshot.CastingTime + "ms)..."); PacketBuilder.AttackTarget(mob.UniqueID, skillshot.ID); if (InfoManager.MonitorSkillCast.WaitOne(500)) { // Skill casted, create character cooldown Thread.Sleep(skillshot.CastingTime); } else { // Timeout: Skill not casted if (!InfoManager.Mobs.ContainsKey(mob.UniqueID)) { // Mob it's dead? break; } else { // Recast skillshot k--; continue; } } } else { // mob selection failed break; } } } } else { w.LogProcess("Skillshots not found"); } } } } }