/// <summary>
 /// Constructor
 /// </summary>
 internal GraalLevelNPC(Framework Server, GraalLevel Level, int Id)
     : base(ScriptType.LEVELNPC)
 {
     this.Server = Server;
     this.Level = Level;
     this.Id = Id;
     this.Save = new SaveIndex(this, 10);
 }
 /// <summary>
 /// Adjust Levels
 /// </summary>
 internal void AdjustLevels()
 {
     this.PlayerLevel = Server.FindLevel(PlayerMap == null ? this.Level : PlayerMap.GetLevelAt(GmapX, GmapY));
 }
        /// <summary>
        /// Set Properties
        /// </summary>
        internal void SetProps(CString Packet)
        {
            bool moved = false;
            while (Packet.BytesLeft > 0)
            {
                Int32 PropId = Packet.ReadGUByte1();

                switch ((Properties)PropId)
                {
                    case Properties.NICKNAME: // 0
                        this.SetNick(Packet.ReadChars(Packet.ReadGUByte1()));
                        break;

                    case Properties.MAXPOWER: // 1
                        this.FullHearts = Packet.ReadGUByte1();
                        break;

                    case Properties.CURPOWER: // 2
                        this.Hearts = (double)Packet.ReadGUByte1() / 2;
                        break;

                    case Properties.RUPEESCOUNT: // 3
                        this.Gralats = (int)Packet.ReadGUByte3();
                        break;

                    case Properties.ARROWSCOUNT: // 4
                        this.Arrows = Packet.ReadGUByte1();
                        break;

                    case Properties.BOMBSCOUNT: // 5
                        this.Bombs = Packet.ReadGUByte1();
                        break;

                    case Properties.GLOVEPOWER: // 6
                        this.GlovePower = Packet.ReadGUByte1();
                        break;

                    case Properties.BOMBPOWER: // 7
                        this.BombPower = Packet.ReadGUByte1();
                        break;

                    case Properties.SWORDPOWER: // 8
                    {
                        Int32 sp = Packet.ReadGUByte1();
                        if (sp > 4)
                        {
                            sp -= 30;
                            Int32 len = Packet.ReadGUByte1();
                            if (len > 0)
                                this.SwordImage = Packet.ReadChars(len);
                        }
                        else this.SwordImage = "sword" + sp + ".png";

                        this.SwordPower = sp;
                        break;
                    }

                    case Properties.SHIELDPOWER: // 9
                    {
                        Int32 sp = Packet.ReadGUByte1();
                        if (sp > 3)
                        {
                            sp -= 10;
                            if (sp < 0) break;
                            Int32 len = Packet.ReadGUByte1();
                            if (len > 0)
                                this.ShieldImage = Packet.ReadChars(len);
                        }
                        else this.ShieldImage = "shield" + sp + ".png";

                        this.ShieldPower = sp;
                        break;
                    }

                    case Properties.ANIMATION: // 10
                        this.Ani = Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.HEADIMAGE: // 11
                    {
                        Int32 len = Packet.ReadGUByte1();
                        this.HeadImage = (len < 100 ? "head" + len + ".png" : Packet.ReadChars(len - 100));
                        break;
                    }

                    case Properties.CURCHAT: // 12
                        this.Chat = Packet.ReadChars(Packet.ReadGUByte1());
                        if (PlayerLevel != null)
                            PlayerLevel.CallNPCs("onPlayerChats", new object[] { this });
                        break;

                    case Properties.PLCOLORS: // 13
                        for (int i = 0; i < 5; i++)
                            this.ColorManager[i] = Packet.ReadGUByte1();
                        break;

                    case Properties.PLAYERID: // 14
                        Packet.ReadGUByte2();
                        break;

                    case Properties.PLAYERX: // 15 - obsolete
                        Packet.ReadGUByte1();
                        //this.X = ((double)Packet.ReadGUByte1() / 2);
                        //moved = true;
                        break;

                    case Properties.PLAYERY: // 16 - obsolete
                        Packet.ReadGUByte1();
                        //this.Y = ((double)Packet.ReadGUByte1() / 2);
                        //moved = true;
                        break;

                    case Properties.PLSPRITE: // 17
                        this.Dir = Packet.ReadGUByte1() % 4;
                        break;

                    case Properties.PLSTATUS: // 18
                        this.PlayerStatus = Packet.ReadGUByte1();
                        if ((this.PlayerStatus & (int)Status.DEAD) != 0)
                        {
                            if (PlayerLevel != null)
                                PlayerLevel.CallNPCs("onPlayerDies", new object[] { this });
                        }
                        break;

                    case Properties.CARRYSPRITE: // 19
                        Packet.ReadGUByte1();
                        break;

                    case Properties.CURLEVEL: // 20
                        this.Level = Packet.ReadChars(Packet.ReadGUByte1()).Trim();
                        if (this.PlayerLevel != null)
                            PlayerLevel.DeletePlayer(this);
                        PlayerLevel = Server.FindLevel(this.Level);
                        PlayerLevel.AddPlayer(this);
                        break;

                    case Properties.HORSEIMG: // 21
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.HORSEBUSHES: // 22
                        Packet.ReadGUByte1();
                        break;

                    case Properties.EFFECTCOLOR: // 23
                    {
                        int len = Packet.ReadGUByte1();
                        if (len > 0)
                            Packet.ReadGUByte4();
                        break;
                    }

                    case Properties.CARRYNPC: // 24
                        Packet.ReadGUByte3();
                        break;

                    case Properties.APCOUNTER: // 25
                        Packet.ReadGUByte2();
                        break;

                    case Properties.MAGICPOINTS: // 26
                        this.Magic = Packet.ReadGUByte1();
                        break;

                    case Properties.KILLSCOUNT: // 27
                        this.Kills = Packet.ReadGByte3();
                        break;

                    case Properties.DEATHSCOUNT: // 28
                        this.Deaths = Packet.ReadGByte3();
                        break;

                    case Properties.ONLINESECS: // 29
                        this.OnlineTime = Packet.ReadGByte3();
                        break;

                    case Properties.IPADDRESS: // 30
                        this.IPAddress = new System.Net.IPAddress(Packet.ReadGUByte5()).ToString();
                        break;

                    case Properties.UDPPORT: // 31
                        Packet.ReadGByte3();
                        break;

                    case Properties.ALIGNMENT: // 32
                        Packet.ReadGUByte1();
                        break;

                    case Properties.ADDITFLAGS: // 33
                        Packet.ReadGUByte1();
                        break;

                    case Properties.ACCOUNTNAME: // 34
                        this.Account = Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.BODYIMAGE: // 35
                        this.BodyImage = Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.PLRATING: // 36
                        Packet.ReadGUByte3();
                        break;

                    case Properties.GATTRIB1: // 37
                    case Properties.GATTRIB2: // 38
                    case Properties.GATTRIB3: // 39
                    case Properties.GATTRIB4: // 40
                    case Properties.GATTRIB5: // 41
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.PLATTACHNPC: // 42
                        Packet.ReadGUByte4();
                        break;

                    case Properties.GMAPLEVELX: // 43
                        GmapX = Packet.ReadGUByte1();
                        break;

                    case Properties.GMAPLEVELY: // 44
                        GmapY = Packet.ReadGUByte1();
                        break;

                    case Properties.PLAYERZ: // 45
                        Packet.ReadGUByte1();
                        break;

                    case Properties.GATTRIB6: // 46
                    case Properties.GATTRIB7: // 47
                    case Properties.GATTRIB8: // 48
                    case Properties.GATTRIB9: // 49
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.JOINLEAVELV: // 50
                        Packet.ReadGUByte1();
                        break;

                    case Properties.CONNECTED: // 51
                        Server.PlayerManager.DeletePlayer(Id);
                        // disconnect player.
                        break;

                    case Properties.LANGUAGE: // 52
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.STATUSMSG: // 53
                        Packet.ReadGUByte1();
                        break;

                    case Properties.GATTRIB10: // 54
                    case Properties.GATTRIB11: // 55
                    case Properties.GATTRIB12: // 56
                    case Properties.GATTRIB13: // 57
                    case Properties.GATTRIB14: // 58
                    case Properties.GATTRIB15: // 59
                    case Properties.GATTRIB16: // 60
                    case Properties.GATTRIB17: // 61
                    case Properties.GATTRIB18: // 62
                    case Properties.GATTRIB19: // 63
                    case Properties.GATTRIB20: // 64
                    case Properties.GATTRIB21: // 65
                    case Properties.GATTRIB22: // 66
                    case Properties.GATTRIB23: // 67
                    case Properties.GATTRIB24: // 68
                    case Properties.GATTRIB25: // 69
                    case Properties.GATTRIB26: // 70
                    case Properties.GATTRIB27: // 71
                    case Properties.GATTRIB28: // 72
                    case Properties.GATTRIB29: // 73
                    case Properties.GATTRIB30: // 74
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.OSTYPE: // 75
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    case Properties.TEXTCODEPG: // 76
                        Packet.ReadGUByte3();
                        break;

                    case Properties.UNKNOWN77: // 77
                        break;

                    case Properties.PIXELX: // 78
                    {
                        int tmp = this.PixelX = Packet.ReadGUByte2();

                        // If the first bit is 1, our position is negative.
                        this.PixelX >>= 1;
                        if ((tmp & 0x0001) != 0)
                            this.PixelX = -this.PixelX;
                        moved = true;
                        break;
                    }

                    case Properties.PIXELY: // 79
                    {
                        int tmp = this.PixelY = Packet.ReadGUByte2();

                        // If the first bit is 1, our position is negative.
                        this.PixelY >>= 1;
                        if ((tmp & 0x0001) != 0)
                            this.PixelY = -this.PixelY;
                        moved = true;
                        break;
                    }

                    case Properties.PIXELZ: // 80
                        Packet.ReadGUByte2();
                        break;

                    case Properties.UNKNOWN81: // 81
                        break;

                    case Properties.COMMUNITY: // 82
                        Packet.ReadChars(Packet.ReadGUByte1());
                        break;

                    default:
                        System.Windows.Forms.MessageBox.Show("Invalid Prop: " + PropId);
                        break;
                }
            }

            if (moved && PlayerLevel != null)
            {
                //bool onGmap = PlayerLevel.Name.EndsWith(".gmap");
                GraalLevelNPC npc = PlayerLevel.isOnNPC(PixelX + touchtestd[dir*2], PixelY + touchtestd[dir*2+1]);
                if (npc != null)
                    npc.Call("onPlayerTouchsMe", new object[] { this });
            }
        }