private void ExecutaRespawMob() { while (this.Active) { if (Client == null) { return; } // Varre todos os cliente foreach (Client client in Client) { if (client.Character == null || client.Character.Mob.ClientId == 0) { return; } //Traz somente os mob morto que esteja na visao do client SMobList[] mobList = client.MobView.Where(a => a.Mob.GameStatus.CurHP < 0).ToArray(); short p1x = client.Character.Mob.LastPosition.X; short p1y = client.Character.Mob.LastPosition.Y; // Varre todos os mobs mortos que o client matou for (int i = 0; i < mobList.Length; i++) { client.MobView.Remove(mobList[i]); short p2x = mobList[i].Mob.LastPosition.X; short p2y = mobList[i].Mob.LastPosition.Y; double ctOposto = p1x - p2x; double ctAdjacente = p1y - p2y; double hipotenusa = Math.Sqrt((ctOposto * ctOposto) + (ctAdjacente * ctAdjacente)); if (hipotenusa < 30) { mobList[i].Mob.GameStatus.CurHP = mobList[i].Mob.GameStatus.MaxHP; client.MobView.Add(mobList[i]); //O mob esta morto mas continua na visao do client, entao da respaw no mob client.Send(P_364.New(mobList[i].Mob, EnterVision.LogIn)); } else { //O mob esta morto e nao esta na visao do client client.MobView.Remove(mobList[i]); } } } // Nasce os mobs a cada 10s Thread.Sleep(10000); } }
// 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)); } }
public byte [] Unk1; // 16 a 35 = 20 // Controlador public static void Controller(Client client, P_213 rcv) { if (rcv.Slot < 0 || rcv.Slot > 3) { client.Close( ); } else { // Retorna o personagem selecionado Character character = client.Account.Characters [rcv.Slot]; if (character == null) { client.Close( ); } else { // Retorna um ClientId vaziu short ClientId = client.Channel.GetClientId( ); if (ClientId < Config.Values.Clients.MinCid) { client.Send(P_101.New("Parece que este canal está lotado. Tente novamente!")); } else { // Retorna a posição de respawn Coord coord = Functions.GetFreeRespawnCoord(client.Channel.Map, character); if (coord == null) { client.Send(P_101.New("Parece que este o mapa está lotado. Tente novamente!")); } else { // Define o ClientId do cliente client.ClientId = character.Mob.ClientId = ClientId; // Define a posição do mob character.Mob.LastPosition = SPosition.New(coord); // Adiciona posição a lista de posições character.Positions.Clear( ); character.Positions.Add(character.Mob.LastPosition); // Define o cliente na coordenada coord.Client = client; // Envia o pacote de entrar no mundo client.Send(P_114.New(character)); // Prepara o pacote de visão do cliente P_364 p364 = P_364.New(character, EnterVision.LogIn); // Envia o pacote de visão do cliente pro cliente client.Send(p364); // Altera o status do cliente client.Status = ClientStatus.Game; // Define o mapa, character do cliente e inicia o Surround client.Map = client.Channel.Map; client.Character = character; client.Surround = new Surround(client); // Atualiza os arredores e envia a visão para todos e para o cliente client.Surround.UpdateSurrounds(null, entered => { entered.ForEach(a => { switch (a) { case Client client2: { client.Send(P_364.New(client2.Character, EnterVision.Normal)); client2.Send(p364); break; } } }); }, null); // Envia uma mensagem pro cliente client.Send(P_101.New("Seja bem-vindo ao mundo do Open WYD Server!")); } } } } }