Add string variable for unlockables and emblems

Skin unlockables / skin emblems are now checked at runtime to see if there's any matches.
This commit is contained in:
Sally Coolatta 2021-04-25 17:54:47 -04:00
parent f0b9e0e415
commit 92107f28d5
10 changed files with 140 additions and 33 deletions

View file

@ -1313,8 +1313,9 @@ static void SendNameAndColor(void)
cv_skin.value = R_SkinAvailable(cv_skin.string);
if ((cv_skin.value < 0) || !R_SkinUsable(consoleplayer, cv_skin.value))
{
CV_StealthSet(&cv_skin, DEFAULTSKIN);
cv_skin.value = 0;
INT32 defaultSkinNum = GetPlayerDefaultSkin(consoleplayer);
CV_StealthSet(&cv_skin, skins[defaultSkinNum].name);
cv_skin.value = defaultSkinNum;
}
// Finally write out the complete packet and send it off.

View file

@ -127,6 +127,33 @@ static float searchfvalue(const char *s)
#endif
// These are for clearing all of various things
void clear_emblems(void)
{
INT32 i;
for (i = 0; i < MAXEMBLEMS; ++i)
{
Z_Free(emblemlocations[i].stringVar);
emblemlocations[i].stringVar = NULL;
}
memset(&emblemlocations, 0, sizeof(emblemlocations));
numemblems = 0;
}
void clear_unlockables(void)
{
INT32 i;
for (i = 0; i < MAXUNLOCKABLES; ++i)
{
Z_Free(unlockables[i].stringVar);
unlockables[i].stringVar = NULL;
}
memset(&unlockables, 0, sizeof(unlockables));
}
void clear_conditionsets(void)
{
UINT8 i;
@ -3017,7 +3044,12 @@ void reademblemdata(MYFILE *f, INT32 num)
else if (fastcmp(word, "COLOR"))
emblemlocations[num-1].color = get_number(word2);
else if (fastcmp(word, "VAR"))
{
Z_Free(emblemlocations[num-1].stringVar);
emblemlocations[num-1].stringVar = Z_StrDup(word2);
emblemlocations[num-1].var = get_number(word2);
}
else
deh_warning("Emblem %d: unknown word '%s'", num, word);
}
@ -3226,14 +3258,9 @@ void readunlockable(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "VAR"))
{
INT32 skinnum = R_SkinAvailable(word2);
Z_Free(unlockables[num].stringVar);
unlockables[num].stringVar = Z_StrDup(word2);
if (skinnum != -1)
{
unlockables[num].variable = (INT16)skinnum;
}
else
{
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
@ -3243,7 +3270,6 @@ void readunlockable(MYFILE *f, INT32 num)
unlockables[num].variable = (INT16)i;
}
}
else
deh_warning("Unlockable %d: unknown word '%s'", num+1, word);
}

View file

@ -84,6 +84,8 @@ void readskincolor(MYFILE *f, INT32 num);
void readthing(MYFILE *f, INT32 num);
void readfreeslots(MYFILE *f);
void readPlayer(MYFILE *f, INT32 num);
void clear_emblems(void);
void clear_unlockables(void);
void clear_levels(void);
void clear_conditionsets(void);
#endif

View file

@ -562,13 +562,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
}
if (clearall || fastcmp(word2, "UNLOCKABLES"))
memset(&unlockables, 0, sizeof(unlockables));
clear_unlockables();
if (clearall || fastcmp(word2, "EMBLEMS"))
{
memset(&emblemlocations, 0, sizeof(emblemlocations));
numemblems = 0;
}
clear_emblems();
if (clearall || fastcmp(word2, "EXTRAEMBLEMS"))
{

View file

@ -496,6 +496,54 @@ UINT8 M_GotHighEnoughRings(INT32 trings)
return false;
}
// Gets the skin number for a SECRET_SKIN unlockable.
INT32 M_UnlockableSkinNum(unlockable_t *unlock)
{
if (unlock->type != SECRET_SKIN)
{
// This isn't a skin unlockable...
return -1;
}
if (unlock->stringVar && strcmp(unlock->stringVar, ""))
{
// Get the skin from the string.
return R_SkinAvailable(unlock->stringVar);
}
else if (unlock->variable >= 0 && unlock->variable < numskins)
{
// Use the number directly.
return unlock->variable;
}
// Invalid skin unlockable.
return -1;
}
// Gets the skin number for a ET_SKIN emblem.
INT32 M_EmblemSkinNum(emblem_t *emblem)
{
if (emblem->type != ET_SKIN)
{
// This isn't a skin emblem...
return -1;
}
if (emblem->stringVar && strcmp(emblem->stringVar, ""))
{
// Get the skin from the string.
return R_SkinAvailable(emblem->stringVar);
}
else if (emblem->var >= 0 && emblem->var < numskins)
{
// Use the number directly.
return emblem->var;
}
// Invalid skin emblem.
return -1;
}
// ----------------
// Misc Emblem shit
// ----------------

