Skip to content

Spawns and welcome

Random spawn points around Los Santos, three seconds of spawn protection, a welcome message, and a car next to each spawn.

index.ts
import { Server, Color, Weapon, Player, type Vehicle } from "@sagl/server";

const server = new Server({ name: "Freeroam", startMoney: 500 });

// x, y, z, heading
const spawns: [number, number, number, number][] = [
  [2495.3, -1687.4, 13.5, 0],     // Grove Street
  [1757.4, -1898.1, 13.6, 270],   // Unity Station
  [1481.2, -1771.6, 18.8, 0],     // City Hall
  [2027.5, -1407.2, 17.2, 180],   // County General
];

server.on("playerJoin", (player) => {
  player.send(`Welcome to ${server.options.name}, ${player.name}!`, Color.Green);
  server.broadcast(`${player.name} joined`, Color.Grey);
});

server.on("playerSpawn", (player) => {
  const [x, y, z, heading] = spawns[Math.floor(Math.random() * spawns.length)];
  player.setPosition({ x, y, z }, heading);
  player.giveWeapon(Weapon.Pistol, 100);
  player.data.protectedUntil = Date.now() + 3000;

  // A car five metres ahead, replacing their last one.
  (player.data.car as Vehicle | undefined)?.destroy();
  const rad = (heading * Math.PI) / 180;
  player.data.car = server.createVehicle(
    [411, 560, 541][Math.floor(Math.random() * 3)],
    { x: x - 5 * Math.sin(rad), y: y + 5 * Math.cos(rad), z },
    heading,
  );
});

// Nobody can hurt a player who has just spawned.
server.on("playerDamage", (victim) => {
  if (Date.now() < ((victim.data.protectedUntil as number) ?? 0)) return false;
});

server.on("playerQuit", (player) => {
  (player.data.car as Vehicle | undefined)?.destroy();
  server.broadcast(`${player.name} left`, Color.Grey);
});

server.listen();