Skip to content

Commit

Permalink
Tests for sleep jobs generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neloreck committed Aug 15, 2023
1 parent 8d1a68e commit 528dbf8
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 54 deletions.
8 changes: 8 additions & 0 deletions src/engine/core/utils/job/__test__/job_create.default.ltx
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,14 @@ meet = meet@generic_lager
path_walk = surge_3_walk
def_state_standing = guard
def_state_moving = patrol
[logic@test_smart_sleep_1]
active = sleeper@test_smart_sleep_1
[sleeper@test_smart_sleep_1]
path_main = sleep_1
[logic@test_smart_sleep_2]
active = sleeper@test_smart_sleep_2
[sleeper@test_smart_sleep_2]
path_main = sleep_2
[logic@test_smart_home_1]
active = mob_home@test_smart_home_1
[mob_home@test_smart_home_1]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[logic@test_smart_sleep_1]
active = sleeper@test_smart_sleep_1
[sleeper@test_smart_sleep_1]
path_main = sleep_1
out_restr = def_restrictor_test
combat_ignore_cond = {=npc_in_zone(smart.base_on_actor_control.ignore_zone)} true
combat_ignore_keep_when_attacked = true
[logic@test_smart_sleep_2]
active = sleeper@test_smart_sleep_2
[sleeper@test_smart_sleep_2]
path_main = sleep_2
out_restr = def_restrictor_test
combat_ignore_cond = {=npc_in_zone(smart.base_on_actor_control.ignore_zone)} true
combat_ignore_keep_when_attacked = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[logic@test_smart_sleep_1]
active = sleeper@test_smart_sleep_1
[sleeper@test_smart_sleep_1]
path_main = sleep_1
invulnerable = {=npc_in_zone(smart.safe_restr)} true
[logic@test_smart_sleep_2]
active = sleeper@test_smart_sleep_2
[sleeper@test_smart_sleep_2]
path_main = sleep_2
invulnerable = {=npc_in_zone(smart.safe_restr)} true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[logic@test_smart_sleep_1]
active = sleeper@test_smart_sleep_1
[sleeper@test_smart_sleep_1]
path_main = sleep_1
[logic@test_smart_sleep_2]
active = sleeper@test_smart_sleep_2
[sleeper@test_smart_sleep_2]
path_main = sleep_2
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[logic@test_smart_sleep_1]
active = sleeper@test_smart_sleep_1
[sleeper@test_smart_sleep_1]
path_main = sleep_1
out_restr = def_restrictor_test
[logic@test_smart_sleep_2]
active = sleeper@test_smart_sleep_2
[sleeper@test_smart_sleep_2]
path_main = sleep_2
out_restr = def_restrictor_test
14 changes: 14 additions & 0 deletions src/engine/core/utils/job/job_create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ describe("jobs_general should correctly generate default jobs", () => {
),
priority: 50,
},
{
jobs: $fromArray(
range(2, 1).map((it) => ({
_precondition_function: expect.any(Function),
_precondition_params: {},
job_id: {
job_type: "path_job",
section: `logic@test_smart_sleep_${it}`,
},
priority: 10,
}))
),
priority: 10,
},
]),
priority: 60,
},
Expand Down
118 changes: 95 additions & 23 deletions src/engine/core/utils/job/job_create_stalker_sleep.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import * as path from "path";

import { describe, expect, it, jest } from "@jest/globals";
import { level } from "xray16";

import { registerZone } from "@/engine/core/database";
import { SmartTerrain, SmartTerrainControl } from "@/engine/core/objects";
import { createStalkerSleepJobs } from "@/engine/core/utils/job/job_create_stalker_sleep";
import { createStalkerSurgeJobs } from "@/engine/core/utils/job/job_create_stalker_surge";
import { range } from "@/engine/core/utils/number";
import { ServerHumanObject } from "@/engine/lib/types";
import { readInGameTestLtx } from "@/fixtures/engine";
import { mockClientGameObject } from "@/fixtures/xray";
import { mockClientGameObject, MockCTime, mockServerAlifeHumanStalker } from "@/fixtures/xray";

