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

Simple daggerspell grinder + deathwalk

SystemShock

New Member
Joined
Aug 18, 2012
Messages
87
Reaction score
4
Simple (Sorc+Witchcraft) grinder + deathwalk

As the title says this is a very simplistic grinder for any set up that includes sorcery and witchcraft that also features a deathwalk(Which is broken at the moment).
The rotation is based around the idea that I want to be able to run constantly, and so it isn't mana intensive(Once mana food, and potions become more available I'll be adding a more mana intensive version for faster killing)

Buffs -
Magic Circle
Insulating Lense
Purge

Rotation -
Whenever magic circle is off cooldown - cast it
Whenever insulating lense is off cooldown - cast it
When below 75% health && Enervate and Earthern Grip are off cooldown - cast Enervate then Earthern Grip
When below 90% mana && Enervate is off - cooldown cast Enervate
when none of the above, cast fire bolt

We also use play dead to drop agro if we're low health, and as a regen ability between kills

so needed spells -
Magic Circle
Insulating Lense
Purge
Enervate
ArcheAge Builder - Arche-Base
arc lightning, chain lightning and meteor aren't used in the rotation but are simply what I have in order to unlock passives

Issues - It's handling of play dead is poor.

So due to current GPS constraints it's impossible, or atleast is as far as I'm aware to make GPS paths on the fly, so you'll have to make a path from the closest nui, to your farming zone yourself, a guide on how to do this can be found in the gps topic -> https://www.thebuddyforum.com/archebuddy-forum/archebuddy-plugins/177764-gps-system-gps-editor.html

Generate a path named, TheGrinder.db3, and put that into the folder with the script.

Installation is standard,
1) Create a folder in plugins named SystemGutted
2) Compile the script and place it in the folder
3) Generate your GPS path, name it TheGrinder.db3 and put it into the folder
4) Run the script

GuttedGrinder.cs
Code:
using System;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using ArcheBuddy.Bot.Classes;

