You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Application-Web/front/editor/PlayerDomains.ts

127 lines
3.8 KiB

import {BallState, Player, PlayerPhantom} from "../model/tactic/Player"
import {TacticComponent, TacticContent} from "../model/tactic/Tactic"
import {removeComponent, updateComponent} from "./TacticContentDomains"
import {removeAllActionsTargeting, spreadNewStateFromOriginStateChange} from "./ActionsDomains"
import {ActionKind} from "../model/tactic/Action";
export function getOrigin(
pathItem: PlayerPhantom,
components: TacticComponent[],
): Player {
// Trust the components to contains only phantoms with valid player origin identifiers
return components.find((c) => c.id == pathItem.originPlayerId)! as Player
}
export function areInSamePath(
a: Player | PlayerPhantom,
b: Player | PlayerPhantom,
) {
if (a.type === "phantom" && b.type === "phantom") {
return a.originPlayerId === b.originPlayerId
}
if (a.type === "phantom") {
return b.id === a.originPlayerId
}
if (b.type === "phantom") {
return a.id === b.originPlayerId
}
return false
}
/**
* @param origin
* @param other
* @param components
* @returns true if the `other` player is the phantom next-to the origin's path.
*/
export function isNextInPath(origin: Player | PlayerPhantom, other: Player | PlayerPhantom, components: TacticComponent[]): boolean {
if (origin.type === "player") {
return origin.path?.items[0] === other.id
}
const originPath = getOrigin(origin, components).path!
return originPath.items!.indexOf(origin.id) === originPath.items!.indexOf(other.id) - 1
}
export function removePlayerPath(
player: Player,
content: TacticContent,
): TacticContent {
if (player.path == null) {
return content
}
for (const pathElement of player.path.items) {
content = removeComponent(pathElement, content)
content = removeAllActionsTargeting(pathElement, content)
}
return updateComponent(
{
...player,
path: null,
},
content,
)
}
export function removePlayer(
player: Player | PlayerPhantom,
content: TacticContent,
): TacticContent {
content = removeAllActionsTargeting(player.id, content)
if (player.type == "phantom") {
const origin = getOrigin(player, content.components)
return truncatePlayerPath(origin, player, content)
}
content = removePlayerPath(player, content)
content = removeComponent(player.id, content)
for (const action of player.actions) {
if (action.type !== ActionKind.SHOOT) {
continue
}
const actionTarget = content.components.find(c => c.id === action.target)! as (Player | PlayerPhantom)
return spreadNewStateFromOriginStateChange(actionTarget, BallState.NONE, content)
}
return content
}
export function truncatePlayerPath(
player: Player,
phantom: PlayerPhantom,
content: TacticContent,
): TacticContent {
if (player.path == null) return content
const path = player.path!
const truncateStartIdx = path.items.indexOf(phantom.id)
for (let i = truncateStartIdx; i < path.items.length; i++) {
const pathPhantomId = path.items[i]
//remove the phantom from the tactic
content = removeComponent(pathPhantomId, content)
content = removeAllActionsTargeting(pathPhantomId, content)
}
return updateComponent(
{
...player,
path:
truncateStartIdx == 0
? null
: {
...path,
items: path.items.toSpliced(truncateStartIdx),
},
},
content,
)
}
export function changePlayerBallState(player: Player | PlayerPhantom, newState: BallState, content: TacticContent): TacticContent {
return spreadNewStateFromOriginStateChange(player, newState, content)
}