describe("jobs_general should correctly generate stalkers sleep jobs", () => {
it("should correctly generate sleep jobs for stalkers when no patrols exist", async () => {
Expand All @@ -30,7 +31,7 @@ describe("jobs_general should correctly generate stalkers sleep jobs", () => {

it("should correctly generate sleep jobs for stalkers when patrols exist", async () => {
const surgeJobsLtx: string = await readInGameTestLtx(
path.resolve(__dirname, "__test__", "job_create_stalker_surge.ltx")
path.resolve(__dirname, "__test__", "job_create_stalker_sleep.ltx")
);

const smartTerrain: SmartTerrain = new SmartTerrain("test_smart");
Expand All @@ -40,29 +41,29 @@ describe("jobs_general should correctly generate stalkers sleep jobs", () => {

jest.spyOn(smartTerrain, "name").mockImplementation(() => "test_smart");

const [jobsList, ltx, count] = createStalkerSurgeJobs(smartTerrain);
const [jobsList, ltx, count] = createStalkerSleepJobs(smartTerrain);

expect(count).toBe(4);
expect(count).toBe(3);
expect(ltx).toBe(surgeJobsLtx);
expect(jobsList).toEqualLuaTables({
jobs: $fromArray(
range(3, 1).map((it) => ({
range(2, 1).map((it) => ({
_precondition_function: expect.any(Function),
_precondition_params: {},
job_id: {
job_type: "path_job",
section: `logic@test_smart_surge_${it}_walk`,
section: `logic@test_smart_sleep_${it}`,
},
priority: 50,
priority: 10,
}))
),
priority: 50,
priority: 10,
});
});

it("should correctly generate sleep jobs for stalkers when patrols exist with restrictors", async () => {
const surgeJobsLtx: string = await readInGameTestLtx(
path.resolve(__dirname, "__test__", "job_create_stalker_surge.restrictors.ltx")
path.resolve(__dirname, "__test__", "job_create_stalker_sleep.restrictors.ltx")
);

const smartTerrain: SmartTerrain = new SmartTerrain("test_smart");
Expand All @@ -74,29 +75,29 @@ describe("jobs_general should correctly generate stalkers sleep jobs", () => {
smartTerrain.defendRestrictor = "def_restrictor_test";
smartTerrain.smartTerrainActorControl = { ignoreZone: "test_ignore_zone" } as SmartTerrainControl;

const [jobsList, ltx, count] = createStalkerSurgeJobs(smartTerrain);
const [jobsList, ltx, count] = createStalkerSleepJobs(smartTerrain);

expect(count).toBe(4);
expect(count).toBe(3);
expect(ltx).toBe(surgeJobsLtx);
expect(jobsList).toEqualLuaTables({
jobs: $fromArray(
range(3, 1).map((it) => ({
range(2, 1).map((it) => ({
_precondition_function: expect.any(Function),
_precondition_params: {},
job_id: {
job_type: "path_job",
section: `logic@test_smart_surge_${it}_walk`,
section: `logic@test_smart_sleep_${it}`,
},
priority: 50,
priority: 10,
}))
),
priority: 50,
priority: 10,
});
});

it("should correctly generate sleep jobs for stalkers when patrols exist, when in restrictor", async () => {
const surgeJobsLtx: string = await readInGameTestLtx(
path.resolve(__dirname, "__test__", "job_create_stalker_surge.ignore.ltx")
path.resolve(__dirname, "__test__", "job_create_stalker_sleep.ignore.ltx")
);

const smartTerrain: SmartTerrain = new SmartTerrain("test_smart");
Expand All @@ -110,23 +111,94 @@ describe("jobs_general should correctly generate stalkers sleep jobs", () => {
smartTerrain.defendRestrictor = "def_restrictor_test";
smartTerrain.smartTerrainActorControl = { ignoreZone: "some_restrictor" } as SmartTerrainControl;

const [jobsList, ltx, count] = createStalkerSurgeJobs(smartTerrain);
const [jobsList, ltx, count] = createStalkerSleepJobs(smartTerrain);

expect(count).toBe(4);
expect(count).toBe(3);
expect(ltx).toBe(surgeJobsLtx);
expect(jobsList).toEqualLuaTables({
jobs: $fromArray(
range(3, 1).map((it) => ({
range(2, 1).map((it) => ({
_precondition_function: expect.any(Function),
_precondition_params: {},
job_id: {
job_type: "path_job",
section: `logic@test_smart_surge_${it}_walk`,
section: `logic@test_smart_sleep_${it}`,
},
priority: 50,
priority: 10,
}))
),
priority: 50,
priority: 10,
});
});

it("should correctly generate sleep jobs for stalkers when patrols exist with invulnerable state", async () => {
const surgeJobsLtx: string = await readInGameTestLtx(
path.resolve(__dirname, "__test__", "job_create_stalker_sleep.invulnerable.ltx")
);

const smartTerrain: SmartTerrain = new SmartTerrain("test_smart");

smartTerrain.ini = smartTerrain.spawn_ini();

jest.spyOn(smartTerrain, "name").mockImplementation(() => "test_smart");

registerZone(mockClientGameObject({ name: () => "def_restrictor_test", inside: () => true }));

smartTerrain.safeRestrictor = "def_restrictor_test";
smartTerrain.smartTerrainActorControl = { ignoreZone: "test_ignore_zone" } as SmartTerrainControl;

const [jobsList, ltx, count] = createStalkerSleepJobs(smartTerrain);

expect(count).toBe(3);
expect(ltx).toBe(surgeJobsLtx);
expect(jobsList).toEqualLuaTables({
jobs: $fromArray(
range(2, 1).map((it) => ({
_precondition_function: expect.any(Function),
_precondition_params: {},
job_id: {
job_type: "path_job",
section: `logic@test_smart_sleep_${it}`,
},
priority: 10,
}))
),
priority: 10,
});
});

it("should correctly use sleep preconditions", () => {
const smartTerrain: SmartTerrain = new SmartTerrain("test_smart");
const stalker: ServerHumanObject = mockServerAlifeHumanStalker();

smartTerrain.ini = smartTerrain.spawn_ini();

jest.spyOn(smartTerrain, "name").mockImplementation(() => "test_smart");

const [jobsList] = createStalkerSleepJobs(smartTerrain);
const precondition = jobsList.jobs.get(1)._precondition_function;

expect(precondition?.(stalker, smartTerrain, { is_safe_job: null }, {})).toBe(false);

jest.spyOn(level, "get_time_hours").mockImplementation(() => 23);
expect(precondition?.(stalker, smartTerrain, { is_safe_job: null }, {})).toBe(true);

jest.spyOn(stalker, "community").mockImplementation(() => "zombied");
expect(precondition?.(stalker, smartTerrain, { is_safe_job: true }, {})).toBe(false);

jest.spyOn(stalker, "community").mockImplementation(() => "stalker");
smartTerrain.alarmStartedAt = MockCTime.mock(2014, 2, 3, 4, 20, 30, 400);
expect(precondition?.(stalker, smartTerrain, { is_safe_job: null }, {})).toBe(true);

smartTerrain.safeRestrictor = "sleep_test_restrictor";
registerZone(mockClientGameObject({ name: () => "sleep_test_restrictor", inside: () => true }));
expect(precondition?.(stalker, smartTerrain, { is_safe_job: null }, {})).toBe(true);

registerZone(mockClientGameObject({ name: () => "sleep_test_restrictor", inside: () => false }));
expect(precondition?.(stalker, smartTerrain, { is_safe_job: null }, {})).toBe(false);

smartTerrain.safeRestrictor = "another_sleep_test_restrictor";
expect(precondition?.(stalker, smartTerrain, { is_safe_job: true }, {})).toBe(true);
expect(precondition?.(stalker, smartTerrain, { is_safe_job: false }, {})).toBe(false);
});
});
38 changes: 10 additions & 28 deletions src/engine/core/utils/job/job_create_stalker_sleep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export function createStalkerSleepJobs(
let ltx: string = "";
let it: TIndex = 1;

// todo: Probably only one job applies by should be more?
while (level.patrol_path_exists(`${smartTerrainName}_sleep_${it}`)) {
const wayName: TName = `${smartTerrainName}_sleep_${it}`;

Expand All @@ -36,46 +35,29 @@ export function createStalkerSleepJobs(
_precondition_params: {},
_precondition_function: (
serverObject: ServerHumanObject,
smart: SmartTerrain,
precondParams: AnyObject
smartTerrain: SmartTerrain,
parameters: AnyObject
): boolean => {
if (serverObject.community() === communities.zombied) {
return false;
}

if (!isInTimeInterval(21, 7)) {
} else if (!isInTimeInterval(21, 7)) {
return false;
}

if (smart.alarmStartedAt === null) {
} else if (smartTerrain.alarmStartedAt === null) {
return true;
}

if (smart.safeRestrictor === null) {
} else if (smartTerrain.safeRestrictor === null) {
return true;
}

if (precondParams.is_safe_job === null) {
precondParams.is_safe_job = isJobPatrolInRestrictor(smart, smart.safeRestrictor, wayName);
if (parameters.is_safe_job === null) {
parameters.is_safe_job = isJobPatrolInRestrictor(smartTerrain, smartTerrain.safeRestrictor, wayName);
}

return precondParams.is_safe_job !== false;
return parameters.is_safe_job !== false;
},
});

let jobLtx: string =
"[logic@" +
wayName +
"]\n" +
"active = sleeper@" +
wayName +
"\n" +
"[sleeper@" +
wayName +
"]\n" +
"path_main = sleep_" +
it +
"\n";
`[logic@${wayName}]\n` + `active = sleeper@${wayName}\n` + `[sleeper@${wayName}]\n` + `path_main = sleep_${it}\n`;

if (
smartTerrain.safeRestrictor !== null &&
Expand All @@ -85,7 +67,7 @@ export function createStalkerSleepJobs(
}

if (smartTerrain.defendRestrictor !== null) {
jobLtx += "out_restr = " + smartTerrain.defendRestrictor + "\n";
jobLtx += `out_restr = ${smartTerrain.defendRestrictor}\n`;
}

if (
Expand Down
2 changes: 1 addition & 1 deletion src/engine/core/utils/job/job_exclusive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function loadExclusiveJob(
ini_path: iniPath,
online: jobOnline,
ini_file: jobIniFile,
job_type: jobType as TName,
job_type: jobType as EJobType,
},
};

Expand Down
2 changes: 1 addition & 1 deletion src/engine/core/utils/job/job_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export interface IJobDescriptor {
export interface IJobListDescriptor {
_precondition_is_monster?: Optional<boolean>;
priority: TRate;
jobs: LuaArray<IJobListDescriptor | IJobDescriptor>;
jobs: LuaArray<IJobDescriptor>;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/engine/core/utils/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ export function round(value: number): number {
* @param startAt - first value in range
*/
export function range(size: number, startAt: number = 0): ReadonlyArray<number> {
return [...Array(size).keys()].map((it: TIndex) => it + startAt);
return [...Array(size)].map((it: TIndex, index) => index + startAt);
}
1 change: 1 addition & 0 deletions src/fixtures/xray/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from "@/fixtures/xray/mocks/interface";
export * from "@/fixtures/xray/mocks/fs";
export * from "@/fixtures/xray/mocks/device.mock";
export * from "@/fixtures/xray/mocks/console.mock";
export * from "@/fixtures/xray/mocks/CTime.mock";
export * from "@/fixtures/xray/mocks/MocksConfig";

export * from "@/fixtures/xray/mockXRay16";
Loading

0 comments on commit 528dbf8

Please sign in to comment.