namespace GuttedSpace
    {
    public class GuttedGrinder : Core
        {
        public int deathcount;
        internal Main mainForm { get; set; }
        private Thread formThread;
        private Thread paintThread;
        public int mobsKilled = 0;
        public long coinPursesStart = 0;
        public long coinPursesCurrent = 0;
        Stopwatch stopwatch = new Stopwatch();
        long runTimeMilli;
        private volatile bool _shouldStop;

        public static string GetPluginAuthor ()
            {
            return "SystemShock";
            }

        public static string GetPluginVersion ()
            {
            return "Evaluation";
            }

        public static string GetPluginDescription ()
            {
            return "TheGrinder is a mob grinder developed by SystemShock, more information for about the project and proper installation guidelines can be found on the forum";
            }


        public void gpsPreMove (GpsPoint point)
            {
            /*
            *
            *We do nothing other than debugging in here at the moment, in the future we'll add combat checks so it can kill anything hostile it meats on the path
            *
            */
            Log("Moving");
            }


        public Creature GetBestNearestMob (Zone zone)
            {
            /*
            *
            *Simple method stole from Out's Example Grinder with a few minor tweaks
            *Locates a mob, checks to make sure it's within our zone and that it either isn't tagged, or is our tag
            *And then declares it as the nearest valid mob for the rest of the script
            *
            */

            Creature mob = null;
            double dist = 999999;//How is distance treated? Nobody knows, oh great Out, are you looking within 999999 meters? or 9999999 pixels? I'd love to know... Hear me oh Great One 

            foreach(var obj in getCreatures())
                {
                if(obj.type == BotTypes.Npc && isAttackable(obj) && (obj.firstHitter == null || obj.firstHitter == me) && isAlive(obj) && me.dist(obj) < dist && zone.ObjInZone(obj)
                    && (hpp(obj) == 100 || obj.aggroTarget == me))
                    {
                    mob = obj;
                    dist = me.dist(obj);
                    }
                }
            return mob;
            }

        public void CancelAttacksOnAnothersMobs ()
            {
            /*
            *
            *Again stolen from Out's example grinder
            *Dude wheres my car, because this one is someone elses
            *
            */
            while(true)
                {
                if(me.isCasting && me.target != null && me.target.firstHitter != null && me.target.firstHitter != me)
                    CancelSkill();
                Thread.Sleep(100);
                }
            }

        public void UseSkillAndWait (string skillName, bool selfTarget = false)
            {
            /*
            *
            *I'm noticing a pattern here, another method stolen from Out 
            *( seriously why are these not just part of the .dll and allow us to override them ¯\_(ツ)_/¯ )
            *
            */

            while(me.isCasting || me.isGlobalCooldown)
                Thread.Sleep(50);
            if(!UseSkill(skillName, true, selfTarget))
                {
                if(me.target != null && GetLastError() == LastError.NoLineOfSight)
                    {
                    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);
                    }
                }
            while(me.isCasting || me.isGlobalCooldown)
                Thread.Sleep(50);
            }

        private void RunForm ()
            {
            /*
            *
            *Lets open the paint lads
            *
            */

            try
                {
                Application.Run(mainForm);
                }
            catch(Exception error)
                {
                Log(error.ToString());
                try
                    {
                    if(mainForm != null)
                        {
                        mainForm.Invoke(new Action(() => mainForm.Close()));
                        mainForm.Invoke(new Action(() => mainForm.Dispose()));
                        }
                    }
                catch
                { }
                }
            }

        public void deathWalk ()
            {
            /*
            *
            *Pretty simple method, just reads your .db3 path file and walks it to the end-point which should be named "spawn"
            *
            */

            Gps gps = new Gps(this);
            gps.LoadDataBase(Application.StartupPath + "\\plugins\\SystemGrinder\\TheGrinderPath.db3");
            gps.onGpsPreMove += gpsPreMove;
            gps.GpsMove("spawn");
            }

        public void checkBuffs ()
            {
            if(buffTime("Magic Defense Boost") == 0 && skillCooldown("Purge") == 0)
                UseSkillAndWait("Purge", true);
            if(skillCooldown("Insulating Lens") == 0)
                UseSkillAndWait("Insulating Lens", true);  
            if(buffTime("Suspected User") > 0){
                Log("SOME FUCKER JUST REPORTED US, I'M GOING TO RUN AWAY NOW");
                UseSkill("Recall");
                Thread.Sleep(30000);
                StopPlugin("SystemGutted\\SystemGutted.dll");
            }
            }

        public void updatePaint ()
            {
            /*
            *
            *Some simple math, timers and set methods to get the values for, and update the paint.
            *
            */
            while(!_shouldStop)
                {
                if((stopwatch.ElapsedMilliseconds % 1000) == 0)
                    {
                    runTimeMilli = (stopwatch.ElapsedMilliseconds / 1000);
                    mainForm.setRunTime(runTimeMilli);
                    mainForm.setMobsKilled(mobsKilled);
                    mainForm.setPursesLooted(coinPursesCurrent - coinPursesStart);
                    mainForm.setHourly((3600 / runTimeMilli) * (coinPursesCurrent - coinPursesStart));
                    
                    }

                }
            }

        public void requestStop ()
            {
            _shouldStop = true;
            }


        public void prepareForCombat ()
            {
            /*
             *
             *Doing some last minute things before combat, which in a daggerspells case is..... casting magic circle
             *
             */

            while(dist(me.target) >= 21)
                ComeTo(me.target, 17);
            if(skillCooldown("Magic Circle") == 0 && dist(me.target) <= 20)
                {
                UseSkillAndWait("Magic Circle");
                Thread.Sleep(100);
                }

            }


        public void PluginRun ()
            {
                Log("Welcome to theGRINDER");
            /*
            *
            *Initializing variables for the paint
            *
            */
            stopwatch.Start();
            coinPursesStart = itemCount(29207);
            coinPursesCurrent = itemCount(29207);

            /*
            *
            *Drawing the paint
            *
            */
            mainForm = new Main();
            formThread = new Thread(RunForm);
            formThread.SetApartmentState(ApartmentState.STA);
            formThread.Start();

            /*
            *
            *Update the paint
            *
            */
            paintThread = new Thread(updatePaint);
            paintThread.SetApartmentState(ApartmentState.STA);
            paintThread.Start();



            /*
            *
            *Make a new task to avoid attacking tagged mobs
            *And make a zone for us to look for mobs in
            *
            */
            new Task(() => { CancelAttacksOnAnothersMobs(); }).Start();
            RoundZone zone = new RoundZone(me.X, me.Y, 100);

            /*
           *
           *And now for something completely different
           *   
           */

            while(true)
                {
                // updatePaint();
                if(me.isAlive())
                    {

                    /*
                    *
                    *Does my hair look okay?
                    *
                    */
                    checkBuffs();

                    Creature bestMob = null;

                    /*
                    *
                    *Well we're alive.... but are we alive 'enough'?
                    *
                    */
                    if((mpp() > 40 && hpp() > 70) || getAggroMobs().Count > 0)
                        {
                        bestMob = GetBestNearestMob(zone);
                        }

                    /*
                    *
                    *Just because we've found the bestmob doesn't mean you should marry it
                    *
                    */

                    if(bestMob != null)
                        {
                        try
                            {

                            while(bestMob != null && isAlive(bestMob) && isExists(bestMob) && isAlive())
                                {

                                /*
                                *
                                *Hey here is an idea, how about we don't help random people kill mobs
                                *
                                */

                                if(bestMob.aggroTarget != me && bestMob.firstHitter != null && bestMob.firstHitter != me)
                                    {
                                    bestMob = null;
                                    break;
                                    }

                                /*
                                *
                                *Why is this random mob attacking me?
                                *No idea but I guess we should kill it
                                *
                                */

                                if(bestMob.firstHitter == null && getAggroMobs().Count > 0 && bestMob != GetBestNearestMob(zone))
                                    bestMob = GetBestNearestMob(zone);

                                /*
                                *
                                *If it's the best mob you should problably target it
                                *
                                */
                                if(me.target != bestMob)
                                    SetTarget(bestMob);

                                /*
                                *
                                *It helps if you look at it Dave
                                *
                                */
                                if(angle(bestMob, me) > 45 && angle(bestMob, me) < 315)
                                    TurnDirectly(bestMob);

                                /*
                                *
                                *AND MY AXE
                                *
                                */
                                prepareForCombat();

                                /*
                                *
                                *If below 33% Hp, then feign death    
                                *
                                */
                                if(hpp() < 33 && skillCooldown("Play Dead") == 0)
                                    {
                                    Thread.Sleep(500);
                                    CancelTarget();
                                    UseSkill("Play Dead");
                                    Thread.Sleep(15000);


                                    }

                                /*
                                *
                                *If below 75% hp, Enervate is off cooldown, Earthern Grip is off cooldown - then Healing Combo
                                *
                                */
                                if((hpp() < 75) && (skillCooldown("Enervate") == 0) && (skillCooldown("Earthen Grip") == 0))
                                    {
                                        Thread.Sleep(1000);
                                    UseSkillAndWait("Enervate");
                                    Thread.Sleep(250);
                                    UseSkillAndWait("Earthen Grip");
                                    Thread.Sleep(50);
                                    }

                                /*
                                *
                                *Well we've got enough health I guess we should try make some mana back
                                *
                                */
                                if((mpp() < 75) && (skillCooldown("Enervate") == 0))
                                    UseSkillAndWait("Enervate");

                                /*
                                *
                                *Well now I guess I'll just throw fucking fireballs
                                *
                                */
                                for(int i = 0; i < 2; i++)
                                    UseSkillAndWait("Flamebolt");
                                /*
                                *
                                *And.... sleep
                                *                            
                                */
                                Thread.Sleep(10);
                                }

                            /*
                            *
                            *Is it dead? Wow I managed to kill something
                            *
                            */
                            if(bestMob != null && !isAlive(bestMob) && isExists(bestMob) && bestMob.type == BotTypes.Npc)
                                {
                                mobsKilled++;

                                }

                            /*
                            *
                            *Its DEAD and it has loot? SHWWEEETTT
                            *
                            */
                            while(bestMob != null && !isAlive(bestMob) && isExists(bestMob) && bestMob.type == BotTypes.Npc && ((Npc)bestMob).dropAvailable && isAlive())
                                {
                                if(me.dist(bestMob) > 3)
                                    ComeTo(bestMob, 1);
                                PickupAllDrop(bestMob);
                                if(itemCount(29207) > (coinPursesCurrent))
                                    {
                                    coinPursesCurrent++;
                                    }
                                }




                            }
                        catch { }

                        }


                    }
                else
                    {
                    /*
                    *
                    *Well if I'm not alive I should problably revive and run back
                    *
                    */
                    while(!me.isAlive())
                        {
                        ResToRespoint();
                        }
                    Random rnd = new Random();
                    Log("Oh dear it appears we died");
                    Thread.Sleep(rnd.Next(60000, 180000));
                    Log("Well we can't hang around here all day, lets get moving shall we?");
                    MoveForward(true);
                    Thread.Sleep(1000);
                    MoveForward(false);
                    Gps gps = new Gps(this);
                    gps.LoadDataBase(Application.StartupPath + "\\plugins\\SystemGutted\\TheGrinder.db3");
                    gps.GpsMove("spawn");
                    }

                Thread.Sleep(10);
                }
            }



        public void PluginStop ()
            {
            try
                {
                if(mainForm != null)
                    {
                    mainForm.Invoke(new Action(() => mainForm.Close()));
                    mainForm.Invoke(new Action(() => mainForm.Dispose()));
                    }
                requestStop();
                }
            catch
            { }

            Log("Thank you for using TheGrinder version " + GetPluginVersion() + " by " + GetPluginAuthor());

            }


        }
    }

main.cs
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GuttedSpace
{
    public partial class Main : Form
    {           

        
        public Main()
        {
            InitializeComponent();
        }
        
        public void setRunTime(long setter){
            this.runTimeEdit.Text = setter.ToString() + " Seconds";
        }
          
        public void setMobsKilled(int setter){
           this.mobsKilledEdit.Text = setter.ToString();
        }
       
       public void setPursesLooted(long setter){
           this.lootedEdit.Text = setter.ToString();
       }
       
       public void setHourly(long setter){  
           this.perHourEdit.Text = setter.ToString();
       }
       
         private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.runTimeEdit = new System.Windows.Forms.Label();
            this.lootedEdit = new System.Windows.Forms.Label();
            this.mobsKilledEdit = new System.Windows.Forms.Label();
            this.perHourEdit = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 36);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(59, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Run Time :";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(13, 59);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(67, 13);
            this.label2.TabIndex = 1;
            this.label2.Text = "Mobs Killed :";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(13, 82);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(100, 13);
            this.label3.TabIndex = 2;
            this.label3.Text = "Coin purses looted :";
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(13, 106);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(107, 13);
            this.label4.TabIndex = 3;
            this.label4.Text = "Coinpurses per hour :";
            // 
            // runeTimeEdit
            // 
            this.runTimeEdit.AutoSize = true;
            this.runTimeEdit.Location = new System.Drawing.Point(126, 36);
            this.runTimeEdit.Name     = "runeTimeEdit";
            this.runTimeEdit.Size     = new System.Drawing.Size(0, 13);
            this.runTimeEdit.TabIndex = 4;
            // 
            // lootedEdit
            // 
            this.lootedEdit.AutoSize = true;
            this.lootedEdit.Location = new System.Drawing.Point(126, 82);
            this.lootedEdit.Name = "lootedEdit";
            this.lootedEdit.Size = new System.Drawing.Size(0, 13);
            this.lootedEdit.TabIndex = 5;
            // 
            // mobsKilledEdit
            // 
            this.mobsKilledEdit.AutoSize = true;
            this.mobsKilledEdit.Location = new System.Drawing.Point(126, 59);
            this.mobsKilledEdit.Name = "mobsKilledEdit";
            this.mobsKilledEdit.Size = new System.Drawing.Size(0, 13);
            this.mobsKilledEdit.TabIndex = 6;
            // 
            // perHourEdit
            // 
            this.perHourEdit.AutoSize = true;
            this.perHourEdit.Location = new System.Drawing.Point(126, 106);
            this.perHourEdit.Name = "perHourEdit";
            this.perHourEdit.Size = new System.Drawing.Size(0, 13);
            this.perHourEdit.TabIndex = 7;
            // 
            // Main
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(300, 173);
            this.Controls.Add(this.perHourEdit);
            this.Controls.Add(this.mobsKilledEdit);
            this.Controls.Add(this.lootedEdit);
            this.Controls.Add(this.runTimeEdit);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Main";
            this.Text = "TheGrinder";
            this.ResumeLayout(false);
            this.PerformLayout();

        }
                private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Label runTimeEdit;
        private System.Windows.Forms.Label lootedEdit;
        private System.Windows.Forms.Label mobsKilledEdit;
        private System.Windows.Forms.Label perHourEdit;


   
    }
}

