All pastes #941800 Raw Edit

Miscellany

public text v1 · immutable
·published 2008-03-13 23:07 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using D2DataNew;
using Mapper;
using Mapper.Pathing;
using Mapper.Pathing.Heuristics;
using Mapper.Pathing.Interfaces;
using Mapper.Pathing.Processors;

namespace PindleSkill.Bots
{
    //This class inherit from BotBase, wich means it is like an "addon" to BotBase
    class Pindle : BotBase
    {
        BotConfig cfg;//holds the current configuration
        bool CheckLife = false;//tell the program if he need to do a life check or not, usefull when you enter game (you dont want to chicken in town)
        GameInfo.GameObject RedTP //will find the red portal
        {
            get
            {
                return base.currentGameInfo.FindGameObject(n => n.ObjectId == GameObjectClass.PermanentTownPortal);
            }
        }

        /// <summary>
        /// Creates a new instance of Pindle class
        /// </summary>
        /// <param name="cfg"></param>
        public Pindle(BotConfig cfg)
            : base(cfg)
        {
            this.cfg = cfg;
        }

        /// <summary>
        /// The bot automatically call this method when it enter game.
        /// The run needs to be coded in there
        /// </summary>
        /// <returns></returns>
        public override bool onGameEnter()
        {
            base.ReportProgress("Game Entered");
            sleep(100);
            //Dont really bother with that.. I have the same thing twice but I need to convert it to use pathing functions correctly
            GameDifficulty diff = GameDifficulty.Nightmare;
            switch (base.cfg.Difficulty)
            {
                case DifficultyType.Normal:
                    diff = GameDifficulty.Normal;
                    break;
                case DifficultyType.Hell:
                    diff = GameDifficulty.Hell;
                    break;
            }

            //if life is lower than 900, or mana lower than 300; go talk to malah to heal
            if (currentGameInfo.Me.Life < 900 || currentGameInfo.Me.Mana < 300)
            {
                ReportProgress("We need to heal, going to malah. life=" + currentGameInfo.Me.Life + " mana=" + currentGameInfo.Me.Mana);
                Console.WriteLine(currentGameInfo.Me.Life + " mana=" + currentGameInfo.Me.Mana);
                //go to the npc
                if (!base.GoToHealingNPC(Act.Five, base.myBot.seed, diff, 300, 5, 10))
                    throw new GameFailedException("Failed to walk to malah");
                //but we need to interact with it manually, so the malah from the list of NPCs
                GameInfo.NPC malah = base.currentGameInfo.FindMonster(n => n.Id == NPCClass.Malah);
                if (malah == null)
                    throw new GameFailedException("Failed to find malah!");
                //those methdos send packets to interact with malah
                base.SendGS(D2PacketsNew.GameClient.GoToTownFolk.Build(UnitType.NPC, malah.UID,(uint) malah.X, (uint)malah.Y));
                sleep(100);
                base.SendGS(D2PacketsNew.GameClient.UnitInteract.Build(UnitType.NPC, malah.UID));
                sleep(100);
                base.SendGS(D2PacketsNew.GameClient.TownFolkInteract.Build(UnitType.NPC, malah.UID));
            }
            ReportProgress("Leaving town");
            //here we walk to the red portal
            if (!base.GoToRedTP(Act.Five, base.myBot.seed, diff, 300, 5, 10))
            {
                ReportProgress("Game failed: Failed to reach red TP");
                throw new GameFailedException("Game failed: Failed to reach red TP");
            }
            //if the portal is not detected, it means that we got stuck somewhere, so run failed
            //note that there is a TODO here wich is to retry pathing
            if (RedTP == null)
            {
                ReportProgress("Game failed: could not locate red TP");
                throw new GameFailedException("Game failed: could not locate red TP");
            }
            //enable life watch
            CheckLife = true;
            //send the packets to enter the red portal
            base.SendGS(D2PacketsNew.GameClient.RunToLocation.Build(RedTP.X, RedTP.Y));
            base.sleep(100);
            base.SendGS(D2PacketsNew.GameClient.RunToTarget.Build(UnitType.GameObject, RedTP.UID));
            base.sleep(100);
            base.SendGS(D2PacketsNew.GameClient.UnitInteract.Build(UnitType.GameObject, RedTP.UID));

            //this is an ugly loop to check if we left town
            int startTime = Environment.TickCount;
            while (base.currentGameInfo.Me.Y < 10000)
            {
                if (Environment.TickCount - startTime > 3000)
                {
                    ReportProgress("Game failed: Failed to leave town");
                    throw new GameFailedException("Game failed: Failed to leave town");
                }
            }

            //we get a path to teleport close to pindle
            LevelMap map = Map.Instance.LoadLevelMap(base.myBot.seed,AreaLevel.NihlathaksTemple,diff);
            List<AStarNode> path = new AStar(map,new DiagonalShortcut(), new TeleportReducer(40)).FindPath(currentGameInfo.Me.Position,new System.Drawing.Point(10062, 13240));

            //we teleport that path
            if (!base.Teleport(path, 3000))
            {
                ReportProgress("Game failed: Failed to teleport to pindle");
                throw new GameFailedException("Game failed: Failed to teleport to pindle");
            }

            sleep(500);

            //tricky way to get pindle... Unkown part len is greater than others.. (dont bother with this)
            //OBSOLETE
            GameInfo.NPC[] pindleAndMinions = currentGameInfo.FindMonsters(NPCClass.DefiledWarrior);

            GameInfo.NPC pindle = null;
            foreach(GameInfo.NPC npc in pindleAndMinions)
            {
                if (pindle == null)
                {
                    pindle = npc;
                    continue;
                }
                if (npc.Unknown.Length > pindle.Unknown.Length)
                    pindle = npc;
            }
            //END OBSOLETE

            //Will kill pindle!
            if (!base.KillMonstersClosest(currentGameInfo.FindMonstersUIDs(NPCClass.DefiledWarrior)
                ,SkillType.Blizzard,SkillType.IceBlast,1500,10000))
            {
                ReportProgress("Game failed: Failed to kill pindle");
                throw new GameFailedException("Game failed: Failed to kill pindle");
            }

            //Pick items and run is done!
            Pickit();
            return true;
        }

        /// <summary>
        /// this gets called when the game is exited, it is there to let clean some variables if we need to
        /// </summary>
        public override void onRunDoneCleanUp()
        {
            CheckLife = false;
        }

        /// <summary>
        /// each packets you receive is passed to that method
        /// You can implement your own packet-specific actions here
        /// </summary>
        /// <param name="packet"></param>
        public override void OverrideReceivePacket(D2PacketsNew.GameServer.GSPacket packet)
        {
            switch (packet.PacketType)
            {
                case D2PacketsNew.D2Packets.GameServerPacket.LifeManaChange:
                    if (CheckLife)
                    {
                        D2PacketsNew.GameServer.LifeManaChange lifeManaChange = new D2PacketsNew.GameServer.LifeManaChange(packet.Data);
                        if (lifeManaChange.Life < 400)
                            Chicken();
                        else if (lifeManaChange.Life < 1000)
                            base.myBelt.DrinkPotion(ref base.myBot);
                    }
                    break;

            }
        }

        //will just leave game..
        public void Chicken()
        {
            //invoke;
            //find a way to t hrow an exception on another thread
            base.SendGS(D2PacketsNew.GameClient.ExitGame.Build());
            /*System.Threading.Thread thread;
            throw new GameFailedException("Chicken!");*/
        }
    }
}