drive automatic fire from server ticks
All checks were successful
build / image (push) Successful in 10s
All checks were successful
build / image (push) Successful in 10s
This commit is contained in:
@@ -125,7 +125,14 @@ const shooterDefinition = defineNetworkedGame<
|
|||||||
if (!player.alive) continue;
|
if (!player.alive) continue;
|
||||||
simulateMovement(player, deltaSeconds);
|
simulateMovement(player, deltaSeconds);
|
||||||
emitFootstep(state, player, tick, emit);
|
emitFootstep(state, player, tick, emit);
|
||||||
if (player.bot) tryFireWeapon(state, player, emit);
|
const repeatingAutomaticFire =
|
||||||
|
player.kind === "human" &&
|
||||||
|
player.firing &&
|
||||||
|
player.lastFirePressed &&
|
||||||
|
WEAPONS[player.weapon].automatic;
|
||||||
|
if (player.bot || repeatingAutomaticFire) {
|
||||||
|
tryFireWeapon(state, player, emit);
|
||||||
|
}
|
||||||
collectNearbyPickup(state, player, emit);
|
collectNearbyPickup(state, player, emit);
|
||||||
player.lastFirePressed = player.firing;
|
player.lastFirePressed = player.firing;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
BOT_COUNT,
|
BOT_COUNT,
|
||||||
BOT_ID_BASE,
|
BOT_ID_BASE,
|
||||||
Weapon,
|
Weapon,
|
||||||
|
createShooterGame,
|
||||||
shooterGame,
|
shooterGame,
|
||||||
} from "../dist/index.js";
|
} from "../dist/index.js";
|
||||||
|
|
||||||
@@ -61,6 +62,43 @@ test("backend simulation is deterministic", () => {
|
|||||||
assert.deepEqual(runHeadlessMatch(2_400), runHeadlessMatch(2_400));
|
assert.deepEqual(runHeadlessMatch(2_400), runHeadlessMatch(2_400));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("held automatic fire follows server ticks while semi-auto remains edge-triggered", () => {
|
||||||
|
const game = createShooterGame({ botCount: 0 });
|
||||||
|
|
||||||
|
const runHeldFire = (weapon, ticks) => {
|
||||||
|
const server = game.createServer();
|
||||||
|
server.addPlayer(1);
|
||||||
|
server.currentState.players.get(1).weapon = weapon;
|
||||||
|
const packet = {
|
||||||
|
sequence: 1,
|
||||||
|
targetTick: 1,
|
||||||
|
observedTick: 0,
|
||||||
|
input: {
|
||||||
|
strafe: 0,
|
||||||
|
forward: 0,
|
||||||
|
yaw: 0,
|
||||||
|
pitch: 0,
|
||||||
|
fire: true,
|
||||||
|
sprint: false,
|
||||||
|
reload: false,
|
||||||
|
weapon,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
assert.deepEqual(server.submitInput(1, packet), { accepted: true });
|
||||||
|
let shots = 0;
|
||||||
|
for (let tick = 0; tick < ticks; tick += 1) {
|
||||||
|
if (tick > 0 && tick % 10 === 0) {
|
||||||
|
assert.deepEqual(server.submitInput(1, packet), { accepted: true });
|
||||||
|
}
|
||||||
|
shots += server.step().events.filter((event) => event.type === "shot").length;
|
||||||
|
}
|
||||||
|
return shots;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.equal(runHeldFire(Weapon.PulseRifle, 60), 10);
|
||||||
|
assert.equal(runHeldFire(Weapon.Scattergun, 100), 1);
|
||||||
|
});
|
||||||
|
|
||||||
test("human hitscan damages the historical target without rewinding live positions", () => {
|
test("human hitscan damages the historical target without rewinding live positions", () => {
|
||||||
const server = shooterGame.createServer();
|
const server = shooterGame.createServer();
|
||||||
server.addPlayer(1);
|
server.addPlayer(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user