What's new
  • Visit Rebornbuddy
  • Visit Resources
  • Visit API Documentation
  • Visit Downloads
  • Visit Portal
  • Visit Panda Profiles
  • Visit LLamamMagic

Добыча руды

Stakasha

Member
Joined
Apr 15, 2015
Messages
56
Reaction score
0
Накидал бота на добычу руды в области, но не могу понять, почему он отрубается, помогите, пожалуйста, разобраться.
Вот код:
Code:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using ArcheBuddy.Bot.Classes;


namespace DefaultNameSpace{
    public class DefaultClass : Core
    {
        private Gps gps;
        int NormalOre = 0;
        int RareOre   = 0;
        
        //когда разберусь, как вывести логи, будеты выводится количество лута, которое собрал персонаж
        int Iron     = 0; int Copper = 0; int Silver = 0; int Gold = 0; int Stone = 0; int Echium = 0; //обычная руда
        int RareIron = 0; int RareCopper = 0; int RareSilver = 0; int RareGold = 0; int RareEchium = 0;     //проки
        int Emerald  = 0; int Topaz = 0; int Diamond = 0; int Sapphire = 0; int Ruby = 0;  //драгоценный камни
        
        
        public static string GetPluginAuthor()
        {
            return "Stakasha";
        }
        
        public static string GetPluginVersion()
        {
            return "1.0.1.0";
        }
        
        public static string GetPluginDescription()
        {
            return "Сбор руды по точкам. Точек можно указать сколько угодно, называть необходимо числами (1, 2, ..., 15, 16,..., n) Бот будет проходить от первой точке к последней. Последняя точка должна быть около первой, чтобы бот мог начать новый груг";
        }
        
        public void UseSkillAndWait(string skillName, bool selfTarget = false)
        {
            //wait cooldowns first, before we try to cast skill
            while (me.isCasting || me.isGlobalCooldown)
                Thread.Sleep(50);
            if (!UseSkill(skillName, true, selfTarget))
            {
                if (me.target != null && GetLastError() == LastError.NoLineOfSight)
                {
                    //No line of sight, try come to target.
                    if (dist(me.target) <= 5)
                        ComeTo(me.target, 2);
                    else if (dist(me.target) <= 10)
                        ComeTo(me.target, 3);
                    else if (dist(me.target) < 20)
                        ComeTo(me.target, 8);
                    else
                        ComeTo(me.target, 8);
                }
            }      
            //wait cooldown again, after we start cast skill
            while (me.isCasting || me.isGlobalCooldown)
                Thread.Sleep(50);
        }
        
        //public void GoToTheStartMine()
        //{
            //   gps = new Gps(this); 
            //   gps.LoadDataBase(Application.StartupPath + "\\Plugins\\miner\\miner_start.db3"); 
            //   gps.GpsMove("Start");
            //   Log("Бежим к старту");
            //   Thread.Sleep(50000);
        //}
        