This plugin is open source so I'll never charge for it, instead how about you buy me a coffee?
 
Last edited:
runs pretty well. could you give us your recommended skill build?
 
is the death walk actually working for you? as it's not even working for me?:P
And i'll add a spec to the OP
no, it did not. ive tested it once. and ive changed the hp threshold to start a fight to 60% cause i use clotharmour :D
 
no, it did not. ive tested it once. and ive changed the hp threshold to start a fight to 60% cause i use clotharmour :D
Glad someones getting use from it :) Gps seems to dislike working for me but once I get it working I'll be re-writing and make a much... cleaner... version. That will include a GUI for setting things like hp/mana thresholds, name of your .db3 path, etc
 
Sounds awesome pal. :) I realy like how it performs right now, its like you intended it to be, with almost no downtime. It was a bit confuseing at first, and it died a lot, untill i checked which skills you actually used :D i just filled up the rest of the skilltree with passivs and since then its been running without failure for about 3 hours now... thanks!
 
Sounds awesome pal. :) I realy like how it performs right now, its like you intended it to be, with almost no downtime. It was a bit confuseing at first, and it died a lot, untill i checked which skills you actually used :D i just filled up the rest of the skilltree with passivs and since then its been running without failure for about 3 hours now... thanks!
yeah as the skilltree I've now listed in the OP shows I basically use 3 attack spells, 3 buffs and playdead. The rest is passives and a few sorcery skills to allow the picking up of more passives :D
 
