mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-09 20:56:43 +00:00
readcondition: Support non-fragmented parameters that can be used for the Challenge Description directly
- "DescriptionOverride" (new!)
- Provide a full description in place of the params and this will be used
- Any conditions that are before it will not be wiped, so you can prefix it if you need to
- Can be used with any other set of Conditions
- `Condition1 = DescriptionOverride Complete the sentence: "ring racers (???)"`
- "Password"
- Now supports passwords that contain spaces
- `Condition1 = Password race as a ring!`
- "WetPlayer"
- Now supports liquids that contain spaces
- HOWEVER, it comes with the following caveats as part of the change:
- The strictness level must be provided first.
- You can't leave the strictness out. The previous default behaviour now requires STANDARD to be explicitly written.
- `Condition1 = WetPlayer Standard Mega Mack` can be used, now.
This commit is contained in:
parent
7d5f0ea3ba
commit
1c4750a0a2
3 changed files with 114 additions and 69 deletions
167
src/deh_soc.c
167
src/deh_soc.c
|
|
@ -72,6 +72,8 @@ fixed_t get_number(const char *word)
|
|||
|
||||
#define PARAMCHECK(n) do { if (!params[n]) { deh_warning("Too few parameters, need %d", n); return; }} while (0)
|
||||
|
||||
#define EXTENDEDPARAMCHECK(spos, n) do { if (!spos || !(*spos)) { deh_warning("Missing extended parameter, need at least %d", n); return; }} while (0)
|
||||
|
||||
/* ======================================================================== */
|
||||
// Load a dehacked file format
|
||||
/* ======================================================================== */
|
||||
|
|
@ -2421,43 +2423,121 @@ void readunlockable(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
// This is a home-grown strtok(" ") equivalent so we can isolate the first chunk without destroying the rest of the line.
|
||||
static void conditiongetparam(char **params, UINT8 paramid, char **spos)
|
||||
{
|
||||
if (*spos == NULL || *(*spos) == '\0')
|
||||
{
|
||||
params[paramid] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
params[paramid] = *spos;
|
||||
while (*(*spos) != '\0' && *(*spos) != ' ')
|
||||
{
|
||||
*(*spos) = toupper(*(*spos));
|
||||
(*spos)++;
|
||||
}
|
||||
if (*(*spos) == ' ')
|
||||
{
|
||||
*(*spos) = '\0';
|
||||
(*spos)++;
|
||||
|
||||
while (*(*spos) == ' ')
|
||||
(*spos)++;
|
||||
}
|
||||
}
|
||||
|
||||
static void readcondition(UINT16 set, UINT32 id, char *word2)
|
||||
{
|
||||
INT32 i;
|
||||
char *params[5]; // condition, requirement, extra info, extra info, stringvar
|
||||
char *spos;
|
||||
const UINT8 MAXCONDITIONPARAMS = 5;
|
||||
char *params[MAXCONDITIONPARAMS]; // condition, requirement, extra info, extra info, stringvar
|
||||
char *spos = NULL;
|
||||
char *stringvar = NULL;
|
||||
|
||||
conditiontype_t ty;
|
||||
conditiontype_t ty = UC_NONE;
|
||||
INT32 re = 0;
|
||||
INT16 x1 = 0, x2 = 0;
|
||||
|
||||
INT32 offset = 0;
|
||||
|
||||
#if 0
|
||||
char *endpos = word2 + strlen(word2);
|
||||
#endif
|
||||
|
||||
spos = strtok(word2, " ");
|
||||
|
||||
for (i = 0; i < 5; ++i)
|
||||
// Lop the leading spaces off
|
||||
if (word2 && *word2)
|
||||
{
|
||||
if (spos != NULL)
|
||||
{
|
||||
params[i] = spos;
|
||||
spos = strtok(NULL, " ");
|
||||
}
|
||||
else
|
||||
params[i] = NULL;
|
||||
spos = word2;
|
||||
while (*spos == ' ')
|
||||
spos++;
|
||||
}
|
||||
|
||||
conditiongetparam(params, 0, &spos);
|
||||
|
||||
if (!params[0])
|
||||
{
|
||||
deh_warning("condition line is empty for condition ID %d", id+1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fastcmp(params[0], "PLAYTIME"))
|
||||
// We do free descriptions first.
|
||||
|
||||
if (fastcmp(params[0], "DESCRIPTIONOVERRIDE"))
|
||||
{
|
||||
EXTENDEDPARAMCHECK(spos, 1);
|
||||
ty = UC_DESCRIPTIONOVERRIDE;
|
||||
|
||||
stringvar = Z_StrDup(spos);
|
||||
}
|
||||
else if (fastcmp(params[0], "PASSWORD"))
|
||||
{
|
||||
EXTENDEDPARAMCHECK(spos, 1);
|
||||
ty = UC_PASSWORD;
|
||||
|
||||
stringvar = Z_StrDup(spos);
|
||||
re = -1;
|
||||
}
|
||||
|
||||
if (ty != UC_NONE)
|
||||
goto setcondition;
|
||||
|
||||
// Now conditions that take one standard param and one free description.
|
||||
|
||||
conditiongetparam(params, 1, &spos);
|
||||
|
||||
if (fastcmp(params[0], "WETPLAYER"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
//EXTENDEDPARAMCHECK(spos, 2);
|
||||
ty = UCRP_WETPLAYER;
|
||||
re = MFE_UNDERWATER;
|
||||
x1 = 1;
|
||||
|
||||
if (fastcmp(params[1], "STRICT"))
|
||||
re |= MFE_TOUCHWATER;
|
||||
else if (fastcmp(params[1], "STANDARD"))
|
||||
;
|
||||
else
|
||||
{
|
||||
deh_warning("liquid strictness requirement \"%s\" invalid for condition ID %d", params[1], id+1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (spos && *spos)
|
||||
stringvar = Z_StrDup(spos);
|
||||
}
|
||||
|
||||
if (ty != UC_NONE)
|
||||
goto setcondition;
|
||||
|
||||
// Now for all other conditions.
|
||||
|
||||
for (i = 2; i < MAXCONDITIONPARAMS; i++)
|
||||
{
|
||||
conditiongetparam(params, i, &spos);
|
||||
}
|
||||
|
||||
if (ty != UC_NONE)
|
||||
;
|
||||
else if (fastcmp(params[0], "PLAYTIME"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
ty = UC_PLAYTIME + offset;
|
||||
|
|
@ -2627,13 +2707,6 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
//PARAMCHECK(1);
|
||||
ty = UC_ADDON + offset;
|
||||
}
|
||||
else if (fastcmp(params[0], "PASSWORD"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
ty = UC_PASSWORD;
|
||||
stringvar = Z_StrDup(params[1]);
|
||||
re = -1;
|
||||
}
|
||||
else if (fastcmp(params[0], "SPRAYCAN"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
|
|
@ -2844,27 +2917,6 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
deh_warning("Trigger ID %d out of range (0 - 31) for condition ID %d", re, id+1);
|
||||
return;
|
||||
}
|
||||
|
||||
// The following undid the effects of strtok.
|
||||
// Unfortunately, there is no way it can reasonably undo the effects of strupr.
|
||||
// If we want custom descriptions for map execution triggers, we're gonna need a different method.
|
||||
#if 0
|
||||
// undo affect of strtok
|
||||
i = 5;
|
||||
// so spos will still be the strtok from earlier
|
||||
while (i >= 2)
|
||||
{
|
||||
if (!spos)
|
||||
continue;
|
||||
while (*spos != '\0')
|
||||
spos++;
|
||||
if (spos < endpos)
|
||||
*spos = ' ';
|
||||
spos = params[--i];
|
||||
}
|
||||
|
||||
stringvar = Z_StrDup(params[2]);
|
||||
#endif
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "FALLOFF")
|
||||
|| (++offset && fastcmp(params[0], "TOUCHOFFROAD"))
|
||||
|
|
@ -2886,32 +2938,13 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
//PARAMCHECK(1);
|
||||
ty = UCRP_TRIPWIREHYUU + offset;
|
||||
}
|
||||
else if (fastcmp(params[0], "WETPLAYER"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
ty = UCRP_WETPLAYER;
|
||||
re = MFE_UNDERWATER;
|
||||
x1 = 1;
|
||||
|
||||
if (params[2])
|
||||
{
|
||||
if (fastcmp(params[2], "STRICT"))
|
||||
re |= MFE_TOUCHWATER;
|
||||
else
|
||||
{
|
||||
deh_warning("liquid strictness requirement \"%s\" invalid for condition ID %d", params[2], id+1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stringvar = Z_StrDup(params[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Invalid condition name %s for condition ID %d", params[0], id+1);
|
||||
return;
|
||||
}
|
||||
|
||||
setcondition:
|
||||
M_AddRawCondition(set, (UINT8)id, ty, re, x1, x2, stringvar);
|
||||
}
|
||||
|
||||
|
|
@ -2954,7 +2987,7 @@ void readconditionset(MYFILE *f, UINT16 setnum)
|
|||
|
||||
// Now get the part after
|
||||
word2 = tmp += 2;
|
||||
strupr(word2);
|
||||
//strupr(word2);
|
||||
|
||||
if (fastncmp(word, "CONDITION", 9))
|
||||
{
|
||||
|
|
|
|||
13
src/m_cond.c
13
src/m_cond.c
|
|
@ -1241,6 +1241,8 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
{
|
||||
switch (cn->type)
|
||||
{
|
||||
case UC_NONE:
|
||||
return false;
|
||||
case UC_PLAYTIME: // Requires total playing time >= x
|
||||
return (gamedata->totalplaytime >= (unsigned)cn->requirement);
|
||||
case UC_ROUNDSPLAYED: // Requires any level completed >= x times
|
||||
|
|
@ -1359,6 +1361,7 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
// Just for string building
|
||||
case UC_AND:
|
||||
case UC_COMMA:
|
||||
case UC_DESCRIPTIONOVERRIDE:
|
||||
return true;
|
||||
|
||||
case UCRP_PREFIX_GRANDPRIX:
|
||||
|
|
@ -1550,7 +1553,7 @@ static boolean M_CheckConditionSet(conditionset_t *c, player_t *player)
|
|||
continue;
|
||||
|
||||
// Skip entries that are JUST for string building
|
||||
if (cn->type == UC_AND || cn->type == UC_COMMA)
|
||||
if (cn->type == UC_AND || cn->type == UC_COMMA || cn->type == UC_DESCRIPTIONOVERRIDE)
|
||||
continue;
|
||||
|
||||
lastID = cn->id;
|
||||
|
|
@ -1962,6 +1965,8 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
return "&";
|
||||
case UC_COMMA:
|
||||
return ",";
|
||||
case UC_DESCRIPTIONOVERRIDE:
|
||||
return cn->stringvar;
|
||||
|
||||
case UCRP_PREFIX_GRANDPRIX:
|
||||
return "GRAND PRIX:";
|
||||
|
|
@ -2140,7 +2145,7 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
case UCRP_WETPLAYER:
|
||||
return va("without %s %s",
|
||||
(cn->requirement & MFE_TOUCHWATER) ? "touching any" : "going into",
|
||||
cn->stringvar);
|
||||
(cn->stringvar) ? cn->stringvar : "water");
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
@ -2208,6 +2213,10 @@ char *M_BuildConditionSetString(UINT16 unlockid)
|
|||
stopasap = true;
|
||||
work = "???";
|
||||
}
|
||||
else if (cn->type == UC_DESCRIPTIONOVERRIDE)
|
||||
{
|
||||
stopasap = true;
|
||||
}
|
||||
worklen = strlen(work);
|
||||
|
||||
strncat(message, work, len);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ extern "C" {
|
|||
// [required] <optional>
|
||||
typedef enum
|
||||
{
|
||||
UC_NONE,
|
||||
|
||||
UC_PLAYTIME, // PLAYTIME [tics]
|
||||
UC_ROUNDSPLAYED, // ROUNDSPLAYED [x played]
|
||||
UC_TOTALRINGS, // TOTALRINGS [x collected]
|
||||
|
|
@ -68,6 +70,7 @@ typedef enum
|
|||
// Just for string building
|
||||
UC_AND,
|
||||
UC_COMMA,
|
||||
UC_DESCRIPTIONOVERRIDE,
|
||||
|
||||
UCRP_REQUIRESPLAYING, // All conditions below this can only be checked if (Playing() && gamestate == GS_LEVEL).
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue