Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/runtime/weapons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1038,8 +1038,7 @@ export function createQuakeWeaponsController({
function quakeAimTrace(ray: QuakeViewRay): QuakeUseTrace | null {
const collisionWorld = getCollisionWorld();
let best: { score: number; trace: QuakeUseTrace } | null = null;
for (const shootable of getShootables()) {
if (shootable.dead) continue;
for (const shootable of aimAssistTargets()) {
const target = shootableAimPoint(shootable);
const targetDirection = normalizeVec3([
target[0] - ray.origin[0],
Expand All @@ -1060,6 +1059,15 @@ export function createQuakeWeaponsController({
return best?.trace ?? null;
}

function* aimAssistTargets(): Iterable<QuakeWeaponShootableTarget> {
for (const shootable of getShootables()) {
if (!shootable.dead) yield shootable;
}
for (const target of getDamageableBrushTargets?.() ?? []) {
if (!target.dead && isWeaponTraceDamageableBrushTarget(target.entity)) yield target;
}
}

function fireWeaponProfile(profile: QuakeRuntimeWeaponFireProfile, now: number): boolean {
if (profile.kind === "hitscan-pellets") return fireShotgunPellets(profile);
if (profile.kind === "projectile") {
Expand Down
54 changes: 43 additions & 11 deletions test/gameplay/weaponDamageableBrushTargets.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,35 @@ test("projectiles can damage health trigger brush targets over earlier world tra
assert.deepEqual(damagedBrushes, [{ amount: 1, entityIndex: 138 }]);
});

test("health trigger brush targets can use weapon source aim correction", () => {
const controller = createWeaponsController({
damageableBrushTargets: [
damageableBrushTarget({
bounds: {
min: [1, -0.1, -0.02],
max: [2, 0.1, 0.02],
},
classname: "trigger_multiple",
health: 1,
index: 270,
}),
],
entities: [
quakeEntity({
classname: "trigger_multiple",
health: 1,
index: 270,
}),
],
traceUse: () => null,
});

const trace = controller.weaponTraceAtCrosshair();

assert.equal(trace?.classname, "trigger_multiple");
assert.equal(trace?.entityIndex, 270);
});

test("non-button damageable brush targets do not bypass world trace", () => {
const controller = createWeaponsController({
damageableBrushTargets: [
Expand All @@ -108,7 +137,17 @@ test("non-button damageable brush targets do not bypass world trace", () => {
assert.equal(trace?.entityIndex, undefined);
});

function createWeaponsController({ damageBrushEntity = () => false, damageableBrushTargets, entities }) {
function createWeaponsController({
damageBrushEntity = () => false,
damageableBrushTargets,
entities,
traceUse = () => ({
classname: "worldspawn",
end: [0.1, 0, 0],
fraction: 0.01,
planeNormal: [-1, 0, 0],
}),
}) {
const entityByIndex = new Map(entities.map((entity) => [entity.index, entity]));
return weapons.createQuakeWeaponsController({
scene: { camera: { state: { rotX: 90, rotY: 180 } } },
Expand All @@ -120,14 +159,7 @@ function createWeaponsController({ damageBrushEntity = () => false, damageableBr
damageShootable: () => false,
getActiveWeapon: () => "nailgun",
getAmmo: () => 100,
getCollisionWorld: () => ({
traceUse: () => ({
classname: "worldspawn",
end: [0.1, 0, 0],
fraction: 0.01,
planeNormal: [-1, 0, 0],
}),
}),
getCollisionWorld: () => ({ traceUse }),
getDamageableBrushTargets: () => damageableBrushTargets,
getEntities: () => entityByIndex,
getPlayerEyeHeight: () => 0.92,
Expand All @@ -143,12 +175,12 @@ function createWeaponsController({ damageBrushEntity = () => false, damageableBr
});
}

function damageableBrushTarget({ classname, health, index }) {
function damageableBrushTarget({ bounds, classname, health, index }) {
return {
dead: false,
entity: quakeEntity({ classname, health, index }),
origin: [0, 0, 0],
bounds: {
bounds: bounds ?? {
min: [-100, -100, -100],
max: [100, 100, 100],
},
Expand Down
Loading