Skip to content

Commit

Permalink
Server objects mocks extended. Full tests coverage for relation utils.
Browse files Browse the repository at this point in the history
  • Loading branch information
Neloreck committed Jun 23, 2023
1 parent 9a096ca commit f357a89
Show file tree
Hide file tree
Showing 14 changed files with 452 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { abort } from "@/engine/core/utils/assertion";
import { parseStringsList } from "@/engine/core/utils/ini/parse";
import { LuaLogger } from "@/engine/core/utils/logging";
import { changeTeamSquadGroup } from "@/engine/core/utils/object/object_general";
import { setSquadRelationToActor } from "@/engine/core/utils/relation";
import { TCommunity } from "@/engine/lib/constants/communities";
import { levels, TLevel } from "@/engine/lib/constants/levels";
import {
Expand Down Expand Up @@ -255,7 +256,10 @@ export class SimulationBoardManager extends AbstractCoreManager {
logger.info("Creating squad in smart:", squad.name(), smartTerrain.name());

squad.createSquadMembers(smartTerrain);
squad.updateSquadRelationToActor();

if (squad.relationship) {
setSquadRelationToActor(squad, squad.relationship);
}

this.assignSquadToSmartTerrain(squad, smartTerrain.id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { StatisticsManager } from "@/engine/core/managers/interface/StatisticsManager";
import { giveInfo, hasAlifeInfo, hasAlifeInfos, hasFewAlifeInfos } from "@/engine/core/utils/info_portion";
import { LuaLogger } from "@/engine/core/utils/logging";
import { increaseNumberRelationBetweenCommunityAndId } from "@/engine/core/utils/relation";
import { increaseCommunityGoodwillToId } from "@/engine/core/utils/relation";
import { spawnItemsForObjectFromList } from "@/engine/core/utils/spawn";
import { readTimeFromPacket, writeTimeToPacket } from "@/engine/core/utils/time";
import { captions } from "@/engine/lib/constants/captions/captions";
Expand Down Expand Up @@ -246,7 +246,7 @@ export class AchievementsManager extends AbstractCoreManager {
}

giveInfo(infoPortions.sim_bandit_attack_harder);
increaseNumberRelationBetweenCommunityAndId(communities.stalker, registry.actor.id(), 200);
increaseCommunityGoodwillToId(communities.stalker, registry.actor.id(), 200);

EventsManager.getInstance().emitEvent<ITipNotification>(EGameEvent.NOTIFICATION, {
type: ENotificationType.TIP,
Expand Down Expand Up @@ -364,10 +364,10 @@ export class AchievementsManager extends AbstractCoreManager {

const actorId: TNumberId = registry.actor.id();

increaseNumberRelationBetweenCommunityAndId(communities.stalker, actorId, 200);
increaseNumberRelationBetweenCommunityAndId(communities.freedom, actorId, 200);
increaseNumberRelationBetweenCommunityAndId(communities.dolg, actorId, 200);
increaseNumberRelationBetweenCommunityAndId(communities.bandit, actorId, 200);
increaseCommunityGoodwillToId(communities.stalker, actorId, 200);
increaseCommunityGoodwillToId(communities.freedom, actorId, 200);
increaseCommunityGoodwillToId(communities.dolg, actorId, 200);
increaseCommunityGoodwillToId(communities.bandit, actorId, 200);

EventsManager.getInstance().emitEvent<ITipNotification>(EGameEvent.NOTIFICATION, {
type: ENotificationType.TIP,
Expand Down Expand Up @@ -605,7 +605,7 @@ export class AchievementsManager extends AbstractCoreManager {
])
) {
giveInfo(infoPortions.sim_stalker_help_harder);
increaseNumberRelationBetweenCommunityAndId(communities.stalker, registry.actor.id(), 100);
increaseCommunityGoodwillToId(communities.stalker, registry.actor.id(), 100);

EventsManager.getInstance().emitEvent<ITipNotification>(EGameEvent.NOTIFICATION, {
type: ENotificationType.TIP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ESmartTerrainStatus } from "@/engine/core/objects/server/smart_terrain/
import { isWeapon } from "@/engine/core/utils/check/is";
import { parseConditionsList, pickSectionFromCondList, readIniString, TConditionList } from "@/engine/core/utils/ini";
import { LuaLogger } from "@/engine/core/utils/logging";
import { ERelation, setSquadRelationToActorById } from "@/engine/core/utils/relation";
import { ERelation, updateSquadIdRelationToActor } from "@/engine/core/utils/relation";
import { readTimeFromPacket, writeTimeToPacket } from "@/engine/core/utils/time";
import { logicsConfig } from "@/engine/lib/configs/LogicsConfig";
import {
Expand Down Expand Up @@ -75,7 +75,7 @@ export class SmartTerrainControl {
for (const [id, squad] of SimulationBoardManager.getInstance().getSmartTerrainDescriptorById(
this.smartTerrain.id
)!.assignedSquads) {
setSquadRelationToActorById(id, ERelation.NEUTRAL);
updateSquadIdRelationToActor(id, ERelation.NEUTRAL);
}

this.alarmStartedAt = null;
Expand Down Expand Up @@ -142,7 +142,7 @@ export class SmartTerrainControl {

for (const [squadId] of SimulationBoardManager.getInstance().getSmartTerrainDescriptorById(this.smartTerrain.id)!
.assignedSquads) {
setSquadRelationToActorById(squadId, ERelation.ENEMY);
updateSquadIdRelationToActor(squadId, ERelation.ENEMY);
}
}

Expand Down
22 changes: 0 additions & 22 deletions src/engine/core/objects/server/squad/Squad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -830,28 +830,6 @@ export class Squad extends cse_alife_online_offline_group implements ISimulation
}
}

/**
* Set relation of squad to object with desired parameter.
* In case of no parameter provided squad members relation will be updated with already in-memory stored value.
*
* @param relation - optional, new relation between squad and actor
*/
public updateSquadRelationToActor(relation: Optional<ERelation> = this.relationship): void {
if (relation !== null) {
const simulator: AlifeSimulator = alife();

for (const squadMember of this.squad_members()) {
const object: Optional<ClientObject> = registry.objects.get(squadMember.id)?.object;

if (object !== null) {
setClientObjectRelation(object, registry.actor, relation);
} else {
setServerObjectRelation(simulator.object(squadMember.id), simulator.actor(), relation);
}
}
}
}

/**
* Set squad position in current level by supplied vector.
*/
Expand Down
243 changes: 225 additions & 18 deletions src/engine/core/utils/relation/set.test.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,246 @@
import { describe, it } from "@jest/globals";
import { describe, expect, it } from "@jest/globals";
import { alife, level, relation_registry } from "xray16";

import { registerStoryLink } from "@/engine/core/database";
import {
increaseCommunityGoodwillToId,
setClientObjectRelation,
setGoodwillFromCommunityToCommunity,
setObjectSympathy,
setRelationFromCommunityToCommunity,
setServerObjectRelation,
setSquadRelationToActor,
setSquadRelationToCommunity,
setSquadRelationWithObject,
updateSquadIdRelationToActor,
} from "@/engine/core/utils/relation/set";
import { ERelation } from "@/engine/core/utils/relation/types";
import { communities } from "@/engine/lib/constants/communities";
import { ClientObject, ServerActorObject, ServerCreatureObject, ServerHumanObject, TIndex } from "@/engine/lib/types";
import { mockRelationsSquads } from "@/fixtures/engine";
import { mockActorClientGameObject, mockClientGameObject, mockServerAlifeCreatureActor } from "@/fixtures/xray";
import { CLIENT_SIDE_REGISTRY } from "@/fixtures/xray/mocks/interface";
import { mockServerAlifeCreatureAbstract } from "@/fixtures/xray/mocks/objects/server/cse_alife_creature_abstract.mock";

describe("'relation/set' utils", () => {
it("'setClientObjectsRelation' should correctly check relation", () => {
// todo;
it("'setClientObjectRelation' should correctly set objects relation", () => {
expect(() => setClientObjectRelation(null, null, ERelation.ENEMY)).toThrow();
expect(() => setClientObjectRelation(mockClientGameObject(), null, ERelation.ENEMY)).toThrow();
expect(() => setClientObjectRelation(null, mockClientGameObject(), ERelation.ENEMY)).toThrow();

const first: ClientObject = mockClientGameObject();
const second: ClientObject = mockClientGameObject();
const third: ClientObject = mockClientGameObject();

setClientObjectRelation(first, second, ERelation.ENEMY);
expect(first.force_set_goodwill).toHaveBeenCalledWith(-1000, second);

setClientObjectRelation(second, third, ERelation.FRIEND);
expect(second.force_set_goodwill).toHaveBeenCalledWith(1000, third);

setClientObjectRelation(third, first, ERelation.NEUTRAL);
expect(third.force_set_goodwill).toHaveBeenCalledWith(0, first);
});

it("'setServerObjectsRelation' should correctly check relation", () => {
// todo;
it("'setServerObjectRelation' should correctly set objects relation", () => {
expect(() => setServerObjectRelation(null, null, ERelation.ENEMY)).toThrow();
expect(() => setServerObjectRelation(mockServerAlifeCreatureAbstract(), null, ERelation.ENEMY)).toThrow();
expect(() => setServerObjectRelation(null, mockServerAlifeCreatureAbstract(), ERelation.ENEMY)).toThrow();

const first: ServerCreatureObject = mockServerAlifeCreatureAbstract();
const second: ServerCreatureObject = mockServerAlifeCreatureAbstract();
const third: ServerCreatureObject = mockServerAlifeCreatureAbstract();

setServerObjectRelation(first, second, ERelation.ENEMY);
expect(first.force_set_goodwill).toHaveBeenCalledWith(-1000, second.id);

setServerObjectRelation(second, third, ERelation.FRIEND);
expect(second.force_set_goodwill).toHaveBeenCalledWith(1000, third.id);

setServerObjectRelation(third, first, ERelation.NEUTRAL);
expect(third.force_set_goodwill).toHaveBeenCalledWith(0, first.id);
});

it("'setGoodwillBetweenCommunities' should correctly set community goodwill", () => {
setGoodwillFromCommunityToCommunity(null, communities.actor, 500);
expect(relation_registry.set_community_relation).not.toHaveBeenCalled();

setGoodwillFromCommunityToCommunity(communities.none, communities.actor, 500);
expect(relation_registry.set_community_relation).not.toHaveBeenCalled();

setGoodwillFromCommunityToCommunity(communities.actor, communities.none, 500);
expect(relation_registry.set_community_relation).not.toHaveBeenCalled();

setGoodwillFromCommunityToCommunity(communities.monolith, communities.actor, -500);
expect(relation_registry.set_community_relation).toHaveBeenCalledWith(
communities.monolith,
communities.actor,
-500
);
});

it("'setNumberRelationBetweenCommunities' should correctly check relation", () => {
// todo;
it("'setRelationFromCommunityToCommunity' should correctly check relation", () => {
setRelationFromCommunityToCommunity(null, communities.actor, ERelation.FRIEND);
expect(relation_registry.set_community_relation).not.toHaveBeenCalled();

setRelationFromCommunityToCommunity(communities.none, communities.actor, ERelation.FRIEND);
expect(relation_registry.set_community_relation).not.toHaveBeenCalled();

setRelationFromCommunityToCommunity(communities.actor, communities.none, ERelation.FRIEND);
expect(relation_registry.set_community_relation).not.toHaveBeenCalled();

setRelationFromCommunityToCommunity(communities.monolith, communities.actor, ERelation.FRIEND);
expect(relation_registry.set_community_relation).toHaveBeenCalledWith(
communities.monolith,
communities.actor,
1000
);
});

it("'increaseNumberRelationBetweenCommunityAndId' should correctly check relation", () => {
// todo;
increaseCommunityGoodwillToId(null, 400, 500);
expect(relation_registry.change_community_goodwill).not.toHaveBeenCalled();

increaseCommunityGoodwillToId(communities.none, 400, 500);
expect(relation_registry.change_community_goodwill).not.toHaveBeenCalled();

increaseCommunityGoodwillToId(communities.actor, null, 500);
expect(relation_registry.change_community_goodwill).not.toHaveBeenCalled();

increaseCommunityGoodwillToId(communities.monolith, 400, -500);
expect(relation_registry.change_community_goodwill).toHaveBeenCalledWith(communities.monolith, 400, -500);
});

it("'setRelationBetweenCommunities' should correctly check relation", () => {
// todo;
it("'setObjectSympathy' should correctly set sympathy", () => {
const object: ClientObject = mockClientGameObject();

setObjectSympathy(object, -10);
setObjectSympathy(object, -0.5);
setObjectSympathy(object, 0);
setObjectSympathy(object, 0.1);
setObjectSympathy(object, 0.5);
setObjectSympathy(object, 0.9);
setObjectSympathy(object, 1);
setObjectSympathy(object, 5);
setObjectSympathy(object, 10);

expect(object.set_sympathy).toHaveBeenNthCalledWith(1, 0);
expect(object.set_sympathy).toHaveBeenNthCalledWith(2, 0);
expect(object.set_sympathy).toHaveBeenNthCalledWith(3, 0);
expect(object.set_sympathy).toHaveBeenNthCalledWith(4, 0.1);
expect(object.set_sympathy).toHaveBeenNthCalledWith(5, 0.5);
expect(object.set_sympathy).toHaveBeenNthCalledWith(6, 0.9);
expect(object.set_sympathy).toHaveBeenNthCalledWith(7, 1);
expect(object.set_sympathy).toHaveBeenNthCalledWith(8, 1);
expect(object.set_sympathy).toHaveBeenNthCalledWith(9, 1);
});

it("'setObjectSympathy' should correctly check relation", () => {
// todo;
it("'setSquadRelationToCommunity' should correctly set squad members relation", () => {
const { neutralSquad, mixedSquad } = mockRelationsSquads();

expect(() => setSquadRelationToCommunity(55, communities.bandit, ERelation.ENEMY)).toThrow();
expect(() => setSquadRelationToCommunity("test", communities.bandit, ERelation.ENEMY)).toThrow();

setSquadRelationToCommunity(neutralSquad.id, communities.bandit, ERelation.ENEMY);

for (const member of neutralSquad.squad_members()) {
expect(level.object_by_id(member.id)?.set_community_goodwill).toHaveBeenCalledWith(communities.bandit, -1000);
}

registerStoryLink(mixedSquad.id, "test-sid");
setSquadRelationToCommunity("test-sid", communities.army, ERelation.FRIEND);

for (const member of mixedSquad.squad_members()) {
expect(level.object_by_id(member.id)?.set_community_goodwill).toHaveBeenCalledWith(communities.army, 1000);
}
});

it("'setSquadRelationToCommunity' should correctly check relation", () => {
// todo;
it("'setSquadRelationWithObject' should correctly set relation", () => {
const { neutralSquad, mixedSquad, enemy } = mockRelationsSquads();

setSquadRelationWithObject(neutralSquad.id, level.object_by_id(enemy.id) as ClientObject, ERelation.FRIEND);

let index: TIndex = 1;

for (const it of neutralSquad.squad_members()) {
expect(it.object.force_set_goodwill).toHaveBeenCalledWith(1000, enemy.id);
expect(alife().object<ServerHumanObject>(enemy.id)?.force_set_goodwill).toHaveBeenNthCalledWith(
index++,
1000,
it.object.id
);
}

registerStoryLink(mixedSquad.id, "test-sid-mixed");

const actor: ClientObject = mockActorClientGameObject();
const actorServerObject: ServerActorObject = mockServerAlifeCreatureActor();

setSquadRelationWithObject("test-sid-mixed", actor, ERelation.ENEMY);

index = 1;

for (const it of mixedSquad.squad_members()) {
expect(it.object.force_set_goodwill).toHaveBeenCalledWith(-1000, actorServerObject.id);
expect(actorServerObject.force_set_goodwill).toHaveBeenNthCalledWith(index++, -1000, it.object.id);
}
});

it("'setSquadRelationToObject' should correctly check relation", () => {
// todo;
it("'updateSquadIdRelationToActor' should correctly update relation", () => {
const actor: ClientObject = mockActorClientGameObject();

mockServerAlifeCreatureActor();

expect(() => updateSquadIdRelationToActor(55, ERelation.ENEMY)).toThrow();
expect(() => updateSquadIdRelationToActor("test", ERelation.ENEMY)).toThrow();

const { neutralSquad, mixedSquad, enemy } = mockRelationsSquads();

updateSquadIdRelationToActor(neutralSquad.id, ERelation.FRIEND);

for (const it of neutralSquad.squad_members()) {
expect(level.object_by_id(it.id)?.force_set_goodwill).toHaveBeenCalledWith(1000, actor);
}

// Remove from level, force offline.
for (const it of mixedSquad.squad_members()) {
CLIENT_SIDE_REGISTRY.delete(it.id);
}

mixedSquad.relationship = ERelation.ENEMY;
registerStoryLink(mixedSquad.id, "another-sid");
updateSquadIdRelationToActor("another-sid");

for (const it of mixedSquad.squad_members()) {
expect(it.object.force_set_goodwill).toHaveBeenCalledWith(-1000, actor.id());
}
});

it("'setSquadRelationToActorById' should correctly check relation", () => {
// todo;
it("'setSquadRelationToActor' should correctly update relation", () => {
const actor: ClientObject = mockActorClientGameObject();

mockServerAlifeCreatureActor();

expect(() => updateSquadIdRelationToActor(55, ERelation.ENEMY)).toThrow();
expect(() => updateSquadIdRelationToActor("test", ERelation.ENEMY)).toThrow();

const { neutralSquad, mixedSquad, enemy } = mockRelationsSquads();

setSquadRelationToActor(neutralSquad, ERelation.FRIEND);

for (const it of neutralSquad.squad_members()) {
expect(level.object_by_id(it.id)?.force_set_goodwill).toHaveBeenCalledWith(1000, actor);
}

// Remove from level, force offline.
for (const it of mixedSquad.squad_members()) {
CLIENT_SIDE_REGISTRY.delete(it.id);
}

setSquadRelationToActor(mixedSquad, ERelation.ENEMY);

for (const it of mixedSquad.squad_members()) {
expect(it.object.force_set_goodwill).toHaveBeenCalledWith(-1000, actor.id());
}
});
});
Loading

0 comments on commit f357a89

Please sign in to comment.