File size: 2,907 Bytes
f676ff2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const Player = require('./Player');
const { BOT_LIFETIME_MIN_MS, BOT_LIFETIME_MAX_MS } = require('../../../shared/constants');

class Bot extends Player {
  constructor(id, name, skinId) {
    super(id, name, skinId);
    this.isBot = true;
    this.decisionTimer = 0;
    // Track when the bot was created and assign a random lifetime between min/max
    this.spawnTime = Date.now();
    this.lifetime = BOT_LIFETIME_MIN_MS + Math.floor(Math.random() * (BOT_LIFETIME_MAX_MS - BOT_LIFETIME_MIN_MS));
  }

  updateAI(room) {
    this.decisionTimer--;
    if (this.decisionTimer <= 0) {
      // Make a new decision every 15-30 frames (~500ms - 1s) to simulate human reaction delay
      this.decisionTimer = 15 + Math.floor(Math.random() * 15);

      let targetX = this.x;
      let targetY = this.y;

      // 1. Scan for the nearest player/other bot
      let closestPlayer = null;
      let minPlayerDist = Infinity;

      for (const other of room.players.values()) {
        if (other.id === this.id) continue;
        const dx = other.x - this.x;
        const dy = other.y - this.y;
        const dist = Math.sqrt(dx * dx + dy * dy);

        if (dist < minPlayerDist) {
          minPlayerDist = dist;
          closestPlayer = other;
        }
      }

      // If a target is close enough (within 450 pixels)
      if (closestPlayer && minPlayerDist < 450) {
        // If we have more orbits, chase them!
        if (this.orbits.length > closestPlayer.orbits.length) {
          targetX = closestPlayer.x;
          targetY = closestPlayer.y;
          this.isBoosting = this.stamina > 30; // Boost when chasing if we have enough stamina
        } else {
          // Otherwise, run away from them in the opposite direction!
          const dx = closestPlayer.x - this.x;
          const dy = closestPlayer.y - this.y;
          targetX = this.x - dx * 2;
          targetY = this.y - dy * 2;
          this.isBoosting = this.stamina > 20; // Boost to escape!
        }
      } else {
        this.isBoosting = false; // Rest and recover stamina when collecting/wandering
        // 2. Otherwise, look for the nearest pickup
        let closestPickup = null;
        let minPickupDist = Infinity;

        for (const pickup of room.pickups.list()) {
          const dx = pickup.x - this.x;
          const dy = pickup.y - this.y;
          const dist = Math.sqrt(dx * dx + dy * dy);

          if (dist < minPickupDist) {
            minPickupDist = dist;
            closestPickup = pickup;
          }
        }

        if (closestPickup) {
          targetX = closestPickup.x;
          targetY = closestPickup.y;
        } else {
          // Random wander if no pickups or players
          targetX = this.x + (Math.random() - 0.5) * 400;
          targetY = this.y + (Math.random() - 0.5) * 400;
        }
      }

      this.setInput(targetX, targetY);
    }
  }
}

module.exports = Bot;