        //Call on plugin start
        public void PluginRun()
        {
            ClearLogs(); 
            //GoToTheStartMine();
            SetGroupStatus("Сбор руды", false);
            double searchDist = 20;
            //установить отбор, по карте можно собирать не только руду
            uint[] doodadSearchIds = new uint[]{1671,          //залежи железа
            466};          //заросли сорняка
            
            gps = new Gps(this); 
            gps.LoadDataBase(Application.StartupPath + "\\Plugins\\miner\\miner.db3");     //Точки называются числами (1, 2, 3, ..., 15, ..., n)
            
            var _GpsPoints = gps.GetAllGpsPoints();
            int count      = _GpsPoints.Count(); 
            Log("Всего точек: " + count);
            int tochka = 1; //точка старта
            gps.GpsMove(tochka.ToString());
            Log(System.DateTime.Now.ToLongTimeString() + ": Пришли на старт, точка: " + tochka);
            
            //int vremenno = 3;//количество точек, по которым бегает персонаж (времеено, пока разбираюсь с gps)
            bool mining = true;
            while(mining)
            {
                if (GetGroupStatus("Сбор руды") && me.isAlive())
                {
                    try
                    {
                        //Log("loop");
                        Thread.Sleep(500);
                        var needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist && doodadSearchIds.Contains(w.id));
                        if(needdoodads.Count()>0)
                        {
                            foreach(var doodad in needdoodads)
                            {
                                if(doodad!=null && ((doodad.name == "Залежи железа") || (doodad.name == "Порода с блестящими вкраплениями")))//Залежи железа;Порода с блестящими вкраплениями
                                {
                                    if(doodad.name == "Выработанные залежи")
                                        Log(System.DateTime.Now.ToLongTimeString() + ": Это мы добаывать не будем: " + doodad.name);
                                    else
                                    {
                                        if(me.laborPoints<200)
                                        {
                                            UseItem("Большая бутыль с имбирным напитком");
                                            Log(System.DateTime.Now.ToLongTimeString() + ": Выпил баночку");
                                            Thread.Sleep(500);
                                        }
                                        
                                        if(me.laborPoints<30)
                                        {
                                            mining = false;
                                        }
                                        
                                        
                                        CheckAggro();
                                        var needdoodadskills = doodad.getUseSkills();
                                        //Log(System.DateTime.Now.ToLongTimeString() + ": Найдено: " + string.Format("{0} Его ID: {1} Расстояние до объекта: {2}",
                                        //doodad.name,
                                        //doodad.id,
                                        //dist(doodad,me)));
                                        ComeTo(doodad);
                                        Thread.Sleep(500);
                                        Log(System.DateTime.Now.ToLongTimeString() + ": Обрабатываю: " + doodad.name);//, #FFDFD991,false);
                                        UseDoodadSkill(needdoodadskills[0].id, doodad, true, 0.4); 
                                        //процедуру записи в лог дропнутого лута надо сюда добавить
                                        
                                        if(doodad.name == "Порода с блестящими вкраплениями") 
                                            RareOre++;
                                        else
                                            NormalOre++;
                                        Thread.Sleep(500);
                                    }
                                }
                            }
                        }
                        else
                        {
                            tochka++;
                            if (tochka<(count+1))   
                            {
                                //Log(System.DateTime.Now.ToLongTimeString() + ": Рядом нет руды. Перемещаемся к точке: " + tochka.ToString());
                                gps.GpsMove(tochka.ToString());
                                CheckAggro();
                            }
                            else
                            {
                                tochka = 1;
                                //Log(System.DateTime.Now.ToLongTimeString() + ": Возвращаемся в начало");
                                gps.GpsMove(tochka.ToString());
                                Log(System.DateTime.Now.ToLongTimeString() + ": Ждем респа руды");
                                Thread.Sleep(5000);   //Установка времени ожидания респа, после прохождения круга (1 секунда = 1000)
                            }
                            //Thread.Sleep(500);
                        }
                    }
                    catch(Exception ex)
                    {
                        //Log(ex.Message);
                        Log("Что-то пошло не так");
                    }
                }
                
            }
            //Log("Exit loop");
        }
        
        public void CheckAggro()
        {                     
            // Log(DateTime.Now.ToLongTimeString() + " : CheckAggro");
            if(getAggroMobs().Count > 0)
            {         
                //Log(DateTime.Now.ToLongTimeString() + " : " + getAggroMobs().Count.ToString());
                foreach(var obj in  getAggroMobs())
                {   
                    Log(DateTime.Now.ToLongTimeString() + ": " + obj.name + ": KILL!!! KILL!!! KILL!!!");    
                    SetTarget(obj);
                    TurnDirectly(me.target);
                    //Log(DateTime.Now.ToLongTimeString() + ": fighting");
                    while(obj.isAlive())
                    {        
                        TurnDirectly(me.target);
                        if (skillCooldown("Сокрушение разума") == 0)
                        {
                            UseSkillAndWait("Сокрушение разума");
                            UseSkillAndWait("Хватка земли");
                        }
                        
                        for (int i=0;i<2;i++)
                            UseSkillAndWait("Сгустки пламени");
                        
                        if(!obj.inFight)
                            return;
                    }
                    Log(DateTime.Now.ToLongTimeString() + " : fight is over");
                }
            } 
        }        
        
        
        //Call on plugin stop
        public void PluginStop()
        { 
            ClearLogs();
            Log("Обработано обычной породы :" + NormalOre.ToString()); 
            Log("Обработано редкой породы :" + RareOre.ToString());
        }
    }
}


UPD. Отредактировал код. Плагин вполне работоспособный для фарма руды. Необходимо только создать карту с маршрутом.
 
Last edited:
Накидал бота на добычу руды в области, но не могу понять, почему он отрубается, помогите, пожалуйста, разобраться.
Бот проходит круг, когда руда кончается, скрипт выключается.
Code:
            .....
            while(true)
                  ..........                  
                    for(int i=0;true;i++)
                   ..............
У вас бесконечный цикл в бесконечном цикле. Используйте в for количество элементов в списке needdoodads.
 
Code:
            .....
            while(true)
                  ..........                  
                    for(int i=0;true;i++)
                   ..............
У вас бесконечный цикл в бесконечном цикле. Используйте в for количество элементов в списке needdoodads.

Спасибо, очень помогли, все работает теперь.

Возник еще вопрос:
Можно ли в строке
Code:
List<DoodadObject> needdoodads = getDoodads();
установить отбор по расстоянию и объекту, чтобы у меня сразу был список руды в определенном радиусе от меня?
 
Спасибо, очень помогли, все работает теперь.

