@adatechnology/game-player 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-FRZ6ISLA.js → chunk-RUFQCNZH.js} +2 -2
- package/dist/{chunk-FRZ6ISLA.js.map → chunk-RUFQCNZH.js.map} +1 -1
- package/dist/index.global.js +3 -2
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/testing.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
deriveVitals,
|
|
8
8
|
drawWound,
|
|
9
9
|
playerTextOf
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RUFQCNZH.js";
|
|
11
11
|
|
|
12
12
|
// src/furniture-push.ts
|
|
13
13
|
var FURNITURE_PUSH_DEFAULTS = {
|
|
@@ -119,7 +119,8 @@ var DOOR_USE_DEFAULTS = {
|
|
|
119
119
|
reachSeconds: 0.3,
|
|
120
120
|
swingSeconds: { base: 0.45, perKg: 0.02, min: 0.45, max: 1.6 },
|
|
121
121
|
releaseSeconds: 0.22,
|
|
122
|
-
|
|
122
|
+
// the length of the recorded handle shaken (game-audio door_locked_rattle, 0.6 to 0.83 s): the hand lets go as the sound ends
|
|
123
|
+
rattleSeconds: 0.75,
|
|
123
124
|
stepFraction: 0.04,
|
|
124
125
|
endTolerance: 0.02
|
|
125
126
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/furniture-push.ts","../src/door-use.ts"],"sourcesContent":["/**\n * Pushing furniture on foot: hold the interaction button against a piece, a timer that grows with its mass fills, and the player then walks with it.\n * Engine-agnostic: the host says where the player wants to go and answers whether the volume of the piece can go there; this says how fast, and when it locks.\n */\n\nexport type FurniturePushPhase = 'idle' | 'grip' | 'push' | 'strain'\nexport type FurniturePushBlock = 'too_heavy' | 'obstacle' | null\n\n/** Every number of the push; a game overrides what it wants (`createFurniturePush(rules)`). */\nexport interface FurniturePushRules {\n /** The most the player's legs put on the floor, newtons: with the friction it says the heaviest thing that moves. */\n readonly forceN: number\n readonly gravity: number\n /** Static friction of a base on a floor, by the material of the piece. */\n readonly frictionByMaterial: Readonly<Record<string, number>>\n readonly defaultFriction: number\n /** The hold before the push: `base + perKg * mass`, at most `max` seconds. */\n readonly gripSeconds: { readonly base: number; readonly perKg: number; readonly max: number }\n /** Metres per second: `max` with nothing on the hands, `min` at the limit of the force. */\n readonly speed: { readonly max: number; readonly min: number }\n /** A press shorter than this is not a push (the host keeps it for a tap, such as grabbing). */\n readonly tapSeconds: number\n /** How long the effort stays after the last step that was refused, so that it does not flicker. */\n readonly strainHoldSeconds: number\n}\n\nexport const FURNITURE_PUSH_DEFAULTS: FurniturePushRules = {\n forceN: 500,\n gravity: 9.81,\n frictionByMaterial: { wood_soft: 0.4, wood_hard: 0.4, mdf: 0.4, plywood: 0.4, steel: 0.35, aluminium: 0.35, cast_iron: 0.4, copper: 0.35, plastic: 0.35, rubber: 0.8, fabric: 0.45, foam: 0.5, ceramic: 0.5, glass: 0.3, tempered_glass: 0.3, brick: 0.6, concrete: 0.65 },\n defaultFriction: 0.45,\n gripSeconds: { base: 0.4, perKg: 0.015, max: 2.5 },\n speed: { max: 1.8, min: 0.35 },\n tapSeconds: 0.2,\n strainHoldSeconds: 0.25,\n}\n\nexport type FurniturePushTarget = { readonly massKg: number; readonly material?: string }\n\nconst frictionOf = (target: FurniturePushTarget, rules: FurniturePushRules): number => (target.material !== undefined ? rules.frictionByMaterial[target.material] : undefined) ?? rules.defaultFriction\n\nconst loadShare = (target: FurniturePushTarget, rules: FurniturePushRules): number => (frictionOf(target, rules) * target.massKg * rules.gravity) / rules.forceN\n\nexport const gripSecondsFor = (massKg: number, rules: FurniturePushRules = FURNITURE_PUSH_DEFAULTS): number => Math.min(rules.gripSeconds.max, rules.gripSeconds.base + rules.gripSeconds.perKg * Math.max(0, massKg))\n\n/** Whether the legs overcome the friction of the piece on the floor. */\nexport const canPush = (target: FurniturePushTarget, rules: FurniturePushRules = FURNITURE_PUSH_DEFAULTS): boolean => loadShare(target, rules) <= 1\n\n/** Metres per second with the piece on the hands: slower the closer it is to the limit of the force, 0 past it. */\nexport const pushSpeedFor = (target: FurniturePushTarget, rules: FurniturePushRules = FURNITURE_PUSH_DEFAULTS): number => {\n const share = loadShare(target, rules)\n return share > 1 ? 0 : rules.speed.max + (rules.speed.min - rules.speed.max) * share\n}\n\nexport type FurniturePushInput = {\n /** Where the player wants to go on the floor: a unit vector, or `[0, 0]` standing. */\n readonly walk: readonly [number, number]\n /** Whether the volume of the piece (and the player behind it) can move by this offset. */\n readonly isFree: (dx: number, dz: number) => boolean\n}\n\nexport type FurniturePushStep = {\n readonly dx: number\n readonly dz: number\n /** The grip closed on this update. */\n readonly engaged: boolean\n /** A step was refused now and the one before was not: the moment the piece hits something. */\n readonly hitObstacle: boolean\n}\n\nexport interface FurniturePush {\n readonly phase: FurniturePushPhase\n /** How far the hold timer is, 0 to 1. */\n readonly progress: number\n readonly block: FurniturePushBlock\n readonly heldSeconds: number\n /** Whether the hold is still short enough to be a tap. */\n readonly isTap: boolean\n begin(target: FurniturePushTarget): void\n release(): void\n update(dt: number, input: FurniturePushInput): FurniturePushStep\n}\n\nconst STILL: FurniturePushStep = { dx: 0, dz: 0, engaged: false, hitObstacle: false }\n\nexport function createFurniturePush(overrides: Partial<FurniturePushRules> = {}): FurniturePush {\n const rules: FurniturePushRules = { ...FURNITURE_PUSH_DEFAULTS, ...overrides }\n let phase: FurniturePushPhase = 'idle'\n let target: FurniturePushTarget = { massKg: 0 }\n let held = 0\n let gripSeconds = 1\n let speed = 0\n let block: FurniturePushBlock = null\n let refused = 0\n let wasRefused = false\n\n const walkWith = (dt: number, input: FurniturePushInput): FurniturePushStep => {\n refused = Math.max(0, refused - dt)\n if (block === 'too_heavy') return STILL\n const [x, z] = input.walk\n if ((x === 0 && z === 0) || dt <= 0) {\n if (refused === 0) {\n phase = 'push'\n block = null\n wasRefused = false\n }\n return STILL\n }\n const dx = x * speed * dt\n const dz = z * speed * dt\n if (input.isFree(dx, dz)) {\n if (refused === 0) {\n phase = 'push'\n block = null\n }\n wasRefused = false\n return { dx, dz, engaged: false, hitObstacle: false }\n }\n const hitObstacle = !wasRefused\n wasRefused = true\n refused = rules.strainHoldSeconds\n phase = 'strain'\n block = 'obstacle'\n return { dx: 0, dz: 0, engaged: false, hitObstacle }\n }\n\n return {\n get phase() {\n return phase\n },\n get progress() {\n return phase === 'idle' ? 0 : Math.min(1, held / gripSeconds)\n },\n get block() {\n return block\n },\n get heldSeconds() {\n return held\n },\n get isTap() {\n return phase === 'grip' && held < rules.tapSeconds\n },\n begin(next) {\n target = next\n phase = 'grip'\n held = 0\n block = null\n refused = 0\n wasRefused = false\n gripSeconds = gripSecondsFor(next.massKg, rules)\n speed = pushSpeedFor(next, rules)\n },\n release() {\n phase = 'idle'\n held = 0\n block = null\n },\n update(dt, input) {\n if (phase === 'idle') return STILL\n held += dt\n if (phase !== 'grip') return walkWith(dt, input)\n if (held < gripSeconds) return STILL\n if (canPush(target, rules)) phase = 'push'\n else {\n phase = 'strain'\n block = 'too_heavy'\n }\n return { ...STILL, engaged: true }\n },\n }\n}\n","/**\n * Opening and closing a hinged or sliding leaf by hand (a house door, a wardrobe or fridge door, a drawer, a car door, a hood): the hand reaches the handle, the leaf\n * follows the hand at a speed set by its mass, stops where something is in its way, and a locked leaf only rattles.\n * Engine-agnostic: the host says how open the leaf is (0 closed, 1 open) and answers whether it can go to a new opening; this says how far it goes each step.\n */\n\nexport type DoorUsePhase = 'idle' | 'reach' | 'swing' | 'release' | 'rattle'\nexport type DoorUseBlock = 'locked' | 'obstacle' | null\n\n/** Every number of the use; a game overrides what it wants (`createDoorUse(rules)`). */\nexport interface DoorUseRules {\n /** The hand going to the handle before the leaf moves, seconds. */\n readonly reachSeconds: number\n /** A full swing: `base + perKg * mass` of the leaf, between `min` and `max` seconds (a fridge door is quick, a car door slower, a steel door slower still). */\n readonly swingSeconds: { readonly base: number; readonly perKg: number; readonly min: number; readonly max: number }\n /** The hand letting go and coming back, seconds. */\n readonly releaseSeconds: number\n /** How long a locked leaf is shaken before the hand gives up, seconds. */\n readonly rattleSeconds: number\n /** The part of the swing tested at a time against what is around (smaller is finer and costs more). */\n readonly stepFraction: number\n /** Within this of closed or open a leaf counts as there: the last use's way no longer turns it round. */\n readonly endTolerance: number\n}\n\nexport const DOOR_USE_DEFAULTS: DoorUseRules = {\n reachSeconds: 0.3,\n swingSeconds: { base: 0.45, perKg: 0.02, min: 0.45, max: 1.6 },\n releaseSeconds: 0.22,\n rattleSeconds: 0.6,\n stepFraction: 0.04,\n endTolerance: 0.02,\n}\n\nexport type DoorUseTarget = {\n /** How open the leaf is now, 0 closed to 1 open. */\n readonly opening: number\n readonly massKg: number\n readonly locked?: boolean\n /** Where the last use sent this leaf: a leaf stopped between closed and open goes the other way (a door blocked half open closes). */\n readonly lastGoal?: 0 | 1\n}\n\nexport type DoorUseStep = {\n readonly phase: DoorUsePhase\n /** How open the leaf is after the step. */\n readonly opening: number\n /** The phase's own progress, 0 to 1 (how far the hand is to the handle, how far the swing went, how much of the rattle is left). */\n readonly progress: number\n /** Set on the step the leaf stopped short or would not move. */\n readonly block: DoorUseBlock\n /** The leaf got where it was going on this step (fully open or fully closed). */\n readonly arrived: boolean\n}\n\n/** Seconds of a full swing for a leaf of this mass. */\nexport const swingSecondsFor = (massKg: number, rules: DoorUseRules = DOOR_USE_DEFAULTS): number =>\n Math.min(rules.swingSeconds.max, Math.max(rules.swingSeconds.min, rules.swingSeconds.base + rules.swingSeconds.perKg * Math.max(0, massKg)))\n\nexport interface DoorUse {\n readonly phase: DoorUsePhase\n /** Where the leaf is going: 1 opening, 0 closing. */\n readonly goal: 0 | 1\n readonly opening: number\n /**\n * Starts using a leaf: the other way from where the last use sent it (`lastGoal`), else a closed or half-open leaf opens and an open\n * one closes. A use in the middle of a swing turns it round.\n * Answers the goal (1 open, 0 closed), or null when the leaf is locked (it rattles instead).\n */\n begin(target: DoorUseTarget): 0 | 1 | null\n /** Advances the use; `isFree(from, to)` answers whether the leaf can go from one opening to the other (nothing in the way of its sweep). */\n step(dt: number, isFree: (from: number, to: number) => boolean): DoorUseStep\n /** Lets go at once. */\n cancel(): void\n}\n\nexport function createDoorUse(rules: Partial<DoorUseRules> = {}): DoorUse {\n const r: DoorUseRules = { ...DOOR_USE_DEFAULTS, ...rules, swingSeconds: { ...DOOR_USE_DEFAULTS.swingSeconds, ...rules.swingSeconds } }\n let phase: DoorUsePhase = 'idle'\n let goal: 0 | 1 = 1\n let opening = 0\n let time = 0\n let swing = 1\n let start = 0\n\n const out = (progress: number, arrived = false, b: DoorUseBlock = null): DoorUseStep => ({ phase, opening, progress: Math.max(0, Math.min(1, progress)), block: b, arrived })\n\n return {\n get phase() {\n return phase\n },\n get goal() {\n return goal\n },\n get opening() {\n return opening\n },\n begin(target) {\n opening = Math.max(0, Math.min(1, target.opening))\n time = 0\n if (target.locked) {\n phase = 'rattle'\n return null\n }\n // in the middle of a swing the hand is already on the handle: the leaf turns round at once\n if (phase === 'swing' || phase === 'reach') goal = goal === 1 ? 0 : 1\n else if (target.lastGoal !== undefined && opening > r.endTolerance && opening < 1 - r.endTolerance) goal = target.lastGoal === 1 ? 0 : 1\n else goal = opening > 0.5 ? 0 : 1\n swing = swingSecondsFor(target.massKg, r)\n start = opening\n phase = phase === 'swing' ? 'swing' : 'reach'\n return goal\n },\n step(dt, isFree) {\n if (phase === 'idle') return out(0)\n time += dt\n if (phase === 'rattle') {\n const p = time / r.rattleSeconds\n if (p >= 1) {\n phase = 'idle'\n return out(1, false, 'locked')\n }\n return out(p, false, time === dt ? 'locked' : null)\n }\n if (phase === 'reach') {\n const p = time / r.reachSeconds\n if (p < 1) return out(p)\n phase = 'swing'\n time = 0\n start = opening\n }\n if (phase === 'swing') {\n const want = goal - opening\n const reach = Math.min(Math.abs(want), dt / swing)\n // the sweep is tested a little at a time, so a leaf stops at the first thing in its way and not past it\n let moved = 0\n let stopped = false\n while (moved < reach - 1e-9) {\n const inc = Math.min(r.stepFraction, reach - moved)\n const next = opening + Math.sign(want) * inc\n if (!isFree(opening, next)) {\n stopped = true\n break\n }\n opening = next\n moved += inc\n }\n const travel = Math.abs(goal - start) || 1\n if (stopped) {\n phase = 'release'\n time = 0\n return out(1 - Math.abs(goal - opening) / travel, false, 'obstacle')\n }\n if (Math.abs(goal - opening) < 1e-6) {\n opening = goal\n phase = 'release'\n time = 0\n return out(1, true)\n }\n return out(1 - Math.abs(goal - opening) / travel)\n }\n // release\n const p = time / r.releaseSeconds\n if (p >= 1) {\n phase = 'idle'\n }\n return out(p, false, null)\n },\n cancel() {\n phase = 'idle'\n time = 0\n },\n }\n}\n"],"mappings":"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","names":["p"]}
|
|
1
|
+
{"version":3,"sources":["../src/furniture-push.ts","../src/door-use.ts"],"sourcesContent":["/**\n * Pushing furniture on foot: hold the interaction button against a piece, a timer that grows with its mass fills, and the player then walks with it.\n * Engine-agnostic: the host says where the player wants to go and answers whether the volume of the piece can go there; this says how fast, and when it locks.\n */\n\nexport type FurniturePushPhase = 'idle' | 'grip' | 'push' | 'strain'\nexport type FurniturePushBlock = 'too_heavy' | 'obstacle' | null\n\n/** Every number of the push; a game overrides what it wants (`createFurniturePush(rules)`). */\nexport interface FurniturePushRules {\n /** The most the player's legs put on the floor, newtons: with the friction it says the heaviest thing that moves. */\n readonly forceN: number\n readonly gravity: number\n /** Static friction of a base on a floor, by the material of the piece. */\n readonly frictionByMaterial: Readonly<Record<string, number>>\n readonly defaultFriction: number\n /** The hold before the push: `base + perKg * mass`, at most `max` seconds. */\n readonly gripSeconds: { readonly base: number; readonly perKg: number; readonly max: number }\n /** Metres per second: `max` with nothing on the hands, `min` at the limit of the force. */\n readonly speed: { readonly max: number; readonly min: number }\n /** A press shorter than this is not a push (the host keeps it for a tap, such as grabbing). */\n readonly tapSeconds: number\n /** How long the effort stays after the last step that was refused, so that it does not flicker. */\n readonly strainHoldSeconds: number\n}\n\nexport const FURNITURE_PUSH_DEFAULTS: FurniturePushRules = {\n forceN: 500,\n gravity: 9.81,\n frictionByMaterial: { wood_soft: 0.4, wood_hard: 0.4, mdf: 0.4, plywood: 0.4, steel: 0.35, aluminium: 0.35, cast_iron: 0.4, copper: 0.35, plastic: 0.35, rubber: 0.8, fabric: 0.45, foam: 0.5, ceramic: 0.5, glass: 0.3, tempered_glass: 0.3, brick: 0.6, concrete: 0.65 },\n defaultFriction: 0.45,\n gripSeconds: { base: 0.4, perKg: 0.015, max: 2.5 },\n speed: { max: 1.8, min: 0.35 },\n tapSeconds: 0.2,\n strainHoldSeconds: 0.25,\n}\n\nexport type FurniturePushTarget = { readonly massKg: number; readonly material?: string }\n\nconst frictionOf = (target: FurniturePushTarget, rules: FurniturePushRules): number => (target.material !== undefined ? rules.frictionByMaterial[target.material] : undefined) ?? rules.defaultFriction\n\nconst loadShare = (target: FurniturePushTarget, rules: FurniturePushRules): number => (frictionOf(target, rules) * target.massKg * rules.gravity) / rules.forceN\n\nexport const gripSecondsFor = (massKg: number, rules: FurniturePushRules = FURNITURE_PUSH_DEFAULTS): number => Math.min(rules.gripSeconds.max, rules.gripSeconds.base + rules.gripSeconds.perKg * Math.max(0, massKg))\n\n/** Whether the legs overcome the friction of the piece on the floor. */\nexport const canPush = (target: FurniturePushTarget, rules: FurniturePushRules = FURNITURE_PUSH_DEFAULTS): boolean => loadShare(target, rules) <= 1\n\n/** Metres per second with the piece on the hands: slower the closer it is to the limit of the force, 0 past it. */\nexport const pushSpeedFor = (target: FurniturePushTarget, rules: FurniturePushRules = FURNITURE_PUSH_DEFAULTS): number => {\n const share = loadShare(target, rules)\n return share > 1 ? 0 : rules.speed.max + (rules.speed.min - rules.speed.max) * share\n}\n\nexport type FurniturePushInput = {\n /** Where the player wants to go on the floor: a unit vector, or `[0, 0]` standing. */\n readonly walk: readonly [number, number]\n /** Whether the volume of the piece (and the player behind it) can move by this offset. */\n readonly isFree: (dx: number, dz: number) => boolean\n}\n\nexport type FurniturePushStep = {\n readonly dx: number\n readonly dz: number\n /** The grip closed on this update. */\n readonly engaged: boolean\n /** A step was refused now and the one before was not: the moment the piece hits something. */\n readonly hitObstacle: boolean\n}\n\nexport interface FurniturePush {\n readonly phase: FurniturePushPhase\n /** How far the hold timer is, 0 to 1. */\n readonly progress: number\n readonly block: FurniturePushBlock\n readonly heldSeconds: number\n /** Whether the hold is still short enough to be a tap. */\n readonly isTap: boolean\n begin(target: FurniturePushTarget): void\n release(): void\n update(dt: number, input: FurniturePushInput): FurniturePushStep\n}\n\nconst STILL: FurniturePushStep = { dx: 0, dz: 0, engaged: false, hitObstacle: false }\n\nexport function createFurniturePush(overrides: Partial<FurniturePushRules> = {}): FurniturePush {\n const rules: FurniturePushRules = { ...FURNITURE_PUSH_DEFAULTS, ...overrides }\n let phase: FurniturePushPhase = 'idle'\n let target: FurniturePushTarget = { massKg: 0 }\n let held = 0\n let gripSeconds = 1\n let speed = 0\n let block: FurniturePushBlock = null\n let refused = 0\n let wasRefused = false\n\n const walkWith = (dt: number, input: FurniturePushInput): FurniturePushStep => {\n refused = Math.max(0, refused - dt)\n if (block === 'too_heavy') return STILL\n const [x, z] = input.walk\n if ((x === 0 && z === 0) || dt <= 0) {\n if (refused === 0) {\n phase = 'push'\n block = null\n wasRefused = false\n }\n return STILL\n }\n const dx = x * speed * dt\n const dz = z * speed * dt\n if (input.isFree(dx, dz)) {\n if (refused === 0) {\n phase = 'push'\n block = null\n }\n wasRefused = false\n return { dx, dz, engaged: false, hitObstacle: false }\n }\n const hitObstacle = !wasRefused\n wasRefused = true\n refused = rules.strainHoldSeconds\n phase = 'strain'\n block = 'obstacle'\n return { dx: 0, dz: 0, engaged: false, hitObstacle }\n }\n\n return {\n get phase() {\n return phase\n },\n get progress() {\n return phase === 'idle' ? 0 : Math.min(1, held / gripSeconds)\n },\n get block() {\n return block\n },\n get heldSeconds() {\n return held\n },\n get isTap() {\n return phase === 'grip' && held < rules.tapSeconds\n },\n begin(next) {\n target = next\n phase = 'grip'\n held = 0\n block = null\n refused = 0\n wasRefused = false\n gripSeconds = gripSecondsFor(next.massKg, rules)\n speed = pushSpeedFor(next, rules)\n },\n release() {\n phase = 'idle'\n held = 0\n block = null\n },\n update(dt, input) {\n if (phase === 'idle') return STILL\n held += dt\n if (phase !== 'grip') return walkWith(dt, input)\n if (held < gripSeconds) return STILL\n if (canPush(target, rules)) phase = 'push'\n else {\n phase = 'strain'\n block = 'too_heavy'\n }\n return { ...STILL, engaged: true }\n },\n }\n}\n","/**\n * Opening and closing a hinged or sliding leaf by hand (a house door, a wardrobe or fridge door, a drawer, a car door, a hood): the hand reaches the handle, the leaf\n * follows the hand at a speed set by its mass, stops where something is in its way, and a locked leaf only rattles.\n * Engine-agnostic: the host says how open the leaf is (0 closed, 1 open) and answers whether it can go to a new opening; this says how far it goes each step.\n */\n\nexport type DoorUsePhase = 'idle' | 'reach' | 'swing' | 'release' | 'rattle'\nexport type DoorUseBlock = 'locked' | 'obstacle' | null\n\n/** Every number of the use; a game overrides what it wants (`createDoorUse(rules)`). */\nexport interface DoorUseRules {\n /** The hand going to the handle before the leaf moves, seconds. */\n readonly reachSeconds: number\n /** A full swing: `base + perKg * mass` of the leaf, between `min` and `max` seconds (a fridge door is quick, a car door slower, a steel door slower still). */\n readonly swingSeconds: { readonly base: number; readonly perKg: number; readonly min: number; readonly max: number }\n /** The hand letting go and coming back, seconds. */\n readonly releaseSeconds: number\n /** How long a locked leaf is shaken before the hand gives up, seconds. */\n readonly rattleSeconds: number\n /** The part of the swing tested at a time against what is around (smaller is finer and costs more). */\n readonly stepFraction: number\n /** Within this of closed or open a leaf counts as there: the last use's way no longer turns it round. */\n readonly endTolerance: number\n}\n\nexport const DOOR_USE_DEFAULTS: DoorUseRules = {\n reachSeconds: 0.3,\n swingSeconds: { base: 0.45, perKg: 0.02, min: 0.45, max: 1.6 },\n releaseSeconds: 0.22,\n // the length of the recorded handle shaken (game-audio door_locked_rattle, 0.6 to 0.83 s): the hand lets go as the sound ends\n rattleSeconds: 0.75,\n stepFraction: 0.04,\n endTolerance: 0.02,\n}\n\nexport type DoorUseTarget = {\n /** How open the leaf is now, 0 closed to 1 open. */\n readonly opening: number\n readonly massKg: number\n readonly locked?: boolean\n /** Where the last use sent this leaf: a leaf stopped between closed and open goes the other way (a door blocked half open closes). */\n readonly lastGoal?: 0 | 1\n}\n\nexport type DoorUseStep = {\n readonly phase: DoorUsePhase\n /** How open the leaf is after the step. */\n readonly opening: number\n /** The phase's own progress, 0 to 1 (how far the hand is to the handle, how far the swing went, how much of the rattle is left). */\n readonly progress: number\n /** Set on the step the leaf stopped short or would not move. */\n readonly block: DoorUseBlock\n /** The leaf got where it was going on this step (fully open or fully closed). */\n readonly arrived: boolean\n}\n\n/** Seconds of a full swing for a leaf of this mass. */\nexport const swingSecondsFor = (massKg: number, rules: DoorUseRules = DOOR_USE_DEFAULTS): number =>\n Math.min(rules.swingSeconds.max, Math.max(rules.swingSeconds.min, rules.swingSeconds.base + rules.swingSeconds.perKg * Math.max(0, massKg)))\n\nexport interface DoorUse {\n readonly phase: DoorUsePhase\n /** Where the leaf is going: 1 opening, 0 closing. */\n readonly goal: 0 | 1\n readonly opening: number\n /**\n * Starts using a leaf: the other way from where the last use sent it (`lastGoal`), else a closed or half-open leaf opens and an open\n * one closes. A use in the middle of a swing turns it round.\n * Answers the goal (1 open, 0 closed), or null when the leaf is locked (it rattles instead).\n */\n begin(target: DoorUseTarget): 0 | 1 | null\n /** Advances the use; `isFree(from, to)` answers whether the leaf can go from one opening to the other (nothing in the way of its sweep). */\n step(dt: number, isFree: (from: number, to: number) => boolean): DoorUseStep\n /** Lets go at once. */\n cancel(): void\n}\n\nexport function createDoorUse(rules: Partial<DoorUseRules> = {}): DoorUse {\n const r: DoorUseRules = { ...DOOR_USE_DEFAULTS, ...rules, swingSeconds: { ...DOOR_USE_DEFAULTS.swingSeconds, ...rules.swingSeconds } }\n let phase: DoorUsePhase = 'idle'\n let goal: 0 | 1 = 1\n let opening = 0\n let time = 0\n let swing = 1\n let start = 0\n\n const out = (progress: number, arrived = false, b: DoorUseBlock = null): DoorUseStep => ({ phase, opening, progress: Math.max(0, Math.min(1, progress)), block: b, arrived })\n\n return {\n get phase() {\n return phase\n },\n get goal() {\n return goal\n },\n get opening() {\n return opening\n },\n begin(target) {\n opening = Math.max(0, Math.min(1, target.opening))\n time = 0\n if (target.locked) {\n phase = 'rattle'\n return null\n }\n // in the middle of a swing the hand is already on the handle: the leaf turns round at once\n if (phase === 'swing' || phase === 'reach') goal = goal === 1 ? 0 : 1\n else if (target.lastGoal !== undefined && opening > r.endTolerance && opening < 1 - r.endTolerance) goal = target.lastGoal === 1 ? 0 : 1\n else goal = opening > 0.5 ? 0 : 1\n swing = swingSecondsFor(target.massKg, r)\n start = opening\n phase = phase === 'swing' ? 'swing' : 'reach'\n return goal\n },\n step(dt, isFree) {\n if (phase === 'idle') return out(0)\n time += dt\n if (phase === 'rattle') {\n const p = time / r.rattleSeconds\n if (p >= 1) {\n phase = 'idle'\n return out(1, false, 'locked')\n }\n return out(p, false, time === dt ? 'locked' : null)\n }\n if (phase === 'reach') {\n const p = time / r.reachSeconds\n if (p < 1) return out(p)\n phase = 'swing'\n time = 0\n start = opening\n }\n if (phase === 'swing') {\n const want = goal - opening\n const reach = Math.min(Math.abs(want), dt / swing)\n // the sweep is tested a little at a time, so a leaf stops at the first thing in its way and not past it\n let moved = 0\n let stopped = false\n while (moved < reach - 1e-9) {\n const inc = Math.min(r.stepFraction, reach - moved)\n const next = opening + Math.sign(want) * inc\n if (!isFree(opening, next)) {\n stopped = true\n break\n }\n opening = next\n moved += inc\n }\n const travel = Math.abs(goal - start) || 1\n if (stopped) {\n phase = 'release'\n time = 0\n return out(1 - Math.abs(goal - opening) / travel, false, 'obstacle')\n }\n if (Math.abs(goal - opening) < 1e-6) {\n opening = goal\n phase = 'release'\n time = 0\n return out(1, true)\n }\n return out(1 - Math.abs(goal - opening) / travel)\n }\n // release\n const p = time / r.releaseSeconds\n if (p >= 1) {\n phase = 'idle'\n }\n return out(p, false, null)\n },\n cancel() {\n phase = 'idle'\n time = 0\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;AA0BO,IAAM,0BAA8C;AAAA,EACzD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,oBAAoB,EAAE,WAAW,KAAK,WAAW,KAAK,KAAK,KAAK,SAAS,KAAK,OAAO,MAAM,WAAW,MAAM,WAAW,KAAK,QAAQ,MAAM,SAAS,MAAM,QAAQ,KAAK,QAAQ,MAAM,MAAM,KAAK,SAAS,KAAK,OAAO,KAAK,gBAAgB,KAAK,OAAO,KAAK,UAAU,KAAK;AAAA,EACzQ,iBAAiB;AAAA,EACjB,aAAa,EAAE,MAAM,KAAK,OAAO,OAAO,KAAK,IAAI;AAAA,EACjD,OAAO,EAAE,KAAK,KAAK,KAAK,KAAK;AAAA,EAC7B,YAAY;AAAA,EACZ,mBAAmB;AACrB;AAIA,IAAM,aAAa,CAAC,QAA6B,WAAuC,OAAO,aAAa,SAAY,MAAM,mBAAmB,OAAO,QAAQ,IAAI,WAAc,MAAM;AAExL,IAAM,YAAY,CAAC,QAA6B,UAAuC,WAAW,QAAQ,KAAK,IAAI,OAAO,SAAS,MAAM,UAAW,MAAM;AAEnJ,IAAM,iBAAiB,CAAC,QAAgB,QAA4B,4BAAoC,KAAK,IAAI,MAAM,YAAY,KAAK,MAAM,YAAY,OAAO,MAAM,YAAY,QAAQ,KAAK,IAAI,GAAG,MAAM,CAAC;AAG9M,IAAM,UAAU,CAAC,QAA6B,QAA4B,4BAAqC,UAAU,QAAQ,KAAK,KAAK;AAG3I,IAAM,eAAe,CAAC,QAA6B,QAA4B,4BAAoC;AACxH,QAAM,QAAQ,UAAU,QAAQ,KAAK;AACrC,SAAO,QAAQ,IAAI,IAAI,MAAM,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO;AACjF;AA+BA,IAAM,QAA2B,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,OAAO,aAAa,MAAM;AAE7E,SAAS,oBAAoB,YAAyC,CAAC,GAAkB;AAC9F,QAAM,QAA4B,EAAE,GAAG,yBAAyB,GAAG,UAAU;AAC7E,MAAI,QAA4B;AAChC,MAAI,SAA8B,EAAE,QAAQ,EAAE;AAC9C,MAAI,OAAO;AACX,MAAI,cAAc;AAClB,MAAI,QAAQ;AACZ,MAAI,QAA4B;AAChC,MAAI,UAAU;AACd,MAAI,aAAa;AAEjB,QAAM,WAAW,CAAC,IAAY,UAAiD;AAC7E,cAAU,KAAK,IAAI,GAAG,UAAU,EAAE;AAClC,QAAI,UAAU,YAAa,QAAO;AAClC,UAAM,CAAC,GAAG,CAAC,IAAI,MAAM;AACrB,QAAK,MAAM,KAAK,MAAM,KAAM,MAAM,GAAG;AACnC,UAAI,YAAY,GAAG;AACjB,gBAAQ;AACR,gBAAQ;AACR,qBAAa;AAAA,MACf;AACA,aAAO;AAAA,IACT;AACA,UAAM,KAAK,IAAI,QAAQ;AACvB,UAAM,KAAK,IAAI,QAAQ;AACvB,QAAI,MAAM,OAAO,IAAI,EAAE,GAAG;AACxB,UAAI,YAAY,GAAG;AACjB,gBAAQ;AACR,gBAAQ;AAAA,MACV;AACA,mBAAa;AACb,aAAO,EAAE,IAAI,IAAI,SAAS,OAAO,aAAa,MAAM;AAAA,IACtD;AACA,UAAM,cAAc,CAAC;AACrB,iBAAa;AACb,cAAU,MAAM;AAChB,YAAQ;AACR,YAAQ;AACR,WAAO,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,OAAO,YAAY;AAAA,EACrD;AAEA,SAAO;AAAA,IACL,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,WAAW;AACb,aAAO,UAAU,SAAS,IAAI,KAAK,IAAI,GAAG,OAAO,WAAW;AAAA,IAC9D;AAAA,IACA,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAAA,IACA,IAAI,QAAQ;AACV,aAAO,UAAU,UAAU,OAAO,MAAM;AAAA,IAC1C;AAAA,IACA,MAAM,MAAM;AACV,eAAS;AACT,cAAQ;AACR,aAAO;AACP,cAAQ;AACR,gBAAU;AACV,mBAAa;AACb,oBAAc,eAAe,KAAK,QAAQ,KAAK;AAC/C,cAAQ,aAAa,MAAM,KAAK;AAAA,IAClC;AAAA,IACA,UAAU;AACR,cAAQ;AACR,aAAO;AACP,cAAQ;AAAA,IACV;AAAA,IACA,OAAO,IAAI,OAAO;AAChB,UAAI,UAAU,OAAQ,QAAO;AAC7B,cAAQ;AACR,UAAI,UAAU,OAAQ,QAAO,SAAS,IAAI,KAAK;AAC/C,UAAI,OAAO,YAAa,QAAO;AAC/B,UAAI,QAAQ,QAAQ,KAAK,EAAG,SAAQ;AAAA,WAC/B;AACH,gBAAQ;AACR,gBAAQ;AAAA,MACV;AACA,aAAO,EAAE,GAAG,OAAO,SAAS,KAAK;AAAA,IACnC;AAAA,EACF;AACF;;;ACjJO,IAAM,oBAAkC;AAAA,EAC7C,cAAc;AAAA,EACd,cAAc,EAAE,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,KAAK,IAAI;AAAA,EAC7D,gBAAgB;AAAA;AAAA,EAEhB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAChB;AAwBO,IAAM,kBAAkB,CAAC,QAAgB,QAAsB,sBACpE,KAAK,IAAI,MAAM,aAAa,KAAK,KAAK,IAAI,MAAM,aAAa,KAAK,MAAM,aAAa,OAAO,MAAM,aAAa,QAAQ,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC;AAmBtI,SAAS,cAAc,QAA+B,CAAC,GAAY;AACxE,QAAM,IAAkB,EAAE,GAAG,mBAAmB,GAAG,OAAO,cAAc,EAAE,GAAG,kBAAkB,cAAc,GAAG,MAAM,aAAa,EAAE;AACrI,MAAI,QAAsB;AAC1B,MAAI,OAAc;AAClB,MAAI,UAAU;AACd,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAEZ,QAAM,MAAM,CAAC,UAAkB,UAAU,OAAO,IAAkB,UAAuB,EAAE,OAAO,SAAS,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC,GAAG,OAAO,GAAG,QAAQ;AAE3K,SAAO;AAAA,IACL,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,IAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ;AACZ,gBAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,OAAO,CAAC;AACjD,aAAO;AACP,UAAI,OAAO,QAAQ;AACjB,gBAAQ;AACR,eAAO;AAAA,MACT;AAEA,UAAI,UAAU,WAAW,UAAU,QAAS,QAAO,SAAS,IAAI,IAAI;AAAA,eAC3D,OAAO,aAAa,UAAa,UAAU,EAAE,gBAAgB,UAAU,IAAI,EAAE,aAAc,QAAO,OAAO,aAAa,IAAI,IAAI;AAAA,UAClI,QAAO,UAAU,MAAM,IAAI;AAChC,cAAQ,gBAAgB,OAAO,QAAQ,CAAC;AACxC,cAAQ;AACR,cAAQ,UAAU,UAAU,UAAU;AACtC,aAAO;AAAA,IACT;AAAA,IACA,KAAK,IAAI,QAAQ;AACf,UAAI,UAAU,OAAQ,QAAO,IAAI,CAAC;AAClC,cAAQ;AACR,UAAI,UAAU,UAAU;AACtB,cAAMA,KAAI,OAAO,EAAE;AACnB,YAAIA,MAAK,GAAG;AACV,kBAAQ;AACR,iBAAO,IAAI,GAAG,OAAO,QAAQ;AAAA,QAC/B;AACA,eAAO,IAAIA,IAAG,OAAO,SAAS,KAAK,WAAW,IAAI;AAAA,MACpD;AACA,UAAI,UAAU,SAAS;AACrB,cAAMA,KAAI,OAAO,EAAE;AACnB,YAAIA,KAAI,EAAG,QAAO,IAAIA,EAAC;AACvB,gBAAQ;AACR,eAAO;AACP,gBAAQ;AAAA,MACV;AACA,UAAI,UAAU,SAAS;AACrB,cAAM,OAAO,OAAO;AACpB,cAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK;AAEjD,YAAI,QAAQ;AACZ,YAAI,UAAU;AACd,eAAO,QAAQ,QAAQ,MAAM;AAC3B,gBAAM,MAAM,KAAK,IAAI,EAAE,cAAc,QAAQ,KAAK;AAClD,gBAAM,OAAO,UAAU,KAAK,KAAK,IAAI,IAAI;AACzC,cAAI,CAAC,OAAO,SAAS,IAAI,GAAG;AAC1B,sBAAU;AACV;AAAA,UACF;AACA,oBAAU;AACV,mBAAS;AAAA,QACX;AACA,cAAM,SAAS,KAAK,IAAI,OAAO,KAAK,KAAK;AACzC,YAAI,SAAS;AACX,kBAAQ;AACR,iBAAO;AACP,iBAAO,IAAI,IAAI,KAAK,IAAI,OAAO,OAAO,IAAI,QAAQ,OAAO,UAAU;AAAA,QACrE;AACA,YAAI,KAAK,IAAI,OAAO,OAAO,IAAI,MAAM;AACnC,oBAAU;AACV,kBAAQ;AACR,iBAAO;AACP,iBAAO,IAAI,GAAG,IAAI;AAAA,QACpB;AACA,eAAO,IAAI,IAAI,KAAK,IAAI,OAAO,OAAO,IAAI,MAAM;AAAA,MAClD;AAEA,YAAM,IAAI,OAAO,EAAE;AACnB,UAAI,KAAK,GAAG;AACV,gBAAQ;AAAA,MACV;AACA,aAAO,IAAI,GAAG,OAAO,IAAI;AAAA,IAC3B;AAAA,IACA,SAAS;AACP,cAAQ;AACR,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":["p"]}
|
package/dist/testing.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adatechnology/game-player",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Pure, seeded player body for games: vitals from an attribute sheet, stamina, wounds and bleeding, an optional individual infection, being grabbed and breaking free, knock-downs, low-wall vaults, footstep noise, panic, shove and melee against any crowd. A literal port of the team game's player. Knows nothing about any game.",
|
|
6
6
|
"keywords": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dist"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@adatechnology/game-contracts": "^0.
|
|
45
|
+
"@adatechnology/game-contracts": "^0.23.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^22.10.7",
|