ёбанные удаления надеюсь финальные
This commit is contained in:
@@ -4749,34 +4749,62 @@ function startCustomTooltips() {
|
||||
return homeSkaters > awaySkaters ? "home" : awaySkaters > homeSkaters ? "away" : "";
|
||||
}
|
||||
|
||||
// BUILD96: one persistent strength-transition plate.
|
||||
// When the game moves from a real advantage into temporary equal strength
|
||||
// (for example 4x5 -> 3x4 -> 4x4), keep the same plate on the team that held
|
||||
// the advantage. Only the configured strength caption and the next transition
|
||||
// countdown change. A pure coincidental 4x4 that did not originate from an
|
||||
// advantage still produces no plate.
|
||||
function penaltyDisplayEntriesByTargetSide(step) {
|
||||
const home = sortedPenaltyEntries("home");
|
||||
const away = sortedPenaltyEntries("away");
|
||||
const all = [...home, ...away].sort((a, b) => Number(a.event.remainingMs || 0) - Number(b.event.remainingMs || 0)
|
||||
|| Number(a.event.createdAt || 0) - Number(b.event.createdAt || 0));
|
||||
if (!all.length) {
|
||||
return { home: [], away: [], routedToAdvantage: false, advantageSide: "", transitionEntry: null };
|
||||
return { home: [], away: [], routedToAdvantage: false, advantageSide: "", plateSide: "", holdingEqualStrength: false, transitionEntry: null };
|
||||
}
|
||||
|
||||
const advantageSide = penaltyLocalAdvantageSide(home.length, away.length);
|
||||
const transitionEntry = all[0] || null;
|
||||
if (!advantageSide) {
|
||||
return { home: [], away: [], routedToAdvantage: false, advantageSide: "", transitionEntry: all[0] || null };
|
||||
const rememberedSide = String(state.hockeyPenaltyAdvantageCycle.lastAdvantageSide || "");
|
||||
const canHoldEqualStrength = Boolean(state.hockeyPenaltyAdvantageCycle.hadAdvantage)
|
||||
&& ["home", "away"].includes(rememberedSide);
|
||||
if (!canHoldEqualStrength) {
|
||||
return { home: [], away: [], routedToAdvantage: false, advantageSide: "", plateSide: "", holdingEqualStrength: false, transitionEntry };
|
||||
}
|
||||
return {
|
||||
home: rememberedSide === "home" && transitionEntry ? [transitionEntry] : [],
|
||||
away: rememberedSide === "away" && transitionEntry ? [transitionEntry] : [],
|
||||
routedToAdvantage: false,
|
||||
advantageSide: "",
|
||||
plateSide: rememberedSide,
|
||||
holdingEqualStrength: true,
|
||||
transitionEntry,
|
||||
};
|
||||
}
|
||||
|
||||
const transitionEntry = all[0] || null;
|
||||
return {
|
||||
home: advantageSide === "home" && transitionEntry ? [transitionEntry] : [],
|
||||
away: advantageSide === "away" && transitionEntry ? [transitionEntry] : [],
|
||||
routedToAdvantage: true,
|
||||
advantageSide,
|
||||
plateSide: advantageSide,
|
||||
holdingEqualStrength: false,
|
||||
transitionEntry,
|
||||
};
|
||||
}
|
||||
|
||||
function rememberPenaltyAdvantagePlan(displayPlan) {
|
||||
if (!displayPlan?.routedToAdvantage || !["home", "away"].includes(String(displayPlan.advantageSide || ""))) return;
|
||||
const nextSide = String(displayPlan.advantageSide);
|
||||
const changed = !state.hockeyPenaltyAdvantageCycle.hadAdvantage
|
||||
|| String(state.hockeyPenaltyAdvantageCycle.lastAdvantageSide || "") !== nextSide;
|
||||
state.hockeyPenaltyAdvantageCycle.hadAdvantage = true;
|
||||
state.hockeyPenaltyAdvantageCycle.lastAdvantageSide = String(displayPlan.advantageSide);
|
||||
state.hockeyPenaltyAdvantageCycle.lastAdvantageSide = nextSide;
|
||||
// BUILD96: persist the owner immediately. This matters if Runtime is reloaded
|
||||
// during the following temporary equal-strength phase (for example 4x4).
|
||||
if (changed && !state.hockeyTimerHydrating) hockeyScheduleTimerSave(true);
|
||||
}
|
||||
|
||||
function resetPenaltyAdvantageCycle() {
|
||||
@@ -6540,12 +6568,15 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
event.id,
|
||||
Math.round(Number(event.remainingMs || 0) / 1000),
|
||||
Boolean(event.running),
|
||||
Boolean(event.startedOnce),
|
||||
Boolean(event.finished),
|
||||
event.preset || "",
|
||||
event.player?.id || "",
|
||||
event.infraction?.id || "",
|
||||
].join(":" )).join(";"),
|
||||
board.history.map((item) => item.id || "").join(","),
|
||||
Boolean(state.hockeyPenaltyAdvantageCycle.hadAdvantage),
|
||||
String(state.hockeyPenaltyAdvantageCycle.lastAdvantageSide || ""),
|
||||
].join("|");
|
||||
if (
|
||||
force
|
||||
@@ -6930,8 +6961,8 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
const fullStrengthSide = penaltyFullStrengthSide();
|
||||
board.penalties = board.penalties.filter((item) => item.id !== event.id);
|
||||
const side = String(event.player?.side || event.side || "").toLowerCase();
|
||||
const remainingOnSide = board.penalties.filter((item) => !item.finished && hockeyEventReady(item) && String(item.player?.side || item.side || "").toLowerCase() === side).length;
|
||||
const remainingTotal = board.penalties.filter((item) => !item.finished && hockeyEventReady(item)).length;
|
||||
const remainingOnSide = board.penalties.filter((item) => !item.finished && hockeyEventReady(item) && hockeyPenaltyHasStarted(item) && String(item.player?.side || item.side || "").toLowerCase() === side).length;
|
||||
const remainingTotal = board.penalties.filter((item) => !item.finished && hockeyEventReady(item) && hockeyPenaltyHasStarted(item)).length;
|
||||
const clearCommonSelection = board.selectedEventId === event.id;
|
||||
const clearSideSelection = board.selectedPreviewEventIds?.[side] === event.id;
|
||||
if (clearCommonSelection) board.selectedEventId = null;
|
||||
@@ -6950,7 +6981,10 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
had_advantage: hadAdvantage,
|
||||
full_strength_side: fullStrengthSide,
|
||||
});
|
||||
if (remainingTotal <= 0) resetPenaltyAdvantageCycle();
|
||||
if (remainingTotal <= 0) {
|
||||
resetPenaltyAdvantageCycle();
|
||||
hockeyScheduleTimerSave(true);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} else if (command === "set_time") {
|
||||
@@ -6987,7 +7021,10 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
});
|
||||
state.vmixPenaltyMirrors.delete(penaltyMirrorKey(component, event));
|
||||
hockeySyncPenaltySideMappingContext({ force: true }).catch(() => {});
|
||||
if (!board.penalties.some((item) => !item.finished && hockeyEventReady(item))) resetPenaltyAdvantageCycle();
|
||||
if (!board.penalties.some((item) => !item.finished && hockeyEventReady(item) && hockeyPenaltyHasStarted(item))) {
|
||||
resetPenaltyAdvantageCycle();
|
||||
hockeyScheduleTimerSave(true);
|
||||
}
|
||||
rebalanceVmixPenaltyTargets({ force: true, hideUnused: true }).catch((error) => console.error("Penalty target remove rebalance error", error));
|
||||
return true;
|
||||
}
|
||||
@@ -7089,7 +7126,7 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
hockeySyncPenaltySideMappingContext({ force: true }).catch(() => {});
|
||||
const hadAdvantage = Boolean(state.hockeyPenaltyAdvantageCycle.hadAdvantage);
|
||||
const fullStrengthSide = penaltyFullStrengthSide();
|
||||
const remainingTotal = board.penalties.filter((item) => !item.finished && hockeyEventReady(item)).length;
|
||||
const remainingTotal = board.penalties.filter((item) => !item.finished && hockeyEventReady(item) && hockeyPenaltyHasStarted(item)).length;
|
||||
const finishBySide = new Map();
|
||||
completedEvents.forEach((event) => {
|
||||
const side = String(event.player?.side || event.side || "").toLowerCase();
|
||||
@@ -7099,7 +7136,7 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
.catch((error) => console.error("Penalty target ticker rebalance error", error))
|
||||
.finally(() => {
|
||||
finishBySide.forEach((event, side) => {
|
||||
const remainingOnSide = board.penalties.filter((item) => !item.finished && hockeyEventReady(item) && String(item.player?.side || item.side || "").toLowerCase() === side).length;
|
||||
const remainingOnSide = board.penalties.filter((item) => !item.finished && hockeyEventReady(item) && hockeyPenaltyHasStarted(item) && String(item.player?.side || item.side || "").toLowerCase() === side).length;
|
||||
fireConfiguredTimerFinishActions("penalty", {
|
||||
side, component, event,
|
||||
remaining_on_side: remainingOnSide,
|
||||
@@ -7108,7 +7145,10 @@ function openTimerQuickEditor(focusActionId = "") {
|
||||
full_strength_side: fullStrengthSide,
|
||||
});
|
||||
});
|
||||
if (remainingTotal <= 0) resetPenaltyAdvantageCycle();
|
||||
if (remainingTotal <= 0) {
|
||||
resetPenaltyAdvantageCycle();
|
||||
hockeyScheduleTimerSave(true);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -11573,6 +11613,9 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
durationMs: Math.max(0, Math.round(Number(event.durationMs || 0))),
|
||||
remainingMs: Math.max(0, Math.round(Number(event.remainingMs || 0))),
|
||||
running: Boolean(event.running) && !Boolean(event.finished),
|
||||
startedOnce: Boolean(event.startedOnce || event.running)
|
||||
|| (Math.max(0, Number(event.durationMs || 0)) > 0
|
||||
&& Math.max(0, Number(event.remainingMs ?? event.durationMs ?? 0)) < Math.max(0, Number(event.durationMs || 0))),
|
||||
finished: Boolean(event.finished),
|
||||
readyEmitted: Boolean(event.readyEmitted),
|
||||
assignedEmitted: Boolean(event.assignedEmitted),
|
||||
@@ -11611,6 +11654,12 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
penalty_board: {
|
||||
penalties: (board?.penalties || []).slice(0, 64).map(hockeyPenaltySnapshot),
|
||||
history: (board?.history || []).slice(0, 64).map(hockeyHistorySnapshot),
|
||||
advantage_cycle: {
|
||||
had_advantage: Boolean(state.hockeyPenaltyAdvantageCycle.hadAdvantage),
|
||||
last_advantage_side: ["home", "away"].includes(String(state.hockeyPenaltyAdvantageCycle.lastAdvantageSide || ""))
|
||||
? String(state.hockeyPenaltyAdvantageCycle.lastAdvantageSide)
|
||||
: "",
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -11644,11 +11693,22 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
updateTimerNodes(mainComponent, timerState);
|
||||
}
|
||||
|
||||
let restoredPenaltyAdvantageCycle = null;
|
||||
const boardComponent = hockeyPenaltyBoardComponent();
|
||||
if (boardComponent) {
|
||||
const source = timers?.penalty_board && typeof timers.penalty_board === "object"
|
||||
? timers.penalty_board
|
||||
: {};
|
||||
const savedCycle = source?.advantage_cycle && typeof source.advantage_cycle === "object"
|
||||
? source.advantage_cycle
|
||||
: null;
|
||||
if (savedCycle) {
|
||||
const savedSide = String(savedCycle.last_advantage_side || "");
|
||||
restoredPenaltyAdvantageCycle = {
|
||||
hadAdvantage: Boolean(savedCycle.had_advantage) && ["home", "away"].includes(savedSide),
|
||||
lastAdvantageSide: ["home", "away"].includes(savedSide) ? savedSide : "",
|
||||
};
|
||||
}
|
||||
const board = createHockeyBoardState(boardComponent);
|
||||
board.penalties = (Array.isArray(source.penalties) ? source.penalties : [])
|
||||
.slice(0, 64)
|
||||
@@ -11664,7 +11724,12 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
||||
refreshHockeyBoardNodes(boardComponent);
|
||||
}
|
||||
state.hockeyTimerGameId = String(gameId || "");
|
||||
resetPenaltyAdvantageCycle();
|
||||
if (restoredPenaltyAdvantageCycle) {
|
||||
state.hockeyPenaltyAdvantageCycle.hadAdvantage = Boolean(restoredPenaltyAdvantageCycle.hadAdvantage);
|
||||
state.hockeyPenaltyAdvantageCycle.lastAdvantageSide = String(restoredPenaltyAdvantageCycle.lastAdvantageSide || "");
|
||||
} else {
|
||||
resetPenaltyAdvantageCycle();
|
||||
}
|
||||
state.hockeyPenaltyMappingContextSignature = "";
|
||||
hockeySyncPenaltySideMappingContext({ force: true }).catch(() => {});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user