By Rob Evans • 10/5/2025
This is a free-for-all "5 lives and out" style game. Last one standing wins!
import "./battlecore/device.bst";
import "./battlecore/fsm.bst";
import "./battlecore/game.bst";
import "./battlecore/net.bst";
import "./battlecore/player.bst";
import "./battlecore/screens.bst";
import "./battlecore/storage.bst";
import "./battlecore/weapon.bst";
import "./battlecore/audio.bst";
import "./battlecore/lights.bst";
program {
name "Slayer Classic";
author "Irrelon Software Limited";
version "1.0.1";
}
std::debug.setSerialLogEnabled(false);
bool gameIsTeamBased = false;
battlecore::audio.setAudioPack("robot");
state "MAIN_MENU" {
event "ENTER" (EventData evt) => {
std::console.log("Leaving state: ", evt.oldState);
std::console.log("Entering state: MAIN_MENU");
battlecore::screens.setScreen("MAIN_MENU");
battlecore::audio.trackStart("01 - device/001 - battle core ready.wav");
}
}
state "IN_GAME" {
event "ENTER" (EventData evt) => {
std::console.log("Leaving state: ", evt.oldState);
std::console.log("Entering state: IN_GAME");
// Update the display to the IN_GAME screen
battlecore::screens.setScreen("IN_GAME");
// TODO: This is a placeholder audio track, we need to add a track for the game start
battlecore::audio.trackStart("02 - game/001 - enemy neutralised.wav");
}
event "TRIGGER_DOWN" (EventData evt) => {
// Check if the player is currently alive
// TODO: This might no longer be required. We could simply define a DEAD and RESPAWNING
// state then apply logic for those states. This is more efficient and also makes
// sense because both those states are going to have different screens displayed.
if (!battlecore::player.getIsAlive()) {
// Check if the player is already respawning
if (battlecore::player.getIsRespawning()) {
return;
}
// Check if player-initiated respawns are allowed
if (battlecore::game.getRespawnMode() == 0) {
// Player-initiated respawns are allowed, respawn now
battlecore::player.respawn();
}
// Since the player is not alive, we don't want
// to take any other action so return now
return;
}
// Check if we are currently busy (reloading, changing weapon etc)
if (battlecore::weapon.getIsBusy()) {
return;
}
// Check if we have enough ammo
if (battlecore::weapon.getAmmo() == 0) {
// We don't have enough ammo, so don't fire, play out of ammo sound
int i = std::math.randomInt(0, 2);
if (i == 0) {
battlecore::audio.trackStart("03 - shots/008 - dry shot1.wav");
} else if (i == 1) {
battlecore::audio.trackStart("03 - shots/009 - dry shot2.wav");
} else {
battlecore::audio.trackStart("03 - shots/010 - dry shot3.wav");
}
battlecore::lights.flash(255, 0, 0, 80, 1);
return;
}
// Check if the current weapon is charge-based or shot-based
if (battlecore::weapon.getIsChargeBased()) {
// Weapon is charge based, start charging
battlecore::weapon.setIsCharging(true);
return;
}
// Weapon is not charge-based, fire shot
battlecore::audio.trackStart("03 - shots/002 - sniper shot1.wav");
battlecore::lights.sweep(255, 0, 0, 80, 200);
battlecore::weapon.fire();
}
event "TRIGGER_UP" (EventData evt) => {
// If our weapon isn't charge-based, simply return and do nothing
if (!battlecore::weapon.getIsChargeBased()) {
return;
}
// Stop charging and fire shot
battlecore::weapon.setIsCharging(false);
battlecore::audio.trackStart("03 - shots/007 - laser pistol shot5.wav");
battlecore::lights.sweep(255, 0, 0, 80, 200);
battlecore::weapon.fire();
}
// TODO: Support gears of war style reload where timing the reload
// to the exact bar gives you a power / damage boost on the next shot
event "RELOAD_DOWN" (EventData evt) => {
// Check if we are currently busy (already reloading etc)
if (battlecore::weapon.getIsBusy()) {
return;
}
// Check if we are already at full ammo
if (battlecore::weapon.getAmmo() == battlecore::weapon.getAmmoMax()) {
return;
}
battlecore::weapon.incrementBusyCount(1);
// Play reload sound
battlecore::audio.trackStart("04 - reloads/001 - pistol reload1.wav");
after battlecore::weapon.getReloadDelayMs() {
// Reload
battlecore::weapon.reload();
battlecore::weapon.decrementBusyCount(1);
}
}
event "IR_IN" (EventData evt) => {
// Check if we are playing a team-based game and if the hit came from our own team
if (battlecore::game.getIsTeamBased() == true && evt.teamId == battlecore::player.getTeamId()) {
return;
}
// Check if the hit came from our own tagger
if (evt.playerId == battlecore::player.getPlayerId()) {
return;
}
// Check if bullet is a damage type
if (evt.bulletTypeId == 3) {
battlecore::player.takeDamage(evt.hitValue);
return;
}
// Check if bullet is a healing type
if (evt.bulletTypeId == 4) {
battlecore::player.takeHealing(evt.hitValue);
return;
}
}
}