Add UCRP_MAKERETIRE

- `Condition1 = MakeRetire Eggrobo`
- Fires when:
    - Not a cooperative context
    - You've finished in good standing
    - Another player has both
        - PF_NOCONTEST
        - The skin specified in the condition
Also makes rivalname-handling for K_InitGrandPrixBots `const char *`, since the author of this commit had to reference that code.
This commit is contained in:
toaster 2023-10-05 14:36:00 +01:00
parent 764141946d
commit b937b1a7bc
4 changed files with 73 additions and 1 deletions

View file

@ -2777,6 +2777,13 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
//PARAMCHECK(1);
ty = UCRP_FINISHCOOL + offset;
}
else if (fastcmp(params[0], "MAKERETIRE"))
{
PARAMCHECK(1);
ty = UCRP_MAKERETIRE;
stringvar = Z_StrDup(params[1]);
re = -1;
}
else if ((offset=0) || fastcmp(params[0], "FINISHPLACE")
|| (++offset && fastcmp(params[0], "FINISHPLACEEXACT")))
{

View file

@ -217,7 +217,7 @@ void K_InitGrandPrixBots(void)
for (j = 0; j < numplayers; j++)
{
player_t *p = &players[competitors[j]];
char *rivalname = skins[p->skin].rivals[i];
const char *rivalname = skins[p->skin].rivals[i];
INT32 rivalnum = R_SkinAvailable(rivalname);
// Intentionally referenced before (currently dummied out) unlock check. Such a tease!

View file

@ -864,6 +864,7 @@ void M_UpdateConditionSetsPending(void)
{
case UC_CHARACTERWINS:
case UCRP_ISCHARACTER:
case UCRP_MAKERETIRE:
{
cn->requirement = R_SkinAvailable(cn->stringvar);
@ -1153,6 +1154,58 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
&& numtargets >= maptargets);
case UCRP_NOCONTEST:
return (player->pflags & PF_NOCONTEST);
case UCRP_MAKERETIRE:
{
// You can't "make" someone retire in coop.
if (K_Cooperative() == true)
{
return false;
}
// The following is basically UCRP_FINISHCOOL,
// but without the M_NotFreePlay check since this
// condition is already dependent on other players.
if ((player->exiting
&& !(player->pflags & PF_NOCONTEST)
&& !K_IsPlayerLosing(player)) == false)
{
return false;
}
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] == false)
{
continue;
}
// This player is ME!
if (player == players+i)
{
continue;
}
// This player didn't NO CONTEST.
if (!(players[i].pflags & PF_NOCONTEST))
{
continue;
}
// This player doesn't have the right skin.
if (players[i].skin != cn->requirement)
{
continue;
}
// Okay, the right player is dead!
break;
}
return (i != MAXPLAYERS);
}
case UCRP_FINISHPLACE:
return (player->exiting
&& !(player->pflags & PF_NOCONTEST)
@ -1748,6 +1801,16 @@ static const char *M_GetConditionString(condition_t *cn)
return "break every prison";
case UCRP_NOCONTEST:
return "NO CONTEST";
case UCRP_MAKERETIRE:
{
if (cn->requirement < 0 || !skins[cn->requirement].realname[0])
return va("INVALID CHAR CONDITION \"%d:%d\"", cn->type, cn->requirement);
work = M_GetConditionCharacter(cn->requirement, false);
return va("make %s retire", work);
}
case UCRP_FINISHPLACE:
case UCRP_FINISHPLACEEXACT:
return va("finish in %d%s%s", cn->requirement, M_GetNthType(cn->requirement),

View file

@ -89,6 +89,8 @@ typedef enum
UCRP_FINISHALLPRISONS, // Break all prisons
UCRP_NOCONTEST, // No Contest
UCRP_MAKERETIRE, // Make another player of [skin] No Contest
UCRP_FINISHPLACE, // Finish at least [place]
UCRP_FINISHPLACEEXACT, // Finish at [place] exactly