|
|
|
@ -1,12 +1,34 @@
|
|
|
|
|
import { equals, Pos, ratioWithinBase } from "../geo/Pos"
|
|
|
|
|
|
|
|
|
|
import { BallState, Player, PlayerInfo, PlayerLike, PlayerPhantom, PlayerTeam } from "../model/tactic/Player"
|
|
|
|
|
import { Ball, BALL_ID, BALL_TYPE, CourtObject } from "../model/tactic/CourtObjects"
|
|
|
|
|
import { ComponentId, StepContent, TacticComponent } from "../model/tactic/Tactic"
|
|
|
|
|
import {
|
|
|
|
|
BallState,
|
|
|
|
|
Player,
|
|
|
|
|
PlayerInfo,
|
|
|
|
|
PlayerLike,
|
|
|
|
|
PlayerPhantom,
|
|
|
|
|
PlayerTeam,
|
|
|
|
|
} from "../model/tactic/Player"
|
|
|
|
|
import {
|
|
|
|
|
Ball,
|
|
|
|
|
BALL_ID,
|
|
|
|
|
BALL_TYPE,
|
|
|
|
|
CourtObject,
|
|
|
|
|
} from "../model/tactic/CourtObjects"
|
|
|
|
|
import {
|
|
|
|
|
ComponentId,
|
|
|
|
|
StepContent,
|
|
|
|
|
TacticComponent,
|
|
|
|
|
} from "../model/tactic/Tactic"
|
|
|
|
|
|
|
|
|
|
import { overlaps } from "../geo/Box"
|
|
|
|
|
import { RackedCourtObject, RackedPlayer } from "./RackedItems"
|
|
|
|
|
import { getComponent, getOrigin, getPrecomputedPosition, removePlayer, tryGetComponent } from "./PlayerDomains"
|
|
|
|
|
import {
|
|
|
|
|
getComponent,
|
|
|
|
|
getOrigin,
|
|
|
|
|
getPrecomputedPosition,
|
|
|
|
|
removePlayer,
|
|
|
|
|
tryGetComponent,
|
|
|
|
|
} from "./PlayerDomains"
|
|
|
|
|
import { Action, ActionKind } from "../model/tactic/Action.ts"
|
|
|
|
|
import { spreadNewStateFromOriginStateChange } from "./ActionsDomains.ts"
|
|
|
|
|
|
|
|
|
@ -179,9 +201,9 @@ export function moveComponent(
|
|
|
|
|
phantomIdx == 0
|
|
|
|
|
? origin
|
|
|
|
|
: getComponent(
|
|
|
|
|
originPathItems[phantomIdx - 1],
|
|
|
|
|
content.components,
|
|
|
|
|
)
|
|
|
|
|
originPathItems[phantomIdx - 1],
|
|
|
|
|
content.components,
|
|
|
|
|
)
|
|
|
|
|
// detach the action from the screen target and transform it to a regular move action to the phantom.
|
|
|
|
|
content = updateComponent(
|
|
|
|
|
{
|
|
|
|
@ -189,18 +211,18 @@ export function moveComponent(
|
|
|
|
|
actions: playerBeforePhantom.actions.map((a) =>
|
|
|
|
|
a.target === referent
|
|
|
|
|
? {
|
|
|
|
|
...a,
|
|
|
|
|
segments: a.segments.toSpliced(
|
|
|
|
|
a.segments.length - 2,
|
|
|
|
|
1,
|
|
|
|
|
{
|
|
|
|
|
...a.segments[a.segments.length - 1],
|
|
|
|
|
next: component.id,
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
target: component.id,
|
|
|
|
|
type: ActionKind.MOVE,
|
|
|
|
|
}
|
|
|
|
|
...a,
|
|
|
|
|
segments: a.segments.toSpliced(
|
|
|
|
|
a.segments.length - 2,
|
|
|
|
|
1,
|
|
|
|
|
{
|
|
|
|
|
...a.segments[a.segments.length - 1],
|
|
|
|
|
next: component.id,
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
target: component.id,
|
|
|
|
|
type: ActionKind.MOVE,
|
|
|
|
|
}
|
|
|
|
|
: a,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
@ -213,9 +235,9 @@ export function moveComponent(
|
|
|
|
|
...component,
|
|
|
|
|
pos: isPhantom
|
|
|
|
|
? {
|
|
|
|
|
type: "fixed",
|
|
|
|
|
...newPos,
|
|
|
|
|
}
|
|
|
|
|
type: "fixed",
|
|
|
|
|
...newPos,
|
|
|
|
|
}
|
|
|
|
|
: newPos,
|
|
|
|
|
},
|
|
|
|
|
content,
|
|
|
|
@ -300,9 +322,9 @@ export function computeTerminalState(
|
|
|
|
|
comp.type === "player"
|
|
|
|
|
? getPlayerTerminalState(comp, content, computedPositions)
|
|
|
|
|
: {
|
|
|
|
|
...comp,
|
|
|
|
|
frozen: true,
|
|
|
|
|
},
|
|
|
|
|
...comp,
|
|
|
|
|
frozen: true,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
@ -438,10 +460,20 @@ export function drainTerminalStateOnChildContent(
|
|
|
|
|
const initialChildCompsCount = childContent.components.length
|
|
|
|
|
|
|
|
|
|
for (const component of childContent.components) {
|
|
|
|
|
if (component.type !== "phantom" && component.frozen && !tryGetComponent(component.id, parentTerminalState.components)) {
|
|
|
|
|
if (
|
|
|
|
|
component.type !== "phantom" &&
|
|
|
|
|
component.frozen &&
|
|
|
|
|
!tryGetComponent(component.id, parentTerminalState.components)
|
|
|
|
|
) {
|
|
|
|
|
if (component.type === "player")
|
|
|
|
|
childContent = removePlayer(component, childContent)
|
|
|
|
|
else childContent = {...childContent, components: childContent.components.filter(c => c.id !== component.id)}
|
|
|
|
|
else
|
|
|
|
|
childContent = {
|
|
|
|
|
...childContent,
|
|
|
|
|
components: childContent.components.filter(
|
|
|
|
|
(c) => c.id !== component.id,
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -451,17 +483,13 @@ export function drainTerminalStateOnChildContent(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function mapToParentContent(content: StepContent): StepContent {
|
|
|
|
|
|
|
|
|
|
function mapToParentActions(actions: Action[]): Action[] {
|
|
|
|
|
return actions.map((a) => ({
|
|
|
|
|
...a,
|
|
|
|
|
target: a.target + "-parent",
|
|
|
|
|
segments: a.segments.map((s) => ({
|
|
|
|
|
...s,
|
|
|
|
|
next:
|
|
|
|
|
typeof s.next === "string"
|
|
|
|
|
? s.next + "-parent"
|
|
|
|
|
: s.next,
|
|
|
|
|
next: typeof s.next === "string" ? s.next + "-parent" : s.next,
|
|
|
|
|
})),
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
@ -475,12 +503,17 @@ export function mapToParentContent(content: StepContent): StepContent {
|
|
|
|
|
...p,
|
|
|
|
|
id: p.id + "-parent",
|
|
|
|
|
actions: mapToParentActions(p.actions),
|
|
|
|
|
path: p.path && { items: p.path.items.map(p => p + "-parent") },
|
|
|
|
|
path: p.path && {
|
|
|
|
|
items: p.path.items.map((p) => p + "-parent"),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
...p,
|
|
|
|
|
pos: p.pos.type == "follows" ? { ...p.pos, attach: p.pos.attach + "-parent" } : p.pos,
|
|
|
|
|
pos:
|
|
|
|
|
p.pos.type == "follows"
|
|
|
|
|
? { ...p.pos, attach: p.pos.attach + "-parent" }
|
|
|
|
|
: p.pos,
|
|
|
|
|
id: p.id + "-parent",
|
|
|
|
|
originPlayerId: p.originPlayerId + "-parent",
|
|
|
|
|
actions: mapToParentActions(p.actions),
|
|
|
|
@ -489,7 +522,10 @@ export function mapToParentContent(content: StepContent): StepContent {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function selectContent(id: string, content: StepContent, parentContent: StepContent | null): StepContent {
|
|
|
|
|
export function selectContent(
|
|
|
|
|
id: string,
|
|
|
|
|
content: StepContent,
|
|
|
|
|
parentContent: StepContent | null,
|
|
|
|
|
): StepContent {
|
|
|
|
|
return parentContent && id.endsWith("-parent") ? parentContent : content
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|