contra-renderer/www/js/moves/pullByDancers.ts

145 lines
4.9 KiB
TypeScript

import { HandConnection, HandTo, BalanceWeight, PositionKind, ShortLinesPosition, SemanticPosition } from "../interpreterCommon.js";
import { SemanticAnimationKind } from "../lowLevelMove.js";
import { Hand } from "../rendererConstants.js";
import { ISingleVariantMoveInterpreter, LowLevelMovesForAllDancers, MoveInterpreter, MoveInterpreterCtorArgs, PartialLowLevelMove, SemanticPositionsForAllDancers, SingleVariantMoveInterpreter, Variant, VariantCollection, moveInterpreters } from "./_moveInterpreter.js";
const moveName = "pull by dancers";
class PullByDancersSingleVariant extends SingleVariantMoveInterpreter<PullByDancers, typeof moveName> {
moveAsVariants(previousMoveVariant: string): VariantCollection {
const res = new Map<string, Variant>();
for (const toShortLines of [true, false]) {
try {
res.set(toShortLines ? "ToShortLines" : "FullPullBy", {
lowLevelMoves: this.moveAsLowLevelMovesTo(toShortLines),
previousMoveVariant
});
}
catch { }
}
return res;
}
moveAsLowLevelMovesTo(toShortLines: boolean): LowLevelMovesForAllDancers {
// TODO Might make sense to think of pull by as not a full swap?
// e.g., in Blue and Green Candles, it's treated as only getting to
// ShortLinesPosition.Middle* before doing an allemande.
return this.handlePairedMove(this.move.parameters.who, ({ startPos, around, withPos }) => {
if (toShortLines) {
if (startPos.kind !== PositionKind.Circle) {
throw new Error("ToShortLines variant of " + this.move.move + " only makes sense starting from a circle.");
}
}
// TODO Adjust facing?
const startPosition = {
...startPos,
hands: new Map<Hand, HandConnection>([
[
this.moveInterpreter.hand,
{ hand: this.moveInterpreter.hand, to: around === "Center" ? HandTo.DiagonalAcrossCircle : HandTo.DancerForward }
]]),
facing: startPos.which.facingAcross(),
};
const endPos: SemanticPosition = toShortLines
? {
...withPos,
hands: undefined,
facing: startPosition.facing,
kind: PositionKind.ShortLines,
which: ShortLinesPosition.fromSide(withPos.which.leftRightSide(), "Middle"),
longLines: undefined, // Needed to satisfy type-checker.
}
: {
...withPos,
hands: undefined,
facing: startPosition.facing,
};
const passBy: PartialLowLevelMove = {
beats: this.moveInterpreter.pullBeats,
endPosition: endPos,
movementPattern: {
kind: SemanticAnimationKind.PassBy,
around,
side: this.moveInterpreter.hand,
withHands: true,
facing: "Start",
otherPath: "Swap",
}
};
if (this.move.parameters.bal) {
return this.combine([
{
beats: this.moveInterpreter.balancePartBeats,
endPosition: {
...startPosition,
balance: BalanceWeight.Forward,
},
movementPattern: {
kind: SemanticAnimationKind.Linear,
}
},
{
beats: this.moveInterpreter.balancePartBeats,
endPosition: {
...startPosition,
balance: BalanceWeight.Backward,
},
movementPattern: {
kind: SemanticAnimationKind.Linear,
}
},
passBy], startPosition);
} else {
return this.combine([passBy], startPosition);
}
}, !toShortLines ? undefined : ({startPos}) => {
return this.combine([{
beats: this.move.beats,
movementPattern: {
kind: SemanticAnimationKind.Linear,
},
endPosition: {
...startPos,
kind: PositionKind.ShortLines,
which: ShortLinesPosition.fromSide(startPos.which.leftRightSide(), "Far"),
facing: startPos.which.facingAcross(),
hands: undefined,
longLines: undefined,
}
}], startPos);
});
}
}
class PullByDancers extends MoveInterpreter<typeof moveName> {
public readonly hand: Hand;
public readonly balancePartBeats: number;
public readonly pullBeats: number;
constructor(args: MoveInterpreterCtorArgs<typeof moveName>) {
super(args);
this.hand = this.move.parameters.hand ? Hand.Right : Hand.Left;
const balanceBeats = this.move.parameters.bal
? this.move.beats > 4
? this.move.beats - 4
: this.move.beats > 2
? 2
: this.move.beats / 2
: 0;
this.balancePartBeats = balanceBeats / 2;
this.pullBeats = this.move.beats - balanceBeats;
}
buildSingleVariantMoveInterpreter(startingPos: SemanticPositionsForAllDancers): ISingleVariantMoveInterpreter {
return new PullByDancersSingleVariant(this, startingPos);
}
}
moveInterpreters.set(moveName, PullByDancers);