import { CoupleRole } from "../danceCommon.js"; import { Facing, SemanticPosition, PositionKind, CircleSide } from "../interpreterCommon.js"; import { Move } from "../libfigureMapper.js"; import { SemanticAnimationKind } from "../lowLevelMove.js"; import { Hand } from "../rendererConstants.js"; import { ISingleVariantMoveInterpreter, LowLevelMovesForAllDancers, MoveInterpreter, SemanticPositionsForAllDancers, SingleVariantMoveInterpreter, moveInterpreters } from "./_moveInterpreter.js"; const moveName: Move["move"] = "pass through"; class PassThroughSingleVariant extends SingleVariantMoveInterpreter { moveAsLowLevelMoves(): LowLevelMovesForAllDancers { if (this.move.parameters.dir === "left diagonal" || this.move.parameters.dir === "right diagonal") { // TODO There's logic for this below, but unsure it's right. throw new Error(this.move.move + " with dir of " + this.move.parameters.dir + " is unsupported."); } const alongSet = this.move.parameters.dir === "along"; const passShoulder = this.move.parameters.shoulder ? Hand.Right : Hand.Left; // Special-case this. if (this.move.note?.includes("2s shooting the 1s down the center") ?? false) { return this.handleCircleMove(({ id, startPos }) => { const facing = id.coupleRole === CoupleRole.Ones ? Facing.Down : Facing.Up; const endPos: SemanticPosition = { kind: PositionKind.ShortLines, which: startPos.which.unfoldToShortLines(CircleSide.Top), facing, setOffset: (startPos.setOffset ?? 0) + (facing === Facing.Up ? -0.5 : +0.5), lineOffset: startPos.lineOffset, }; return this.combine([{ beats: this.move.beats, endPosition: endPos, movementPattern: { kind: SemanticAnimationKind.PassBy, around: startPos.which.leftRightSide(), side: endPos.which.isLeft() ? Hand.Left : Hand.Right, withHands: false, facing: "Forward", otherPath: "Swap", }, }], startPos); }); } return this.handleMove(({ startPos }) => { if (alongSet && startPos.kind === PositionKind.Circle) { const facing = startPos.which.facingUpOrDown(); const endPos: SemanticPosition = { kind: PositionKind.Circle, which: startPos.which, facing, setOffset: (startPos.setOffset ?? 0) + (facing === Facing.Up ? -0.5 : +0.5), lineOffset: startPos.lineOffset, }; return this.combine([{ beats: this.move.beats, endPosition: endPos, movementPattern: { kind: SemanticAnimationKind.PassBy, around: startPos.which.leftRightSide(), side: passShoulder, withHands: false, facing: "Start", otherPath: "Swap", }, }], startPos); } else if (!alongSet && startPos.kind === PositionKind.Circle) { const facing = startPos.which.facingAcross(); const endPos: SemanticPosition = { kind: PositionKind.Circle, which: startPos.which.swapAcross(), facing, setOffset: (startPos.setOffset ?? 0) + (this.move.parameters.dir === "across" ? 0 : (this.move.parameters.dir === "left diagonal") === startPos.which.isLeft() ? -1 : +1), lineOffset: startPos.lineOffset, }; return this.combine([{ beats: this.move.beats, endPosition: endPos, movementPattern: { kind: SemanticAnimationKind.PassBy, around: startPos.which.topBottomSide(), side: passShoulder, withHands: false, facing: "Forward", otherPath: "Swap", }, }], startPos); } else if (alongSet && startPos.kind === PositionKind.ShortLines) { // TODO This assumes short *wavy* lines. const endPos: SemanticPosition = { ...startPos, balance: undefined, // TODO only swap sometimes... which: startPos.which.swapOnSide(), setOffset: (startPos.setOffset ?? 0) + (startPos.facing === Facing.Up ? -0.5 : +0.5), }; return this.combine([{ beats: this.move.beats, endPosition: endPos, movementPattern: { kind: SemanticAnimationKind.Linear }, }], startPos); } else { throw new Error(this.move.move + " with dir of " + this.move.parameters.dir + " starting from " + startPos.kind + " is unsupported."); } }); } } class PassThrough extends MoveInterpreter { buildSingleVariantMoveInterpreter(startingPos: SemanticPositionsForAllDancers): ISingleVariantMoveInterpreter { return new PassThroughSingleVariant(this, startingPos); } } moveInterpreters.set(moveName, PassThrough);