Teams and scores¶
Two teams with their own skins and spawns, no friendly fire, and a kill score every player's HUD shows (see the score HUD).
index.ts
import { Server, Player, Color, Weapon, BodyPart } from "@sagl/server";
const server = new Server({ name: "Team Deathmatch", clientFiles: "./client" });
server.clientScripts.useClientFile("scripts/hud.js");
type Team = "grove" | "ballas";
const teams: Record<Team, { skin: number; spawn: [number, number, number]; color: number }> = {
grove: { skin: 105, spawn: [2495, -1687, 13.5], color: 0x40c040 },
ballas: { skin: 102, spawn: [2181, -1494, 23.9], color: 0xa040c0 },
};
const score: Record<Team, number> = { grove: 0, ballas: 0 };
const score$ = server.channel("score");
const teamOf = (p: Player) => p.data.team as Team;
server.on("playerJoin", (player) => {
// Put them on the smaller team.
const count = (t: Team) => server.players.filter((p) => teamOf(p) === t).length;
player.data.team = count("grove") <= count("ballas") ? "grove" : "ballas";
player.send(`You're with ${player.data.team}.`, teams[teamOf(player)].color);
score$.send(player, score);
});
server.on("playerSpawn", (player) => {
const team = teams[teamOf(player)];
const [x, y, z] = team.spawn;
player.skin = team.skin;
player.setPosition({ x, y, z });
player.giveWeapon(Weapon.AK47, 300);
});
server.on("playerDamage", (victim, attacker, hit) => {
if (attacker instanceof Player && teamOf(attacker) === teamOf(victim)) return false;
if (hit.bodyPart === BodyPart.Head) return hit.damage * 1.5;
});
server.on("playerDeath", (player, killer) => {
if (!(killer instanceof Player) || teamOf(killer) === teamOf(player)) return;
score[teamOf(killer)] += 1;
score$.broadcast(score);
if (score[teamOf(killer)] >= 25) {
server.broadcast(`${teamOf(killer)} win!`, teams[teamOf(killer)].color);
score.grove = score.ballas = 0;
score$.broadcast(score);
}
});
server.listen();