Map markers¶
Markers from a data file¶
Shops listed in a client file, put on the map once when the script runs.
client/data/places.json
[
{ "id": "ammu-downtown", "name": "Ammu-Nation", "x": 1368, "y": -1279, "icon": 6 },
{ "id": "burger-mall", "name": "Burger Shot", "x": 1199, "y": -918, "icon": 10 },
{ "id": "pns-idlewood", "name": "Pay 'n' Spray", "x": 2073, "y": -1831, "icon": 63 }
]
client/scripts/places.js
const places = JSON.parse(sagl.files.read("data/places.json") ?? "[]");
for (const p of places) {
sagl.map.setMarker(p.id, { x: p.x, y: p.y, icon: p.icon, label: p.name });
}
Teammates¶
The gamemode sends teammates' positions every few seconds; the script keeps one marker per teammate.
client/scripts/team-map.js
let shown = new Set();
sagl.on("team:positions", (mates) => {
const now = new Set();
for (const m of mates) {
sagl.map.setMarker(`mate-${m.id}`, { x: m.x, y: m.y, color: "#40c040", label: m.name });
now.add(`mate-${m.id}`);
}
for (const id of shown) if (!now.has(id)) sagl.map.removeMarker(id);
shown = now;
});
index.ts (gamemode)
setInterval(() => {
for (const p of server.players) {
const mates = server.players
.filter((o) => o !== p && o.data.team === p.data.team)
.map((o) => ({ id: o.id, name: o.name, x: o.position.x, y: o.position.y }));
p.emit("team:positions", mates);
}
}, 3000);
An interior map¶
Inside a building, show only its floor plan, GTA V style; put the world back when they leave.