diff --git a/src/deh_soc.c b/src/deh_soc.c index a38bfd4fa..fd66fb246 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2973,6 +2973,32 @@ static void readcondition(UINT16 set, UINT32 id, char *word2) return; } } + else if (fastcmp(params[0], "FINISHGRADE")) + { + PARAMCHECK(1); + ty = UCRP_FINISHGRADE; + + re = -1; + if (!params[1][1]) + { + switch (params[1][0]) + { + case 'E': { re = GRADE_E; break; } + case 'D': { re = GRADE_D; break; } + case 'C': { re = GRADE_C; break; } + case 'B': { re = GRADE_B; break; } + case 'A': { re = GRADE_A; break; } + case 'S': { re = GRADE_S; break; } + default: { break; } + } + } + + if (re == -1) + { + deh_warning("Invalid grade %s for condition ID %d", params[1], id+1); + return; + } + } else if ((offset=0) || fastcmp(params[0], "FINISHTIME") || (++offset && fastcmp(params[0], "FINISHTIMEEXACT")) || (++offset && fastcmp(params[0], "FINISHTIMELEFT"))) diff --git a/src/k_tally.cpp b/src/k_tally.cpp index eba1452c8..15e11a2c7 100644 --- a/src/k_tally.cpp +++ b/src/k_tally.cpp @@ -800,6 +800,9 @@ void level_tally_t::Tick(void) transition = 0; transitionTime = TICRATE/7; delay = TICRATE/2; + + // for UCRP_FINISHGRADE + owner->roundconditions.checkthisframe = true; } else { diff --git a/src/m_cond.c b/src/m_cond.c index 8c8dfb6fc..8eb78c96c 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1623,6 +1623,14 @@ boolean M_CheckCondition(condition_t *cn, player_t *player) && !(player->pflags & PF_NOCONTEST) && M_NotFreePlay() && player->position == cn->requirement); + case UCRP_FINISHGRADE: + return (player->exiting + && !(player->pflags & PF_NOCONTEST) + && M_NotFreePlay() + && (player->tally.active == true) + && (player->tally.state >= TALLY_ST_GRADE_APPEAR) + && (player->tally.state < TALLY_ST_DONE) + && (player->tally.rank >= cn->requirement)); case UCRP_FINISHTIME: return (player->exiting && !(player->pflags & PF_NOCONTEST) @@ -2446,6 +2454,29 @@ static const char *M_GetConditionString(condition_t *cn) return va("finish in %d%s%s", cn->requirement, M_GetNthType(cn->requirement), ((cn->type == UCRP_FINISHPLACE && cn->requirement > 1) ? " or better" : "")); + case UCRP_FINISHGRADE: + { + char gradeletter = '?'; + const char *orbetter = ""; + + switch (cn->requirement) + { + case GRADE_E: { gradeletter = 'E'; break; } + case GRADE_D: { gradeletter = 'D'; break; } + case GRADE_C: { gradeletter = 'C'; break; } + case GRADE_B: { gradeletter = 'B'; break; } + case GRADE_A: { gradeletter = 'A'; break; } + case GRADE_S: { gradeletter = 'S'; break; } + default: { break; } + } + + if (cn->requirement < GRADE_S) + orbetter = " or better"; + + return va("get grade %c%s", + gradeletter, orbetter + ); + } case UCRP_FINISHTIME: return va("finish in %i:%02i.%02i", G_TicsToMinutes(cn->requirement, true), diff --git a/src/m_cond.h b/src/m_cond.h index 1f747f263..832200d08 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -110,6 +110,8 @@ typedef enum UCRP_FINISHPLACE, // Finish at least [place] UCRP_FINISHPLACEEXACT, // Finish at [place] exactly + UCRP_FINISHGRADE, // Finish with at least grade [grade] + UCRP_FINISHTIME, // Finish <= [time, tics] UCRP_FINISHTIMEEXACT, // Finish == [time, tics] UCRP_FINISHTIMELEFT, // Finish with at least [time, tics] to spare