mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-27 07:51:36 +00:00
UCRP_TRIGGER: Convert to roundconditions_t
- Previously was extern scope UINT32 for all players, but this permits one player in a netgame taking a secret path while others don't. - Attempted to make user-specifiable string, but while I can undo the effects of strtok for the condition, I cannot undo the effects of strupr - so it's disabled for now until we come up with a more robust and hopefully direct system. - Also removed some old SRB2-originated assumptions that you couldn't unlock anything in multiplayer from the unlocktrigger system.
This commit is contained in:
parent
42a985d061
commit
4802f96249
7 changed files with 63 additions and 36 deletions
|
|
@ -1162,6 +1162,7 @@ bool CallFunc_HaveUnlockableTrigger(ACSVM::Thread *thread, const ACSVM::Word *ar
|
|||
{
|
||||
UINT8 id = 0;
|
||||
bool unlocked = false;
|
||||
auto info = &static_cast<Thread *>(thread)->info;
|
||||
|
||||
(void)argC;
|
||||
|
||||
|
|
@ -1171,9 +1172,11 @@ bool CallFunc_HaveUnlockableTrigger(ACSVM::Thread *thread, const ACSVM::Word *ar
|
|||
{
|
||||
CONS_Printf("Bad unlockable trigger ID %d\n", id);
|
||||
}
|
||||
else
|
||||
else if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
unlocked = (unlocktriggers & (1 << id));
|
||||
unlocked = (info->mo->player->roundconditions.unlocktriggers & (1 << id));
|
||||
}
|
||||
|
||||
thread->dataStk.push(unlocked);
|
||||
|
|
|
|||
|
|
@ -348,6 +348,9 @@ struct roundconditions_t
|
|||
boolean hit_midair;
|
||||
|
||||
mobjeflag_t wet_player;
|
||||
|
||||
// 32 triggers, one bit each, for map execution
|
||||
UINT32 unlocktriggers;
|
||||
};
|
||||
|
||||
// player_t struct for all skybox variables
|
||||
|
|
|
|||
|
|
@ -2346,6 +2346,10 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
INT32 offset = 0;
|
||||
|
||||
#if 0
|
||||
char *endpos = word2 + strlen(word2);
|
||||
#endif
|
||||
|
||||
spos = strtok(word2, " ");
|
||||
|
||||
for (i = 0; i < 5; ++i)
|
||||
|
|
@ -2473,19 +2477,6 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(params[0], "TRIGGER"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
ty = UC_TRIGGER;
|
||||
re = atoi(params[1]);
|
||||
|
||||
// constrained by 32 bits
|
||||
if (re < 0 || re > 31)
|
||||
{
|
||||
deh_warning("Trigger ID %d out of range (0 - 31) for condition ID %d", re, id+1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(params[0], "TOTALMEDALS"))
|
||||
{
|
||||
PARAMCHECK(1);
|
||||
|
|
@ -2617,6 +2608,40 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(params[0], "TRIGGER"))
|
||||
{
|
||||
PARAMCHECK(2); // strictly speaking at LEAST two
|
||||
ty = UCRP_TRIGGER;
|
||||
re = atoi(params[1]);
|
||||
|
||||
// constrained by 32 bits
|
||||
if (re < 0 || re > 31)
|
||||
{
|
||||
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];
|
||||
}
|
||||
#endif
|
||||
|
||||
stringvar = Z_StrDup(params[2]);
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "FALLOFF")
|
||||
|| (++offset && fastcmp(params[0], "TOUCHOFFROAD"))
|
||||
|| (++offset && fastcmp(params[0], "TOUCHSNEAKERPANEL"))
|
||||
|
|
|
|||
|
|
@ -5096,9 +5096,6 @@ void G_InitNew(UINT8 pencoremode, INT32 map, boolean resetplayer, boolean skippr
|
|||
}
|
||||
}
|
||||
|
||||
// Reset unlockable triggers
|
||||
unlocktriggers = 0;
|
||||
|
||||
// clear itemfinder, just in case
|
||||
if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
|
||||
CV_StealthSetValue(&cv_itemfinder, 0);
|
||||
|
|
|
|||
12
src/m_cond.c
12
src/m_cond.c
|
|
@ -35,10 +35,6 @@
|
|||
gamedata_t *gamedata = NULL;
|
||||
boolean netUnlocked[MAXUNLOCKABLES];
|
||||
|
||||
// Map triggers for linedef executors
|
||||
// 32 triggers, one bit each
|
||||
UINT32 unlocktriggers;
|
||||
|
||||
// The meat of this system lies in condition sets
|
||||
conditionset_t conditionSets[MAXCONDITIONSETS];
|
||||
|
||||
|
|
@ -704,8 +700,6 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
}
|
||||
case UC_MAPTIME: // Requires time on map <= x
|
||||
return (G_GetBestTime(cn->extrainfo1) <= (unsigned)cn->requirement);
|
||||
case UC_TRIGGER: // requires map trigger set
|
||||
return !!(unlocktriggers & (1 << cn->requirement));
|
||||
case UC_TOTALMEDALS: // Requires number of emblems >= x
|
||||
return (M_GotEnoughMedals(cn->requirement));
|
||||
case UC_EMBLEM: // Requires emblem x to be obtained
|
||||
|
|
@ -791,6 +785,9 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
|
|||
&& player->realtime < timelimitintics
|
||||
&& (timelimitintics + extratimeintics + secretextratime - player->realtime) >= (unsigned)cn->requirement);
|
||||
|
||||
case UCRP_TRIGGER: // requires map trigger set
|
||||
return !!(player->roundconditions.unlocktriggers & (1 << cn->requirement));
|
||||
|
||||
case UCRP_FALLOFF:
|
||||
return (player->roundconditions.fell_off == (cn->requirement == 1));
|
||||
case UCRP_TOUCHOFFROAD:
|
||||
|
|
@ -1176,6 +1173,9 @@ static const char *M_GetConditionString(condition_t *cn)
|
|||
G_TicsToSeconds(cn->requirement),
|
||||
G_TicsToCentiseconds(cn->requirement));
|
||||
|
||||
case UCRP_TRIGGER:
|
||||
return cn->stringvar;
|
||||
|
||||
case UCRP_FALLOFF:
|
||||
return (cn->requirement == 1) ? "fall off the course" : "without falling off";
|
||||
case UCRP_TOUCHOFFROAD:
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ typedef enum
|
|||
UC_MAPENCORE, // MAPENCORE [map]
|
||||
UC_MAPSPBATTACK, // MAPSPBATTACK [map]
|
||||
UC_MAPTIME, // MAPTIME [map] [time to beat, tics]
|
||||
UC_TRIGGER, // TRIGGER [trigger number]
|
||||
UC_TOTALMEDALS, // TOTALMEDALS [number of emblems]
|
||||
UC_EMBLEM, // EMBLEM [emblem number]
|
||||
UC_UNLOCKABLE, // UNLOCKABLE [unlockable number]
|
||||
|
|
@ -76,6 +75,8 @@ typedef enum
|
|||
UCRP_FINISHTIMEEXACT, // Finish == [time, tics]
|
||||
UCRP_FINISHTIMELEFT, // Finish with at least [time, tics] to spare
|
||||
|
||||
UCRP_TRIGGER, // Map execution trigger [id]
|
||||
|
||||
UCRP_FALLOFF, // Fall off (or don't)
|
||||
UCRP_TOUCHOFFROAD, // Touch offroad (or don't)
|
||||
UCRP_TOUCHSNEAKERPANEL, // Either touch sneaker panel (or don't)
|
||||
|
|
@ -262,8 +263,6 @@ extern unlockable_t unlockables[MAXUNLOCKABLES];
|
|||
|
||||
extern INT32 numemblems;
|
||||
|
||||
extern UINT32 unlocktriggers;
|
||||
|
||||
void M_NewGameDataStruct(void);
|
||||
|
||||
// Challenges menu stuff
|
||||
|
|
|
|||
18
src/p_spec.c
18
src/p_spec.c
|
|
@ -1541,17 +1541,18 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
return false;
|
||||
break;
|
||||
case 317:
|
||||
if (actor && actor->player)
|
||||
{ // Unlockable triggers required
|
||||
INT32 trigid = triggerline->args[1];
|
||||
|
||||
if ((modifiedgame && !savemoddata) || (netgame || multiplayer))
|
||||
return false;
|
||||
else if (trigid < 0 || trigid > 31) // limited by 32 bit variable
|
||||
if (trigid < 0 || trigid > 31) // limited by 32 bit variable
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", triggerline->sidenum[0], trigid);
|
||||
return false;
|
||||
}
|
||||
else if (!(unlocktriggers & (1 << trigid)))
|
||||
else if (!(actor && actor->player))
|
||||
return false;
|
||||
else if (!(actor->player->roundconditions.unlocktriggers & (1 << trigid)))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -3296,26 +3297,25 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
|
|||
break;
|
||||
|
||||
case 441: // Trigger unlockable
|
||||
if (!(demo.playback || netgame || multiplayer))
|
||||
{
|
||||
INT32 trigid = args[0];
|
||||
|
||||
if (trigid < 0 || trigid > 31) // limited by 32 bit variable
|
||||
CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger: bad trigger ID %d\n", trigid);
|
||||
else
|
||||
else if (mo && mo->player)
|
||||
{
|
||||
UINT32 flag = 1 << trigid;
|
||||
|
||||
if (unlocktriggers & flag)
|
||||
if (mo->player->roundconditions.unlocktriggers & flag)
|
||||
{
|
||||
// Execute one time only
|
||||
break;
|
||||
}
|
||||
|
||||
unlocktriggers |= flag;
|
||||
mo->player->roundconditions.unlocktriggers |= flag;
|
||||
|
||||
// Unlocked something?
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
if (!demo.playback && M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
{
|
||||
gamedata->deferredsave = true; // only save if unlocked something
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue