62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import Decimal, { type DecimalSource } from "break_eternity.js";
|
|
import type { BehaviourDisplayInfo, BehaviourLink, BehaviourSocket, Resource, Resources, SerializedBehaviour } from "../types";
|
|
|
|
export abstract class Behaviour {
|
|
public readonly id: string;
|
|
public readonly kind: string;
|
|
public readonly inputLinks: BehaviourLink[];
|
|
|
|
constructor(source: SerializedBehaviour) {
|
|
this.id = source.id;
|
|
this.kind = source.kind;
|
|
this.inputLinks = source.inputLinks.pins;
|
|
}
|
|
|
|
public getDisplayInfo(): BehaviourDisplayInfo {
|
|
return {
|
|
storages: {},
|
|
sockets: [
|
|
...this.inputs.map((input, index) => ({
|
|
type: 'input',
|
|
index,
|
|
resource: input,
|
|
} satisfies BehaviourSocket)),
|
|
...this.outputs.map((output, index) => ({
|
|
type: 'output',
|
|
index,
|
|
resource: output,
|
|
} satisfies BehaviourSocket)),
|
|
],
|
|
};
|
|
}
|
|
|
|
public abstract get inputs(): Resource[];
|
|
public abstract get outputs(): Resource[];
|
|
|
|
/** Withdraws up to `amount` of `resource` from this behaviour's storage, returning how much was actually taken. */
|
|
public abstract take(resource: Resource, amount: DecimalSource): Decimal;
|
|
|
|
protected abstract give(resource: Resource, amount: DecimalSource): void;
|
|
|
|
/** Snapshot of everything currently held, keyed by resource. */
|
|
public abstract getStorage(): Partial<Resources>;
|
|
|
|
abstract reset(): void;
|
|
|
|
/**
|
|
* Advances this behaviour by `deltaTime`. Must pull whatever inputs it needs (via `resolve`)
|
|
* before advancing its own cycle, so that a cycle only completes once enough input was actually
|
|
* available — otherwise it stalls and tries again on a later tick.
|
|
*
|
|
* `fairShare(sourceId, resource)` caps how much of `resource` may be pulled from `sourceId` this
|
|
* tick: when several behaviours are linked to the same source for the same resource, each is
|
|
* capped to an equal share of what that source held right after its own tick, regardless of
|
|
* pull order, instead of whoever asks first draining it.
|
|
*/
|
|
abstract tick(
|
|
deltaTime: number,
|
|
resolve: (id: string) => Behaviour | undefined,
|
|
fairShare: (sourceId: string, resource: Resource) => Decimal,
|
|
): void;
|
|
}
|