Возник еще вопрос:
Можно ли в строке
Code:
List<DoodadObject> needdoodads = getDoodads();
установить отбор по расстоянию и объекту, чтобы у меня сразу был список руды в определенном радиусе от меня?

Что то вроде этого:
Code:
using System.Linq;
...
double searchDist = 20; //Дистанция
uint[] doodadSearchIds = new uint[]{1671, //Id Залежи железа
                                    466}; //??
var needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist &&
                                            doodadSearchIds.Contains(w.id));
foreach(var doodad in needdoodads)
{
    if(doodad!=null)
    {
        Log(string.Format("Объект: {0} Его ID: {1} Расстояние до объекта: {2}",
                            doodad.name,
                            doodad.id,
                            dist(doodad,me)));
    }
}
 
Что то вроде этого:
Code:
using System.Linq;
...
double searchDist = 20; //Дистанция
uint[] doodadSearchIds = new uint[]{1671, //Id Залежи железа
                                    466}; //??
var needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist &&
                                            doodadSearchIds.Contains(w.id));
foreach(var doodad in needdoodads)
{
    if(doodad!=null)
    {
        Log(string.Format("Объект: {0} Его ID: {1} Расстояние до объекта: {2}",
                            doodad.name,
                            doodad.id,
                            dist(doodad,me)));
    }
}
Спасибо, отлично помогло.
Но скрипт выключается, когда выкапывается последняя руда
Code:
ClearLogs(); 
            while(true)
            {
                double searchDist = 20;
                uint[] doodadSearchIds = new uint[]{1671,
                466};
            
                var needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist &&
                doodadSearchIds.Contains(w.id));
                
                foreach(var doodad in needdoodads)
                {
                    if(doodad!=null)
                    {
                        var needdoodadskills = doodad.getUseSkills();
                        Log(string.Format("Объект: {0} Его ID: {1} Расстояние до объекта: {2}",
                        doodad.name,
                        doodad.id,
                        dist(doodad,me)));
                        
                        ComeTo(doodad);
                        Thread.Sleep(500);
                        UseDoodadSkill(needdoodadskills[0].id, doodad, true, 0.4);
                        Thread.Sleep(500);
                    }
                }
            }
 
Попробуй так:
Code:
              ClearLogs(); 
            while(true)
            {
try
{
Log("loop");
Thread.Sleep(500);

                double searchDist = 20;
                uint[] doodadSearchIds = new uint[]{1671,
                466};
            
                var needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist &&
                doodadSearchIds.Contains(w.id));
              
                foreach(var doodad in needdoodads)
                {
                    if(doodad!=null)
                    {
                        var needdoodadskills = doodad.getUseSkills();
                        Log(string.Format("Объект: {0} Его ID: {1} Расстояние до объекта: {2}",
                        doodad.name,
                        doodad.id,
                        dist(doodad,me)));
                        
                        ComeTo(doodad);
                        Thread.Sleep(500);
                        UseDoodadSkill(needdoodadskills[0].id, doodad, true, 0.4);
                        Thread.Sleep(500);
                    }
                }
}
catch(Exception ex)
{
	Log(ex.Message);
}
			}
Log("Exit loop");
 
в логах вот такое сообщение:
Индекс за пределами диапазона. Индекс должен быть положительным числом, а его размер не должен превышать размер коллекции.
Но скрипт отрабатывает так, как я и хотел.
Спасибо огромное за помощь.
 
в логах вот такое сообщение:

Но скрипт отрабатывает так, как я и хотел.
Спасибо огромное за помощь.
Для исправления этой ошибке поставьте проверку на то, что в коллекции needdoodadskills есть элементы.
 
Спасибо, все отлично работает.

Исключение вызывалось не только из-за количества, но и из-за появления Выработанной руды, у которой такой же код, как и у нормальной.

Вот в этой строке все дело
Code:
UseDoodadSkill(needdoodadskills[0].id, doodad, true, 0.4);
Обычную руду перерабатывает нормально, когда попадается Порода с блестящими вкраплениями, вызывается исключение на индекс.
Получается, что на обычную руду и прокнутую юзаются разные скилы?

