From e77d83d6f28d8a8d70b0dd9a973e65191bc33bac Mon Sep 17 00:00:00 2001 From: Reece Dunham Date: Sat, 13 Apr 2024 11:51:14 -0400 Subject: [PATCH] feat(contracts): Implement contract creation kill conditions (#414) --- components/contracts/contractRouting.ts | 10 +- components/contracts/dataGen.ts | 82 - components/statemachines/contractCreation.ts | 480 ++- components/types/types.ts | 6 +- .../contractCreation.test.ts.snap | 3544 +++++++++++++++++ tests/src/contractCreation.test.ts | 113 + tests/testData/contractCreationCases.json | 363 ++ 7 files changed, 4364 insertions(+), 234 deletions(-) create mode 100644 tests/src/__snapshots__/contractCreation.test.ts.snap create mode 100644 tests/src/contractCreation.test.ts create mode 100644 tests/testData/contractCreationCases.json diff --git a/components/contracts/contractRouting.ts b/components/contracts/contractRouting.ts index bbdb8efb..14b1fd8d 100644 --- a/components/contracts/contractRouting.ts +++ b/components/contracts/contractRouting.ts @@ -49,8 +49,8 @@ import { import { log, LogLevel } from "../loggingInterop" import { randomUUID } from "crypto" import { + createObjectivesForTarget, createTimeLimit, - TargetCreator, } from "../statemachines/contractCreation" import { createSniperLoadouts, SniperCharacter } from "../menus/sniper" import { GetForPlay2Body } from "../types/gameSchemas" @@ -277,13 +277,13 @@ contractRoutingRouter.post( return } - req.body.creationData.Targets.forEach((target) => { + for (const target of req.body.creationData.Targets) { if (!target.Selected) { - return + continue } - objectives.push(...new TargetCreator(target).build()) - }) + objectives.push(...createObjectivesForTarget(target)) + } req.body.creationData.ContractConditionIds.forEach( (contractConditionId) => { diff --git a/components/contracts/dataGen.ts b/components/contracts/dataGen.ts index b9183176..1de792ca 100644 --- a/components/contracts/dataGen.ts +++ b/components/contracts/dataGen.ts @@ -833,85 +833,3 @@ export function complications(timeString: string) { targetsOnly, ] } - -/* -const PISTOL_ELIM = { - $any: { - "?": { - $or: [ - { - $eq: ["$.#", "pistol"], - }, - { - $eq: ["$.#", "close_combat_pistol_elimination"], - }, - ], - }, - in: ["$Value.KillMethodBroad", "$Value.KillMethodStrict"], - }, -} - -export class StateMachineGenerationContext { - public createKillMethodStateMachine(): void { - this.weaponTargetStateMachine = { - _comment: `Eliminate ${this.targetId} using weapon`, - Type: "statemachine", - Id: this.weaponTargetStateMachineId, - Category: "secondary", - Definition: { - Scope: "Hit", - Context: { - Targets: [this.targetId], - }, - States: { - Start: { - Kill: [ - { - Condition: { - $and: [ - { - $eq: [ - "$Value.RepositoryId", - this.targetId, - ], - }, - { - $eq: [ - "$Value.KillMethodStrict", - this.genContextParams - .KillMethodStrict, - ], - }, - ], - }, - Transition: "Success", - }, - { - Condition: { - $eq: ["$Value.RepositoryId", this.targetId], - }, - Transition: "Failure", - }, - ], - }, - }, - }, - } - } - - private kmConditions(killMethodBroad) { - switch (killMethodBroad) { - case "pistol": - return PISTOL_ELIM - default: - // weapon - return { - $eq: [ - "$Value.KillMethodStrict", - this.genContextParams.KillMethodStrict, - ], - } - } - } -} - */ diff --git a/components/statemachines/contractCreation.ts b/components/statemachines/contractCreation.ts index c594d79f..1e713d27 100644 --- a/components/statemachines/contractCreation.ts +++ b/components/statemachines/contractCreation.ts @@ -16,19 +16,21 @@ * along with this program. If not, see . */ -import type { MissionManifestObjective } from "../types/types" +import type { MissionManifestObjective, RepositoryId } from "../types/types" import { randomUUID } from "crypto" +import assert from "assert" /** * The payload provided to the game for each target in the create menu route. */ -export interface IContractCreationPayload { +export type ContractCreationNpcTargetPayload = { RepositoryId: string Selected: boolean Weapon: { RepositoryId: string KillMethodBroad: string KillMethodStrict: string + RequiredKillMethod: string RequiredKillMethodType: number } Outfit: { @@ -39,169 +41,216 @@ export interface IContractCreationPayload { } /** - * The target creator API. + * @internal */ -export class TargetCreator { - // @ts-expect-error TODO: type this - private _targetSm - // @ts-expect-error TODO: type this - private _outfitSm - private _targetConds: undefined | unknown[] = undefined - - /** - * The constructor. - * - * @param _params The contract creation payload. - */ - public constructor(private readonly _params: IContractCreationPayload) {} - - private _requireTargetConds(): void { - if (!this._targetConds || !Array.isArray(this._targetConds)) { - this._targetConds = [] - } - } - - private _bootstrapEntrySm(): void { - this._targetSm = { - Type: "statemachine", - Id: randomUUID(), - BriefingText: { - $loc: { - key: "UI_CONTRACT_GENERAL_OBJ_KILL", - data: `$($repository ${this._params.RepositoryId}).Name`, - }, +export const createTargetKillObjective = ( + params: ContractCreationNpcTargetPayload, +): MissionManifestObjective => ({ + Type: "statemachine", + Id: randomUUID(), + BriefingText: { + $loc: { + key: "UI_CONTRACT_GENERAL_OBJ_KILL", + data: `$($repository ${params.RepositoryId}).Name`, + }, + }, + HUDTemplate: { + display: { + $loc: { + key: "UI_CONTRACT_GENERAL_OBJ_KILL", + data: `$($repository ${params.RepositoryId}).Name`, }, - HUDTemplate: { - display: { - $loc: { - key: "UI_CONTRACT_GENERAL_OBJ_KILL", - data: `$($repository ${this._params.RepositoryId}).Name`, + }, + }, + Category: "primary", + Definition: { + Scope: "Hit", + Context: { + Targets: [params.RepositoryId], + }, + States: { + Start: { + Kill: { + Condition: { + $eq: ["$Value.RepositoryId", params.RepositoryId], }, + Transition: "Success", }, }, - Category: "primary", - Definition: { - Scope: "Hit", - Context: { - Targets: [this._params.RepositoryId], - }, - States: { - Start: { - Kill: [ - // this is the base state machine, we don't have fail states - { - Condition: { + }, + }, +}) + +/** + * @internal + */ +export const createRequiredOutfitObjective = ( + params: ContractCreationNpcTargetPayload, +): MissionManifestObjective => ({ + Type: "statemachine", + Id: randomUUID(), + Category: "secondary", + Definition: { + Scope: "Hit", + Context: { + Targets: [params.RepositoryId], + }, + States: { + Start: { + Kill: [ + { + Condition: { + $and: [ + { $eq: [ "$Value.RepositoryId", - this._params.RepositoryId, + params.RepositoryId, ], }, - Transition: "Success", - }, - ], + params.Outfit.IsHitmanSuit + ? { + $eq: [ + "$Value.OutfitIsHitmanSuit", + true, + ], + } + : { + $eq: [ + "$Value.OutfitRepositoryId", + params.Outfit.RepositoryId, + ], + }, + ], + }, + Transition: "Success", }, - }, + // state machines fall through to the next state if the condition is not met + { + Condition: { + $eq: ["$Value.RepositoryId", params.RepositoryId], + }, + Transition: "Failure", + }, + ], }, - } + }, + }, + TargetConditions: [], +}) + +/** + * Create the target, weapon, and kill conditions for a contracts target. + * @param params The parameters from the request. + * @param customIds Custom objective IDs for testing purposes. + */ +export function createObjectivesForTarget( + params: ContractCreationNpcTargetPayload, + customIds?: { base: string; kill: string; outfit: string }, +): MissionManifestObjective[] { + const targetSm = createTargetKillObjective(params) + + if (customIds?.base) { + targetSm.Id = customIds.base } - private _createOutfitSm(hmSuit: boolean): void { - this._requireTargetConds() + const objectives: MissionManifestObjective[] = [targetSm] - this._outfitSm = { - Type: "statemachine", - Id: randomUUID(), - Category: "secondary", - Definition: { - Scope: "Hit", - Context: { - Targets: [this._params.RepositoryId], - }, - States: { - Start: { - Kill: [ - { - Condition: { - $and: [ - { - $eq: [ - "$Value.RepositoryId", - this._params.RepositoryId, - ], - }, - hmSuit - ? { - $eq: [ - "$Value.OutfitIsHitmanSuit", - true, - ], - } - : { - $eq: [ - "$Value.OutfitRepositoryId", - this._params.Outfit - .RepositoryId, - ], - }, - ], - }, - Transition: "Success", - }, - { - Condition: { - $eq: [ - "$Value.RepositoryId", - this._params.RepositoryId, - ], - }, - Transition: "Failure", - }, - ], - }, - }, - }, + // if the required field is true, that means the user requested something OTHER than any disguise + if (params.Outfit.Required) { + const outfitSm = createRequiredOutfitObjective(params) + + if (customIds?.outfit) { + outfitSm.Id = customIds.outfit } - this._targetConds?.push({ - Type: hmSuit ? "hitmansuit" : "disguise", - RepositoryId: this._params.Outfit.RepositoryId, + targetSm.TargetConditions ??= [] + + targetSm.TargetConditions.push({ + Type: params.Outfit.IsHitmanSuit ? "hitmansuit" : "disguise", + RepositoryId: params.Outfit.RepositoryId, + // for contract creation it's always optional, only escalations set hard fail conditions HardCondition: false, - ObjectiveId: this._outfitSm.Id, - // ioi moment + ObjectiveId: outfitSm.Id, + // "Amazing!" - Athena Savalas KillMethod: "", }) + + objectives.push(outfitSm) } - /** - * Get the array of finalized state machines. - * - * @returns The state machines. - */ - public build(): MissionManifestObjective[] { - this._bootstrapEntrySm() + if (params.Weapon.RequiredKillMethodType !== 0) { + const weaponSm = createWeaponObjective( + params.Weapon, + params.RepositoryId, + ) - if (this._params.Outfit.Required) { - // not any disguise - this._createOutfitSm(this._params.Outfit.IsHitmanSuit) + if (customIds?.kill) { + weaponSm.Id = customIds.kill } - const values = [this._targetSm] + targetSm.TargetConditions ??= [] - if (this._outfitSm) { - values.push(this._outfitSm) - } + targetSm.TargetConditions.push({ + Type: "killmethod", + RepositoryId: params.Weapon.RepositoryId, + // for contract creation it's always optional, only escalations set hard fail conditions + HardCondition: false, + ObjectiveId: weaponSm.Id, + KillMethod: params.Weapon.RequiredKillMethod, + }) - if (this._targetConds && Array.isArray(this._targetConds)) { - this._targetSm.TargetConditions = this._targetConds - } + objectives.push(weaponSm) + } - return values + return objectives +} + +/** + * Create an objective for killing a target with a specific weapon. + * @param weapon The weapon details from the request. + * @param npcId The target NPC's repository ID. + */ +function createWeaponObjective( + weapon: Weapon, + npcId: RepositoryId, +): MissionManifestObjective { + return { + Type: "statemachine", + Id: randomUUID(), + Category: "secondary", + Definition: { + Scope: "Hit", + Context: { + Targets: [npcId], + }, + States: { + Start: { + Kill: [ + { + Condition: { + $and: [ + { + $eq: ["$Value.RepositoryId", npcId], + }, + genStateMachineKillSuccessCondition(weapon), + ], + }, + }, + { + Condition: { + $eq: ["$Value.RepositoryId", npcId], + }, + Transition: "Failure", + }, + ], + }, + }, + }, } } /** - * The time limit creator API. - * + * Create a time limit objective. * @param time The amount of time to use in seconds. * @param optional If the objective should be optional or not. * @returns The generated state machine. @@ -258,18 +307,14 @@ export function createTimeLimit( Scope: "session", States: { Start: { - IntroCutEnd: [ - { - Transition: "TimerRunning", - }, - ], + IntroCutEnd: { + Transition: "TimerRunning", + }, }, TimerRunning: { - exit_gate: [ - { - Transition: "Success", - }, - ], + exit_gate: { + Transition: "Success", + }, $timer: [ { Condition: { @@ -283,3 +328,150 @@ export function createTimeLimit( }, } } + +/** + * These are all the possible ways to get a kill in contracts mode. + */ +export const enum ContractKillMethod { + Any, + AnyMelee, + ObjectMelee, + AnyThrown, + ObjectThrown, + Pistol, + PistolElimination, + Smg, + AssaultRifle, + Shotgun, + SniperRifle, + AnyPoison, + ConsumedPoison, + InjectedPoison, + AnyAccident, + ExplosiveDevice, + FiberWire, + UnarmedNeckSnap, +} + +type Weapon = ContractCreationNpcTargetPayload["Weapon"] +type KillSuccessStateCondition = unknown + +export function genStateMachineKillSuccessCondition( + weapon: Weapon, +): KillSuccessStateCondition { + const km = weaponToKillMethod(weapon) + + if (km === ContractKillMethod.PistolElimination) { + return { + $any: { + "?": { + $or: [ + { + $eq: ["$.#", "pistol"], + }, + { + $eq: ["$.#", "close_combat_pistol_elimination"], + }, + ], + }, + in: ["$Value.KillMethodBroad", "$Value.KillMethodStrict"], + }, + } + } + + if (km === ContractKillMethod.Pistol) { + return { + $any: { + "?": { + $or: [ + { + $eq: ["$.#", "pistol"], + }, + { + $eq: ["$.#", "close_combat_pistol_elimination"], + }, + ], + }, + in: ["$Value.KillMethodBroad", "$Value.KillMethodStrict"], + }, + } + } + + return { + $any: { + "?": { + $eq: ["$.#", weapon.RequiredKillMethod], + }, + in: ["$Value.KillMethodBroad", "$Value.KillMethodStrict"], + }, + } +} + +/** + * Get the equivalent kill method from a weapon object. + * @param weapon The weapon's details. + */ +export function weaponToKillMethod(weapon: Weapon): ContractKillMethod { + const type = weapon.RequiredKillMethodType + + if (type === 0) { + return ContractKillMethod.Any + } + + switch (weapon.KillMethodBroad) { + case "pistol": + return ContractKillMethod.Pistol + case "smg": + return ContractKillMethod.Smg + case "sniperrifle": + return ContractKillMethod.SniperRifle + case "assaultrifle": + return ContractKillMethod.AssaultRifle + case "shotgun": + return ContractKillMethod.Shotgun + case "close_combat_pistol_elimination": + return ContractKillMethod.PistolElimination + case "fiberwire": + return ContractKillMethod.FiberWire + case "throw": { + return type === 1 + ? ContractKillMethod.AnyThrown + : ContractKillMethod.ObjectThrown + } + case "melee_lethal": { + return type === 1 + ? ContractKillMethod.AnyMelee + : ContractKillMethod.ObjectMelee + } + case "poison": { + if (weapon.KillMethodStrict === "consumed_poison" && type === 2) { + return ContractKillMethod.ConsumedPoison + } + + if ( + weapon.KillMethodStrict === "injected_poison" && + weapon.RequiredKillMethodType === 2 + ) { + return ContractKillMethod.InjectedPoison + } + + assert( + type === 1, + `Unhandled poison: ${weapon.KillMethodStrict} ${type}`, + ) + + return ContractKillMethod.AnyPoison + } + case "unarmed": + return ContractKillMethod.UnarmedNeckSnap + case "accident": + return ContractKillMethod.AnyAccident + case "explosive": + return ContractKillMethod.ExplosiveDevice + default: { + assert.fail( + `Unhandled condition: ${weapon.KillMethodBroad} ${type}`, + ) + } + } +} diff --git a/components/types/types.ts b/components/types/types.ts index 57226810..69e785a1 100644 --- a/components/types/types.ts +++ b/components/types/types.ts @@ -18,7 +18,7 @@ import type * as core from "express-serve-static-core" -import type { IContractCreationPayload } from "../statemachines/contractCreation" +import type { ContractCreationNpcTargetPayload } from "../statemachines/contractCreation" import { Request } from "express" import { ChallengeContext, @@ -1144,7 +1144,7 @@ export interface GameLocationsData { /** * The body sent with the CreateFromParams request from the game during the final phase of contract creation. * - * @see IContractCreationPayload + * @see ContractCreationNpcTargetPayload */ export interface CreateFromParamsBody { creationData: { @@ -1152,7 +1152,7 @@ export interface CreateFromParamsBody { Description: string ContractId: string ContractPublicId: string - Targets: IContractCreationPayload[] + Targets: ContractCreationNpcTargetPayload[] ContractConditionIds: string[] } } diff --git a/tests/src/__snapshots__/contractCreation.test.ts.snap b/tests/src/__snapshots__/contractCreation.test.ts.snap new file mode 100644 index 00000000..6a0132ed --- /dev/null +++ b/tests/src/__snapshots__/contractCreation.test.ts.snap @@ -0,0 +1,3544 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'accident explosion' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 90e997f4-67c6-486d-afb9-63c4424b1fd1).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 90e997f4-67c6-486d-afb9-63c4424b1fd1).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "accident_explosion", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "a8a0c154-c36f-413e-8f29-b83a1b7a22f0", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "accident_explosion", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "90e997f4-67c6-486d-afb9-63c4424b1fd1", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'any melee weapon' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "melee_lethal", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "2c649c52-f85a-4b29-838a-31c2525cc862", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "melee_lethal", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'any method' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 390807a3-7f83-4bf9-a454-7e55e0559090).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 390807a3-7f83-4bf9-a454-7e55e0559090).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Type": "hitmansuit", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'any poison' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository f25ced88-e077-47f1-a84f-700e21509494).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository f25ced88-e077-47f1-a84f-700e21509494).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "poison", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "7d668011-77f9-4cae-97f1-e3eda5e0c8b2", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "poison", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'any thrown weapon' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "throw", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "2c649c52-f85a-4b29-838a-31c2525cc862", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "throw", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'consumed poison explicit' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository f25ced88-e077-47f1-a84f-700e21509494).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository f25ced88-e077-47f1-a84f-700e21509494).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "consumed_poison", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "7d668011-77f9-4cae-97f1-e3eda5e0c8b2", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "consumed_poison", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'drowning accident' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 963c2774-cb9a-4b0c-ab69-210b2405383b).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 963c2774-cb9a-4b0c-ab69-210b2405383b).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "aab7f28d-84d9-47d1-be52-d142f5970086", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "accident_drown", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "aab7f28d-84d9-47d1-be52-d142f5970086", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "accident_drown", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "963c2774-cb9a-4b0c-ab69-210b2405383b", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'explosive device explicit' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "aab7f28d-84d9-47d1-be52-d142f5970086", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "explosive", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "e68927af-746d-41fa-83e2-402da0163262", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "aab7f28d-84d9-47d1-be52-d142f5970086", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "explosive", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'fall (push) accident' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "accident_push", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "accident_push", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'falling object accident' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "aab7f28d-84d9-47d1-be52-d142f5970086", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "accident_suspended_object", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "aab7f28d-84d9-47d1-be52-d142f5970086", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "accident_suspended_object", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'fiber wire explicit' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 6d5bf7f7-56bb-4329-acbd-2c6f341f0d79).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 6d5bf7f7-56bb-4329-acbd-2c6f341f0d79).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Type": "hitmansuit", + }, + { + "HardCondition": false, + "KillMethod": "fiberwire", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "1a11a060-358c-4054-98ec-d3491af1d7c6", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "fiberwire", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'fire accident' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 5b54d9fb-fa85-4302-a8d5-c5c5e97344c4).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "accident_burn", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "accident_burn", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'injected poison explicit' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository f25ced88-e077-47f1-a84f-700e21509494).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository f25ced88-e077-47f1-a84f-700e21509494).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "injected_poison", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "cdc20ebf-cd83-4707-8732-913c0f970cb5", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "injected_poison", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "f25ced88-e077-47f1-a84f-700e21509494", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'neck snap (unarmed)' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 390807a3-7f83-4bf9-a454-7e55e0559090).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 390807a3-7f83-4bf9-a454-7e55e0559090).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Type": "hitmansuit", + }, + { + "HardCondition": false, + "KillMethod": "unarmed", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "unarmed", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'pistol elimination specific' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 6d5bf7f7-56bb-4329-acbd-2c6f341f0d79).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 6d5bf7f7-56bb-4329-acbd-2c6f341f0d79).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Type": "hitmansuit", + }, + { + "HardCondition": false, + "KillMethod": "close_combat_pistol_elimination", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "73875794-5a86-410e-84a4-1b5b2f7e5a54", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + { + "$any": { + "?": { + "$or": [ + { + "$eq": [ + "$.#", + "pistol", + ], + }, + { + "$eq": [ + "$.#", + "close_combat_pistol_elimination", + ], + }, + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'pistol explicit' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 6d5bf7f7-56bb-4329-acbd-2c6f341f0d79).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 6d5bf7f7-56bb-4329-acbd-2c6f341f0d79).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Type": "hitmansuit", + }, + { + "HardCondition": false, + "KillMethod": "pistol", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "73875794-5a86-410e-84a4-1b5b2f7e5a54", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + { + "$any": { + "?": { + "$or": [ + { + "$eq": [ + "$.#", + "pistol", + ], + }, + { + "$eq": [ + "$.#", + "close_combat_pistol_elimination", + ], + }, + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'screwdriver melee' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "melee_lethal", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "2c649c52-f85a-4b29-838a-31c2525cc862", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "melee_lethal", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'screwdriver thrown weapon' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 2fa9698f-eb9b-4991-8aaf-3bddcf23e247).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Type": "disguise", + }, + { + "HardCondition": false, + "KillMethod": "throw", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "2c649c52-f85a-4b29-838a-31c2525cc862", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "throw", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`real world input data with createObjectivesForTarget > kill conditions: 'shotgun' 1`] = ` +[ + { + "BriefingText": { + "$loc": { + "data": "$($repository 390807a3-7f83-4bf9-a454-7e55e0559090).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository 390807a3-7f83-4bf9-a454-7e55e0559090).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + "TargetConditions": [ + { + "HardCondition": false, + "KillMethod": "", + "ObjectiveId": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Type": "hitmansuit", + }, + { + "HardCondition": false, + "KillMethod": "shotgun", + "ObjectiveId": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "RepositoryId": "545ff36e-b43c-4a35-9ab3-680b23b9e354", + "Type": "killmethod", + }, + ], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + "TargetConditions": [], + "Type": "statemachine", + }, + { + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + { + "$any": { + "?": { + "$eq": [ + "$.#", + "shotgun", + ], + }, + "in": [ + "$Value.KillMethodBroad", + "$Value.KillMethodStrict", + ], + }, + }, + ], + }, + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "390807a3-7f83-4bf9-a454-7e55e0559090", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "3df3bec8-17e6-4007-b1ac-5bd14485209a", + "Type": "statemachine", + }, +] +`; + +exports[`state machines > can use createTargetKillObjective 1`] = ` +{ + "BriefingText": { + "$loc": { + "data": "$($repository b69187a0-0860-403f-9616-981127fef877).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + "Category": "primary", + "Definition": { + "Context": { + "Targets": [ + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$($repository b69187a0-0860-403f-9616-981127fef877).Name", + "key": "UI_CONTRACT_GENERAL_OBJ_KILL", + }, + }, + }, + "Id": "00000000-0000-0000-0000-000000000000", + "Type": "statemachine", +} +`; + +exports[`state machines > outfits > can create an outfit state machine - id: a2deb86a-f38c-47d3-af98-848ea22500d6, is suit: 1, is required: 0 1`] = ` +{ + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "00000000-0000-0000-0000-000000000000", + "TargetConditions": [], + "Type": "statemachine", +} +`; + +exports[`state machines > outfits > can create an outfit state machine - id: b47eff05-6e65-4b27-860d-b114077e084c, is suit: 0, is required: 1 1`] = ` +{ + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "b47eff05-6e65-4b27-860d-b114077e084c", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "00000000-0000-0000-0000-000000000000", + "TargetConditions": [], + "Type": "statemachine", +} +`; + +exports[`state machines > outfits > can create an outfit state machine - id: e4d6dcb4-6c2c-44f5-98a6-b41ec1d92dee, is suit: 1, is required: 1 1`] = ` +{ + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + { + "$eq": [ + "$Value.OutfitIsHitmanSuit", + true, + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "00000000-0000-0000-0000-000000000000", + "TargetConditions": [], + "Type": "statemachine", +} +`; + +exports[`state machines > outfits > can create an outfit state machine - id: f1f7850d-9292-4cfc-b66e-e5661ef4a142, is suit: 0, is required: 0 1`] = ` +{ + "Category": "secondary", + "Definition": { + "Context": { + "Targets": [ + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Scope": "Hit", + "States": { + "Start": { + "Kill": [ + { + "Condition": { + "$and": [ + { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + { + "$eq": [ + "$Value.OutfitRepositoryId", + "f1f7850d-9292-4cfc-b66e-e5661ef4a142", + ], + }, + ], + }, + "Transition": "Success", + }, + { + "Condition": { + "$eq": [ + "$Value.RepositoryId", + "b69187a0-0860-403f-9616-981127fef877", + ], + }, + "Transition": "Failure", + }, + ], + }, + }, + }, + "Id": "00000000-0000-0000-0000-000000000000", + "TargetConditions": [], + "Type": "statemachine", +} +`; + +exports[`time limits > can create a time limit - seconds: 91, optional: 0 1`] = ` +{ + "BriefingName": "$loc UI_CONTRACT_UGC_TIME_LIMIT_NAME", + "BriefingText": { + "$loc": { + "data": "$formatstring 01:31", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_PRIMARY_DESC", + }, + }, + "Category": "primary", + "CombinedDisplayInHud": true, + "Definition": { + "Scope": "session", + "States": { + "Start": { + "IntroCutEnd": { + "Transition": "TimerRunning", + }, + }, + "TimerRunning": { + "$timer": [ + { + "Condition": { + "$after": 91, + }, + "Transition": "Failure", + }, + ], + "exit_gate": { + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$formatstring 01:31", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_PRIMARY_DESC", + }, + }, + }, + "Id": "1a596216-381e-4592-9798-26f156973942", + "Image": "images/contractconditions/condition_contrac_time_limit.jpg", + "LongBriefingText": { + "$loc": { + "data": "$formatstring 01:31", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_PRIMARY_DESC", + }, + }, + "ObjectiveType": "custom", + "OnActive": { + "IfInProgress": { + "State": "Completed", + }, + }, + "Type": "statemachine", +} +`; + +exports[`time limits > can create a time limit - seconds: 91, optional: 1 1`] = ` +{ + "BriefingName": "$loc UI_CONTRACT_UGC_TIME_LIMIT_NAME", + "BriefingText": { + "$loc": { + "data": "$formatstring 01:31", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_SECONDARY_DESC", + }, + }, + "Category": "secondary", + "CombinedDisplayInHud": true, + "Definition": { + "Scope": "session", + "States": { + "Start": { + "IntroCutEnd": { + "Transition": "TimerRunning", + }, + }, + "TimerRunning": { + "$timer": [ + { + "Condition": { + "$after": 91, + }, + "Transition": "Failure", + }, + ], + "exit_gate": { + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$formatstring 01:31", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_SECONDARY_DESC", + }, + }, + }, + "Id": "1a596216-381e-4592-9798-26f156973942", + "Image": "images/contractconditions/condition_contrac_time_limit.jpg", + "LongBriefingText": { + "$loc": { + "data": "$formatstring 01:31", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_SECONDARY_DESC", + }, + }, + "ObjectiveType": "custom", + "OnActive": { + "IfInProgress": { + "State": "Completed", + }, + }, + "Type": "statemachine", +} +`; + +exports[`time limits > can create a time limit - seconds: 346, optional: 0 1`] = ` +{ + "BriefingName": "$loc UI_CONTRACT_UGC_TIME_LIMIT_NAME", + "BriefingText": { + "$loc": { + "data": "$formatstring 05:46", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_PRIMARY_DESC", + }, + }, + "Category": "primary", + "CombinedDisplayInHud": true, + "Definition": { + "Scope": "session", + "States": { + "Start": { + "IntroCutEnd": { + "Transition": "TimerRunning", + }, + }, + "TimerRunning": { + "$timer": [ + { + "Condition": { + "$after": 346, + }, + "Transition": "Failure", + }, + ], + "exit_gate": { + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$formatstring 05:46", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_PRIMARY_DESC", + }, + }, + }, + "Id": "1a596216-381e-4592-9798-26f156973942", + "Image": "images/contractconditions/condition_contrac_time_limit.jpg", + "LongBriefingText": { + "$loc": { + "data": "$formatstring 05:46", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_PRIMARY_DESC", + }, + }, + "ObjectiveType": "custom", + "OnActive": { + "IfInProgress": { + "State": "Completed", + }, + }, + "Type": "statemachine", +} +`; + +exports[`time limits > can create a time limit - seconds: 346, optional: 1 1`] = ` +{ + "BriefingName": "$loc UI_CONTRACT_UGC_TIME_LIMIT_NAME", + "BriefingText": { + "$loc": { + "data": "$formatstring 05:46", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_SECONDARY_DESC", + }, + }, + "Category": "secondary", + "CombinedDisplayInHud": true, + "Definition": { + "Scope": "session", + "States": { + "Start": { + "IntroCutEnd": { + "Transition": "TimerRunning", + }, + }, + "TimerRunning": { + "$timer": [ + { + "Condition": { + "$after": 346, + }, + "Transition": "Failure", + }, + ], + "exit_gate": { + "Transition": "Success", + }, + }, + }, + }, + "HUDTemplate": { + "display": { + "$loc": { + "data": "$formatstring 05:46", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_SECONDARY_DESC", + }, + }, + }, + "Id": "1a596216-381e-4592-9798-26f156973942", + "Image": "images/contractconditions/condition_contrac_time_limit.jpg", + "LongBriefingText": { + "$loc": { + "data": "$formatstring 05:46", + "key": "UI_CONTRACT_UGC_TIME_LIMIT_SECONDARY_DESC", + }, + }, + "ObjectiveType": "custom", + "OnActive": { + "IfInProgress": { + "State": "Completed", + }, + }, + "Type": "statemachine", +} +`; diff --git a/tests/src/contractCreation.test.ts b/tests/src/contractCreation.test.ts new file mode 100644 index 00000000..1bb1ed51 --- /dev/null +++ b/tests/src/contractCreation.test.ts @@ -0,0 +1,113 @@ +/* + * The Peacock Project - a HITMAN server replacement. + * Copyright (C) 2021-2024 The Peacock Project Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { describe, expect, test } from "vitest" +import * as cc from "../../components/statemachines/contractCreation" +import { ContractCreationNpcTargetPayload } from "../../components/statemachines/contractCreation" +import { nilUuid } from "../../components/utils" +// @ts-expect-error No JSON imports allowed - TS language server will choke on trying to resolve JSON +// imports from the config manager, some of which are megabytes large, a nightmare for performance. +import killCases from "../testData/contractCreationCases.json" + +/** dummy data for basic operations that require no special cases, or as a base to build data with */ +const partialObjData: ContractCreationNpcTargetPayload = { + RepositoryId: "b69187a0-0860-403f-9616-981127fef877", + Selected: true, + Weapon: { + RepositoryId: nilUuid, + RequiredKillMethod: "", + RequiredKillMethodType: 0, + KillMethodStrict: "", + KillMethodBroad: "", + }, + Outfit: { + Required: false, + RepositoryId: "48a7f8a4-37ae-4522-a8b0-db746d970a7f", + IsHitmanSuit: true, + }, +} + +describe("state machines", () => { + test("can use createTargetKillObjective", () => { + const objective = cc.createTargetKillObjective(partialObjData) + + objective.Id = nilUuid + + expect(objective).toMatchSnapshot() + }) + + describe("outfits", () => { + test.each([ + ["e4d6dcb4-6c2c-44f5-98a6-b41ec1d92dee", +true, +true], + ["a2deb86a-f38c-47d3-af98-848ea22500d6", +true, +false], + ["b47eff05-6e65-4b27-860d-b114077e084c", +false, +true], + ["f1f7850d-9292-4cfc-b66e-e5661ef4a142", +false, +false], + ])( + "can create an outfit state machine - id: %s, is suit: %i, is required: %i", + (id, isSuit, isRequired) => { + const objective = cc.createRequiredOutfitObjective({ + ...partialObjData, + Outfit: { + RepositoryId: id, + IsHitmanSuit: Boolean(isSuit), + Required: Boolean(isRequired), + }, + }) + + objective.Id = nilUuid + expect(objective).toMatchSnapshot() + }, + ) + }) +}) + +describe("real world input data with createObjectivesForTarget", () => { + test.each(killCases)( + "kill conditions: $name", + // @ts-expect-error TS doesn't wanna narrow this + (options: { + name: string + params: ContractCreationNpcTargetPayload + }) => { + const objectives = cc.createObjectivesForTarget(options.params, { + // because we are comparing against snapshots, we intentionally use custom IDs for each of the generated objectives + base: "094a2f76-e0b4-4ab6-bf54-b5bdfdd8a0c6", + kill: "3df3bec8-17e6-4007-b1ac-5bd14485209a", + outfit: "59bfbf74-c38f-4cd4-bcd7-d0c44cd0940c", + }) + + expect(objectives).toMatchSnapshot() + }, + ) +}) + +describe("time limits", () => { + test.each([ + [91, +true], + [91, +false], + [346, +false], + [346, +true], + ])( + "can create a time limit - seconds: %i, optional: %i", + (time, optional) => { + expect( + cc.createTimeLimit(time, Boolean(optional)), + ).toMatchSnapshot() + }, + ) +}) diff --git a/tests/testData/contractCreationCases.json b/tests/testData/contractCreationCases.json new file mode 100644 index 00000000..96565af7 --- /dev/null +++ b/tests/testData/contractCreationCases.json @@ -0,0 +1,363 @@ +[ + { + "name": "pistol explicit", + "params": { + "RepositoryId": "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + "Selected": true, + "Weapon": { + "RepositoryId": "73875794-5a86-410e-84a4-1b5b2f7e5a54", + "KillMethodBroad": "pistol", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "pistol" + }, + "Outfit": { + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Required": true, + "IsHitmanSuit": true + } + } + }, + { + "name": "pistol elimination specific", + "params": { + "RepositoryId": "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + "Selected": true, + "Weapon": { + "RepositoryId": "73875794-5a86-410e-84a4-1b5b2f7e5a54", + "KillMethodBroad": "close_combat_pistol_elimination", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "close_combat_pistol_elimination" + }, + "Outfit": { + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Required": true, + "IsHitmanSuit": true + } + } + }, + { + "name": "fiber wire explicit", + "params": { + "RepositoryId": "6d5bf7f7-56bb-4329-acbd-2c6f341f0d79", + "Selected": true, + "Weapon": { + "RepositoryId": "1a11a060-358c-4054-98ec-d3491af1d7c6", + "KillMethodBroad": "fiberwire", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "fiberwire" + }, + "Outfit": { + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Required": true, + "IsHitmanSuit": true + } + } + }, + { + "name": "screwdriver thrown weapon", + "params": { + "RepositoryId": "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + "Selected": true, + "Weapon": { + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "KillMethodBroad": "throw", + "KillMethodStrict": "", + "RequiredKillMethodType": 3.0, + "RequiredKillMethod": "throw" + }, + "Outfit": { + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "any thrown weapon", + "params": { + "RepositoryId": "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + "Selected": true, + "Weapon": { + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "KillMethodBroad": "throw", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "throw" + }, + "Outfit": { + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "screwdriver melee", + "params": { + "RepositoryId": "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + "Selected": true, + "Weapon": { + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "KillMethodBroad": "melee_lethal", + "KillMethodStrict": "", + "RequiredKillMethodType": 3.0, + "RequiredKillMethod": "melee_lethal" + }, + "Outfit": { + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "any melee weapon", + "params": { + "RepositoryId": "2fa9698f-eb9b-4991-8aaf-3bddcf23e247", + "Selected": true, + "Weapon": { + "RepositoryId": "12cb6b51-a6dd-4bf5-9653-0ab727820cac", + "KillMethodBroad": "melee_lethal", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "melee_lethal" + }, + "Outfit": { + "RepositoryId": "2c649c52-f85a-4b29-838a-31c2525cc862", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "consumed poison explicit", + "params": { + "RepositoryId": "f25ced88-e077-47f1-a84f-700e21509494", + "Selected": true, + "Weapon": { + "RepositoryId": "7d668011-77f9-4cae-97f1-e3eda5e0c8b2", + "KillMethodBroad": "poison", + "KillMethodStrict": "consumed_poison", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "consumed_poison" + }, + "Outfit": { + "RepositoryId": "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "any poison", + "params": { + "RepositoryId": "f25ced88-e077-47f1-a84f-700e21509494", + "Selected": true, + "Weapon": { + "RepositoryId": "7d668011-77f9-4cae-97f1-e3eda5e0c8b2", + "KillMethodBroad": "poison", + "KillMethodStrict": "consumed_poison", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "poison" + }, + "Outfit": { + "RepositoryId": "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "injected poison explicit", + "params": { + "RepositoryId": "f25ced88-e077-47f1-a84f-700e21509494", + "Selected": true, + "Weapon": { + "RepositoryId": "cdc20ebf-cd83-4707-8732-913c0f970cb5", + "KillMethodBroad": "poison", + "KillMethodStrict": "injected_poison", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "injected_poison" + }, + "Outfit": { + "RepositoryId": "eb12cc2b-6dcf-4831-ba4e-ef8e53180e2f", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "falling object accident", + "params": { + "RepositoryId": "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + "Selected": true, + "Weapon": { + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "KillMethodBroad": "accident", + "KillMethodStrict": "accident_suspended_object", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "accident_suspended_object" + }, + "Outfit": { + "RepositoryId": "aab7f28d-84d9-47d1-be52-d142f5970086", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "explosive device explicit", + "params": { + "RepositoryId": "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + "Selected": true, + "Weapon": { + "RepositoryId": "e68927af-746d-41fa-83e2-402da0163262", + "KillMethodBroad": "explosive", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "explosive" + }, + "Outfit": { + "RepositoryId": "aab7f28d-84d9-47d1-be52-d142f5970086", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "accident explosion", + "params": { + "RepositoryId": "90e997f4-67c6-486d-afb9-63c4424b1fd1", + "Selected": true, + "Weapon": { + "RepositoryId": "a8a0c154-c36f-413e-8f29-b83a1b7a22f0", + "KillMethodBroad": "accident", + "KillMethodStrict": "accident_explosion", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "accident_explosion" + }, + "Outfit": { + "RepositoryId": "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "fire accident", + "params": { + "RepositoryId": "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + "Selected": true, + "Weapon": { + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "KillMethodBroad": "accident", + "KillMethodStrict": "accident_burn", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "accident_burn" + }, + "Outfit": { + "RepositoryId": "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "fall (push) accident", + "params": { + "RepositoryId": "5b54d9fb-fa85-4302-a8d5-c5c5e97344c4", + "Selected": true, + "Weapon": { + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "KillMethodBroad": "accident", + "KillMethodStrict": "accident_push", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "accident_push" + }, + "Outfit": { + "RepositoryId": "59c4f7db-f065-4fac-bc6c-5c7ac3758eed", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "drowning accident", + "params": { + "RepositoryId": "963c2774-cb9a-4b0c-ab69-210b2405383b", + "Selected": true, + "Weapon": { + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "KillMethodBroad": "accident", + "KillMethodStrict": "accident_drown", + "RequiredKillMethodType": 2.0, + "RequiredKillMethod": "accident_drown" + }, + "Outfit": { + "RepositoryId": "aab7f28d-84d9-47d1-be52-d142f5970086", + "Required": true, + "IsHitmanSuit": false + } + } + }, + { + "name": "any method", + "params": { + "RepositoryId": "390807a3-7f83-4bf9-a454-7e55e0559090", + "Selected": true, + "Weapon": { + "RepositoryId": "73875794-5a86-410e-84a4-1b5b2f7e5a54", + "KillMethodBroad": "pistol", + "KillMethodStrict": "", + "RequiredKillMethodType": 0.0, + "RequiredKillMethod": "" + }, + "Outfit": { + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Required": true, + "IsHitmanSuit": true + } + } + }, + { + "name": "neck snap (unarmed)", + "params": { + "RepositoryId": "390807a3-7f83-4bf9-a454-7e55e0559090", + "Selected": true, + "Weapon": { + "RepositoryId": "00000000-0000-0000-0000-000000000000", + "KillMethodBroad": "unarmed", + "KillMethodStrict": "", + "RequiredKillMethodType": 3, + "RequiredKillMethod": "unarmed" + }, + "Outfit": { + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Required": true, + "IsHitmanSuit": true + } + } + }, + { + "name": "shotgun", + "params": { + "RepositoryId": "390807a3-7f83-4bf9-a454-7e55e0559090", + "Selected": true, + "Weapon": { + "RepositoryId": "545ff36e-b43c-4a35-9ab3-680b23b9e354", + "KillMethodBroad": "shotgun", + "KillMethodStrict": "", + "RequiredKillMethodType": 1.0, + "RequiredKillMethod": "shotgun" + }, + "Outfit": { + "RepositoryId": "054f443b-824f-4913-8b29-64dfcd82b089", + "Required": true, + "IsHitmanSuit": true + } + } + } +]