public static void Died(short Map_Num, byte Index) { Lists.Structures.NPC NPC = Lists.NPC[Lists.Temp_Map[Map_Num].NPC[Index].Index]; // Solta os itens for (byte i = 0; i < NPC.Drop.Length; i++) { if (NPC.Drop[i].Item_Num > 0) { if (Game.Random.Next(NPC.Drop[i].Chance, 101) == 100) { // Dados do item Lists.Structures.Map_Items Item = new Lists.Structures.Map_Items(); Item.Index = NPC.Drop[i].Item_Num; Item.Amount = NPC.Drop[i].Amount; Item.X = Lists.Temp_Map[Map_Num].NPC[Index].X; Item.Y = Lists.Temp_Map[Map_Num].NPC[Index].Y; // Solta Lists.Temp_Map[Map_Num].Item.Add(Item); } } } // Envia os dados dos itens no chão para o mapa Send.Map_Items(Map_Num); // Reseta os dados do NPC Lists.Temp_Map[Map_Num].NPC[Index].Vital[(byte)Game.Vitals.HP] = 0; Lists.Temp_Map[Map_Num].NPC[Index].Spawn_Timer = Environment.TickCount; Lists.Temp_Map[Map_Num].NPC[Index].Index = 0; Lists.Temp_Map[Map_Num].NPC[Index].Target_Type = 0; Lists.Temp_Map[Map_Num].NPC[Index].Target_Index = 0; Send.Map_NPC_Died(Map_Num, Index); }
private static short Regeneration(short Map_Num, byte Index, byte Vital) { Lists.Structures.NPC Data = Lists.NPC[Lists.Temp_Map[Map_Num].NPC[Index].Index]; // Cálcula o máximo de vital que o NPC possui switch ((Game.Vitals)Vital) { case Game.Vitals.HP: return((short)(Data.Vital[Vital] * 0.05 + Data.Attribute[(byte)Game.Attributes.Vitality] * 0.3)); case Game.Vitals.MP: return((short)(Data.Vital[Vital] * 0.05 + Data.Attribute[(byte)Game.Attributes.Intelligence] * 0.1)); } return(0); }
public static void Logic(short Map_Num) { // Lógica dos NPCs for (byte i = 1; i < Lists.Temp_Map[Map_Num].NPC.Length; i++) { Lists.Structures.Map_NPCs Data = Lists.Temp_Map[Map_Num].NPC[i]; Lists.Structures.NPC NPC_Data = Lists.NPC[Lists.Map[Map_Num].NPC[i].Index]; //////////////// // Surgimento // //////////////// if (Data.Index == 0) { if (Environment.TickCount > Data.Spawn_Timer + (NPC_Data.SpawnTime * 1000)) { Spawn(i, Map_Num); } continue; } else { byte TargetX = 0, TargetY = 0; bool[] CanMove = new bool[(byte)Game.Directions.Count]; short Distance; bool Moved = false; bool Move = false; ///////////////// // Regeneração // ///////////////// if (Environment.TickCount > Loop.Timer_NPC_Regen + 5000) { for (byte v = 0; v < (byte)Game.Vitals.Count; v++) { if (Data.Vital[v] < NPC_Data.Vital[v]) { // Renera os vitais Lists.Temp_Map[Map_Num].NPC[i].Vital[v] += Regeneration(Map_Num, i, v); // Impede que o valor passe do limite if (Lists.Temp_Map[Map_Num].NPC[i].Vital[v] > NPC_Data.Vital[v]) { Lists.Temp_Map[Map_Num].NPC[i].Vital[v] = NPC_Data.Vital[v]; } // Envia os dados aos jogadores do mapa Send.Map_NPC_Vitals(Map_Num, i); } } } ////////////////// // Movimentação // ////////////////// // Atacar ao ver if (NPC_Data.Behaviour == (byte)Behaviour.AttackOnSight) { // Jogador if (Lists.Temp_Map[Map_Num].NPC[i].Target_Index == 0) { for (byte Player_Index = 1; Player_Index <= Game.HigherIndex; Player_Index++) { // Verifica se o jogador está jogando e no mesmo mapa que o NPC if (!Player.IsPlaying(Player_Index)) { continue; } if (Player.Character(Player_Index).Map != Map_Num) { continue; } // Se o jogador estiver no alcance do NPC, ir atrás dele Distance = (short)Math.Sqrt(Math.Pow(Data.X - Player.Character(Player_Index).X, 2) + Math.Pow(Data.Y - Player.Character(Player_Index).Y, 2)); if (Distance <= NPC_Data.Sight) { Lists.Temp_Map[Map_Num].NPC[i].Target_Type = (byte)Game.Target.Player; Lists.Temp_Map[Map_Num].NPC[i].Target_Index = Player_Index; Data = Lists.Temp_Map[Map_Num].NPC[i]; // Mensagem if (!string.IsNullOrEmpty(Lists.NPC[Lists.Temp_Map[Map_Num].NPC[i].Index].SayMsg)) { Send.Message(Player_Index, Lists.NPC[Lists.Temp_Map[Map_Num].NPC[i].Index].Name + ": " + Lists.NPC[Lists.Temp_Map[Map_Num].NPC[i].Index].SayMsg, System.Drawing.Color.White); } break; } } } // NPC if (NPC_Data.AttackNPC && Lists.Temp_Map[Map_Num].NPC[i].Target_Index == 0) { for (byte NPC_Index = 1; NPC_Index < Lists.Temp_Map[Map_Num].NPC.Length; NPC_Index++) { // Verifica se pode atacar if (NPC_Index == i) { continue; } if (Lists.Temp_Map[Map_Num].NPC[NPC_Index].Index == 0) { continue; } if (IsAlied(Data.Index, Lists.Temp_Map[Map_Num].NPC[NPC_Index].Index)) { continue; } // Se o NPC estiver no alcance do NPC, ir atrás dele Distance = (short)Math.Sqrt(Math.Pow(Data.X - Lists.Temp_Map[Map_Num].NPC[NPC_Index].X, 2) + Math.Pow(Data.Y - Lists.Temp_Map[Map_Num].NPC[NPC_Index].Y, 2)); if (Distance <= NPC_Data.Sight) { Lists.Temp_Map[Map_Num].NPC[i].Target_Type = (byte)Game.Target.NPC; Lists.Temp_Map[Map_Num].NPC[i].Target_Index = NPC_Index; Data = Lists.Temp_Map[Map_Num].NPC[i]; break; } } } } if (Data.Target_Type == (byte)Game.Target.Player) { // Verifica se o jogador ainda está disponível if (!Player.IsPlaying(Data.Target_Index) || Player.Character(Data.Target_Index).Map != Map_Num) { Lists.Temp_Map[Map_Num].NPC[i].Target_Type = 0; Lists.Temp_Map[Map_Num].NPC[i].Target_Index = 0; Data = Lists.Temp_Map[Map_Num].NPC[i]; } // Posição do alvo else { TargetX = Player.Character(Data.Target_Index).X; TargetY = Player.Character(Data.Target_Index).Y; } } else if (Data.Target_Type == (byte)Game.Target.NPC) { // Verifica se o NPC ainda está disponível if (Lists.Temp_Map[Map_Num].NPC[Data.Target_Index].Index == 0) { Lists.Temp_Map[Map_Num].NPC[i].Target_Type = 0; Lists.Temp_Map[Map_Num].NPC[i].Target_Index = 0; Data = Lists.Temp_Map[Map_Num].NPC[i]; } // Posição do alvo else { TargetX = Lists.Temp_Map[Map_Num].NPC[Data.Target_Index].X; TargetY = Lists.Temp_Map[Map_Num].NPC[Data.Target_Index].Y; } } // Verifica se o alvo saiu do alcance do NPC Distance = (short)Math.Sqrt(Math.Pow(Data.X - TargetX, 2) + Math.Pow(Data.Y - TargetY, 2)); if (Distance > NPC_Data.Sight) { Lists.Temp_Map[Map_Num].NPC[i].Target_Type = 0; Lists.Temp_Map[Map_Num].NPC[i].Target_Index = 0; Data = Lists.Temp_Map[Map_Num].NPC[i]; } // Evita que ele se movimente sem sentido if (Data.Target_Index > 0) { Move = true; } else { // Define o alvo a zona do NPC if (Lists.Map[Map_Num].NPC[i].Zone > 0) { if (Lists.Map[Map_Num].Tile[Data.X, Data.Y].Zone != Lists.Map[Map_Num].NPC[i].Zone) { for (byte x2 = 0; x2 <= Lists.Map[Map_Num].Width; x2++) { for (byte y2 = 0; y2 <= Lists.Map[Map_Num].Height; y2++) { if (Lists.Map[Map_Num].Tile[x2, y2].Zone == Lists.Map[Map_Num].NPC[i].Zone) { if (!Map.Tile_Blocked(Map_Num, x2, y2)) { TargetX = x2; TargetY = y2; Move = true; break; } } } } } } } // Movimenta o NPC if (Move) { // Verifica como o NPC pode se mover if (NPC_Data.Flee_Helth == 0 || Data.Vital[(byte)Game.Vitals.HP] > NPC_Data.Vital[(byte)Game.Vitals.HP] * (NPC_Data.Flee_Helth / 100.0)) { // Para perto do alvo CanMove[(byte)Game.Directions.Up] = Data.Y > TargetY; CanMove[(byte)Game.Directions.Down] = Data.Y < TargetY; CanMove[(byte)Game.Directions.Left] = Data.X > TargetX; CanMove[(byte)Game.Directions.Right] = Data.X < TargetX; } else { // Para longe do alvo CanMove[(byte)Game.Directions.Up] = Data.Y < TargetY; CanMove[(byte)Game.Directions.Down] = Data.Y > TargetY; CanMove[(byte)Game.Directions.Left] = Data.X < TargetX; CanMove[(byte)Game.Directions.Right] = Data.X > TargetX; } // Aleatoriza a forma que ele vai se movimentar até o alvo if (Game.Random.Next(0, 2) == 0) { for (byte d = 0; d < (byte)Game.Directions.Count; d++) { if (!Moved && CanMove[d] && NPC.Move(Map_Num, i, (Game.Directions)d)) { Moved = true; } } } else { for (short d = (byte)Game.Directions.Count - 1; d >= 0; d--) { if (!Moved && CanMove[d] && NPC.Move(Map_Num, i, (Game.Directions)d)) { Moved = true; } } } } // Move-se aleatoriamente if (NPC_Data.Behaviour == (byte)Behaviour.Friendly || Data.Target_Index == 0) { if (Game.Random.Next(0, 3) == 0 && !Moved) { if (NPC_Data.Movement == Movements.MoveRandomly) { NPC.Move(Map_Num, i, (Game.Directions)Game.Random.Next(0, 4), 1, true); } else if (NPC_Data.Movement == Movements.TurnRandomly) { Lists.Temp_Map[Map_Num].NPC[i].Direction = (Game.Directions)Game.Random.Next(0, 4); Send.Map_NPC_Direction(Map_Num, i); } } } //////////// // Ataque // //////////// short Next_X = Data.X, Next_Y = Data.Y; Map.NextTile(Data.Direction, ref Next_X, ref Next_Y); if (Data.Target_Type == (byte)Game.Target.Player) { // Verifica se o jogador está na frente do NPC if (Map.HasPlayer(Map_Num, Next_X, Next_Y) == Data.Target_Index) { Attack_Player(Map_Num, i, Data.Target_Index); } } else if (Data.Target_Type == (byte)Game.Target.NPC) { // Verifica se o NPC alvo está na frente do NPC if (Map.HasNPC(Map_Num, Next_X, Next_Y) == Data.Target_Index) { Attack_NPC(Map_Num, i, Data.Target_Index); } } } } }
private void List_SelectedIndexChanged(object sender, EventArgs e) { // Atualiza a lista Selected = Lists.NPC[List.SelectedIndex + 1]; Update_Data(); }