Вот такой готовый рабочий код получился:
Code:
 public void PluginRun()
        {
            ClearLogs(); 
            
            SetGroupStatus("Сбор руды", false);
            double searchDist = 20;
            uint[] doodadSearchIds = new uint[]{1671,          //залежи железа
            466};          //заросли сорняка
            ClearLogs();
            gps = new Gps(this); 
            gps.LoadDataBase(Application.StartupPath + "\\Plugins\\miner\\miner.db3"); 
            //var needdoodads =  getDoodads();
            
            while(true)
            {
                if (GetGroupStatus("Сбор руды") && me.isAlive())
                {
                    try
                    {
                        //Log("loop");
                        Thread.Sleep(500);
                        var needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist && doodadSearchIds.Contains(w.id));
                        if(needdoodads.Count()>0)
                        {
                            foreach(var doodad in needdoodads)
                            {
                                if(doodad!=null && ((doodad.name == "Залежи железа") || (doodad.name == "Порода с блестящими вкраплениями")))//Залежи железа;Порода с блестящими вкраплениями
                                {
                                    if(doodad.name == "Выработанные залежи")
                                        Log("Это мы добаывать не будем: " + doodad.name);
                                    else
                                    {
                                        var needdoodadskills = doodad.getUseSkills();
                                        Log(string.Format("Объект: {0} Его ID: {1} Расстояние до объекта: {2}",
                                        doodad.name,
                                        doodad.id,
                                        dist(doodad,me)));
                                        Log("Бежим к руде");
                                        ComeTo(doodad);
                                        Thread.Sleep(500);
                                        UseDoodadSkill(needdoodadskills[0].id, doodad, true, 0.4); 
                                        Log("Добыл руду");
                                        Thread.Sleep(500);
                                    }
                                }
                            }
                        }
                        else
                        {
                            Log("Ждем респа руды");
                            while(needdoodads.Count()==0)
                            {
                                Thread.Sleep(5000);
                                needdoodads = getDoodads().Where(w => dist(w, me) <= searchDist && doodadSearchIds.Contains(w.id));
                                if(needdoodads.Count()>0)
                                    Log("Руда реснулась");
                            }
                            //ClearLogs();
                            //gps.GpsMove("2");
                            Thread.Sleep(5000);
                        }
                    }
                    catch(Exception ex)
                    {
                        Log(ex.Message);
                    }
                }
                //else
                //ClearLogs(); 
                
            }
            //Log("Exit loop");
        }
 
Last edited:
Все хорошо работает, но заметил, что если запустить 2 плагина, то процессор очень сильно загружается.
Как снизить нагрузку на процессор?
 
Наверное процессор слабоват. Linq на некоторых процессорах тормозит.
 
Intel Core i5-4670, 3.4 GHz
Если запускать сразу два плагина, процессор Updater.exe начинает кушать почти 50% процессора.
Подозреваю, что вся нагрузка идет из-за бесконечного цикла.
 
Подскажите, пожалуйста, как можно вывести в логи сообщение о том, что именно я добыл?
 
Last edited:
Подскажите, как проверять добывает ли кто-нибудь уже руду с месторождения?
 
Подскажите, как проверять добывает ли кто-нибудь уже руду с месторождения?
Даже не знаю, да и не вижу в этом особого смысла, у меня бот бегает в тихих неприметных местах, где мало людей. Тем более, с перчатками и бафами руда в секунду улетает, бот до нее дойти даже не успеет.
 
Подскажите, пожалуйста, как можно вывести в логи сообщение о том, что именно я добыл?
Используйте событие onNewInvItem
Подскажите, как проверять добывает ли кто-нибудь уже руду с месторождения?

Возвращает список кастующих на дудад существ, не учитывая себя.
Code:
        public IEnumerable<Creature> GetVeinCasters(DoodadObject doodad)
        {
            return getCreatures().Where(w => w.castObject == doodad && w.uniqId != me.uniqId);
        }
 
Используйте событие onNewInvItem


Возвращает список кастующих на дудад существ, не учитывая себя.
Code:
        public IEnumerable<Creature> GetVeinCasters(DoodadObject doodad)
        {
            return getCreatures().Where(w => w.castObject == doodad && w.uniqId != me.uniqId);
        }
Если не трудно, можно пример использования onNewInvItem? А то самостоятельно не очень получается разобраться(((
 
Если не трудно, можно пример использования onNewInvItem? А то самостоятельно не очень получается разобраться(((
Code:
....
//список id предметов которые мы будем отслеживать
private static uint[] itemIds = {8022,//Железная руда
					  8081}; //Чистая железная руда

....
onNewInvItem += NewItemInvent; //подписываемся на событие где нибудь в начале скрипта
....
void NewItemInvent(Item item, int count) //Функция обработчик события
{
	if(itemIds.Contains(item.id)) // Проверяем, что итем подходит
	{
		Log(item.name);
		//тут уже делаем что нужно с количеством.
	}
}
 
Code:
....
//список id предметов которые мы будем отслеживать
private static uint[] itemIds = {8022,//Железная руда
					  8081}; //Чистая железная руда

....
onNewInvItem += NewItemInvent; //подписываемся на событие где нибудь в начале скрипта
....
void NewItemInvent(Item item, int count) //Функция обработчик события
{
	if(itemIds.Contains(item.id)) // Проверяем, что итем подходит
	{
		Log(item.name);
		//тут уже делаем что нужно с количеством.
	}
}
Спасибо, все получилось.
 
Back
Top