fix desynchronization when pass arrows are removed
continuous-integration/drone/push Build is passing Details

maxime 1 year ago
parent 2c95bf6c99
commit 1328fa50c6

@ -20,17 +20,26 @@ import { BALL_TYPE } from "../model/tactic/CourtObjects"
export function getActionKind( export function getActionKind(
target: TacticComponent | null, target: TacticComponent | null,
ballState: BallState, ballState: BallState,
): ActionKind { ): { kind: ActionKind; nextState: BallState } {
switch (ballState) { switch (ballState) {
case BallState.HOLDS_ORIGIN: case BallState.HOLDS_ORIGIN:
return target
? { kind: ActionKind.SHOOT, nextState: BallState.PASSED_ORIGIN }
: { kind: ActionKind.DRIBBLE, nextState: ballState }
case BallState.HOLDS_BY_PASS: 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_ORIGIN:
case BallState.PASSED: case BallState.PASSED:
case BallState.NONE: case BallState.NONE:
return target && target.type != BALL_TYPE return {
kind:
target && target.type != BALL_TYPE
? ActionKind.SCREEN ? ActionKind.SCREEN
: ActionKind.MOVE : ActionKind.MOVE,
nextState: ballState,
}
} }
} }
@ -38,7 +47,7 @@ export function getActionKindBetween(
origin: Player | PlayerPhantom, origin: Player | PlayerPhantom,
target: TacticComponent | null, target: TacticComponent | null,
state: BallState, state: BallState,
): ActionKind { ): { kind: ActionKind; nextState: BallState } {
//remove the target if the target is a phantom that is within the origin's path //remove the target if the target is a phantom that is within the origin's path
if ( if (
target != null && 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) // action is invalid if the origin already moves (unless the origin holds a ball which will lead to a ball pass)
if ( 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 return false
} }
//Action is valid if the target is null //Action is valid if the target is null
@ -84,6 +95,7 @@ export function isActionValid(
(hasBoundWith(target, origin, components) || (hasBoundWith(target, origin, components) ||
hasBoundWith(origin, target, components)) hasBoundWith(origin, target, components))
) { ) {
console.log("b")
return false return false
} }
@ -92,6 +104,7 @@ export function isActionValid(
origin.actions.find((a) => a.target === target?.id) || origin.actions.find((a) => a.target === target?.id) ||
target?.actions.find((a) => a.target === origin.id) target?.actions.find((a) => a.target === origin.id)
) { ) {
console.log("c")
return false return false
} }
@ -101,6 +114,7 @@ export function isActionValid(
if (areInSamePath(origin, target)) return false if (areInSamePath(origin, target)) return false
if (alreadyHasAnAnteriorActionWith(origin, target, components)) { if (alreadyHasAnAnteriorActionWith(origin, target, components)) {
console.log("e")
return false return false
} }
} }
@ -165,6 +179,7 @@ function alreadyHasAnAnteriorActionWith(
phantom.actions.find( phantom.actions.find(
(a) => (a) =>
typeof a.target === "string" && typeof a.target === "string" &&
moves(a.type) &&
originOriginPath.indexOf(a.target) !== -1, originOriginPath.indexOf(a.target) !== -1,
) )
) { ) {
@ -181,6 +196,7 @@ function alreadyHasAnAnteriorActionWith(
phantom.actions.find( phantom.actions.find(
(a) => (a) =>
typeof a.target === "string" && typeof a.target === "string" &&
moves(a.type) &&
targetOriginPath.indexOf(a.target) > targetIdx, targetOriginPath.indexOf(a.target) > targetIdx,
) )
) { ) {
@ -284,7 +300,7 @@ export function createAction(
const action: Action = { const action: Action = {
target: toId, target: toId,
type: getActionKind(component, origin.ballState), type: getActionKind(component, origin.ballState).kind,
segments: [{ next: toId }], segments: [{ next: toId }],
} }
@ -305,7 +321,7 @@ export function createAction(
const action: Action = { const action: Action = {
target: phantomId, target: phantomId,
type: getActionKind(null, origin.ballState), type: getActionKind(null, origin.ballState).kind,
segments: [{ next: phantomId }], segments: [{ next: phantomId }],
} }
return { return {
@ -360,21 +376,22 @@ export function removeAction(
action.type == ActionKind.SHOOT && action.type == ActionKind.SHOOT &&
(origin.type === "player" || origin.type === "phantom") (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( content = changePlayerBallState(
origin, origin,
BallState.HOLDS_BY_PASS, BallState.HOLDS_BY_PASS,
content, content,
) )
else if (origin.ballState === BallState.PASSED_ORIGIN) } else if (origin.ballState === BallState.PASSED_ORIGIN) {
content = changePlayerBallState( content = changePlayerBallState(
origin, origin,
BallState.HOLDS_ORIGIN, BallState.HOLDS_ORIGIN,
content, content,
) )
}
if (target.type === "player" || target.type === "phantom")
content = changePlayerBallState(target, BallState.NONE, content)
} }
if (target.type === "phantom") { if (target.type === "phantom") {
@ -385,7 +402,7 @@ export function removeAction(
path = getOrigin(origin, content.components).path 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) 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 /// if the new state removes the ball from the player, remove all actions that were meant to shoot the ball
deleteAction = true 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 ( } else if (
(newState === BallState.HOLDS_BY_PASS || (newState === BallState.HOLDS_BY_PASS ||
newState === BallState.HOLDS_ORIGIN) && newState === BallState.HOLDS_ORIGIN) &&
@ -464,16 +481,18 @@ export function spreadNewStateFromOriginStateChange(
i-- // step back i-- // step back
} else { } else {
// do not change the action type if it is a shoot action // do not change the action type if it is a shoot action
const type = const { kind, nextState } = getActionKindBetween(
action.type == ActionKind.SHOOT origin,
? ActionKind.SHOOT actionTarget,
: getActionKindBetween(origin, actionTarget, newState) newState,
)
origin = { origin = {
...origin, ...origin,
ballState: nextState,
actions: origin.actions.toSpliced(i, 1, { actions: origin.actions.toSpliced(i, 1, {
...action, ...action,
type, type: kind,
}), }),
} }
content = updateComponent(origin, content) content = updateComponent(origin, content)

@ -88,11 +88,11 @@ export function dropBallOnComponent(
const component = content.components[targetedComponentIdx] const component = content.components[targetedComponentIdx]
if (component.type === "player" || component.type === "phantom") { if (component.type === "player" || component.type === "phantom") {
const newState = setAsOrigin const newState =
? component.ballState === BallState.PASSED || setAsOrigin ||
component.ballState === BallState.PASSED_ORIGIN component.ballState === BallState.PASSED_ORIGIN ||
? BallState.PASSED_ORIGIN component.ballState === BallState.HOLDS_ORIGIN
: BallState.HOLDS_ORIGIN ? BallState.HOLDS_ORIGIN
: BallState.HOLDS_BY_PASS : BallState.HOLDS_BY_PASS
content = changePlayerBallState(component, newState, content) content = changePlayerBallState(component, newState, content)

@ -621,7 +621,7 @@ function CourtPlayerArrowAction({
next: ratioWithinBase(arrowHeadPos, courtBounds()), next: ratioWithinBase(arrowHeadPos, courtBounds()),
}, },
], ],
type: getActionKind(target, playerInfo.ballState), type: getActionKind(target, playerInfo.ballState).kind,
isInvalid: isInvalid:
!overlaps(headPos, courtBounds()) || !overlaps(headPos, courtBounds()) ||
!isActionValid(player, target, content.components), !isActionValid(player, target, content.components),
@ -632,7 +632,7 @@ function CourtPlayerArrowAction({
setPreviewAction({ setPreviewAction({
origin: playerInfo.id, origin: playerInfo.id,
type: getActionKind(null, playerInfo.ballState), type: getActionKind(null, playerInfo.ballState).kind,
target: ratioWithinBase(headPos, courtBounds()), target: ratioWithinBase(headPos, courtBounds()),
segments: [ segments: [
{ {
@ -668,12 +668,16 @@ function CourtPlayerArrowAction({
newContent, newContent,
false, false,
) )
const ballState =
player.ballState === BallState.HOLDS_ORIGIN
? BallState.PASSED_ORIGIN
: BallState.PASSED
newContent = updateComponent( newContent = updateComponent(
{ {
...(newContent.components.find( ...(newContent.components.find(
(c) => c.id == player.id, (c) => c.id == player.id,
)! as Player | PlayerPhantom), )! as Player | PlayerPhantom),
ballState: BallState.PASSED, ballState,
}, },
newContent, newContent,
) )

Loading…
Cancel
Save