public static P_36C New(int ClientId, SPosition Src, SPosition Dst, int Type, int Speed, byte[] Directions) { P_36C tmp = new P_36C { Header = SHeader.New(0x36C, Marshal.SizeOf <P_36C>(), ClientId), Src = Src, Type = Type, Speed = Speed, Directions = new byte[12], Unk1 = new byte[12], Dst = Dst, }; if (Directions != null) { Array.Copy(Directions, tmp.Directions, tmp.Directions.Length); } return(tmp); }
public void ExecutaAndarMob() { while (this.Active) { for (int i = 0; i < Client.Count(); i++) { for (int a = 0; a < Client[i].MobView.Where(b => b.Mob.Merchant == 0).Count(); a++) { //if que decide se o mob anda ou não (50% de chance de andar) if (_rand.Next(0, 100) > 50) { SMobList mob = Client[i].MobView[a]; int x, y; //if para evitar erro do random if (mob.PositionInicial.X < mob.PositionFinal.X) { x = _rand.Next(mob.PositionInicial.X, mob.PositionFinal.X); } else { x = _rand.Next(mob.PositionFinal.X, mob.PositionInicial.X); } if (mob.PositionInicial.Y < mob.PositionFinal.Y) { y = _rand.Next(mob.PositionInicial.Y, mob.PositionFinal.Y); } else { y = _rand.Next(mob.PositionFinal.Y, mob.PositionInicial.Y); } // Prepara o pacote de andar dos mobs / npc P_36C p36c = P_36C.New(mob.Mob.ClientId, mob.PositionInicial, SPosition.New(x, y), 0, mob.Speed, new byte[12]); // Envia o pacote de andar Client[i].Send(p36c); } } } // Mob / Npc anda a cada 5s Thread.Sleep(5000); } }
public static void Teleport(Client client, SPosition sPosition) { //Adiciona posição a lista de posições client.Character.Positions.Clear(); client.Character.Positions.Add(client.Character.Mob.LastPosition); P_36C p36C = P_36C.New(client.ClientId, client.Character.Mob.LastPosition, sPosition, 1); //envia para a nova coordenada client.Send(p36C); // Atualiza os arredores Functions.UpdateFromaWorld(client, p36C); client.Character.Positions.Add(sPosition); //Atualiza a ultima posicao para o destino client.Character.Mob.LastPosition = sPosition; }
// Controlador public static void Controller(Client Client, P_36C Rcv) { // Guarda a posição original do personagem Coord cur = Client.Map.GetCoord(Client.Character.Mob.LastPosition); // Guarda a posição de destino Coord dst = Client.Map.GetCoord(Rcv.Dst); // Verifica se as posições de origem e destino são a mesma if (Client.Character.Mob.LastPosition == Rcv.Dst) { return; } // Verifica se o caminho de destino está vaziu else if (!dst.CanWalk) { // Manda cliente de volta pra posição inicial Log.Error("Impossivel de andar"); return; } //// Verifica se a posição de origem está na lista de posições do personagem //else if ( !Client.Character.Positions.Contains ( Rcv.Src ) ) { // // Manda cliente de volta pra posição inicial // Log.Error ( 1 ); // Sendback ( ); // return; //} // Valida o caminho pelo HeightMap SPosition position = Rcv.Src; List <SPosition> positions = new List <SPosition>() { position }; int cHeight = Config.HeightMap(position), oHeight = cHeight; foreach (byte direction in Rcv.Directions) { if (direction == 0) { break;// Chegou ao fim } switch (direction) { case 49: position.X--; position.Y--; break; // -X -Y case 50: position.Y--; break; // -Y case 51: position.X++; position.Y--; break; // +X -Y case 52: position.X--; break; // -X case 54: position.X++; break; // +X case 55: position.X--; position.Y++; break; // -X +Y case 56: position.Y++; break; // +Y case 57: position.X++; position.Y++; break; // +X +Y default: Client.Close($"Unk direction: {direction}"); break; // Coordenada inválida } // Guarda a altura do mapa de destino oHeight = Config.HeightMap(position); // Verifica se a mudança de altura é maior que 9 if (Math.Abs(cHeight - oHeight) > 9) { // Manda cliente de volta pra posição inicial Log.Error(2); Sendback(); return; } // Atualiza a altura do mapa atual cHeight = oHeight; // Adiciona a posição a lista positions.Add(position); } // Atualiza a lista de posições do personagem Client.Character.Positions.Clear(); Client.Character.Positions.AddRange(positions); // Atualiza a posição do personagem Client.Character.Mob.LastPosition = Rcv.Dst; // Atualiza a posição no mapa cur.Client = null; dst.Client = Client; // Pacote do andar P_36C p36C = New(Client.ClientId, Rcv.Src, Rcv.Dst, Rcv.Type, Rcv.Speed, Rcv.Directions); // Atualiza os arredores Functions.UpdateFromaWorld(Client, p36C); // Funções ajudantes void Sendback() { Client.Send(New(Client.ClientId, SPosition.New(cur), SPosition.New(cur), 1, 0, null)); } }
// Controlador public static void Controller(Client Client, P_36C Rcv, bool Is36C) { // Guarda a posição original do personagem Coord cur = Client.Map.GetCoord(Client.Character.Mob.LastPosition); // Guarda a posição de destino Coord dst = Client.Map.GetCoord(Rcv.Dst); // Verifica se as posições de origem e destino são a mesma if (Client.Character.Mob.LastPosition == Rcv.Dst) { return; } // Verifica se o caminho de destino está vaziu else if (!dst.CanWalk) { // Manda cliente de volta pra posição inicial Log.Error(0); Sendback( ); return; } // Verifica se a posição de origem está na lista de posições do personagem else if (!Client.Character.Positions.Contains(Rcv.Src)) { // Manda cliente de volta pra posição inicial Log.Error(1); Sendback( ); return; } // Valida o caminho pelo HeightMap SPosition position = Rcv.Src; List <SPosition> positions = new List <SPosition> ( ) { position }; int cHeight = Config.HeightMap(position), oHeight = cHeight; // Verifica qual pacote foi enviado if (Is36C) { foreach (byte direction in Rcv.Directions) { switch (direction) { case 0: continue; // Chegou ao fim case 49: position.X--; position.Y--; break; // -X -Y case 50: position.Y--; break; // -Y case 51: position.X++; position.Y--; break; // +X -Y case 52: position.X--; break; // -X case 54: position.X++; break; // +X case 55: position.X--; position.Y++; break; // -X +Y case 56: position.Y++; break; // +Y case 57: position.X++; position.Y++; break; // +X +Y default: Client.Close($"Unk direction: {direction}"); break; // Coordenada inválida } // Guarda a altura do mapa de destino oHeight = Config.HeightMap(position); // Verifica se a mudança de altura é maior que 9 if (Math.Abs(cHeight - oHeight) > 9) { // Manda cliente de volta pra posição inicial Log.Error(2); Sendback( ); return; } // Atualiza a altura do mapa atual cHeight = oHeight; // Adiciona a posição a lista positions.Add(position); } } else { // Adiciona a posição a lista positions.Add(Rcv.Dst); // INCOMPLETO, NADA FEITO AQUI AINDA!!! } // Atualiza a lista de posições do personagem Client.Character.Positions.Clear( ); Client.Character.Positions.AddRange(positions); // Atualiza a posição do personagem Client.Character.Mob.LastPosition = Rcv.Dst; // Atualiza a posição no mapa cur.Client = null; dst.Client = Client; // Pacote do andar P_36C p36C = New(Client.ClientId, Rcv.Src, Rcv.Dst, Rcv.Type, Rcv.Speed, Rcv.Directions); // Atualiza os arredores Client.Surround.UpdateSurrounds(same => { // Varre a lista foreach (object o in same) { switch (o) { case Client client2: { client2.Send(p36C); break; } } } }, entered => { // Visão do cliente P_364 p364 = P_364.New(Client.Character, EnterVision.Normal); p364.Position = SPosition.New(cur); // Varre a lista foreach (object o in entered) { switch (o) { case Client client2: { client2.Send(p364); client2.Send(p36C); Client.Send(P_364.New(client2.Character, EnterVision.Normal)); break; } } } }, left => { // Visão do cliente P_165 p165 = P_165.New(Client.ClientId, LeaveVision.Normal); // Varre a lista foreach (object o in left) { switch (o) { case Client client2: { client2.Send(p36C); client2.Send(p165); Client.Send(P_165.New(client2.ClientId, LeaveVision.Normal)); break; } } } }); // Funções ajudantes void Sendback( ) { Client.Send(New(Client.ClientId, SPosition.New(cur), SPosition.New(cur), 1, 0, null)); } }