BF Portal / script learning
hello
i tried to make my own mode idea
i made the map and barriers and how it looks
the hard part was scripting/blocks for the mode
i did this but i find it nothing works in it i would love to learn how to do it right and whats wrong with my script
// --------------------- Global Variables ---------------------
declare const modlib: any;
let SCORE_LIMIT = 500;
let HVT_HEALTH_MULTIPLIER = 2;
let HVT_KILL_POINTS = 50;
let REGULAR_KILL_POINTS = 5;
let SUPPORT_POINTS = 1;
let RESET_DURATION = 3;
let ANNOUNCEMENT_INTERVAL = 30; // seconds
let PRE_GAME_WAIT = 10; // seconds before deployment
let REBALANCE_INTERVAL = 60; // seconds
type Player = any;
let Team1Players: Player[] = [];
let Team2Players: Player[] = [];
let Team1HVT: Player | null = null;
let Team2HVT: Player | null = null;
let announcementTimer: any = null;
let matchStarted = false;
// --------------------- Helper Functions ---------------------
function getAllPlayers(): Player[] {
return modlib.getPlayers ? modlib.getPlayers() : [];
}
function balanceTeams() {
const all = getAllPlayers();
Team1Players = [];
Team2Players = [];
for (let i = 0; i < all.length; i++) {
const p = all[i];
if (Team1Players.length <= Team2Players.length) {
modlib.setPlayerTeam(p, 1);
Team1Players.push(p);
} else {
modlib.setPlayerTeam(p, 2);
Team2Players.push(p);
}
}
modlib.displayGameMessage(`Balanced: T1=${Team1Players.length} | T2=${Team2Players.length}`);
}
function pickRandomAlive(players: Player[]): Player | null {
const alive = players.filter(p => p.isAlive && p.isAlive());
if (alive.length === 0) return null;
return alive[Math.floor(Math.random() * alive.length)];
}
function assignHVT(player: Player, teamNum: number) {
if (!player) return;
player.setMaxHealth(player.getMaxHealth() * HVT_HEALTH_MULTIPLIER);
player.setWorldIcon(1);
player.setWorldIconText('HVT');
giveHVTSupportKit(player);
modlib.displayGameMessage(`Team ${teamNum} HVT: ${player.getName()}`);
modlib.triggerAudio('HVTAssignedSound');
updateHVTIndicator(player, teamNum, true);
}
function giveHVTSupportKit(player: Player) {
player.clearInventory();
player.addItem('Bandage', 5);
player.addItem('WeaponPistol', 1);
player.addItem('SmokeGrenade', 2);
player.enableAbility('RadarPing');
}
function updateHUD() {
const s1 = modlib.getScore(1);
const s2 = modlib.getScore(2);
const h1 = Team1HVT && Team1HVT.isAlive() ? Team1HVT.getName() : 'Dead';
const h2 = Team2HVT && Team2HVT.isAlive() ? Team2HVT.getName() : 'Dead';
let leader = 'Tied';
if (s1 > s2) leader = 'Team 1 leads';
if (s2 > s1) leader = 'Team 2 leads';
modlib.displayGameMessage(`Score: 1=${s1} | 2=${s2} | HVTs: [${h1}] vs [${h2}] | ${leader}`);
}
function timedAnnouncements() {
updateHUD();
announcementTimer = setTimeout(timedAnnouncements, ANNOUNCEMENT_INTERVAL * 1000);
}
function updateHVTIndicator(player: Player | null, teamNum: number, alive: boolean) {
if (!player) return;
const color = alive ? (teamNum === 1 ? 'blue' : 'red') : 'gray';
modlib.setMapIndicator(player.getPosition(), color, `Team${teamNum} HVT`);
}
function startPreGamePhase() {
modlib.displayGameMessage('Waiting for players to deploy...');
balanceTeams();
setTimeout(() => {
modlib.displayGameMessage('Match starting now!');
matchStarted = true;
startMatch();
}, PRE_GAME_WAIT * 1000);
}
function startMatch() {
balanceTeams();
Team1HVT = pickRandomAlive(Team1Players);
Team2HVT = pickRandomAlive(Team2Players);
if (Team1HVT) assignHVT(Team1HVT, 1);
if (Team2HVT) assignHVT(Team2HVT, 2);
timedAnnouncements();
scheduleRebalance();
}
function scheduleRebalance() {
setTimeout(() => {
if (!matchStarted) return;
balanceTeams();
scheduleRebalance();
}, REBALANCE_INTERVAL * 1000);
}
function checkWin() {
const s1 = modlib.getScore(1);
const s2 = modlib.getScore(2);
if (s1 >= SCORE_LIMIT) endMatch('Team 1 Wins!');
else if (s2 >= SCORE_LIMIT) endMatch('Team 2 Wins!');
}
function endMatch(msg: string) {
modlib.displayGameMessage(msg);
modlib.triggerAudio('GameEndSound');
modlib.endGame();
clearTimeout(announcementTimer);
}
// --------------------- Event Handlers ---------------------
function onPlayerJoined(player: Player) {
balanceTeams();
if (!matchStarted) {
modlib.displayWorldMessage(player, 'Welcome — game will start soon.');
}
// force respawn
player.respawn();
}
function onPlayerDied(victim: Player, killer: Player) {
if (!matchStarted) return;
if (!victim) return;
if (victim === Team1HVT) {
modlib.addScore(2, HVT_KILL_POINTS);
modlib.displayGameMessage('Team 2 killed Team1 HVT!');
modlib.triggerAudio('HVTKilledSound');
updateHVTIndicator(Team1HVT, 1, false);
setTimeout(() => {
Team1HVT = pickRandomAlive(Team1Players);
if (Team1HVT) assignHVT(Team1HVT, 1);
}, RESET_DURATION * 1000);
} else if (victim === Team2HVT) {
modlib.addScore(1, HVT_KILL_POINTS);
modlib.displayGameMessage('Team 1 killed Team2 HVT!');
modlib.triggerAudio('HVTKilledSound');
updateHVTIndicator(Team2HVT, 2, false);
setTimeout(() => {
Team2HVT = pickRandomAlive(Team2Players);
if (Team2HVT) assignHVT(Team2HVT, 2);
}, RESET_DURATION * 1000);
} else {
if (killer && killer.getTeamId) {
modlib.addScore(killer.getTeamId(), REGULAR_KILL_POINTS);
}
}
updateHUD();
checkWin();
}
function onPlayerHealed(healer: Player, target: Player, amount: number) {
if (!matchStarted) return;
if (!healer || !target) return;
const t = healer.getTeamId();
if (target === Team1HVT && t === 1) {
modlib.addScore(1, SUPPORT_POINTS);
} else if (target === Team2HVT && t === 2) {
modlib.addScore(2, SUPPORT_POINTS);
}
updateHUD();
}
// --------------------- Main ---------------------
export function OngoingGlobal() {
startPreGamePhase();
modlib.on('playerJoined', (p: Player) => onPlayerJoined(p));
modlib.on('playerDied', (v: Player, k: Player) => onPlayerDied(v, k));
modlib.on('playerHealed', (h: Player, t: Player, amt: number) => onPlayerHealed(h, t, amt));
}
uploaded the file to ( its json but i made it txt so u can see)