View file

@ -92,6 +92,7 @@ typedef struct
UINT8 sprite; ///< emblem sprite to use, 0 - 25
UINT16 color; ///< skincolor to use
INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin)
char *stringVar; ///< String version
char hint[110]; ///< Hint for emblem hints menu
UINT8 collected; ///< Do you have this emblem?
} emblem_t;
@ -116,6 +117,7 @@ typedef struct
UINT8 showconditionset;
INT16 type;
INT16 variable;
char *stringVar;
UINT8 nocecho;
UINT8 nochecklist;
UINT8 unlocked;
@ -186,4 +188,7 @@ UINT8 M_GotHighEnoughScore(INT32 tscore);
UINT8 M_GotLowEnoughTime(INT32 tictime);
UINT8 M_GotHighEnoughRings(INT32 trings);
INT32 M_UnlockableSkinNum(unlockable_t *unlock);
INT32 M_EmblemSkinNum(emblem_t *emblem);
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved)

View file

@ -5115,11 +5115,16 @@ static boolean SignSkinCheck(player_t *player, INT32 num)
// Player invalid, only show characters that are unlocked from the start.
for (i = 0; i < MAXUNLOCKABLES; i++)
{
if (unlockables[i].type == SECRET_SKIN && unlockables[i].variable == num)
if (unlockables[i].type == SECRET_SKIN)
{
INT32 lockedSkin = M_UnlockableSkinNum(&unlockables[i]);
if (lockedSkin == num)
{
return false;
}
}
}
return true;
}

View file

@ -11964,6 +11964,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
INT32 j;
emblem_t* emblem = M_GetLevelEmblems(gamemap);
skincolornum_t emcolor;
boolean validEmblem = true;
while (emblem)
{
@ -11988,8 +11989,19 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting
mobj->color = (UINT16)emcolor;
if (emblemlocations[j].collected
|| (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin))
validEmblem = !emblemlocations[j].collected;
if (emblemlocations[j].type == ET_SKIN)
{
INT32 skinnum = M_EmblemSkinNum(&emblemlocations[j]);
if (players[0].skin != skinnum)
{
validEmblem = false;
}
}
if (validEmblem == false)
{
P_UnsetThingPosition(mobj);
mobj->flags |= MF_NOCLIP;

View file

@ -247,12 +247,16 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
for (i = 0; i < MAXUNLOCKABLES; i++)
{
INT32 unlockSkin = -1;
if (unlockables[i].type != SECRET_SKIN)
{
continue;
}
if (unlockables[i].variable == skinnum)
unlockSkin = M_UnlockableSkinNum(&unlockables[i]);
if (unlockSkin == skinnum)
{
unlockID = i;
break;
@ -294,8 +298,7 @@ INT32 R_SkinAvailable(const char *name)
return -1;
}
// Gets the player to the first usuable skin in the game. (If your mod locked them all, then you kinda stupid)
void SetPlayerDefaultSkin(INT32 playernum)
INT32 GetPlayerDefaultSkin(INT32 playernum)
{
INT32 i;
@ -303,12 +306,18 @@ void SetPlayerDefaultSkin(INT32 playernum)
{
if (R_SkinUsable(playernum, i))
{
SetPlayerSkinByNum(playernum, i);
return;
return i;
}
}
I_Error("All characters are locked.");
I_Error("All characters are locked!");
return 0;
}
// Gets the player to the first usuable skin in the game. (If your mod locked them all, then you kinda stupid)
void SetPlayerDefaultSkin(INT32 playernum)
{
SetPlayerSkinByNum(playernum, GetPlayerDefaultSkin(playernum));
}
// network code calls this when a 'skin change' is received
@ -325,7 +334,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname)
if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname);
else if(server || IsPlayerAdmin(consoleplayer))
else if (server || IsPlayerAdmin(consoleplayer))
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
SetPlayerDefaultSkin(playernum);
@ -417,7 +426,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum);
else if(server || IsPlayerAdmin(consoleplayer))
else if (server || IsPlayerAdmin(consoleplayer))
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
SetPlayerDefaultSkin(playernum);

View file

@ -89,6 +89,8 @@ extern skin_t skins[MAXSKINS];
/// Function prototypes
void R_InitSkins(void);
INT32 GetPlayerDefaultSkin(INT32 playernum);
void SetPlayerDefaultSkin(INT32 playernum);
void SetPlayerSkin(INT32 playernum,const char *skinname);
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
boolean R_SkinUsable(INT32 playernum, INT32 skinnum);