From 1328fa50c60c5a62be82a04cb051aad11523f723 Mon Sep 17 00:00:00 2001 From: maxime Date: Sat, 27 Jan 2024 21:51:05 +0100 Subject: [PATCH] fix desynchronization when pass arrows are removed --- front/editor/ActionsDomains.ts | 63 ++++++++++++++++++---------- front/editor/TacticContentDomains.ts | 12 +++--- front/views/Editor.tsx | 10 +++-- 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/front/editor/ActionsDomains.ts b/front/editor/ActionsDomains.ts index 8bb4200..da988ce 100644 --- a/front/editor/ActionsDomains.ts +++ b/front/editor/ActionsDomains.ts @@ -20,17 +20,26 @@ import { BALL_TYPE } from "../model/tactic/CourtObjects" export function getActionKind( target: TacticComponent | null, ballState: BallState, -): ActionKind { +): { kind: ActionKind; nextState: BallState } { switch (ballState) { case BallState.HOLDS_ORIGIN: + return target + ? { kind: ActionKind.SHOOT, nextState: BallState.PASSED_ORIGIN } + : { kind: ActionKind.DRIBBLE, nextState: ballState } case BallState.HOLDS_BY_PASS: - return target ? ActionKind.SHOOT : ActionKind.DRIBBLE + return target + ? { kind: ActionKind.SHOOT, nextState: BallState.PASSED } + : { kind: ActionKind.DRIBBLE, nextState: ballState } case BallState.PASSED_ORIGIN: case BallState.PASSED: case BallState.NONE: - return target && target.type != BALL_TYPE - ? ActionKind.SCREEN - : ActionKind.MOVE + return { + kind: + target && target.type != BALL_TYPE + ? ActionKind.SCREEN + : ActionKind.MOVE, + nextState: ballState, + } } } @@ -38,7 +47,7 @@ export function getActionKindBetween( origin: Player | PlayerPhantom, target: TacticComponent | null, state: BallState, -): ActionKind { +): { kind: ActionKind; nextState: BallState } { //remove the target if the target is a phantom that is within the origin's path if ( target != null && @@ -63,9 +72,11 @@ export function isActionValid( // action is invalid if the origin already moves (unless the origin holds a ball which will lead to a ball pass) if ( - origin.actions.find((a) => moves(a.type)) && - origin.ballState != BallState.HOLDS_BY_PASS + origin.ballState != BallState.HOLDS_BY_PASS && + origin.ballState != BallState.HOLDS_ORIGIN && + origin.actions.find((a) => moves(a.type)) ) { + console.log("a") return false } //Action is valid if the target is null @@ -84,6 +95,7 @@ export function isActionValid( (hasBoundWith(target, origin, components) || hasBoundWith(origin, target, components)) ) { + console.log("b") return false } @@ -92,6 +104,7 @@ export function isActionValid( origin.actions.find((a) => a.target === target?.id) || target?.actions.find((a) => a.target === origin.id) ) { + console.log("c") return false } @@ -101,6 +114,7 @@ export function isActionValid( if (areInSamePath(origin, target)) return false if (alreadyHasAnAnteriorActionWith(origin, target, components)) { + console.log("e") return false } } @@ -165,6 +179,7 @@ function alreadyHasAnAnteriorActionWith( phantom.actions.find( (a) => typeof a.target === "string" && + moves(a.type) && originOriginPath.indexOf(a.target) !== -1, ) ) { @@ -181,6 +196,7 @@ function alreadyHasAnAnteriorActionWith( phantom.actions.find( (a) => typeof a.target === "string" && + moves(a.type) && targetOriginPath.indexOf(a.target) > targetIdx, ) ) { @@ -284,7 +300,7 @@ export function createAction( const action: Action = { target: toId, - type: getActionKind(component, origin.ballState), + type: getActionKind(component, origin.ballState).kind, segments: [{ next: toId }], } @@ -305,7 +321,7 @@ export function createAction( const action: Action = { target: phantomId, - type: getActionKind(null, origin.ballState), + type: getActionKind(null, origin.ballState).kind, segments: [{ next: phantomId }], } return { @@ -360,21 +376,22 @@ export function removeAction( action.type == ActionKind.SHOOT && (origin.type === "player" || origin.type === "phantom") ) { - if (origin.ballState === BallState.PASSED) + if (target.type === "player" || target.type === "phantom") + content = changePlayerBallState(target, BallState.NONE, content) + + if (origin.ballState === BallState.PASSED) { content = changePlayerBallState( origin, BallState.HOLDS_BY_PASS, content, ) - else if (origin.ballState === BallState.PASSED_ORIGIN) + } else if (origin.ballState === BallState.PASSED_ORIGIN) { content = changePlayerBallState( origin, BallState.HOLDS_ORIGIN, content, ) - - if (target.type === "player" || target.type === "phantom") - content = changePlayerBallState(target, BallState.NONE, content) + } } if (target.type === "phantom") { @@ -385,7 +402,7 @@ export function removeAction( path = getOrigin(origin, content.components).path } - if (path != null && path.items.find((c) => c == target.id)) { + if (path != null && path.items.find((c) => c === target.id)) { content = removePlayer(target, content) } } @@ -447,7 +464,7 @@ export function spreadNewStateFromOriginStateChange( ) { /// if the new state removes the ball from the player, remove all actions that were meant to shoot the ball deleteAction = true - targetState = BallState.NONE // then remove the ball for the target as well + targetState = BallState.NONE // Then remove the ball for the target as well } else if ( (newState === BallState.HOLDS_BY_PASS || newState === BallState.HOLDS_ORIGIN) && @@ -464,16 +481,18 @@ export function spreadNewStateFromOriginStateChange( i-- // step back } else { // do not change the action type if it is a shoot action - const type = - action.type == ActionKind.SHOOT - ? ActionKind.SHOOT - : getActionKindBetween(origin, actionTarget, newState) + const { kind, nextState } = getActionKindBetween( + origin, + actionTarget, + newState, + ) origin = { ...origin, + ballState: nextState, actions: origin.actions.toSpliced(i, 1, { ...action, - type, + type: kind, }), } content = updateComponent(origin, content) diff --git a/front/editor/TacticContentDomains.ts b/front/editor/TacticContentDomains.ts index 1c6bfda..4a18439 100644 --- a/front/editor/TacticContentDomains.ts +++ b/front/editor/TacticContentDomains.ts @@ -88,12 +88,12 @@ export function dropBallOnComponent( const component = content.components[targetedComponentIdx] if (component.type === "player" || component.type === "phantom") { - const newState = setAsOrigin - ? component.ballState === BallState.PASSED || - component.ballState === BallState.PASSED_ORIGIN - ? BallState.PASSED_ORIGIN - : BallState.HOLDS_ORIGIN - : BallState.HOLDS_BY_PASS + const newState = + setAsOrigin || + component.ballState === BallState.PASSED_ORIGIN || + component.ballState === BallState.HOLDS_ORIGIN + ? BallState.HOLDS_ORIGIN + : BallState.HOLDS_BY_PASS content = changePlayerBallState(component, newState, content) } diff --git a/front/views/Editor.tsx b/front/views/Editor.tsx index de7c749..e5ce71b 100644 --- a/front/views/Editor.tsx +++ b/front/views/Editor.tsx @@ -621,7 +621,7 @@ function CourtPlayerArrowAction({ next: ratioWithinBase(arrowHeadPos, courtBounds()), }, ], - type: getActionKind(target, playerInfo.ballState), + type: getActionKind(target, playerInfo.ballState).kind, isInvalid: !overlaps(headPos, courtBounds()) || !isActionValid(player, target, content.components), @@ -632,7 +632,7 @@ function CourtPlayerArrowAction({ setPreviewAction({ origin: playerInfo.id, - type: getActionKind(null, playerInfo.ballState), + type: getActionKind(null, playerInfo.ballState).kind, target: ratioWithinBase(headPos, courtBounds()), segments: [ { @@ -668,12 +668,16 @@ function CourtPlayerArrowAction({ newContent, false, ) + const ballState = + player.ballState === BallState.HOLDS_ORIGIN + ? BallState.PASSED_ORIGIN + : BallState.PASSED newContent = updateComponent( { ...(newContent.components.find( (c) => c.id == player.id, )! as Player | PlayerPhantom), - ballState: BallState.PASSED, + ballState, }, newContent, )