Skip to content

Commit

Permalink
Do not handle hear callback after object death (stalker, monster).
Browse files Browse the repository at this point in the history
Signed-off-by: Neloreck <[email protected]>
  • Loading branch information
Neloreck committed Dec 27, 2024
1 parent d7836a3 commit 431e71b
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
6 changes: 6 additions & 0 deletions src/engine/core/binders/creature/MonsterBinder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,9 +498,15 @@ describe("MonsterBinder", () => {

jest.spyOn(SchemeHear, "onObjectHearSound").mockImplementation(jest.fn());

// Do not listen for self.
binder.onHearSound(object, object.id(), 128, X_VECTOR, 10);
expect(SchemeHear.onObjectHearSound).not.toHaveBeenCalled();

// Do not listen when dead.
jest.spyOn(object, "alive").mockImplementationOnce(() => false);
binder.onHearSound(object, ACTOR_ID, 128, X_VECTOR, 10);
expect(SchemeHear.onObjectHearSound).not.toHaveBeenCalled();

binder.onHearSound(object, ACTOR_ID, 128, X_VECTOR, 10);
expect(SchemeHear.onObjectHearSound).toHaveBeenCalledWith(object, ACTOR_ID, 128, X_VECTOR, 10);
});
Expand Down
20 changes: 17 additions & 3 deletions src/engine/core/binders/creature/MonsterBinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,13 @@ export class MonsterBinder extends object_binder {

/**
* On monster hear sound.
* Handle surrounding sounds and process danger / aggression based on sound type and power.
* Handle surrounding sounds and process danger / aggression / condlists based on sound type and power.
*
* @param object - game object hearing sounds
* @param sourceId - ID of object producing sound
* @param soundType - mask object with types of sounds heard
* @param soundPosition - vector with 3d position of sounds source
* @param soundPower - power level of sound
*/
public onHearSound(
object: GameObject,
Expand All @@ -310,8 +316,16 @@ export class MonsterBinder extends object_binder {
soundPosition: Vector,
soundPower: TRate
): void {
if (sourceId !== object.id()) {
SchemeHear.onObjectHearSound(object, sourceId, soundType, soundPosition, soundPower);
// Don't handle own sounds.
if (sourceId === object.id()) {
return;
}

// Don't handle sounds when dead.
if (!object.alive()) {
return;
}

SchemeHear.onObjectHearSound(object, sourceId, soundType, soundPosition, soundPower);
}
}
23 changes: 21 additions & 2 deletions src/engine/core/binders/creature/StalkerBinder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SoundManager } from "@/engine/core/managers/sounds";
import { initializeObjectThemes } from "@/engine/core/managers/sounds/utils";
import { TradeManager } from "@/engine/core/managers/trade";
import { syncObjectHitSmartTerrainAlert } from "@/engine/core/objects/smart_terrain/utils";
import { SchemeHear } from "@/engine/core/schemes/shared/hear";
import { SchemePostCombatIdle } from "@/engine/core/schemes/stalker/combat_idle";
import { SchemeReachTask } from "@/engine/core/schemes/stalker/reach_task";
import { ISchemeWoundedState } from "@/engine/core/schemes/stalker/wounded";
Expand All @@ -18,7 +19,8 @@ import {
syncSpawnedObjectPosition,
} from "@/engine/core/utils/object";
import { emitSchemeEvent, setupObjectLogicsOnSpawn } from "@/engine/core/utils/scheme";
import { ZERO_VECTOR } from "@/engine/lib/constants/vectors";
import { ACTOR_ID } from "@/engine/lib/constants/ids";
import { X_VECTOR, ZERO_VECTOR } from "@/engine/lib/constants/vectors";
import { AnyObject, EScheme, ESchemeEvent, ESchemeType, GameObject, ServerHumanObject } from "@/engine/lib/types";
import { mockRegisteredActor, mockSchemeState, resetRegistry } from "@/fixtures/engine";
import { resetFunctionMock } from "@/fixtures/jest";
Expand Down Expand Up @@ -177,7 +179,24 @@ describe("StalkerBinder", () => {

it.todo("should correctly handle death event");

it.todo("should correctly handle hear event");
it("should handle hear event", () => {
const object: GameObject = MockGameObject.mock();
const binder: StalkerBinder = new StalkerBinder(object);

jest.spyOn(SchemeHear, "onObjectHearSound").mockImplementation(jest.fn());

// Do not listen for self.
binder.onHearSound(object, object.id(), 128, X_VECTOR, 10);
expect(SchemeHear.onObjectHearSound).not.toHaveBeenCalled();

// Do not listen when dead.
jest.spyOn(object, "alive").mockImplementationOnce(() => false);
binder.onHearSound(object, ACTOR_ID, 128, X_VECTOR, 10);
expect(SchemeHear.onObjectHearSound).not.toHaveBeenCalled();

binder.onHearSound(object, ACTOR_ID, 128, X_VECTOR, 10);
expect(SchemeHear.onObjectHearSound).toHaveBeenCalledWith(object, ACTOR_ID, 128, X_VECTOR, 10);
});

it.todo("should correctly handle use event");

Expand Down
20 changes: 16 additions & 4 deletions src/engine/core/binders/creature/StalkerBinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,21 +390,33 @@ export class StalkerBinder extends object_binder {
}

/**
* todo: Description.
* On stalker hear sound.
* Handle surrounding sounds and process danger / aggression / condlists based on sound type and power.
*
* @param object - game object hearing sounds
* @param sourceId - ID of object producing sound
* @param soundType - mask object with types of sounds heard
* @param soundPosition - vector with 3d position of sounds source
* @param soundPower - power level of sound
*/
public onHearSound(
object: GameObject,
whoId: TNumberId,
sourceId: TNumberId,
soundType: TSoundType,
soundPosition: Vector,
soundPower: TRate
): void {
// Don't handle own sounds.
if (whoId === object.id()) {
if (sourceId === object.id()) {
return;
}

// Don't handle sounds when dead.
if (!object.alive()) {
return;
}

SchemeHear.onObjectHearSound(object, whoId, soundType, soundPosition, soundPower);
SchemeHear.onObjectHearSound(object, sourceId, soundType, soundPosition, soundPower);
}

/**
Expand Down

0 comments on commit 431e71b

Please sign in to comment.