basic logic

This commit is contained in:
azykov@mail.ru
2026-08-31 22:01:35 +03:00
parent 2860bb837a
commit d96a6e2e92
6 changed files with 66 additions and 88 deletions
+41 -21
View File
@@ -1,4 +1,4 @@
import { Resource, Resources, SerializedConverter, SerializedNodeBehaviour as SerializedBehaviour, SerializedNodeBehaviour, SerializedConverterOutput, SerializedConverterInput } from "../../types";
import { Resource, Resources, SerializedConverter, SerializedNodeBehaviour as SerializedBehaviour, SerializedNodeBehaviour } from "../../types";
export type BehaviourResourcePin = {
resource: Resource;
@@ -16,6 +16,7 @@ export type BehaviourLink = {
}
export type BehaviourInput = BehaviourResourcePin & {
rate: number; // per second of tick deltaTime
link: BehaviourLink;
}
@@ -24,6 +25,7 @@ export type BehaviourInputs = {
}
export type BehaviourOutput = BehaviourResourcePin & {
rate: number; // per second of tick deltaTime
}
export type BehaviourOutputs = {
@@ -41,51 +43,73 @@ export abstract class Behaviour {
public readonly kind: string;
public readonly inputs: BehaviourInputs;
public readonly outputs: BehaviourOutputs;
protected readonly storage: Partial<Resources> = {};
constructor(source: SerializedBehaviour) {
this.id = source.id;
this.kind = source.kind;
this.outputs = {
pins: source.outputs.pins.map((input) => ({
resource: input.resource,
pins: source.outputs.pins.map((output) => ({
resource: output.resource,
rate: output.rate,
})),
}
this.inputs = {
pins: source.inputs.pins.map((input) => ({
resource: input.resource,
rate: input.rate,
link: input.link,
})),
}
}
public reset() {
for (const res of Object.keys(this.storage))
delete (this.storage[res as Resource]);
}
abstract getDisplayInfo(): BehaviourDisplayInfo;
abstract tick(deltaTime: number): void;
}
/** Withdraws up to `amount` of `resource` from this behaviour's storage, returning how much was actually taken. */
protected take(resource: Resource, amount: number): number {
const available = this.storage[resource] ?? 0;
const taken = Math.min(available, amount);
this.storage[resource] = available - taken;
return taken;
}
export type ResourceUsageRule = {
resource: Resource;
speed: number; // per second
protected give(resource: Resource, amount: number): void {
this.storage[resource] = (this.storage[resource] ?? 0) + amount;
}
/** Fills this behaviour's own storage from its outputs' production rates. */
public produce(deltaTime: number): void {
for (const output of this.outputs.pins)
this.give(output.resource, output.rate * deltaTime);
}
/** Pulls resources into this behaviour's storage from whatever each input pin is linked to. */
public pull(deltaTime: number, resolve: (id: string) => Behaviour | undefined): void {
for (const input of this.inputs.pins) {
const source = resolve(input.link.target);
if (!source)
continue;
const taken = source.take(input.link.resource, input.rate * deltaTime);
this.give(input.resource, taken);
}
}
}
export class Converter extends Behaviour {
public outputRules: ResourceUsageRule[] = [];
rules: { inputs: SerializedConverterInput[]; outputs: SerializedConverterOutput[]; };
constructor(source: SerializedNodeBehaviour & SerializedConverter) {
if (source.kind !== 'converter')
throw new Error('Invalid source');
super(source);
this.rules = {
inputs: source.inputs.pins,
outputs: source.outputs.pins,
};
}
public getDisplayInfo(): BehaviourDisplayInfo {
return {
storages: {},
storages: { 'Буфер': { ...this.storage } as Resources },
links: this.inputs.pins.map((input) => input.link),
sockets: [
...this.inputs.pins.map((input, index) => ({
@@ -101,10 +125,6 @@ export class Converter extends Behaviour {
],
}
}
tick(deltaTime: number): void {
}
}
// export class Storage extends Behaviour {