So the "Gutting" of the old script... which is to say a much neater re-write is complete.
Death walk should now work 100% of the time, it is for me.
Should now handle play dead alot better, you know, it'll actually play dead.
Source code now contains 100% more sarcastic comments
Death walk actually works
A lovely little paint that tells you, Time running (in seconds, It's late and I cba converting), Total kills, Total coinpurses looted, coinpurses per hour(this may or may not work)
now with 100% less crash bugs, when i was testing it originally closing the paint, crashed AB, stopping the plugin, crashed AB.

Code has been updated in the OP
Most things have a comment so I guess it may be of some value to people trying to learn

Coming Soon -
Anti bot report :O
 
hmm the new code is not compiling anyone having this issue?

11:29:54 PM: c:\Users\wilder\Desktop\Archebuddy\Plugins\SystemGutted\Simple Grinder.cs(16,18) : error CS0246: The type or namespace name 'Main' could not be found (are you missing a using directive or an assembly reference?)
 
yea it seems to be something with the new code it dosent let me compile and i dont know anything about code so i cant fix it.
 
Guttedgrinder.cs updated to make coinpurses per hour work.
Also forgot to mention that I've put very simple handling of the suspected user debuff in
 
Last edited:
Testing this now, would be cool to see party use incorporated so that it will kill mobs tagged by party members :D
 
To kill mobs tagged by a party member I believe all you'd have to do is
change
Code:
                if(obj.type == BotTypes.Npc && isAttackable(obj) && (obj.firstHitter == null || obj.firstHitter == me) && isAlive(obj) && me.dist(obj) < dist && zone.ObjInZone(obj)
to
Code:
                if(obj.type == BotTypes.Npc && isAttackable(obj) && (obj.firstHitter == null || obj.firstHitter == me || obj.firstHitter == PartyMember) && isAlive(obj) && me.dist(obj) < dist && zone.ObjInZone(obj)

in the GetBestNearestMob method.
Personally I can't test it as I never party, but if you want to make the change and get back to me on whether it works, if it does I'll add it to the OP
 
I might be doing something wrong but when I try to change it I get this error
'ArcheBuddy.Bot.Classes.PartyMember' is a 'type' but is used like a 'variable'
 
Back
Top