fixed prio score penalty on sked fail

This commit is contained in:
Marc Froehlich
2026-08-10 03:06:06 +02:00
parent 00aefdacd5
commit 401f271d56
2 changed files with 42 additions and 32 deletions
@@ -83,12 +83,13 @@ public class PriorityCalculator {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
double score = 100.0; double score = 100.0;
// if (!member.isWorked()) { /*
// score += 200.0; * A manual Sked-fail mark represents an explicit operator decision. The
// } * penalty is therefore applied after all positive contributions, including
* an imminent sked. Applying it earlier would allow the later sked boost to
//"worked" for scoring is derived ONLY from per-band flags (worked144/432/...) * almost completely cancel the failure mark.
// EnumSet<Band> workedBandsForScoring = getWorkedBands(member); */
boolean manualSkedFailed = false;
if (workedBandsForScoring.isEmpty()) { if (workedBandsForScoring.isEmpty()) {
score += 200.0; // never worked on any supported band -> higher priority score += 200.0; // never worked on any supported band -> higher priority
@@ -190,9 +191,11 @@ public class PriorityCalculator {
} }
// Manual sked fail (path likely bad) => strong, permanent penalty until reset // Manual sked fail (path likely bad) => strong, permanent penalty until reset
if (mx.manualSkedFailed) { /*
score *= 0.15; * Remember the explicit failure state here. The actual penalty is applied
} * after the sked contribution has been calculated.
*/
manualSkedFailed = mx.manualSkedFailed;
} }
} }
@@ -226,10 +229,25 @@ public class PriorityCalculator {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// 8) Legacy penalty: failed attempts in ChatMember // 8) Legacy penalty: failed attempts in ChatMember
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// --------------------------------------------------------------------
// 8) Legacy penalty: failed attempts in ChatMember
// --------------------------------------------------------------------
if (member.getFailedQSOAttempts() > 0) { if (member.getFailedQSOAttempts() > 0) {
score = score / (member.getFailedQSOAttempts() + 1); score = score / (member.getFailedQSOAttempts() + 1);
} }
// --------------------------------------------------------------------
// 9) Explicit operator override: manual Sked fail
// --------------------------------------------------------------------
if (manualSkedFailed) {
/*
* Apply the penalty to the complete result. This includes an imminent
* sked and prevents its strong time-dependent boost from cancelling the
* operator's explicit failure assessment.
*/
score *= 0.15;
}
return Math.max(0.0, score); return Math.max(0.0, score);
} }
@@ -4388,10 +4388,10 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
/** /**
* Resolves and selects a priority candidate. * Resolves and selects a priority candidate.
* *
* If the station is currently visible in the member table, selecting it there is * <p>The common selection helper is used deliberately. It updates Further Info,
* preferred because the existing table-selection listener then keeps the rest of * prepares the directed message and selects the corresponding table row when
* the UI in sync. If the station is filtered out, we still show FurtherInfo and * the row is currently visible. A candidate hidden by an active table filter
* prepare the /cq text so the priority list remains useful with active filters. * remains usable without changing or resetting that filter.</p>
*/ */
private void selectTopCandidate( private void selectTopCandidate(
kst4contest.controller.ScoreService.TopCandidate candidate, kst4contest.controller.ScoreService.TopCandidate candidate,
@@ -4408,25 +4408,17 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
return; return;
} }
// if (tbl_chatMember.getItems().contains(resolved)) { /*
// tbl_chatMember.getSelectionModel().select(resolved); * This is an explicit operator action and therefore follows the same path
// tbl_chatMember.scrollTo(resolved); * as a timeline click. The exact callsign and category stored in the
// } else { * TopCandidate remain authoritative.
// selectedCallSignInfoStageChatMember = resolved; *
// chatcontroller.getScoreService().setSelectedChatMember(selectedCallSignInfoStageChatMember); * focusChatMemberAndPrepareCq() also handles candidates which are currently
// * hidden by a FilteredList. In that case the table row cannot be selected,
// selectedCallSignFurtherInfoPane.getChildren().setAll(generateFurtherInfoAbtSelectedCallsignBP(resolved)); * but Further Info, ScoreService selection and the prepared /cq message are
// txt_chatMessageUserInput.clear(); * still updated.
// txt_chatMessageUserInput.setText("/cq " + resolved.getCallSign() + " "); */
// txt_chatMessageUserInput.requestFocus(); focusChatMemberAndPrepareCq(resolved);
// txt_chatMessageUserInput.selectEnd();
// }
tbl_chatMember.getSelectionModel().select(resolved); //new mechanic for selectionchange events due to textfield
//manipulation...
// Keep ScoreService selection in sync even if the visible table selection path was used.
chatcontroller.getScoreService().setSelectedChatMember(resolved);
} }
/** /**