diff --git a/src/engine/scripts/declarations/conditions/object.test.ts b/src/engine/scripts/declarations/conditions/object.test.ts index 03652ba1d..37c2ff657 100644 --- a/src/engine/scripts/declarations/conditions/object.test.ts +++ b/src/engine/scripts/declarations/conditions/object.test.ts @@ -73,7 +73,6 @@ describe("object conditions declaration", () => { checkXrCondition("has_enemy"); checkXrCondition("has_actor_enemy"); checkXrCondition("see_enemy"); - checkXrCondition("heavy_wounded"); checkXrCondition("mob_has_enemy"); checkXrCondition("mob_was_hit"); checkXrCondition("squad_in_zone"); @@ -394,7 +393,16 @@ describe("object conditions implementation", () => { it.todo("hitted_on_bone should check object hit bone"); - it.todo("best_pistol should check object has pistol"); + it("best_pistol should check object has pistol", () => { + const object: GameObject = MockGameObject.mock(); + + jest.spyOn(object, "item_in_slot").mockImplementation(() => MockGameObject.mock()); + expect(callXrCondition("best_pistol", MockGameObject.mockActor(), object)).toBe(true); + expect(object.item_in_slot).toHaveBeenCalledWith(1); + + jest.spyOn(object, "item_in_slot").mockImplementation(() => null); + expect(callXrCondition("best_pistol", MockGameObject.mockActor(), object)).toBe(false); + }); it.todo("deadly_hit should check if hit is deadly"); @@ -406,19 +414,76 @@ describe("object conditions implementation", () => { it.todo("is_alive should check if stalker is alive"); - it.todo("is_dead should check if object is dead"); + it("is_dead should check if object is dead", () => { + const object: GameObject = MockGameObject.mock(); + + expect(callXrCondition("is_dead", MockGameObject.mockActor(), object, "test-sid")).toBe(true); + + registerStoryLink(object.id(), "test-sid"); + + expect(callXrCondition("is_dead", MockGameObject.mockActor(), object, "test-sid")).toBe(false); + + jest.spyOn(object, "alive").mockImplementation(() => false); + + expect(callXrCondition("is_dead", MockGameObject.mockActor(), object, "test-sid")).toBe(true); + }); + + it("story_object_exist should check if object exist", () => { + const object: GameObject = MockGameObject.mock(); + + expect(callXrCondition("story_object_exist", MockGameObject.mockActor(), object, "test-sid")).toBe(false); + + registerStoryLink(object.id(), "test-sid"); + + expect(callXrCondition("story_object_exist", MockGameObject.mockActor(), object, "test-sid")).toBe(true); + }); + + it("npc_has_item should check if object has item", () => { + const object: GameObject = MockGameObject.mock(); + + expect(callXrCondition("npc_has_item", MockGameObject.mockActor(), object, "test-section")).toBe(false); + + jest.spyOn(object, "object").mockImplementation(() => MockGameObject.mock()); + + expect(callXrCondition("npc_has_item", MockGameObject.mockActor(), object, "test-section")).toBe(true); + expect(object.object).toHaveBeenCalledWith("test-section"); + }); - it.todo("story_object_exist should check if object exist"); + it("has_enemy should check if object has enemy", () => { + const object: GameObject = MockGameObject.mock(); + + expect(callXrCondition("has_enemy", MockGameObject.mockActor(), object)).toBe(false); - it.todo("npc_has_item should check if object has item"); + jest.spyOn(object, "best_enemy").mockImplementation(() => MockGameObject.mock()); - it.todo("has_enemy should check if object has enemy"); + expect(callXrCondition("has_enemy", MockGameObject.mockActor(), object)).toBe(true); + expect(object.best_enemy).toHaveBeenCalled(); + }); + + it("has_actor_enemy should check if object has actor as enemy", () => { + const object: GameObject = MockGameObject.mock(); - it.todo("has_actor_enemy should check if object has actor as enemy"); + expect(callXrCondition("has_actor_enemy", MockGameObject.mockActor(), object)).toBe(false); - it.todo("see_enemy should check if object see enemy"); + jest.spyOn(object, "best_enemy").mockImplementation(() => MockGameObject.mock()); + expect(callXrCondition("has_actor_enemy", MockGameObject.mockActor(), object)).toBe(false); - it.todo("heavy_wounded should check if object is heavily wounded"); + jest.spyOn(object, "best_enemy").mockImplementation(() => MockGameObject.mockActor()); + expect(callXrCondition("has_actor_enemy", MockGameObject.mockActor(), object)).toBe(true); + }); + + it("see_enemy should check if object see enemy", () => { + const object: GameObject = MockGameObject.mock(); + + jest.spyOn(object, "see").mockImplementation(() => true); + expect(callXrCondition("see_enemy", MockGameObject.mockActor(), object)).toBe(false); + + jest.spyOn(object, "best_enemy").mockImplementation(() => MockGameObject.mock()); + expect(callXrCondition("see_enemy", MockGameObject.mockActor(), object)).toBe(true); + + jest.spyOn(object, "see").mockImplementation(() => false); + expect(callXrCondition("see_enemy", MockGameObject.mockActor(), object)).toBe(false); + }); it("mob_has_enemy should check if object has enemy", () => { const object: GameObject = MockGameObject.mock(); diff --git a/src/engine/scripts/declarations/conditions/object.ts b/src/engine/scripts/declarations/conditions/object.ts index 1e6e5abf9..5482edc42 100644 --- a/src/engine/scripts/declarations/conditions/object.ts +++ b/src/engine/scripts/declarations/conditions/object.ts @@ -501,64 +501,58 @@ extern("xr_conditions.is_alive", (actor: GameObject, object: AnyGameObject, para }); /** - * todo; + * Whether object is dead or not existing by story ID. */ -extern("xr_conditions.is_dead", (actor: GameObject, object: GameObject, p: [string]): boolean => { - const npc1: Optional = getObjectByStoryId(p[0]); +extern("xr_conditions.is_dead", (actor: GameObject, object: GameObject, [storyId]: [TStringId]): boolean => { + const storyObject: Optional = getObjectByStoryId(storyId); - return !npc1 || !npc1.alive(); + return !storyObject || !storyObject.alive(); }); /** - * todo; + * Whether object with provided story ID exists. */ -extern("xr_conditions.story_object_exist", (actor: GameObject, object: GameObject, p: [string]): boolean => { - return getObjectByStoryId(p[0]) !== null; +extern("xr_conditions.story_object_exist", (actor: GameObject, object: GameObject, [storyId]: [TStringId]): boolean => { + return getObjectByStoryId(storyId) !== null; }); /** - * todo; + * Whether object has item in inventory. */ -extern("xr_conditions.npc_has_item", (actor: GameObject, object: GameObject, p: [string]): boolean => { - return p[0] !== null && object.object(p[0]) !== null; -}); +extern( + "xr_conditions.npc_has_item", + (actor: GameObject, object: GameObject, [section]: [Optional]): boolean => { + return section !== null && object.object(section) !== null; + } +); /** - * todo; + * Whether object has active enemy. */ extern("xr_conditions.has_enemy", (actor: GameObject, object: GameObject): boolean => { return object.best_enemy() !== null; }); /** - * todo; + * Whether object has actor as active enemy. */ extern("xr_conditions.has_actor_enemy", (actor: GameObject, object: GameObject): boolean => { - const bestEnemy: Optional = object.best_enemy(); - - return bestEnemy !== null && bestEnemy.id() === ACTOR_ID; + return object.best_enemy()?.id() === ACTOR_ID; }); /** - * todo; + * Whether object has enemy and see it. */ extern("xr_conditions.see_enemy", (actor: GameObject, object: GameObject): boolean => { const enemy: Optional = object.best_enemy(); - if (enemy !== null) { + if (enemy) { return object.see(enemy); } return false; }); -/** - * todo; - */ -extern("xr_conditions.heavy_wounded", (actor: GameObject, object: GameObject): boolean => { - return isObjectWounded(object.id()); -}); - /** * Whether object has active enemy. */