public void OnBotTargetPlayer(Bot Bot, TargetPlayerArgs args) { ExtraPlayerData TemporaryPlayer = FindPlayer(args.Player); if (TemporaryPlayer == null) { args.Cancel(); return; } else if (TemporaryPlayer.Infected || TemporaryPlayer.Referee) { args.Cancel(); return; } }
/// <summary> /// Handles bot AI /// </summary> public static void HandleBots() { foreach (Bot Bot in Server.Bots.ToArray()) { Random Random = new Random(); if (Bot.Movement) { Vector3S TemporaryLocation = new Vector3S(Bot.Player.Pos.x, Bot.Player.Pos.z, Bot.Player.Pos.y); string PlayerName = ""; if (Bot.FollowPlayers) { #region Find Closest Player bool HitAPlayer = false; Vector3S ClosestLocation = Bot.Player.Level.CWMap.Size * 32; foreach (Player p in Server.Players) { if (p.Level == Bot.Player.Level) { TargetPlayerArgs eargs = new TargetPlayerArgs(p); bool cancel = OnBotTargetPlayer.Call(Bot, eargs).Canceled; if (!cancel) { if (Bot.BlackListPlayers.ContainsKey(p.Username)) { if (Math.Abs(Bot.BlackListPlayers[p.Username] - Bot.shouldCheckAgainLoopInt) > 100) { Bot.BlackListPlayers.Remove(p.Username); } } if (p.Pos - Bot.Player.Pos < ClosestLocation - Bot.Player.Pos && !Bot.BlackListPlayers.ContainsKey(p.Username)) { HitAPlayer = true; ClosestLocation = new Vector3S(p.Pos); PlayerName = p.Username; if (Math.Abs((ClosestLocation.x / 32) - (Bot.LastPos.x / 32)) >= 12 || Math.Abs((ClosestLocation.z / 32) - (Bot.LastPos.z / 32)) >= 12) { Bot.shouldCheckAgainLoopInt = 1000; } } } } } #endregion if (HitAPlayer) { Vector3S TempLocation = new Vector3S(Bot.Player.Pos); TemporaryLocation = new Vector3S(Bot.Player.Pos); Vector3S Pathfound = new Vector3S(Bot.Player.Pos); #region AStar if (Bot.shouldCheckAgain || Bot.Waypoint == null) { Bot.Waypoint = Pathfind(Bot, ClosestLocation); Bot.LastPos = ClosestLocation; } try { Pathfound.x = (short)(Bot.Waypoint.position.X * 32); Pathfound.z = (short)(Bot.Waypoint.position.Z * 32); Pathfound.y = (short)(Bot.Waypoint.position.Y * 32); } catch { Bot.shouldCheckAgainLoopInt = 1000; try { Bot.BlackListPlayers.Add(PlayerName, Bot.shouldCheckAgainLoopInt); } catch { } break; } if (Bot.intLoop >= 2) //Slows down the bots so they arent insta-propogate, it slows them a bit too much though, need to fix { //Also makes them a bit less accurate than instant, but much more accurate than Vector2D.Move() Bot.intLoop = 0; Bot.Waypoint = Bot.Waypoint.next; } else { Bot.intLoop += 1; } TemporaryLocation.x += (short)((Pathfound.x - TemporaryLocation.x) / 2); TemporaryLocation.z += (short)((Pathfound.z - TemporaryLocation.z) / 2); //TemporaryLocation.y += (short)((Pathfound.y - TemporaryLocation.y) / 2); #endregion Block Block1 = Bot.Player.Level.GetBlock(TemporaryLocation / 32); Block Block2 = Bot.Player.Level.GetBlock((TemporaryLocation.x / 32), (TemporaryLocation.z / 32), (TemporaryLocation.y / 32) - 1); Block BlockUnderneath = Bot.Player.Level.GetBlock((TemporaryLocation.x / 32), (TemporaryLocation.z / 32), (TemporaryLocation.y / 32) - 2); Block BlockAbove = Bot.Player.Level.GetBlock((TemporaryLocation.x / 32), (TemporaryLocation.z / 32), (TemporaryLocation.y / 32) + 1); Vector3S delta = new Vector3S((short)Math.Abs(ClosestLocation.x - TemporaryLocation.x), (short)Math.Abs(ClosestLocation.z - TemporaryLocation.z), (short)Math.Abs(ClosestLocation.y - TemporaryLocation.y)); if (Block.CanWalkThrough(BlockUnderneath) && Block.CanWalkThrough(Block2) && !Block.CanEscalate(Block1) && !Block.CanEscalate(Block2)) { TemporaryLocation.y -= 21; } if (Block.CanWalkThrough(Block1) && !Block.CanWalkThrough(Block2) && !Block.CanWalkThrough(BlockUnderneath)) { TemporaryLocation.y += 21; } else if (Block.CanEscalate(Block1) && Block.CanEscalate(Block2) && Pathfound.y > TemporaryLocation.y) { TemporaryLocation.y += 21; } else if (Block.CanWalkThrough(BlockAbove) && !Block.CanWalkThrough(BlockUnderneath) && Pathfound.y > TemporaryLocation.y && !Block.IsOPBlock(BlockUnderneath)) { TemporaryLocation.y += 21; Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 2), 1); } else if (!Block.CanWalkThrough(BlockAbove) && !Block.CanWalkThrough(BlockUnderneath) && !Block.IsOPBlock(BlockAbove)) { Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) + 1), 0); } if (Block.CanWalkThrough(BlockUnderneath) && !Block.CanWalkThrough(Bot.Player.Level.GetBlock((Bot.Player.oldPos.x / 32), (Bot.Player.oldPos.z / 32), (Bot.Player.oldPos.y / 32) - 2)) && !Block.IsOPBlock(BlockUnderneath) && Pathfound.y > TemporaryLocation.y) { Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 2), 1); } if ((!Block.IsOPBlock(Block1) && !Block.IsOPBlock(Block2)) && (!Block.CanWalkThrough(Block1) && !Block.CanWalkThrough(Block2)) && (Block1 != Block.BlockList.UNKNOWN && Block2 != Block.BlockList.UNKNOWN)) { Bot.Player.Level.BlockChange(TemporaryLocation / 32, 0); Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 1), 0); } if (!Block.CanWalkThrough(BlockUnderneath) && (Pathfound.y / 32) < (TemporaryLocation.y / 32) && !Block.IsOPBlock(BlockUnderneath)) { Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 2), 0); } MoveEventArgs eargs = new MoveEventArgs(TemporaryLocation, Bot.Player.Pos); bool cancel = OnBotMove.Call(Bot, eargs).Canceled; if (cancel) { TemporaryLocation = TempLocation; } } } Bot.Player.Pos = TemporaryLocation; Bot.Player.UpdatePosition(true); //Pls leave this true, bots dont appear properly otherwise } } }
/// <summary> /// Handles bot AI /// </summary> public static void HandleBots() { foreach (Bot Bot in Server.Bots) { Random Random = new Random(); bool PlayerBelow = false; if (Bot.Movement) { Vector3S TemporaryLocation = new Vector3S(Bot.Player.Pos.x, Bot.Player.Pos.z, Bot.Player.Pos.y); if (Bot.FollowPlayers) //TODO - Fix jumping (you can jump infinately), fix bot locking on target (locks on one target only) { #region Find Closest Player bool HitAPlayer = false; Vector3S ClosestLocation = Bot.Player.Level.Size * 32; foreach (Player p in Server.Players) { if (p.Level == Bot.Player.Level) { TargetPlayerArgs eargs = new TargetPlayerArgs(p); bool cancel = OnBotTargetPlayer.Call(Bot, eargs).Canceled; if (!cancel) { HitAPlayer = true; if (p.Pos - Bot.Player.Pos < ClosestLocation - Bot.Player.Pos) { ClosestLocation = new Vector3S(p.Pos); } } } } #endregion if (HitAPlayer) { Vector3S TempLocation = new Vector3S(Bot.Player.Pos); TemporaryLocation = new Vector3S(Bot.Player.Pos); TemporaryLocation.Move(13, ClosestLocation); MoveEventArgs eargs = new MoveEventArgs(TemporaryLocation, Bot.Player.Pos); bool cancel = OnBotMove.Call(Bot, eargs).Canceled; if (cancel){ TemporaryLocation = TempLocation; } } } bool ShouldBreakBlock = true; if (Block.CanWalkThrough(Bot.Player.Level.GetBlock(Vector3S.MinusY(TemporaryLocation, 64) / 32)) && Bot.Player.Pos.y / 32 > 1) TemporaryLocation.y = (short)(Bot.Player.Pos.y - 21); //Gravity, 21 is a nice value, doesn't float too much and doesnt fall too far. if (Block.CanWalkThrough(Bot.Player.Level.GetBlock(TemporaryLocation / 32)) && Block.CanWalkThrough(Bot.Player.Level.GetBlock(Vector3S.MinusY(TemporaryLocation, 32) / 32))) { Bot.Player.Pos = TemporaryLocation; //Make sure the bot doesnt walk through walls } else if (Bot.Jumping) //Jumping { if (Block.CanWalkThrough(Bot.Player.Level.GetBlock(TemporaryLocation / 32)) && Block.CanWalkThrough(Bot.Player.Level.GetBlock(Vector3S.MinusY(TemporaryLocation, -32) / 32))) { Bot.Player.Pos.y = (short)(Bot.Player.Pos.y + 21); ShouldBreakBlock = false; } } if (Bot.BreakBlocks && ShouldBreakBlock) //Can't go through dat wall, try and break it { if (Random.Next(1, 5) == 3 && !Block.IsOPBlock(Bot.Player.Level.GetBlock(TemporaryLocation / 32))) Bot.Player.Level.BlockChange(Convert.ToUInt16(TemporaryLocation.x / 32), Convert.ToUInt16(TemporaryLocation.z / 32), Convert.ToUInt16(TemporaryLocation.y / 32), Block.BlockList.AIR); if (Random.Next(1, 5) == 3 && !Block.IsOPBlock(Bot.Player.Level.GetBlock(new Vector3S(Convert.ToUInt16(TemporaryLocation.x / 32), Convert.ToUInt16(TemporaryLocation.z / 32), Convert.ToUInt16((TemporaryLocation.y - 32) / 32))))) Bot.Player.Level.BlockChange(Convert.ToUInt16(TemporaryLocation.x / 32), Convert.ToUInt16(TemporaryLocation.z / 32), Convert.ToUInt16((TemporaryLocation.y - 32) / 32), Block.BlockList.AIR); if (PlayerBelow) { try { if (Random.Next(1, 5) == 3 && !Block.IsOPBlock(Bot.Player.Level.GetBlock(new Vector3S(Convert.ToUInt16(TemporaryLocation.x / 32), Convert.ToUInt16(TemporaryLocation.z / 32), Convert.ToUInt16((TemporaryLocation.y - 64) / 32))))) Bot.Player.Level.BlockChange(Convert.ToUInt16(TemporaryLocation.x / 32), Convert.ToUInt16(TemporaryLocation.z / 32), Convert.ToUInt16((TemporaryLocation.y - 64) / 32), Block.BlockList.AIR); } catch { } } } Bot.Player.Rot = new byte[] { (byte)(Bot.Player.Rot[0] + 1), (byte)(Bot.Player.Rot[1] + 1) }; Bot.Player.UpdatePosition(true); //Pls leave this true, bots dont appear properly otherwise } } }
/// <summary> /// Handles bot AI /// </summary> public static void HandleBots() { foreach (Bot Bot in Server.Bots.ToArray()) { Random Random = new Random(); if (Bot.Movement) { Vector3S TemporaryLocation = new Vector3S(Bot.Player.Pos.x, Bot.Player.Pos.z, Bot.Player.Pos.y); string PlayerName = ""; if (Bot.FollowPlayers) { #region Find Closest Player bool HitAPlayer = false; Vector3S ClosestLocation = Bot.Player.Level.Size * 32; foreach (Player p in Server.Players) { if (p.Level == Bot.Player.Level) { TargetPlayerArgs eargs = new TargetPlayerArgs(p); bool cancel = OnBotTargetPlayer.Call(Bot, eargs).Canceled; if (!cancel) { if (Bot.BlackListPlayers.ContainsKey(p.Username)) { if (Math.Abs(Bot.BlackListPlayers[p.Username] - Bot.shouldCheckAgainLoopInt) > 100) { Bot.BlackListPlayers.Remove(p.Username); } } if (p.Pos - Bot.Player.Pos < ClosestLocation - Bot.Player.Pos && !Bot.BlackListPlayers.ContainsKey(p.Username)) { HitAPlayer = true; ClosestLocation = new Vector3S(p.Pos); PlayerName = p.Username; if (Math.Abs((ClosestLocation.x / 32) - (Bot.LastPos.x / 32)) >= 12 || Math.Abs((ClosestLocation.z / 32) - (Bot.LastPos.z / 32)) >= 12) { Bot.shouldCheckAgainLoopInt = 1000; } } } } } #endregion if (HitAPlayer) { Vector3S TempLocation = new Vector3S(Bot.Player.Pos); TemporaryLocation = new Vector3S(Bot.Player.Pos); Vector3S Pathfound = new Vector3S(Bot.Player.Pos); #region AStar if (Bot.shouldCheckAgain || Bot.Waypoint == null) { Bot.Waypoint = Pathfind(Bot, ClosestLocation); Bot.LastPos = ClosestLocation; } try { Pathfound.x = (short)(Bot.Waypoint.position.X * 32); Pathfound.z = (short)(Bot.Waypoint.position.Z * 32); Pathfound.y = (short)(Bot.Waypoint.position.Y * 32); } catch { Bot.shouldCheckAgainLoopInt = 1000; try { Bot.BlackListPlayers.Add(PlayerName, Bot.shouldCheckAgainLoopInt); } catch { } break; } if (Bot.intLoop >= 2) //Slows down the bots so they arent insta-propogate, it slows them a bit too much though, need to fix { //Also makes them a bit less accurate than instant, but much more accurate than Vector2D.Move() Bot.intLoop = 0; Bot.Waypoint = Bot.Waypoint.next; } else { Bot.intLoop += 1; } TemporaryLocation.x += (short)((Pathfound.x - TemporaryLocation.x) / 2); TemporaryLocation.z += (short)((Pathfound.z - TemporaryLocation.z) / 2); //TemporaryLocation.y += (short)((Pathfound.y - TemporaryLocation.y) / 2); #endregion Block Block1 = Bot.Player.Level.GetBlock(TemporaryLocation / 32); Block Block2 = Bot.Player.Level.GetBlock((TemporaryLocation.x / 32), (TemporaryLocation.z / 32), (TemporaryLocation.y / 32) - 1); Block BlockUnderneath = Bot.Player.Level.GetBlock((TemporaryLocation.x / 32), (TemporaryLocation.z / 32), (TemporaryLocation.y / 32) - 2); Block BlockAbove = Bot.Player.Level.GetBlock((TemporaryLocation.x / 32), (TemporaryLocation.z / 32), (TemporaryLocation.y / 32) + 1); Vector3S delta = new Vector3S((short)Math.Abs(ClosestLocation.x - TemporaryLocation.x), (short)Math.Abs(ClosestLocation.z - TemporaryLocation.z), (short)Math.Abs(ClosestLocation.y - TemporaryLocation.y)); if (Block.CanWalkThrough(BlockUnderneath) && Block.CanWalkThrough(Block2) && !Block.CanEscalate(Block1) && !Block.CanEscalate(Block2)) { TemporaryLocation.y -= 21; } if (Block.CanWalkThrough(Block1) && !Block.CanWalkThrough(Block2) && !Block.CanWalkThrough(BlockUnderneath)) { TemporaryLocation.y += 21; } else if (Block.CanEscalate(Block1) && Block.CanEscalate(Block2) && Pathfound.y > TemporaryLocation.y) { TemporaryLocation.y += 21; } else if (Block.CanWalkThrough(BlockAbove) && !Block.CanWalkThrough(BlockUnderneath) && Pathfound.y > TemporaryLocation.y && !Block.IsOPBlock(BlockUnderneath)) { TemporaryLocation.y += 21; Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 2), 1); } else if (!Block.CanWalkThrough(BlockAbove) && !Block.CanWalkThrough(BlockUnderneath) && !Block.IsOPBlock(BlockAbove)) { Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) + 1), 0); } if (Block.CanWalkThrough(BlockUnderneath) && !Block.CanWalkThrough(Bot.Player.Level.GetBlock((Bot.Player.oldPos.x / 32), (Bot.Player.oldPos.z / 32), (Bot.Player.oldPos.y / 32) - 2)) && !Block.IsOPBlock(BlockUnderneath) && Pathfound.y > TemporaryLocation.y) { Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 2), 1); } if ((!Block.IsOPBlock(Block1) && !Block.IsOPBlock(Block2)) && (!Block.CanWalkThrough(Block1) && !Block.CanWalkThrough(Block2)) && (Block1 != Block.BlockList.UNKNOWN && Block2 != Block.BlockList.UNKNOWN)) { Bot.Player.Level.BlockChange(TemporaryLocation / 32, 0); Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 1), 0); } if (!Block.CanWalkThrough(BlockUnderneath) && (Pathfound.y / 32) < (TemporaryLocation.y / 32) && !Block.IsOPBlock(BlockUnderneath)) { Bot.Player.Level.BlockChange((ushort)(TemporaryLocation.x / 32), (ushort)(TemporaryLocation.z / 32), (ushort)((TemporaryLocation.y / 32) - 2), 0); } MoveEventArgs eargs = new MoveEventArgs(TemporaryLocation, Bot.Player.Pos); bool cancel = OnBotMove.Call(Bot, eargs).Canceled; if (cancel) { TemporaryLocation = TempLocation; } } } Bot.Player.Pos = TemporaryLocation; Bot.Player.UpdatePosition(true); //Pls leave this true, bots dont appear properly otherwise } } }